From eed3d93e8b4515b0d1dbf0a8dc265987b9449000 Mon Sep 17 00:00:00 2001 From: Kaj-Michael Lang Date: Sat, 26 Jan 2008 15:40:57 +0200 Subject: [PATCH] Remodelling of GPS handling for hildon. Work in progress still. --- ...uetooth-hildon.c => gps-bluetooth-maemo.c} | 48 +--------- src/gps-conn.c | 2 + src/gps.c | 91 +++++++++++++++---- src/gps.h | 9 ++ src/map.c | 2 +- src/mapper-types.h | 7 +- src/mapper.c | 10 +- src/osm-db.c | 8 +- src/osm-db.h | 2 +- src/settings.h | 1 + src/ui-common.c | 16 ++++ src/ui-common.h | 4 +- 12 files changed, 119 insertions(+), 81 deletions(-) rename src/{gps-bluetooth-hildon.c => gps-bluetooth-maemo.c} (70%) diff --git a/src/gps-bluetooth-hildon.c b/src/gps-bluetooth-maemo.c similarity index 70% rename from src/gps-bluetooth-hildon.c rename to src/gps-bluetooth-maemo.c index 50337d8..ab87909 100644 --- a/src/gps-bluetooth-hildon.c +++ b/src/gps-bluetooth-maemo.c @@ -31,56 +31,12 @@ #include "hildon-mapper.h" #include "mapper.h" -#include "bt-maemo-marshal.h" -#include "bt.h" +#include "gps-bluetooth-maemo-marshal.h" #include "gps.h" #include "settings.h" #include "ui-common.h" #include "gps-conn.h" - -void -gps_connect_response(DBusGProxy * proxy, DBusGProxyCall * call_id) -{ -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) { - GtkWidget *confirm; - printf("Caught remote method exception %s: %s", dbus_g_error_get_name(error), error->message); - gps_disconnect(_gps); - - /* Ask user to re-connect. */ - confirm = hildon_note_new_confirmation(GTK_WINDOW(_window), _("Failed to connect to GPS receiver. Retry?")); - - if (GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm))) - gps_connect_later(); /* Try again later. */ - else { - gps_conn_set_state(RCVR_OFF); - _enable_gps=FALSE; - set_action_activate("gps_enabled", !_enable_gps); - } - - gtk_widget_destroy(confirm); - 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. } */ -} +#include "bluetooth-scan.h" /** * Bluetooth device scanning functions below diff --git a/src/gps-conn.c b/src/gps-conn.c index 6a37a1e..d7f84de 100644 --- a/src/gps-conn.c +++ b/src/gps-conn.c @@ -57,6 +57,8 @@ gps_conn_set_state(Gps *gps, GpsConnState new_conn_state) { switch (gps->io.conn=new_conn_state) { case RCVR_OFF: + _enable_gps=FALSE; + set_action_activate("gps_enabled", !_enable_gps); case RCVR_FIXED: if (connect_banner) { gtk_widget_destroy(connect_banner); diff --git a/src/gps.c b/src/gps.c index 274b62a..06c9ac9 100644 --- a/src/gps.c +++ b/src/gps.c @@ -36,6 +36,8 @@ #include #include #include +#include +#include #include #include "gps.h" @@ -45,6 +47,10 @@ #include "gps-conn.h" #include "track.h" +#ifdef WITH_HILDON_DBUS_BT +#include +#endif + #ifdef WITH_GPSBT #include static gpsbt_t ctx = {0}; @@ -54,7 +60,7 @@ 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) @@ -75,6 +81,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 +127,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 +184,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 +204,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 +325,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 @@ -371,6 +420,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); @@ -378,10 +429,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: @@ -412,18 +461,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 diff --git a/src/gps.h b/src/gps.h index 760b370..694a9bd 100644 --- a/src/gps.h +++ b/src/gps.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -70,16 +71,19 @@ struct _GpsIO { GpsIOSourceType type; GpsConnState conn; GIOChannel *channel; + DBusConnection *dbus_conn; DBusGProxy *rfcomm_req_proxy; #ifdef WITH_BLUEZ struct sockaddr_rc rcvr_addr_rc; #endif struct sockaddr_in rcvr_addr_in; + /* Channel callback IDs*/ guint connect_sid; guint error_sid; guint input_sid; guint clater_sid; guint errors; + /* Input buffer */ gchar buffer[GPS_READ_BUF_SIZE]; gchar *curr; gchar *last; @@ -94,6 +98,11 @@ struct _Gps { gchar *name; /* Name of the connection */ GpsIO io; GpsData data; + /* Event callbacks */ + /* On errors */ + gboolean(* connection_error) (Gps *gps, const gchar *error_str); + /* Connection retry */ + gboolean(* connection_retry) (Gps *gps, const gchar *error_str); }; Gps *_gps; diff --git a/src/map.c b/src/map.c index 9c8840a..fb2a325 100644 --- a/src/map.c +++ b/src/map.c @@ -1201,7 +1201,7 @@ else osm_set_way_range(OSM_RANGE_WAY/4); osm_progress_set_widget(_db, _progress_item); -osm_get_location_data(ilat, ilon, &map_loc); +osm_get_location_data(ilat, ilon, _gps->data.heading, &map_loc); if (map_loc.valid) map_set_place_information(map_loc.street, map_loc.primary, map_loc.secondary); else diff --git a/src/mapper-types.h b/src/mapper-types.h index fd6b391..17abe32 100644 --- a/src/mapper-types.h +++ b/src/mapper-types.h @@ -1,11 +1,12 @@ #include "config.h" -#include -#include - #ifndef _MAPPER_TYPES_H #define _MAPPER_TYPES_H +#include +#include +#include + /** Generic search item list indexes */ typedef enum { ITEM_ID, diff --git a/src/mapper.c b/src/mapper.c index e31e94c..60374a7 100644 --- a/src/mapper.c +++ b/src/mapper.c @@ -286,6 +286,7 @@ switch (mis) { gnome_vfs_init(); /* XXX: Load GPS configuration, then create gps */ _gps=gps_new(GPS_IO_SIMULATION); + _gps->connection_retry=gps_retry_connection; timezone_init(); gpx_init(); variables_init(); @@ -339,6 +340,7 @@ switch (mis) { /* Initialize D-Bus system connection. */ if (NULL == (dbus_conn = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error))) { g_printerr("Failed to open connection to D-Bus: %s.\n", error->message); + popup_error(_window, "Failed to connect to D-Bus."); error = NULL; } @@ -347,12 +349,6 @@ switch (mis) { osso_hw_set_event_cb(_osso, NULL, osso_cb_hw_state, NULL); #endif - #ifdef WITH_HILDON_DBUS_BT - if (NULL == (_rfcomm_req_proxy = dbus_g_proxy_new_for_name(dbus_conn, BTCOND_SERVICE, BTCOND_REQ_PATH, BTCOND_REQ_INTERFACE))) { - g_printerr("Failed to open connection to %s.\n", BTCOND_REQ_INTERFACE); - popup_error(_window, "Bluetooth connection handling failed."); - } - #endif mis=MAPPER_INIT_UI; p=0.9; w="Misc"; @@ -375,7 +371,7 @@ switch (mis) { case MAPPER_INIT_DONE: progress_dialog_remove(init_dialog); if (_enable_gps) - gps_connect_now(_gps); + gps_connect_now(_gps); return FALSE; break; } diff --git a/src/osm-db.c b/src/osm-db.c index be7537f..4fa4183 100644 --- a/src/osm-db.c +++ b/src/osm-db.c @@ -31,7 +31,6 @@ #include "osm.h" #include "latlon.h" -#include "gps.h" #include "osm-db.h" #include "settings.h" @@ -890,7 +889,7 @@ return FALSE; * */ gboolean -osm_get_location_data(gint lat, gint lon, osm_location *map_loc) +osm_get_location_data(gint lat, gint lon, gfloat heading, osm_location *map_loc) { gdouble dist; gboolean check_place=FALSE; @@ -908,7 +907,7 @@ if (map_loc->valid==FALSE) { /* Check if we are still near the same way as last time */ if (map_loc->street && osm_way_distance(lat, lon, map_loc->street->node_f, map_loc->street->node_t, &dist)==TRUE) { /* We are probably on the same way as last time */ - if ( (dist>(gdouble)way_dist_range) || (fabs(_gps->data.heading-map_loc->heading)>10.0)) { + if ( (dist>(gdouble)way_dist_range) || (fabs(heading-map_loc->heading)>10.0)) { /* We have moved a large amount, check way again */ g_printf("*** dist %f over range, checking again\n", dist); osm_way_free(map_loc->street); @@ -951,8 +950,7 @@ if (map_loc->street && osm_way_distance(lat, lon, map_loc->street->node_f, map_l } if (map_loc->changed==TRUE) { - map_loc->heading=_gps->data.heading; - map_loc->speed=_gps->data.speed; + map_loc->heading=heading; } #if 0 diff --git a/src/osm-db.h b/src/osm-db.h index 92d97d5..a836622 100644 --- a/src/osm-db.h +++ b/src/osm-db.h @@ -56,7 +56,7 @@ gboolean osm_way_distance(gint lat, gint lon, osm_way_node *f, osm_way_node *t, gboolean osm_place_get(guint32 id, gint lat, gint lon, osm_place **nr); -gboolean osm_get_location_data(gint lat, gint lon, osm_location *map_loc); +gboolean osm_get_location_data(gint lat, gint lon, gfloat heading, osm_location *map_loc); osm_way_node *osm_way_node_new(guint id, gint lat, gint lon, gint flags); diff --git a/src/settings.h b/src/settings.h index 8d1de74..29a03e5 100644 --- a/src/settings.h +++ b/src/settings.h @@ -6,6 +6,7 @@ #define _MAPPER_SETTINGS_H #include "settings-gconf.h" +#include "mapper-types.h" /** CONFIGURATION INFORMATION. */ gchar *_route_dir_uri; diff --git a/src/ui-common.c b/src/ui-common.c index 635d5ae..221bf6a 100644 --- a/src/ui-common.c +++ b/src/ui-common.c @@ -792,3 +792,19 @@ progress_dialog_remove(GtkWidget *dialog) if (dialog) gtk_widget_destroy(dialog); } + +/** + * Simple dialog to ask if we should try to reconnect to GPS + * returns TRUE or FALSE + */ +gboolean +gps_retry_connection(Gps *gps, const gchar *error) +{ +GtkWidget *confirm; +gboolean r; + +confirm=hildon_note_new_confirmation(GTK_WINDOW(_window), _("Failed to connect to GPS receiver. Retry?")); +r=(GTK_RESPONSE_OK==gtk_dialog_run(GTK_DIALOG(confirm))) ? TRUE : FALSE; +gtk_widget_destroy(confirm); +return r; +} diff --git a/src/ui-common.h b/src/ui-common.h index b0adddf..f4359ee 100644 --- a/src/ui-common.h +++ b/src/ui-common.h @@ -21,6 +21,7 @@ #include #include +#include "gps.h" #include "mapper-types.h" #include "ui-maemo.h" #include "hildon-wrappers.h" @@ -29,7 +30,6 @@ /** The main GtkContainer of the application. */ GtkWidget *_window; - GtkWidget *_gps_widget; /* GPS Tab widget */ @@ -132,4 +132,6 @@ void set_action_activate(const char *name, gboolean active); GtkWidget *progress_dialog(const gchar *title, GtkWidget *progress); void progress_dialog_remove(GtkWidget *dialog); +gboolean gps_retry_connection(Gps *gps, const gchar *error); + #endif -- 2.39.5