]> err.no Git - mapper/blobdiff - src/gps.c
Fix GPS settings dialog so it works.
[mapper] / src / gps.c
index fece5e4e7ea7ae18a31628986183a67aa336bf93..227122e936a2c6611942171aa0a4d0f02809f425 100644 (file)
--- a/src/gps.c
+++ b/src/gps.c
@@ -36,6 +36,8 @@
 #include <errno.h>
 #include <sys/wait.h>
 #include <glib/gstdio.h>
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib.h>
 #include <fcntl.h>
 
 #include "gps.h"
 #include "gps-conn.h"
 #include "track.h"
 
+#ifdef WITH_HILDON_DBUS_BT
+#include <bt-dbus.h>
+#endif
+
 #ifdef WITH_GPSBT
 #include <gpsbt.h>
 static gpsbt_t ctx = {0};
@@ -54,11 +60,29 @@ static gboolean gps_channel_cb_error(GIOChannel *src, GIOCondition condition, gp
 static gboolean gps_channel_cb_input(GIOChannel *src, GIOCondition condition, gpointer data);
 static gboolean gps_channel_cb_connect(GIOChannel * src, GIOCondition condition, gpointer data);
 static gboolean gps_connect_socket(Gps *gps);
-static gboolean gps_connect_file(Gps *gps);
+static gboolean gps_connect_file(Gps *gps, gchar *file);
 
 #define GPSD_NMEA "r+\r\n"
 #define GPSD_PORT (2947)
 
+const GpsTypes gps_types[] = {
+       { GPS_IO_RFCOMM,                "Direct bluetooth connection", TRUE, TRUE},
+       { GPS_IO_HILDON_DBUS,   "Hildon D-Bus", TRUE, TRUE },
+       { GPS_IO_BLUEZ_DBUS,    "Blues D-Bus", TRUE, TRUE},
+       { GPS_IO_FILE,                  "File or device", FALSE, TRUE},
+       { GPS_IO_TCP,                   "TCP Connection", FALSE, TRUE},
+       { GPS_IO_GPSD,                  "GPSD", FALSE, TRUE},
+       { GPS_IO_GYPSY,                 "Gypsy", FALSE, TRUE},
+       { GPS_IO_SIMULATION,    "Simulation", FALSE, FALSE},
+       { 0 }
+};
+
+GpsTypes *
+gps_get_supported_types(void) 
+{
+return gps_types;
+}
+
 /**
  * Init GPS structure
  */
@@ -75,6 +99,8 @@ gps->io.type=type;
 gps->io.conn=RCVR_OFF;
 gps->data.lat=60.20;
 gps->data.lon=22.20;
+gps->connection_error=NULL;
+gps->connection_retry=NULL;
 gps_data_integerize(&gps->data);
 return gps;
 }
@@ -119,6 +145,47 @@ gpsdata->vel_offsetx=(gint)(floor(gpsdata->speed*sin(tmp)+0.5f));
 gpsdata->vel_offsety=-(gint)(floor(gpsdata->speed*cos(tmp)+0.5f));
 }
 
+#ifdef WITH_HILDON_DBUS_BT
+void
+gps_connect_response(DBusGProxy *proxy, DBusGProxyCall *call_id, Gps *gps)
+{
+GError *error = NULL;
+gchar *fdpath = NULL;
+
+if (gps->io.conn==RCVR_DOWN && gps->io.address) {
+       if (!dbus_g_proxy_end_call(gps->io.rfcomm_req_proxy, call_id, &error, G_TYPE_STRING, &fdpath, G_TYPE_INVALID)) {
+               if (error->domain == DBUS_GERROR && error->code == DBUS_GERROR_REMOTE_EXCEPTION) {
+                       /* If we're already connected, it's not an error, unless
+                        * they don't give us the file descriptor path, in which
+                        * case we re-connect.*/
+                       if (!strcmp(BTCOND_ERROR_CONNECTED, dbus_g_error_get_name(error)) || !fdpath) {
+                               g_printerr("Caught remote method exception %s: %s", dbus_g_error_get_name(error), error->message);
+                               gps_disconnect(gps);
+
+                               if (gps->connection_retry==NULL)
+                                       return;
+
+                               if (gps->connection_retry(gps, error->message)==TRUE) {
+                                       gps_connect_later(gps);
+                               } else {
+                                       gps_conn_set_state(gps, RCVR_OFF);
+                               }
+                               return;
+                       }
+               } else {
+                       /* Unknown error. */
+                       g_printerr("Error: %s\n", error->message);
+                       gps_disconnect(_gps);
+                       gps_connect_later(_gps);        /* Try again later. */
+                       return;
+               }
+       }
+       gps_connect_fd(fdpath);
+}
+/* else { Looks like the middle of a disconnect.  Do nothing. } */
+}
+#endif
+
 /**
  * Place a request to connect about 1 second after the function is called.
  */
