Add:Core:New vehicle type gpsd_dbus
authormartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>
Tue, 1 Dec 2009 19:20:27 +0000 (19:20 +0000)
committermartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>
Tue, 1 Dec 2009 19:20:27 +0000 (19:20 +0000)
git-svn-id: https://navit.svn.sourceforge.net/svnroot/navit/trunk/navit@2818 ffa7fe5e-494d-0410-b361-a75ebd5db220

configure.in
navit/vehicle/Makefile.am
navit/vehicle/gpsd_dbus/Makefile.am [new file with mode: 0644]
navit/vehicle/gpsd_dbus/vehicle_gpsd_dbus.c [new file with mode: 0644]

index de59ad9..c3ea643 100644 (file)
@@ -56,6 +56,7 @@ speech_speech_dispatcher=yes; speech_speech_dispatcher_reason=default
 vehicle_demo=yes; vehicle_demo_reason=default
 vehicle_file=yes; vehicle_file_reason=default
 vehicle_gpsd=yes; vehicle_gpsd_reason=default
+vehicle_gpsd_dbus=no; vehicle_gpsd_dbus_reason=default
 vehicle_gypsy=yes; vehicle_gypsy_reason=default
 vehicle_null=no; vehicle_null_reason=default
 vehicle_wince=no; vehicle_wince_reason=default
@@ -521,10 +522,13 @@ if test "x${binding_dbus}" = "xyes" ; then
 fi
 if test "x${binding_dbus}" = "xyes" ; then
        AC_DEFINE(USE_BINDING_DBUS, 1, [Build with binding dbus])
+       vehicle_gpsd_dbus="yes"
+       vehicle_gpsd_dbus_reason="dbus binding present"
 fi
 AC_SUBST(DBUS_CFLAGS)
 AC_SUBST(DBUS_LIBS)
 AM_CONDITIONAL(BINDING_DBUS, test "x${binding_dbus}" = "xyes")
+AM_CONDITIONAL(VEHICLE_GPSD_DBUS, test "x${vehicle_gpsd_dbus}" = "xyes")
 AC_ARG_WITH(dbus-service-dir, [ --with-dbus-service-dir   specify where the dbus service dir resides], DBUS_SERVICE_DIR=$withval, DBUS_SERVICE_DIR="$datarootdir/dbus-1/services")
 AC_SUBST(DBUS_SERVICE_DIR)
 
@@ -853,6 +857,7 @@ navit/vehicle/Makefile
 navit/vehicle/android/Makefile
 navit/vehicle/file/Makefile
 navit/vehicle/gpsd/Makefile
+navit/vehicle/gpsd_dbus/Makefile
 navit/vehicle/gypsy/Makefile
 navit/vehicle/null/Makefile
 navit/vehicle/demo/Makefile
@@ -952,6 +957,7 @@ echo "  android:           $vehicle_android ($vehicle_android_reason)"
 echo "  demo:              $vehicle_demo ($vehicle_demo_reason)"
 echo "  file:              $vehicle_file ($vehicle_file_reason)"
 echo "  gpsd:              $vehicle_gpsd ($vehicle_gpsd_reason)"
+echo "  gpsd_dbus:         $vehicle_gpsd_dbus ($vehicle_gpsd_dbus_reason)"
 echo "  gypsy:             $vehicle_gypsy ($vehicle_gypsy_reason)"
 echo "  null:              $vehicle_null ($vehicle_null_reason)"
 echo "  wince:             $vehicle_wince ($vehicle_wince_reason)"
index f9f803c..c3765fb 100644 (file)
@@ -14,6 +14,9 @@ endif
 if VEHICLE_GPSD
   SUBDIRS += gpsd
 endif
+if VEHICLE_GPSD_DBUS
+  SUBDIRS += gpsd_dbus
+endif
 if VEHICLE_GYPSY
   SUBDIRS += gypsy
 endif
