summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>2008-07-09 21:28:31 +0000
committermartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>2008-07-09 21:28:31 +0000
commitdcb159d7bb1d537475aa150daabba0d29bb8d4e4 (patch)
tree28a8e3432a2082c4b5dcae7a3dc05995f9094312
parent20d4d48c814b215296f4d220d2032acbeb27dd18 (diff)
downloadnavit-dcb159d7bb1d537475aa150daabba0d29bb8d4e4.tar.gz
Patch:vehicle_gypsy:Added patch from RedDog
git-svn-id: http://svn.code.sf.net/p/navit/code/trunk/navit@1205 ffa7fe5e-494d-0410-b361-a75ebd5db220
-rw-r--r--configure.in15
-rw-r--r--navit/vehicle/Makefile.am3
-rw-r--r--navit/vehicle/gpsd/vehicle_gpsd.c2
-rw-r--r--navit/vehicle/gypsy/Makefile.am5
-rw-r--r--navit/vehicle/gypsy/vehicle_gypsy.c314
5 files changed, 338 insertions, 1 deletions
diff --git a/configure.in b/configure.in
index 59898f807..0831683f6 100644
--- a/configure.in
+++ b/configure.in
@@ -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"
diff --git a/navit/vehicle/Makefile.am b/navit/vehicle/Makefile.am
index 8901833f8..ae3a23915 100644
--- a/navit/vehicle/Makefile.am
+++ b/navit/vehicle/Makefile.am
@@ -2,3 +2,6 @@ SUBDIRS=demo file
if VEHICLE_GPSD
SUBDIRS += gpsd
endif
+if VEHICLE_GYPSY
+ SUBDIRS += gypsy
+endif
diff --git a/navit/vehicle/gpsd/vehicle_gpsd.c b/navit/vehicle/gpsd/vehicle_gpsd.c
index 8a8c8dd40..5c39379bf 100644
--- a/navit/vehicle/gpsd/vehicle_gpsd.c
+++ b/navit/vehicle/gpsd/vehicle_gpsd.c
@@ -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
index 000000000..8291adb07
--- /dev/null
+++ b/navit/vehicle/gypsy/Makefile.am
@@ -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
index 000000000..fa7250aad
--- /dev/null
+++ b/navit/vehicle/gypsy/vehicle_gypsy.c
@@ -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);
+}