@@ -135,7 +202,7 @@ gps_connect(Gps *gps)
 {
 switch (gps->io.type) {
        case GPS_IO_FILE:
-               return gps_connect_file(gps);
+               return TRUE;
        break;
        case GPS_IO_RFCOMM:
        case GPS_IO_TCP:
@@ -155,11 +222,12 @@ return FALSE;
  * Helper to open a file or device node
  */
 static gboolean 
-gps_connect_file(Gps *gps)
+gps_connect_file(Gps *gps, gchar *file)
 {
-if (-1==(gps->io.fd=open(gps->io.address, O_RDONLY))) {
+if (-1==(gps->io.fd=open(file, O_RDONLY))) {
        gps_disconnect(gps);
        gps_connect_later(gps);
+       /* Add retry cb */
        return FALSE;
 }
 return TRUE;
@@ -275,18 +343,17 @@ if (gps->io.type==GPS_IO_GPSD) {
 
 #ifdef WITH_HILDON_DBUS_BT
 if (gps->io.type==GPS_IO_HILDON_DBUS && gps->io.rfcomm_req_proxy) {
-               GError *error = NULL;
+       GError *error = NULL;
 
-               dbus_g_proxy_call(gps->io.rfcomm_req_proxy, BTCOND_RFCOMM_CANCEL_CONNECT_REQ, &error, G_TYPE_STRING, gps->io.address, G_TYPE_STRING, "SPP", G_TYPE_INVALID, G_TYPE_INVALID);
-               error = NULL;
-               dbus_g_proxy_call(gps->io.rfcomm_req_proxy,     BTCOND_RFCOMM_DISCONNECT_REQ, &error,G_TYPE_STRING, gps->io.address, G_TYPE_STRING, "SPP", G_TYPE_INVALID, G_TYPE_INVALID);
+       dbus_g_proxy_call(gps->io.rfcomm_req_proxy, BTCOND_RFCOMM_CANCEL_CONNECT_REQ, &error, G_TYPE_STRING, gps->io.address, G_TYPE_STRING, "SPP", G_TYPE_INVALID, G_TYPE_INVALID);
+       error = NULL;
+       dbus_g_proxy_call(gps->io.rfcomm_req_proxy, BTCOND_RFCOMM_DISCONNECT_REQ, &error,G_TYPE_STRING, gps->io.address, G_TYPE_STRING, "SPP", G_TYPE_INVALID, G_TYPE_INVALID);
 }
 #endif
 
 #ifdef WITH_BLUEZ_DBUS_BT
 if (gps->io.type==GPS_IO_BLUEZ_DBUS && gps->io.rfcomm_req_proxy) {
        GError *error = NULL;
-
        
 }
 #endif
@@ -307,12 +374,16 @@ static gboolean
 gps_simulate_move(Gps *gps)
 {
 static gdouble slat=0, slon=0;
+gdouble plat, plon;
+gfloat h;
 g_assert(gps);
 
 if (g_random_double()<0.5) {
        slat=g_random_double_range(-0.0003, 0.0003);
        slon=g_random_double_range(-0.0003, 0.0003);
 }
+plat=gps->data.lat;
+plon=gps->data.lon;
 gps->data.lat+=slat;
 gps->data.lon+=slon;
 BOUND(gps->data.lat, -80.0, 80.0);
@@ -321,8 +392,8 @@ BOUND(gps->data.lon, -80.0, 80.0);
 g_debug("Sim: %f %f\n", gps->data.lat, gps->data.lon);
 
 gps->data.speed=1+g_random_double_range(0.1, 10.0);
-gps->data.heading+=g_random_double_range(-4.0, 4.0);
-BOUND(gps->data.heading, 0, 359);
+h=calculate_course(plat, plon, gps->data.lat, gps->data.lon);
+gps->data.heading=(h<0) ? 360+h : h;
 gps->data.time=time(NULL);
 gps_data_integerize(&gps->data);
 track_add(&gps->data, FALSE);
@@ -369,6 +440,8 @@ gps->io.clater_sid=0;
 gboolean 
 gps_connect_now(Gps *gps)
 {
+GError *error = NULL;
+
 g_assert(gps);
 g_debug("GPS: Connecting GPS type %d to %s:%d\n", gps->io.type, gps->io.address, gps->io.port);
 
@@ -376,10 +449,8 @@ 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
-                       return FALSE;
+               gps_connect_file(gps, gps->io.address);
+               return FALSE;
        break;
        case GPS_IO_TCP:
        case GPS_IO_GPSD:
@@ -410,18 +481,26 @@ switch (gps->io.type) {
        break;
        case GPS_IO_HILDON_DBUS:
 #ifdef WITH_HILDON_DBUS_BT
+               if (NULL == (gps->io.dbus_conn=dbus_g_bus_get(DBUS_BUS_SYSTEM, &error))) {
+                       g_printerr("Failed to get D-Bus connection.");
+                       return FALSE;
+               }
+               if (NULL == (gps->io.rfcomm_req_proxy = dbus_g_proxy_new_for_name(gps->io.dbus_conn, BTCOND_SERVICE, BTCOND_REQ_PATH, BTCOND_REQ_INTERFACE))) {
+                       g_printerr("Failed to open connection to %s.\n", BTCOND_REQ_INTERFACE);
+                       return FALSE;
+                }
+
                if (gps->io.rfcomm_req_proxy) {
                        gboolean mybool = TRUE;
-                       dbus_g_proxy_begin_call(_rfcomm_req_proxy,
-                               BTCOND_RFCOMM_CONNECT_REQ, (DBusGProxyCallNotify)gps_connect_response, NULL, NULL,
+                       dbus_g_proxy_begin_call(gps->io.rfcomm_req_proxy,
+                               BTCOND_RFCOMM_CONNECT_REQ, (DBusGProxyCallNotify)gps_connect_response, gps, NULL,
                                G_TYPE_STRING, gps->io.address,
                                G_TYPE_STRING, "SPP",
                                G_TYPE_BOOLEAN, &mybool,
                                G_TYPE_INVALID);
                }
-#else
-               return FALSE;
 #endif
+               return FALSE;
        break;
        case GPS_IO_RFCOMM:
 #ifdef WITH_BLUEZ