Patch:vehicle_gypsy:Added patch from RedDog
authormartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>
Wed, 9 Jul 2008 21:28:31 +0000 (21:28 +0000)
committermartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>
Wed, 9 Jul 2008 21:28:31 +0000 (21:28 +0000)
git-svn-id: https://navit.svn.sourceforge.net/svnroot/navit/trunk/navit@1205 ffa7fe5e-494d-0410-b361-a75ebd5db220

configure.in
navit/vehicle/Makefile.am
navit/vehicle/gpsd/vehicle_gpsd.c
navit/vehicle/gypsy/Makefile.am [new file with mode: 0644]
navit/vehicle/gypsy/vehicle_gypsy.c [new file with mode: 0644]

index 59898f8..0831683 100644 (file)
@@ -62,6 +62,7 @@ fi
 AM_CONDITIONAL(USE_HILDON, test "${enable_hildon}" = "xyes")
 
 AC_ARG_ENABLE(libgps, [  --disable-libgps             don't use libgps], USE_LIBGPS=$enableval, USE_LIBGPS=yes)
+AC_ARG_ENABLE(gypsy, [  --disable-gypsy             don't use gypsy], USE_GYPSY=$enableval, USE_GYPSY=yes)
 AC_ARG_ENABLE(garmin, [  --disable-garmin             disable garmin support], USE_GARMIN=$enableval, USE_GARMIN=yes)
 
 AC_ARG_ENABLE(samplemap, [  --disable-samplemap             don't build the samplemap], samplemap=$enableval, samplemap=yes)
@@ -371,6 +372,13 @@ AC_SUBST(CEGUI_LIBS)
 AM_CONDITIONAL(GUI_SDL, [test "x$sdl" = "xyes" -a "x$cegui" = "xyes" -a "x$opengl" = "xyes" -a "x$glc" = "xyes" -a "x$xmu" = "xyes" ])
 AM_CONDITIONAL(GRAPHICS_OPENGL, [test "x$opengl" = "xyes" -a "x$glc" = "xyes" ])
 
+if test x"${USE_GYPSY}" = xyes
+then
+       PKG_CHECK_MODULES(GYPSY, gypsy, use_gypsy=yes, use_gypsy=no)
+       AC_SUBST(GYPSY_CFLAGS)
+       AC_SUBST(GYPSY_LIBS)
+fi
+AM_CONDITIONAL(VEHICLE_GYPSY, [test "x$use_gypsy" = "xyes"])
 
 if test x"${USE_LIBGPS}" = xyes
 then
@@ -562,6 +570,7 @@ navit/speech/speech_dispatcher/Makefile
 navit/vehicle/Makefile
 navit/vehicle/file/Makefile
 navit/vehicle/gpsd/Makefile
+navit/vehicle/gypsy/Makefile
 navit/vehicle/demo/Makefile
 navit/xpm/Makefile
 navit/maps/Makefile
@@ -616,6 +625,12 @@ if test x"$enable_hildon" = xyes
         echo "Maemo/Hildon: DISABLED"
 fi
 
+if test x"$use_gypsy" = xyes
+       then
+       echo "Gypsy support: ENABLED"
+       else
+       echo "Gypsy support: DISABLED"
+fi
 if test x"$gpsd" = xyes
        then
        echo "GPSD support: ENABLED"
index 8901833..ae3a239 100644 (file)
@@ -2,3 +2,6 @@ SUBDIRS=demo file
 if VEHICLE_GPSD
   SUBDIRS += gpsd
 endif
+if VEHICLE_GYPSY
+  SUBDIRS += gypsy
+endif
index 8a8c8dd..5c39379 100644 (file)
@@ -234,7 +234,7 @@ vehicle_gpsd_position_attr_get(struct vehicle_priv *priv,
        case attr_position_direction:
                attr->u.numd = &priv->direction;
                break;
-       case attr_position_sats:
+       case attr_position_qual:
                attr->u.num = priv->sats;
                break;
        case attr_position_sats_used:
diff --git a/navit/vehicle/gypsy/Makefile.am b/navit/vehicle/gypsy/Makefile.am
new file mode 100644 (file)
index 0000000..8291adb
--- /dev/null
@@ -0,0 +1,5 @@
+include $(top_srcdir)/Makefile.inc
+AM_CPPFLAGS = @NAVIT_CFLAGS@ -I$(top_srcdir)/navit -DMODULE=vehicle_gypsy
+modulevehicle_LTLIBRARIES = libvehicle_gypsy.la
+libvehicle_gypsy_la_SOURCES = vehicle_gypsy.c
+libvehicle_gypsy_la_LIBADD = @GYPSY_LIBS@
diff --git a/navit/vehicle/gypsy/vehicle_gypsy.c b/navit/vehicle/gypsy/vehicle_gypsy.c
new file mode 100644 (file)
index 0000000..fa7250a
--- /dev/null
@@ -0,0 +1,314 @@
+/**
+ * Navit, a modular navigation system.
+ * Copyright (C) 2005-2008 Navit Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#include <config.h>
+#include <gypsy/gypsy-device.h>
+#include <gypsy/gypsy-control.h>
+#include <gypsy/gypsy-course.h>
+#include <gypsy/gypsy-position.h>
+#include <gypsy/gypsy-satellite.h>
+#include <string.h>
+#include <glib.h>
+#include <math.h>
+#include "debug.h"
+#include "callback.h"
+#include "plugin.h"
+#include "coord.h"
+#include "item.h"
+#include "vehicle.h"
+
+static struct vehicle_priv {
+       char *source;
+       GypsyControl *control;
+       GypsyPosition *position;
+       GypsyDevice *device;
+       GypsyCourse *course;
+       GypsySatellite *satellite;
+       char *path;
+       struct callback_list *cbl;
+       guint retry_interval;
+       struct coord_geo geo;
+       double speed;
+       double direction;
+       double height;
+       int status;
+       int sats;
+       int sats_used;
+       guint retry_timer;
+} *vehicle_last;
+
+#define DEFAULT_RETRY_INTERVAL 10 // seconds
+#define MIN_RETRY_INTERVAL 1 // seconds
+
+static void
+vehicle_gypsy_fixstatus_changed(GypsyDevice *device,
+               gint fixstatus,
+               gpointer userdata)
+{
+       struct vehicle_priv *priv = vehicle_last;
+
+       if (fixstatus==GYPSY_DEVICE_FIX_STATUS_3D || 
+                       fixstatus==GYPSY_DEVICE_FIX_STATUS_2D)
+               priv->status=1; // from gpsd: 1=fix ; 2=DGPS fix
+       else
+               priv->status=0;
+
+       callback_list_call_0(priv->cbl);
+}
+
+static void 
+vehicle_gypsy_position_changed(GypsyPosition *position, 
+               GypsyPositionFields fields_set, int timestamp, 
+               double latitude, double longitude, double altitude, 
+               gpointer userdata)
+{
+       struct vehicle_priv *priv = vehicle_last;
+       int cb = FALSE;
+
+       if (fields_set & GYPSY_POSITION_FIELDS_LATITUDE)
+       {
+               cb = TRUE;
+               priv->geo.lat = latitude;
+       }
+       if (fields_set & GYPSY_POSITION_FIELDS_LONGITUDE)
+       {
+               cb = TRUE;
+               priv->geo.lng = longitude;
+       }
+       if (fields_set & GYPSY_POSITION_FIELDS_ALTITUDE)
+       {
+               cb = TRUE;
+               priv->height = altitude;
+       }
+
+       if (cb)
+               callback_list_call_0(priv->cbl);
+}
+
+static void 
+vehicle_gypsy_satellite_changed(GypsySatellite *satellite, 
+               GPtrArray *satellites,
+               gpointer userdata)
+{
+       struct vehicle_priv *priv = vehicle_last;
+
+       int i, sats, used=0;
+       
+       sats = satellites->len;
+       for (i = 0; i < sats; i++) {
+               GypsySatelliteDetails *details = satellites->pdata[i];
+               if (details->in_use)
+                       used++;
+       }
+
+       priv->sats_used = used;
+       priv->sats = sats;
+       
+       callback_list_call_0(priv->cbl);
+}
+
+static void 
+vehicle_gypsy_course_changed (GypsyCourse *course, 
+               GypsyCourseFields fields,
+               int timestamp,
+               double speed,
+               double direction,
+               double climb,
+               gpointer userdata)
+{
+       struct vehicle_priv *priv = vehicle_last;
+       int cb = FALSE;
+
+       if (fields & GYPSY_COURSE_FIELDS_SPEED)
+       {
+               priv->speed = speed;
+               cb = TRUE;
+       }
+       if (fields & GYPSY_COURSE_FIELDS_DIRECTION)
+       {
+               priv->direction = direction;
+               cb = TRUE;
+       }
+
+       if (cb)
+               callback_list_call_0(priv->cbl);
+}
+
+/**
+ * Attempt to open the gps device.
+ * Return FALSE if retry not required
+ * Return TRUE to try again
+ */
+static gboolean
+vehicle_gypsy_try_open(gpointer *data)
+{
+       struct vehicle_priv *priv = (struct vehicle_priv *)data;
+       char *source = g_strdup(priv->source);
+
+       GError *error = NULL;
+       
+       g_type_init();
+       priv->control = gypsy_control_get_default(); 
+       priv->path = gypsy_control_create(priv->control, source+8, &error); 
+       if (priv->path == NULL) { 
+               g_warning ("Error creating gypsy conrtol path for %s: %s", source+8, error->message); 
+               return TRUE; 
+       }
+       
+       priv->position = gypsy_position_new(priv->path);
+       g_signal_connect(priv->position, "position-changed", G_CALLBACK (vehicle_gypsy_position_changed), NULL);
+
+       priv->satellite = gypsy_satellite_new(priv->path);
+       g_signal_connect(priv->satellite, "satellites-changed", G_CALLBACK (vehicle_gypsy_satellite_changed), NULL);
+
+       priv->course = gypsy_course_new(priv->path);
+       g_signal_connect(priv->course, "course-changed", G_CALLBACK (vehicle_gypsy_course_changed), NULL);
+
+       priv->device = gypsy_device_new(priv->path);
+       g_signal_connect(priv->device, "fix-status-changed", G_CALLBACK (vehicle_gypsy_fixstatus_changed), NULL);
+
+       gypsy_device_start(priv->device, &error);
+       if (error != NULL) { 
+               g_warning ("Error starting gypsy for %s: %s", source+8, error->message); 
+               return TRUE;
+       }
+
+       vehicle_last = priv;
+       dbg(0,"gypsy connected to %d\n", source+8);
+       g_free(source);
+       return FALSE;
+}
+
+/**
+ * Open a connection to gypsy. Will re-try the connection if it fails
+ */
+static void
+vehicle_gypsy_open(struct vehicle_priv *priv)
+{
+       priv->retry_timer=0;
+       if (vehicle_gypsy_try_open((gpointer *)priv)) {
+               priv->retry_timer = g_timeout_add(priv->retry_interval*1000, (GSourceFunc)vehicle_gypsy_try_open, (gpointer *)priv);
+       }
+}
+
+static void
+vehicle_gypsy_close(struct vehicle_priv *priv)
+{
+       if (priv->retry_timer) {
+               g_source_remove(priv->retry_timer);
+               priv->retry_timer=0;
+       }
+       if (priv->path)
+               g_free(priv->path);
+       
+       if (priv->position)
+               g_free(priv->position);
+       
+       if (priv->satellite)
+               g_free(priv->satellite);
+
+       if (priv->course)
+               g_free(priv->course);
+
+       if (priv->device)
+               g_free(priv->device);
+       
+       if (priv->control)
+               g_object_unref(G_OBJECT (priv->control));
+}
+
+static void
+vehicle_gypsy_destroy(struct vehicle_priv *priv)
+{
+       vehicle_gypsy_close(priv);
+       if (priv->source)
+               g_free(priv->source);
+       g_free(priv);
+}
+
+static int
+vehicle_gypsy_position_attr_get(struct vehicle_priv *priv,
+                              enum attr_type type, struct attr *attr)
+{
+       switch (type) {
+       case attr_position_height:
+               attr->u.numd = &priv->height;
+               break;
+       case attr_position_speed:
+               attr->u.numd = &priv->speed;
+               break;
+       case attr_position_direction:
+               attr->u.numd = &priv->direction;
+               break;
+       case attr_position_qual:
+               attr->u.num = priv->sats;
+               break;
+       case attr_position_sats_used:
+               attr->u.num = priv->sats_used;
+               break;
+       case attr_position_coord_geo:
+               attr->u.coord_geo = &priv->geo;
+               break;
+       default:
+               return 0;
+       }
+       attr->type = type;
+       return 1;
+}
+
+struct vehicle_methods vehicle_gypsy_methods = {
+       vehicle_gypsy_destroy,
+       vehicle_gypsy_position_attr_get,
+};
+
+static struct vehicle_priv *
+vehicle_gypsy_new_gypsy(struct vehicle_methods
+                     *meth, struct callback_list
+                     *cbl, struct attr **attrs)
+{
+       struct vehicle_priv *ret;
+       struct attr *source, *retry_int;
+
+       dbg(1, "enter\n");
+       source = attr_search(attrs, NULL, attr_source);
+       ret = g_new0(struct vehicle_priv, 1);
+       ret->source = g_strdup(source->u.str);
+       retry_int = attr_search(attrs, NULL, attr_retry_interval);
+       if (retry_int) {
+               ret->retry_interval = retry_int->u.num;
+               if (ret->retry_interval < MIN_RETRY_INTERVAL) {
+                       dbg(0, "Retry interval %d too small, setting to %d\n", ret->retry_interval, MIN_RETRY_INTERVAL);
+                       ret->retry_interval = MIN_RETRY_INTERVAL;
+               }
+       } else {
+               dbg(0, "Retry interval not defined, setting to %d\n", DEFAULT_RETRY_INTERVAL);
+               ret->retry_interval = DEFAULT_RETRY_INTERVAL;
+       }
+       ret->cbl = cbl;
+       *meth = vehicle_gypsy_methods;
+       vehicle_gypsy_open(ret);
+       return ret;
+}
+
+void
+plugin_init(void)
+{
+       dbg(1, "enter\n");
+       plugin_register_vehicle_type("gypsy", vehicle_gypsy_new_gypsy);
+}