From: Kaj-Michael Lang Date: Wed, 23 Jan 2008 14:43:44 +0000 (+0200) Subject: More work on gpsd support. Add gps_free and gps_set_address functions. X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=059daea2edce2648468253b498d74c8b55ee02cf;p=mapper More work on gpsd support. Add gps_free and gps_set_address functions. --- diff --git a/src/gps.c b/src/gps.c index f8116b3..191007e 100644 --- a/src/gps.c +++ b/src/gps.c @@ -42,8 +42,12 @@ #include "latlon.h" #include "map.h" #include "gps-nmea-parse.h" +#include "gps-conn.h" #include "track.h" +#define GPSD_NMEA "r+\r\n" +#define GPSD_PORT (2947) + static gboolean gps_channel_cb_error(GIOChannel *src, GIOCondition condition, gpointer data); static gboolean gps_channel_cb_input(GIOChannel *src, GIOCondition condition, gpointer data); static gboolean gps_channel_cb_connect(GIOChannel * src, GIOCondition condition, gpointer data); @@ -54,18 +58,41 @@ static gboolean gps_connect_file(Gps *gps); * Init GPS structure */ Gps * -gps_new(void) +gps_new(GpsIOSourceType type) { Gps *gps; gps=g_slice_new0(Gps); gps->data.fix=FIX_NOFIX; gps->io.fd=-1; +gps->io.address=NULL; +gps->io.type=type; gps->io.conn=RCVR_OFF; +gps->data.lat=64.20; +gps->data.lon=22.20; gps_data_integerize(&gps->data); return gps; } +void +gps_set_address(Gps *gps, gchar *address, guint port) +{ +if (gps->io.address) + g_free(gps->io.address); +if (address) + gps->io.address=g_strdup(address); +gps->io.port=port; +} + +void +gps_free(Gps *gps) +{ +gps_disconnect(gps); +if (gps->io.address) + g_free(gps->io.address); +g_slice_free(Gps, gps); +} + /** * Convert the float lat/lon/speed/heading data into integer units. * Also calculate offsets. @@ -113,6 +140,9 @@ switch (gps->io.type) { return FALSE; } +/** + * Helper to open a file or device node + */ static gboolean gps_connect_file(Gps *gps) { @@ -124,6 +154,10 @@ if (-1==(gps->io.fd=open(gps->io.address, O_RDONLY))) { return TRUE; } +/** + * Helper to connect to a socket file descriptor. + * + */ static gboolean gps_connect_socket(Gps *gps) { @@ -176,6 +210,13 @@ if (r != 0) { return TRUE; } +/** + * Disconnect the GPS device. + * - Add channel callbacks are removed + * - Channel is close and shutdown + * - File descriptor is closed + * - Anything special for disconnecting is done + */ void gps_disconnect(Gps *gps) { @@ -223,6 +264,12 @@ if (gps->io.type==GPS_IO_HILDON_DBUS && gps->io.rfcomm_req_proxy) { } #endif +#ifdef WITH_BLUEZ_DBUS_BT +if (gps->io.type==GPS_IO_BLUEZ_DBUS && gps->io.rfcomm_req_proxy) { + GError *error = NULL; +} +#endif + } /** @@ -231,6 +278,8 @@ if (gps->io.type==GPS_IO_HILDON_DBUS && gps->io.rfcomm_req_proxy) { * gps_disconnect() first. * Since this is an idle function, this function returns whether or not it * should be called again, which is always FALSE. + * + * This function prepares for the connection, the gps_connect does the "connecting" if needed. */ gboolean gps_connect_now(Gps *gps) @@ -239,6 +288,8 @@ g_assert(gps); switch (gps->io.type) { case GPS_IO_FILE: + if (!gps->io.address) + return FALSE; if (*gps->io.address=='/') gps->io.fd=open(gps->io.address, O_RDONLY); else @@ -263,18 +314,16 @@ switch (gps->io.type) { case GPS_IO_HILDON_DBUS: #ifdef WITH_HILDON_DBUS_BT if (gps->io.rfcomm_req_proxy) { - gint mybool = TRUE; + gboolean mybool = TRUE; dbus_g_proxy_begin_call(_rfcomm_req_proxy, - BTCOND_RFCOMM_CONNECT_REQ, - (DBusGProxyCallNotify) - rcvr_connect_response, - NULL, NULL, - G_TYPE_STRING, - _rcvr_mac, + BTCOND_RFCOMM_CONNECT_REQ, (DBusGProxyCallNotify)gps_connect_response, NULL, NULL, + G_TYPE_STRING, gps->io.address, G_TYPE_STRING, "SPP", G_TYPE_BOOLEAN, &mybool, G_TYPE_INVALID); } +#else + return FALSE; #endif break; case GPS_IO_RFCOMM: @@ -341,18 +390,33 @@ switch (gps->io.type) { case GPS_IO_RFCOMM: case GPS_IO_GPSD: if ((getsockopt(gps->io.fd, SOL_SOCKET, SO_ERROR, &error, &size) || error)) { - g_printf("Error connecting to receiver; retrying...\n"); + g_printerr("Error connecting to receiver; retrying...\n"); gps_disconnect(gps); gps_connect_later(gps); gps->io.connect_sid=0; + gps->io.errors++; return FALSE; + } + /* Set gpsd to NMEA mode */ + if (gps->io.type==GPS_IO_GPSD) { + GIOStatus status; + gint written; + status=g_io_channel_write_chars(gps->io.channel, GPSD_NMEA, -1, &written, NULL); + if (status!=G_IO_STATUS_NORMAL || written!=sizeof(GPSD_NMEA)) { + g_printerr("Failed to set gpsd to NMEA mode\n"); + gps_disconnect(gps); + gps_connect_later(gps); + gps->io.connect_sid=0; + gps->io.errors++; + return FALSE; + } } break; case GPS_IO_FILE: break; default: - return FALSE; + g_warning("Connection from non-connecting source\n"); break; } @@ -440,6 +504,7 @@ switch (status) { case G_IO_STATUS_EOF: gps_disconnect(gps); gps_connect_later(gps); + gps->io.errors++; return FALSE; break; case G_IO_STATUS_AGAIN: diff --git a/src/gps.h b/src/gps.h index db0592a..0611468 100644 --- a/src/gps.h +++ b/src/gps.h @@ -99,9 +99,10 @@ gint _gmtoffset; DBusGProxy *_rfcomm_req_proxy; -Gps *gps_new(void); +Gps *gps_new(GpsIOSourceType type); +void gps_set_address(Gps *gps, gchar *address, guint port); +void gps_free(Gps *gps); void gps_data_integerize(GpsData *gpsdata); - gboolean gps_connect(Gps *gps); gboolean gps_connect_now(Gps *gps); void gps_connect_later(Gps *gps);