#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; gpsdata->privdata = (void *)malloc(sizeof(struct privdata_t)); if (gpsdata->privdata == NULL) return -1; PRIVATE(gpsdata)->handler = handler; 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; } /* This probably needs to be factored out */ mainloop = g_main_loop_new(NULL, FALSE); dbus_connection_setup_with_g_main(connection, NULL); g_main_loop_run(mainloop); return 0; } #endif /* defined(DBUS_EXPORT_ENABLE) && !defined(S_SPLINT_S) */