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
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)
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
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)"
--- /dev/null
+/**
+ * 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);
+}