From 39f6aff4501ca4c06932b526d1837a93bf9796fc Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Tue, 27 Sep 2011 00:34:33 -0400 Subject: Belated commit of new file created by gpxlogger refactoring. --- libgps_dbus.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 libgps_dbus.c (limited to 'libgps_dbus.c') 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef S_SPLINT_S +#include +#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 +#include +#include +#include + +#include + +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) */ -- cgit v1.2.1