diff --git a/navit/vehicle/gpsd_dbus/Makefile.am b/navit/vehicle/gpsd_dbus/Makefile.am
new file mode 100644 (file)
index 0000000..4685d2e
--- /dev/null
@@ -0,0 +1,6 @@
+include $(top_srcdir)/Makefile.inc
+AM_CPPFLAGS = @NAVIT_CFLAGS@ @DBUS_CFLAGS@ -I$(top_srcdir)/navit -DMODULE=vehicle_gpsd_dbus
+modulevehicle_LTLIBRARIES = libvehicle_gpsd_dbus.la
+libvehicle_gpsd_dbus_la_SOURCES = vehicle_gpsd_dbus.c
+libvehicle_gpsd_dbus_la_LIBADD = @DBUS_LIBS@
+libvehicle_gpsd_dbus_la_LDFLAGS = -module -avoid-version
diff --git a/navit/vehicle/gpsd_dbus/vehicle_gpsd_dbus.c b/navit/vehicle/gpsd_dbus/vehicle_gpsd_dbus.c
new file mode 100644 (file)
index 0000000..6b5ec8d
--- /dev/null
@@ -0,0 +1,245 @@
+/**
+ * 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 <gps.h>
+#include <string.h>
+#include <glib.h>
+#include <math.h>
+#define DBUS_API_SUBJECT_TO_CHANGE
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+#include <errno.h>
+#include "debug.h"
+#include "callback.h"
+#include "plugin.h"
+#include "coord.h"
+#include "item.h"
+#include "vehicle.h"
+#include "event.h"
+
+static char *vehicle_gpsd_dbus_prefix="gpsd_dbus:";
+
+struct vehicle_priv {
+       char *source;
+       char *address;
+       struct callback_list *cbl;
+       DBusConnection *connection;
+       double time, track, speed, altitude;
+       time_t fix_time;
+       struct coord_geo geo;
+       struct attr ** attrs;
+       char fixiso8601[128];
+};
+
+static void
+vehicle_gpsd_dbus_close(struct vehicle_priv *priv)
+{
+       if (priv->connection)
+               dbus_connection_unref(priv->connection);
+       priv->connection=NULL;
+}
+
+static DBusHandlerResult
+vehicle_gpsd_dbus_filter(DBusConnection *connection, DBusMessage *message, void *user_data)
+{
+       struct vehicle_priv *priv=user_data;
+       double time,ept,latitude,longitude,eph,altitude,epv,track,epd,speed,eps,climb,epc;
+       int mode;
+       char *devname;
+
+       if (dbus_message_is_signal(message, "org.gpsd","fix")) {
+               dbus_message_get_args (message, NULL,
+                       DBUS_TYPE_DOUBLE, &time,
+                       DBUS_TYPE_INT32,  &mode,
+                       DBUS_TYPE_DOUBLE, &ept,
+                       DBUS_TYPE_DOUBLE, &latitude,
+                       DBUS_TYPE_DOUBLE, &longitude,
+                       DBUS_TYPE_DOUBLE, &eph,
+                       DBUS_TYPE_DOUBLE, &altitude,
+                       DBUS_TYPE_DOUBLE, &epv,
+                       DBUS_TYPE_DOUBLE, &track,
+                       DBUS_TYPE_DOUBLE, &epd,
+                       DBUS_TYPE_DOUBLE, &speed,
+                       DBUS_TYPE_DOUBLE, &eps,
+                       DBUS_TYPE_DOUBLE, &climb,
+                       DBUS_TYPE_DOUBLE, &epc,
+                       DBUS_TYPE_STRING, &devname,
+                       DBUS_TYPE_INVALID);
+               if (latitude != FP_NAN && longitude != FP_NAN) {
+                       priv->geo.lat=latitude;
+                       priv->geo.lng=longitude;
+               }
+               if (track != FP_NAN)
+                       priv->track=track;
+               if (speed != FP_NAN)
+                       priv->speed=speed;
+               if (altitude != FP_NAN)
+                       priv->altitude=altitude;
+               if (time != priv->time) {
+                       priv->time=time;
+                       priv->fix_time=time;
+                       callback_list_call_attr_0(priv->cbl, attr_position_coord_geo);
+               }
+       }
+       return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+static int
+vehicle_gpsd_dbus_open(struct vehicle_priv *priv)
+{
+       DBusError error;
+
+       dbus_error_init(&error);
+       if (priv->address) {
+               priv->connection = dbus_connection_open(priv->address, &error);
+       } else {
+               priv->connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
+       }
+       if (!priv->connection) {
+               dbg(0,"Failed to open connection to %s message bus: %s\n", priv->address?priv->address:"session",error.message);
+               dbus_error_free(&error);
+               return 0;
+       }
+       dbus_connection_setup_with_g_main(priv->connection, NULL);
+       dbus_bus_add_match(priv->connection,"type='signal',interface='org.gpsd'",&error);
+       dbus_connection_flush(priv->connection);
+       if (dbus_error_is_set(&error)) {
+               dbg(0,"Failed to add match to connection: %s\n", error.message);
+               vehicle_gpsd_dbus_close(priv);
+               return 0;
+       }
+       if (!dbus_connection_add_filter(priv->connection, vehicle_gpsd_dbus_filter, priv, NULL)) {
+               dbg(0,"Failed to add filter to connection\n");
+               vehicle_gpsd_dbus_close(priv);
+               return 0;
+       }
+       return 1;
+}
+
+
+static void
+vehicle_gpsd_dbus_destroy(struct vehicle_priv *priv)
+{
+       vehicle_gpsd_dbus_close(priv);
+       if (priv->source)
+               g_free(priv->source);
+       g_free(priv);
+}
+
+static int
+vehicle_gpsd_dbus_position_attr_get(struct vehicle_priv *priv,
+                              enum attr_type type, struct attr *attr)
+{
+       switch (type) {
+       case attr_position_height:
+               attr->u.numd = &priv->altitude;
+               break;
+       case attr_position_speed:
+               attr->u.numd = &priv->speed;
+               break;
+       case attr_position_direction:
+               attr->u.numd = &priv->track;
+               break;
+       case attr_position_coord_geo:
+               attr->u.coord_geo = &priv->geo;
+               break;
+       case attr_position_time_iso8601:
+               {
+               struct tm tm;
+               if (!priv->fix_time)
+                       return 0;
+               if (gmtime_r(&priv->fix_time, &tm)) {
+                       strftime(priv->fixiso8601, sizeof(priv->fixiso8601),
+                               "%Y-%m-%dT%TZ", &tm);
+                       attr->u.str=priv->fixiso8601;
+               } else
+                       return 0;
+               }
+               break;
+       default:
+               return 0;
+       }
+       attr->type = type;
+       return 1;
+}
+
+static int
+vehicle_gpsd_dbus_set_attr_do(struct vehicle_priv *priv, struct attr *attr, int init)
+{
+       switch (attr->type) {
+       case attr_source:
+               if (strncmp(vehicle_gpsd_dbus_prefix,attr->u.str,strlen(vehicle_gpsd_dbus_prefix))) {
+                       dbg(0,"source must start with '%s'\n", vehicle_gpsd_dbus_prefix);
+                       return 0;
+               }
+               g_free(priv->source);
+               priv->source=g_strdup(attr->u.str);
+               priv->address=priv->source+strlen(vehicle_gpsd_dbus_prefix);
+               if (!priv->address[0])
+                       priv->address=NULL;
+               if (!init) {
+                       vehicle_gpsd_dbus_close(priv);
+                       vehicle_gpsd_dbus_open(priv);
+               }
+               return 1;
+       default:
+               return 0;
+       }
+}
+
+static int
+vehicle_gpsd_dbus_set_attr(struct vehicle_priv *priv, struct attr *attr)
+{
+       return vehicle_gpsd_dbus_set_attr_do(priv, attr, 0);
+}
+
+struct vehicle_methods vehicle_gpsd_methods = {
+       vehicle_gpsd_dbus_destroy,
+       vehicle_gpsd_dbus_position_attr_get,
+       vehicle_gpsd_dbus_set_attr,
+};
+
+static struct vehicle_priv *
+vehicle_gpsd_dbus_new(struct vehicle_methods
+                     *meth, struct callback_list
+                     *cbl, struct attr **attrs)
+{
+       struct vehicle_priv *ret;
+       
+       
+       ret = g_new0(struct vehicle_priv, 1);
+       ret->attrs = attrs;
+       ret->cbl = cbl;
+       *meth = vehicle_gpsd_methods;
+       while (*attrs) {
+               vehicle_gpsd_dbus_set_attr_do(ret, *attrs, 1);
+               attrs++;
+       }
+       vehicle_gpsd_dbus_open(ret);
+       return ret;
+}
+
+void
+plugin_init(void)
+{
+       dbg(1, "enter\n");
+       plugin_register_vehicle_type("gpsd_dbus", vehicle_gpsd_dbus_new);
+}