summaryrefslogtreecommitdiff
path: root/libgps_dbus.c
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>2011-09-27 00:34:33 -0400
committerEric S. Raymond <esr@thyrsus.com>2011-09-27 00:34:33 -0400
commit39f6aff4501ca4c06932b526d1837a93bf9796fc (patch)
tree3ae81388cf9b7caba7bac7f18443a3ac2eec08a2 /libgps_dbus.c
parentd4aa00e0674c66bcf062794796c4db0526260bf5 (diff)
downloadgpsd-39f6aff4501ca4c06932b526d1837a93bf9796fc.tar.gz
Belated commit of new file created by gpxlogger refactoring.
Diffstat (limited to 'libgps_dbus.c')
-rw-r--r--libgps_dbus.c133
1 files changed, 133 insertions, 0 deletions
diff --git a/libgps_dbus.c b/libgps_dbus.c
new file mode 100644
index 00000000..6f031108
--- /dev/null
+++ b/libgps_dbus.c
@@ -0,0 +1,133 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+#include <syslog.h>
+#include <math.h>
+#include <time.h>
+#include <errno.h>
+#include <libgen.h>
+#include <signal.h>
+#ifndef S_SPLINT_S
+#include <unistd.h>
+#endif /* S_SPLINT_S */
+
+#include "gps.h"
+#include "gpsd_config.h"
+
+#if defined(DBUS_EXPORT_ENABLE) && !defined(S_SPLINT_S)
+
+struct privdata_t
+{
+ void (*handler)(struct gps_data_t *);
+};
+#define PRIVATE(gpsdata) ((struct privdata_t *)(gpsdata)->privdata)
+
+#include <glib.h>
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib-lowlevel.h>
+#include <dbus/dbus-glib.h>
+
+#include <glib/gprintf.h>
+
+DBusConnection *connection;
+
+static char gpsd_devname[BUFSIZ];
+
+static DBusHandlerResult handle_gps_fix(DBusMessage * message)
+{
+ DBusError error;
+ /* this packet format was designed before we split eph */
+ double eph;
+ struct gps_data_t gpsdata;
+
+ dbus_error_init(&error);
+
+ (void)memset(&gpsdata, '\0', sizeof(gpsdata));
+ dbus_message_get_args(message,
+ &error,
+ DBUS_TYPE_DOUBLE, &gpsdata.fix.time,
+ DBUS_TYPE_INT32, &gpsdata.fix.mode,
+ DBUS_TYPE_DOUBLE, &gpsdata.fix.ept,
+ DBUS_TYPE_DOUBLE, &gpsdata.fix.latitude,
+ DBUS_TYPE_DOUBLE, &gpsdata.fix.longitude,
+ DBUS_TYPE_DOUBLE, &eph,
+ DBUS_TYPE_DOUBLE, &gpsdata.fix.altitude,
+ DBUS_TYPE_DOUBLE, &gpsdata.fix.epv,
+ DBUS_TYPE_DOUBLE, &gpsdata.fix.track,
+ DBUS_TYPE_DOUBLE, &gpsdata.fix.epd,
+ DBUS_TYPE_DOUBLE, &gpsdata.fix.speed,
+ DBUS_TYPE_DOUBLE, &gpsdata.fix.eps,
+ DBUS_TYPE_DOUBLE, &gpsdata.fix.climb,
+ DBUS_TYPE_DOUBLE, &gpsdata.fix.epc,
+ DBUS_TYPE_STRING, &gpsd_devname, DBUS_TYPE_INVALID);
+
+ if (gpsdata.fix.mode > MODE_NO_FIX )
+ gpsdata.status = STATUS_FIX;
+ else
+ gpsdata.status = STATUS_NO_FIX;
+
+ PRIVATE(&gpsdata)->handler(&gpsdata);
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+/*
+ * Message dispatching function
+ *
+ */
+static DBusHandlerResult signal_handler(DBusConnection * connection,
+ DBusMessage * message)
+{
+ /* dummy, need to use the variable for some reason */
+ connection = NULL;
+
+ if (dbus_message_is_signal(message, "org.gpsd", "fix"))
+ return handle_gps_fix(message);
+ /*
+ * ignore all other messages
+ */
+
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+int gps_dbus_open(void (*handler)(struct gps_data_t *), struct gps_data_t *gpsdata)
+{
+ GMainLoop *mainloop;
+ DBusError error;
+
+ /* set up for line-buffered I/O over the daemon socket */
+ gpsdata->privdata = (void *)malloc(sizeof(struct privdata_t));
+ if (gpsdata->privdata == NULL)
+ return -1;
+ PRIVATE(gpsdata)->handler = handler;
+
+ mainloop = g_main_loop_new(NULL, FALSE);
+
+ dbus_error_init(&error);
+ connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
+ if (dbus_error_is_set(&error)) {
+ syslog(LOG_CRIT, "%s: %s", error.name, error.message);
+ return 3;
+ }
+
+ dbus_bus_add_match(connection, "type='signal'", &error);
+ if (dbus_error_is_set(&error)) {
+ syslog(LOG_CRIT, "unable to add match for signals %s: %s", error.name,
+ error.message);
+ return 4;
+ }
+
+ if (!dbus_connection_add_filter
+ (connection, (DBusHandleMessageFunction) signal_handler, NULL,
+ NULL)) {
+ syslog(LOG_CRIT, "unable to register filter with the connection");
+ return 5;
+ }
+
+ dbus_connection_setup_with_g_main(connection, NULL);
+
+ g_main_loop_run(mainloop);
+ return 0;
+}
+
+#endif /* defined(DBUS_EXPORT_ENABLE) && !defined(S_SPLINT_S) */