summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--clockwatcher.c10
-rw-r--r--gps.h7
-rw-r--r--gpxlogger.c8
-rw-r--r--libgps_dbus.c70
4 files changed, 63 insertions, 32 deletions
diff --git a/clockwatcher.c b/clockwatcher.c
index a7ff2f72..56e07fd3 100644
--- a/clockwatcher.c
+++ b/clockwatcher.c
@@ -66,7 +66,12 @@ static void quit_handler(int signum)
static int dbus_mainloop(void)
{
- return gps_dbus_open(conditionally_log_fix, &gpsdata);;
+ int s;
+ if ((s = gps_dbus_open(&gpsdata)) == 0) {
+ gps_dbus_stream(&gpsdata, 0, conditionally_log_fix);
+ gps_dbus_mainloop();
+ }
+ return s;
}
#endif /* defined(DBUS_EXPORT_ENABLE) && !defined(S_SPLINT_S) */
@@ -148,8 +153,7 @@ static int shm_mainloop(void)
*
**************************************************************************/
-struct method_t
-{
+struct method_t{
const char *name;
int (*method)(void);
const char *description;
diff --git a/gps.h b/gps.h
index aa0aa28c..9a30c5e2 100644
--- a/gps.h
+++ b/gps.h
@@ -1742,10 +1742,14 @@ extern int gps_sock_stream(struct gps_data_t *, unsigned int, /*@null@*/void *);
extern const char /*@observer@*/ *gps_sock_data(const struct gps_data_t *);
extern void gps_shm_close(struct gps_data_t *);
-extern void libgps_trace(int errlevel, const char *, ...);
+extern int gps_dbus_open(struct gps_data_t *);
+extern int gps_dbus_stream(struct gps_data_t *, unsigned int, /*@null@*/void *);
+extern void gps_dbus_mainloop(void);
/* dependencies on struct gpsdata_t end hrere */
+extern void libgps_trace(int errlevel, const char *, ...);
+
extern void gps_clear_fix(/*@ out @*/struct gps_fix_t *);
extern void gps_clear_dop( /*@out@*/ struct dop_t *);
extern void gps_merge_fix(/*@ out @*/struct gps_fix_t *,
@@ -1754,7 +1758,6 @@ extern void gps_merge_fix(/*@ out @*/struct gps_fix_t *,
extern void gps_enable_debug(int, FILE *);
extern /*@observer@*/const char *gps_maskdump(gps_mask_t);
-extern int gps_dbus_open(void (*)(struct gps_data_t *), struct gps_data_t *);
extern double safe_atof(const char *);
extern time_t mkgmtime(register struct tm *);
diff --git a/gpxlogger.c b/gpxlogger.c
index d0032150..60ce409c 100644
--- a/gpxlogger.c
+++ b/gpxlogger.c
@@ -191,8 +191,14 @@ static void quit_handler(int signum)
static int dbus_mainloop(void)
{
+ int s;
+
print_gpx_header();
- return gps_dbus_open(conditionally_log_fix, &gpsdata);
+ if ((s = gps_dbus_open(&gpsdata)) == 0) {
+ gps_dbus_stream(&gpsdata, 0, conditionally_log_fix);
+ gps_dbus_mainloop();
+ }
+ return 0;
}
#endif /* defined(DBUS_EXPORT_ENABLE) && !defined(S_SPLINT_S) */
diff --git a/libgps_dbus.c b/libgps_dbus.c
index 3c05705d..5e124f32 100644
--- a/libgps_dbus.c
+++ b/libgps_dbus.c
@@ -30,8 +30,14 @@ struct privdata_t
#include <glib/gprintf.h>
-DBusConnection *connection;
-
+/*
+ * Unpleasant that we have to declare a static context pointer here - means
+ * you can't have multiple DBUS sessions open (not that this matters
+ * much in practice). The problem is the DBUS API lacks some hook
+ * arguments that it ought to have.
+ */
+static struct gps_data_t *share_gpsdata;
+static DBusConnection *connection;
static char gpsd_devname[BUFSIZ];
static DBusHandlerResult handle_gps_fix(DBusMessage * message)
@@ -39,35 +45,33 @@ 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, &share_gpsdata->fix.time,
+ DBUS_TYPE_INT32, &share_gpsdata->fix.mode,
+ DBUS_TYPE_DOUBLE, &share_gpsdata->fix.ept,
+ DBUS_TYPE_DOUBLE, &share_gpsdata->fix.latitude,
+ DBUS_TYPE_DOUBLE, &share_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_DOUBLE, &share_gpsdata->fix.altitude,
+ DBUS_TYPE_DOUBLE, &share_gpsdata->fix.epv,
+ DBUS_TYPE_DOUBLE, &share_gpsdata->fix.track,
+ DBUS_TYPE_DOUBLE, &share_gpsdata->fix.epd,
+ DBUS_TYPE_DOUBLE, &share_gpsdata->fix.speed,
+ DBUS_TYPE_DOUBLE, &share_gpsdata->fix.eps,
+ DBUS_TYPE_DOUBLE, &share_gpsdata->fix.climb,
+ DBUS_TYPE_DOUBLE, &share_gpsdata->fix.epc,
DBUS_TYPE_STRING, &gpsd_devname, DBUS_TYPE_INVALID);
- if (gpsdata.fix.mode > MODE_NO_FIX )
- gpsdata.status = STATUS_FIX;
+ if (share_gpsdata->fix.mode > MODE_NO_FIX )
+ share_gpsdata->status = STATUS_FIX;
else
- gpsdata.status = STATUS_NO_FIX;
+ share_gpsdata->status = STATUS_NO_FIX;
- PRIVATE(&gpsdata)->handler(&gpsdata);
+ PRIVATE(share_gpsdata)->handler(share_gpsdata);
return DBUS_HANDLER_RESULT_HANDLED;
}
@@ -90,15 +94,13 @@ static DBusHandlerResult signal_handler(DBusConnection * connection,
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
-int gps_dbus_open(void (*handler)(struct gps_data_t *), struct gps_data_t *gpsdata)
+int gps_dbus_open(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);
@@ -121,11 +123,27 @@ int gps_dbus_open(void (*handler)(struct gps_data_t *), struct gps_data_t *gpsda
return 5;
}
- /* This probably needs to be factored out */
+ share_gpsdata = gpsdata;
+ return 0;
+}
+
+int gps_dbus_stream(struct gps_data_t *unused UNUSED,
+ unsigned int flags UNUSED,
+ /*@null@*/ void *handler)
+{
+ /* must refer to the static context here */
+ PRIVATE(share_gpsdata)->handler = (void (*)(struct gps_data_t *))handler;
+ return 0;
+}
+
+void gps_dbus_mainloop(void)
+/* run a DBUS main loop with a specified handler */
+{
+ GMainLoop *mainloop;
+
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) */