]> err.no Git - mapper/commitdiff
Start to rewrite the GPS system to support location information from multiple sources.
authorKaj-Michael Lang <milang@onion.tal.org>
Tue, 22 Jan 2008 18:30:26 +0000 (20:30 +0200)
committerKaj-Michael Lang <milang@onion.tal.org>
Tue, 22 Jan 2008 18:30:26 +0000 (20:30 +0200)
26 files changed:
configure.ac
src/bluetooth-scan.h [new file with mode: 0644]
src/bt.h [deleted file]
src/cb.c
src/config-gconf.c
src/filter-gui.c
src/gps-bluetooth-bluez.c
src/gps-bluetooth-hildon.c
src/gps-browse.c
src/gps-conn.c
src/gps-conn.h
src/gps-nmea-parse.c
src/gps.c
src/gps.h
src/maemo-osso.c
src/map-download.c
src/map-repo.c
src/map.c
src/map.h
src/mapper.c
src/osm-db.c
src/route.c
src/settings-gui.c
src/settings.h
src/track.c
src/ui-common.c

index fcb15e85ab2d870251a10d9ade2870ee15a9b732..deb236fdbe05aa023e1fd0248db319b3d4b57a89 100644 (file)
@@ -106,10 +106,12 @@ if test "x$enable_btdbus" = "xno" ; then
   WITH_BLUEZ_DBUS_BT=no
 else
   WITH_BLUEZ_DBUS_BT=yes
+  WITH_BLUEZ=yes
   PKG_CHECK_MODULES(BLUEZ, bluez)
   AC_SUBST(BLUEZ_LIBS)
   AC_SUBST(BLUEZ_CFLAGS)
   AC_DEFINE([WITH_BLUEZ_DBUS_BT], 1, [bluez D-Bus bluetooth])
+  AC_DEFINE([WITH_BLUEZ], 1, [Bluez RFCOMM])
 fi
 
 AM_CONDITIONAL(HAVE_HILDON_DBUS_BT, [test "$enable_itbtdbus" = "yes"])
diff --git a/src/bluetooth-scan.h b/src/bluetooth-scan.h
new file mode 100644 (file)
index 0000000..bccc3ef
--- /dev/null
@@ -0,0 +1,30 @@
+#ifndef _MAPPER_BLUETOOTH_SCAN_H
+#define _MAPPER_BLUETOOTH_SCAN_H
+
+#include "config.h"
+
+#include <dbus/dbus-glib.h>
+
+#include "utils.h"
+#include "gps.h"
+#include "mapper-types.h"
+
+typedef struct _ScanInfo ScanInfo;
+struct _ScanInfo {
+       GtkWidget *settings_dialog;
+       GtkWidget *txt_rcvr_mac;
+       GtkWidget *scan_dialog;
+       GtkWidget *banner;
+       GtkListStore *store;
+       guint sid;
+#ifdef WITH_HILDON_DBUS_BT
+       DBusGProxy *req_proxy;
+       DBusGProxy *sig_proxy;
+#endif
+};
+
+gint scan_start_search(ScanInfo * scan_info);
+gboolean scan_bluetooth(GtkWidget * widget, ScanInfo * scan_info);
+gboolean scan_bluetooth_idle(ScanInfo * scan_info);
+
+#endif
diff --git a/src/bt.h b/src/bt.h
deleted file mode 100644 (file)
index 635de12..0000000
--- a/src/bt.h
+++ /dev/null
@@ -1,54 +0,0 @@
-#ifndef _MAPPER_BT_H
-#define _MAPPER_BT_H
-
-#include "config.h"
-
-#include <dbus/dbus-glib.h>
-
-#include "utils.h"
-#include "mapper-types.h"
-
-/** This enumerated type defines the possible connection states. */
-typedef enum {
-    /** The receiver is "off", meaning that either the bluetooth radio is
-     * off or the user has requested not to connect to the GPS receiver.
-     * No gtk_banner is visible. */
-       RCVR_OFF,
-
-    /** The connection with the receiver is down.  A gtk_banner is visible with
-     * the text, "Connecting to GPS receiver". */
-       RCVR_DOWN,
-
-    /** The connection with the receiver is up, but a GPS fix is not available.
-     * A gtk_banner is visible with the text, "(Re-)Establishing GPS fix". */
-       RCVR_UP,
-
-    /** The connection with the receiver is up and a GPS fix IS available.
-     * No gtk_banner is visible. */
-       RCVR_FIXED
-} ConnState;
-
-typedef struct _ScanInfo ScanInfo;
-struct _ScanInfo {
-       GtkWidget *settings_dialog;
-       GtkWidget *txt_rcvr_mac;
-       GtkWidget *scan_dialog;
-       GtkWidget *banner;
-       GtkListStore *store;
-       guint sid;
-#ifdef WITH_HILDON_DBUS_BT
-       DBusGProxy *req_proxy;
-       DBusGProxy *sig_proxy;
-#endif
-};
-
-ConnState _conn_state;
-
-void rcvr_disconnect(void);
-void rcvr_connect_later(void);
-gint scan_start_search(ScanInfo * scan_info);
-gboolean rcvr_connect_now(void);
-gboolean scan_bluetooth(GtkWidget * widget, ScanInfo * scan_info);
-gboolean scan_bluetooth_idle(ScanInfo * scan_info);
-
-#endif
index 96370a90244f406b5de456b985151a9270fd36bb..567933bae2311c1e05ae277327269fb762310d1e 100644 (file)
--- a/src/cb.c
+++ b/src/cb.c
@@ -50,7 +50,6 @@
 #include "gps.h"
 #include "map.h"
 #include "mapper-types.h"
-#include "bt.h"
 #include "ui-common.h"
 #include "db.h"
 #include "latlon.h"
@@ -271,7 +270,7 @@ switch (value) {
        break;
 }
 
-MACRO_RECALC_CENTER(new_center_unitx, new_center_unity);
+MACRO_RECALC_CENTER(_gps->data, new_center_unitx, new_center_unity);
 map_center_unit(new_center_unitx, new_center_unity);
 return TRUE;
 }
@@ -311,7 +310,7 @@ gboolean
 menu_cb_goto_gps(GtkAction *action)
 {
 _center_mode = CENTER_LATLON;
-map_center_unit(_gps->unitx, _gps->unity);
+map_center_unit(_gps->data.unitx, _gps->data.unity);
 map_update_location_from_center();
 MACRO_BANNER_SHOW_INFO(_window, _("At GPS coordinates."));
 return TRUE;
@@ -340,8 +339,8 @@ poi_info *p;
 
 if (_center_mode > 0) {
        /* Auto-Center is enabled - use the GPS position. */
-       lat=_gps->lat;
-       lon=_gps->lon;
+       lat=_gps->data.lat;
+       lon=_gps->data.lon;
 } else {
        /* Auto-Center is disabled - use the view center. */
        unit2latlon(_center.unitx, _center.unity, lat, lon);
@@ -390,14 +389,14 @@ return TRUE;
 gboolean 
 cb_zoom_auto(GtkAction * action)
 {
-map_set_autozoom(TRUE);
+map_set_autozoom(TRUE, _gps->data.speed);
 return TRUE;
 }
 
 gboolean 
 cb_zoom_base(GtkAction * action)
 {
-map_set_autozoom(FALSE);
+map_set_autozoom(FALSE, 0);
 map_set_zoom(3);
 return TRUE;
 }
@@ -405,7 +404,7 @@ return TRUE;
 gboolean 
 cb_zoomin(GtkAction * action)
 {
-map_set_autozoom(FALSE);
+map_set_autozoom(FALSE, 0);
 g_idle_add((GSourceFunc)map_zoom_in, NULL);
 return TRUE;
 }
@@ -413,7 +412,7 @@ return TRUE;
 gboolean 
 cb_zoomout(GtkAction * action)
 {
-map_set_autozoom(FALSE);
+map_set_autozoom(FALSE, 0);
 g_idle_add((GSourceFunc)map_zoom_out, NULL);
 return TRUE;
 }
@@ -434,17 +433,15 @@ gboolean
 menu_cb_enable_gps(GtkAction * action)
 {
 if ((_enable_gps = gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action)))) {
-       if (_rcvr_mac) {
-               gps_conn_set_state(RCVR_DOWN);
-               rcvr_connect_now();
-       } else {
+               gps_conn_set_state(_gps, RCVR_DOWN);
+       if (gps_connect_now(_gps)==FALSE) {
                popup_error(_window, _("Cannot enable GPS until a GPS Receiver MAC is set in the Settings dialog box."));
                set_action_activate("gps_enable", FALSE);
        }
 } else {
-       if (_conn_state > RCVR_OFF)
-               gps_conn_set_state(RCVR_OFF);
-       rcvr_disconnect();
+       if (_gps->io.conn > RCVR_OFF)
+               gps_conn_set_state(_gps, RCVR_OFF);
+       gps_disconnect(_gps);
        track_add(0, FALSE);
        _speed_excess=FALSE;
 }
@@ -455,7 +452,7 @@ set_action_sensitive("autocenter_latlon", _enable_gps);
 set_action_sensitive("autocenter_lead", _enable_gps);
 
 map_move_mark();
-gps_show_info(_gps);
+gps_show_info(&_gps->data);
 
 return TRUE;
 }
@@ -478,9 +475,9 @@ menu_cb_settings(GtkAction * action)
 if (settings_dialog()) {
        /* Settings have changed - reconnect to receiver. */
        if (_enable_gps) {
-               gps_conn_set_state(RCVR_DOWN);
-               rcvr_disconnect();
-               rcvr_connect_now();
+               gps_conn_set_state(_gps, RCVR_DOWN);
+               gps_disconnect(_gps);
+               gps_connect_now(_gps);
        }
 }
 MACRO_RECALC_FOCUS_BASE();
@@ -743,7 +740,7 @@ gdouble lat, lon;
 unit2latlon(unitx, unity, lat, lon);
 
 g_snprintf(buffer, sizeof(buffer), "%s: %.02lf %s", _("Distance"),
-        calculate_distance(_gps->lat, _gps->lon, lat, lon) * UNITS_CONVERT[_units], UNITS_TEXT[_units]);
+        calculate_distance(_gps->data.lat, _gps->data.lon, lat, lon) * UNITS_CONVERT[_units], UNITS_TEXT[_units]);
 MACRO_BANNER_SHOW_INFO(_window, buffer);
 }
 
@@ -940,8 +937,8 @@ poi_info poi;
 gdouble lat, lon;
 
 if (_center_mode>0) {
-       lat=_gps->lat;
-       lon=_gps->lon;
+       lat=_gps->data.lat;
+       lon=_gps->data.lon;
 } else {
        unit2latlon(_center.unitx, _center.unity, lat, lon);
 }
@@ -958,8 +955,8 @@ const gchar *name = gtk_action_get_name(action);
 poi_info *p;
 
 if (_center_mode>0) {
-       lat=_gps->lat;
-       lon=_gps->lon;
+       lat=_gps->data.lat;
+       lon=_gps->data.lon;
 } else {
        unit2latlon(_center.unitx, _center.unity, lat, lon);
 }
@@ -985,8 +982,8 @@ menu_cb_search_address(GtkAction *action)
 gdouble lat, lon;
 
 if (_center_mode>0) {
-       lat=_gps->lat;
-       lon=_gps->lon;
+       lat=_gps->data.lat;
+       lon=_gps->data.lon;
 } else {
        unit2latlon(_center.unitx, _center.unity, lat, lon);
 }
@@ -1027,9 +1024,9 @@ return TRUE;
 gboolean 
 cmenu_cb_loc_set_gps(GtkAction * action)
 {
-_gps->unitx = x2unit(_cmenu_position_x);
-_gps->unity = y2unit(_cmenu_position_y);
-unit2latlon(_gps->unitx, _gps->unity, _gps->lat, _gps->lon);
+_gps->data.unitx = x2unit(_cmenu_position_x);
+_gps->data.unity = y2unit(_cmenu_position_y);
+unit2latlon(_gps->data.unitx, _gps->data.unity, _gps->data.lat, _gps->data.lon);
 
 /* Move mark to new location. */
 map_refresh_mark();
index 2eec3af1fe63a8a438e2ff67016256508d342d15..cafda29437182d90d2c11192af61c19f898a8102 100644 (file)
@@ -50,7 +50,6 @@
 #include "db.h"
 #include "poi.h"
 #include "gps.h"
-#include "bt.h"
 #include "ui-common.h"
 #include "settings.h"
 #include "gpx.h"
@@ -236,8 +235,8 @@ config_dir = gnome_vfs_expand_initial_tilde(CONFIG_DIR_NAME);
 g_mkdir_with_parents(config_dir, 0700);
 
 /* Save Receiver MAC from GConf. */
-if (_rcvr_mac)
-       gconf_client_set_string(gconf_client, GCONF_KEY_RCVR_MAC, _rcvr_mac, NULL);
+if (_gps->io.address)
+       gconf_client_set_string(gconf_client, GCONF_KEY_RCVR_MAC, _gps->io.address, NULL);
 else
        gconf_client_unset(gconf_client, GCONF_KEY_RCVR_MAC, NULL);
 
@@ -289,8 +288,8 @@ gconf_client_set_string(gconf_client,
                        INFO_FONT_TEXT[_info_font_size], NULL);
 
 /* Save last latitude/longiture. */
-gconf_client_set_float(gconf_client, GCONF_KEY_LAT, _gps->lat, NULL);
-gconf_client_set_float(gconf_client, GCONF_KEY_LON, _gps->lon, NULL);
+gconf_client_set_float(gconf_client, GCONF_KEY_LAT, _gps->data.lat, NULL);
+gconf_client_set_float(gconf_client, GCONF_KEY_LON, _gps->data.lon, NULL);
 
 /* Save last center latitude/longitude. */
 unit2latlon(_center.unitx, _center.unity, center_lat, center_lon);
@@ -424,7 +423,7 @@ config_dir = gnome_vfs_expand_initial_tilde(CONFIG_DIR_NAME);
 g_mkdir_with_parents(config_dir, 0700);
 
 /* Get Receiver MAC from GConf.  Default is scanned via hci_inquiry. */
-_rcvr_mac = gconf_client_get_string(gconf_client, GCONF_KEY_RCVR_MAC, NULL);
+_gps->io.address = gconf_client_get_string(gconf_client, GCONF_KEY_RCVR_MAC, NULL);
 
 /* Get Auto-Download.  Default is FALSE. */
 _auto_download = gconf_client_get_bool(gconf_client, GCONF_KEY_AUTO_DOWNLOAD, NULL);
@@ -562,10 +561,10 @@ BOUND(_speed_limit, 1, 200);
 _auto_download = gconf_client_get_bool(gconf_client, GCONF_KEY_AUTO_DOWNLOAD, NULL);
 
 /* Get saved location */
-_gps->lat = gconf_client_get_float(gconf_client, GCONF_KEY_LAT, NULL);
-_gps->lon = gconf_client_get_float(gconf_client, GCONF_KEY_LON, NULL);
-if (_gps->lat==0.0) _gps->lat=64.20;
-if (_gps->lon==0.0) _gps->lon=22.20;
+_gps->data.lat = gconf_client_get_float(gconf_client, GCONF_KEY_LAT, NULL);
+_gps->data.lon = gconf_client_get_float(gconf_client, GCONF_KEY_LON, NULL);
+if (_gps->data.lat==0.0) _gps->data.lat=64.20;
+if (_gps->data.lon==0.0) _gps->data.lon=22.20;
 
 /* Home */
 _home.valid=TRUE;
@@ -602,7 +601,7 @@ if (_home.valid==FALSE) {
                center_lat = gconf_value_get_float(value);
                gconf_value_free(value);
        } else {
-               center_lat = _gps->lat;
+               center_lat = _gps->data.lat;
        }
 
        /* Get last saved longitude.  Default is last saved longitude. */
@@ -611,7 +610,7 @@ if (_home.valid==FALSE) {
                center_lon = gconf_value_get_float(value);
                gconf_value_free(value);
        } else {
-               center_lon = _gps->lon;
+               center_lon = _gps->data.lon;
        }
 
        latlon2unit(center_lat, center_lon, _center.unitx, _center.unity);
@@ -700,7 +699,7 @@ if (value) {
 }
 
 /* Initialize _conn_state based on _enable_gps-> */
-_conn_state = (_enable_gps ? RCVR_DOWN : RCVR_OFF);
+_gps->io.conn = (_enable_gps ? RCVR_DOWN : RCVR_OFF);
 
 /* Load the route locations. */
 {
index d04f16d3a683bc220f97579e76dade768878b5fb..251d02dee2d4d79beefd2397a497b79b3c0ce349 100644 (file)
@@ -38,7 +38,6 @@
 #include "gps.h"
 #include "map.h"
 #include "mapper-types.h"
-#include "bt.h"
 #include "ui-common.h"
 #include "settings.h"
 #include "filter.h"
index 8617fcd5c3d59ecc2c8ce5a6ade25b78993fe68e..ff0339157f90876516425447e9a33f489a39c56e 100644 (file)
@@ -21,7 +21,7 @@
 #include <bluetooth/hci_lib.h>
 #include <bluetooth/rfcomm.h>
 
-#include "bt.h"
+#include "bluetooth-scan.h"
 #include "gps.h"
 #include "map.h"
 #include "utils.h"
 #include "ui-common.h"
 #include "gps-conn.h"
 
-struct sockaddr_rc _rcvr_addr = { 0 };
-
-static gint fd;
-
-static gboolean
-channel_cb_connect(GIOChannel * src, GIOCondition condition, gpointer data)
-{
-gint error, size = sizeof(error);
-
-if (*_rcvr_mac != '/' && (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &size) || error)) {
-       g_printf("Error connecting to receiver; retrying...\n");
-       /* Try again. */
-       rcvr_disconnect();
-       rcvr_connect_later();
-} else {
-       g_printf("Connected to receiver!\n");
-       gps_conn_set_state(RCVR_UP);
-       _input_sid = g_io_add_watch_full(_channel, G_PRIORITY_LOW, G_IO_IN | G_IO_PRI, channel_cb_input, NULL, NULL);
-}
-
-_connect_sid = 0;
-return FALSE;
-}
-
-static gboolean 
-rcvr_connect_bt(void)
-{
-int r, e;
-r = connect(fd, (struct sockaddr *)&_rcvr_addr, sizeof(_rcvr_addr));
-e = errno;
-
-/* The socket is non blocking so handle it */
-if (r != 0) {
-       switch (e) {
-       case EAGAIN:
-       case EBUSY:
-       case EINPROGRESS:
-       case EALREADY:
-               g_printf("*** Connection in progress... %d %d\n", e, r);
-               perror("INFO: ");
-               return TRUE;
-       break;
-       case EHOSTUNREACH:
-               g_printf("*** Bluetooth/GPS device not found.\n");
-               rcvr_disconnect();
-#if 0
-        popup_error(_window, _("No bluetooth or GPS device found."));
-        set_action_activate("gps_enable", FALSE);
-#endif
-               return FALSE;
-       break;
-       default:
-               /* Connection failed.  Disconnect and try again later. */
-               g_printf("### Connect failed, retrying... %d %d\n", e, r);
-               perror("ERROR: ");
-               rcvr_disconnect();
-               rcvr_connect_later();
-               return FALSE;
-       break;
-       }
-}
-return TRUE;
-}
-
 gint 
 scan_start_search(ScanInfo * scan_info)
 {
-scan_info->sid = g_idle_add((GSourceFunc)scan_bluetooth_idle, scan_info);
+scan_info->sid=g_idle_add((GSourceFunc)scan_bluetooth_idle, scan_info);
 return 0;
 }
 
-/**
- * Disconnect from the receiver.  This method cleans up any and everything
- * that might be associated with the receiver.
- */
-void 
-rcvr_disconnect(void)
-{
-/* Remove watches. */
-if (_clater_sid) {
-       g_source_remove(_clater_sid);
-       _clater_sid = 0;
-}
-if (_error_sid) {
-       g_source_remove(_error_sid);
-       _error_sid = 0;
-}
-if (_connect_sid) {
-       g_source_remove(_connect_sid);
-       _connect_sid = 0;
-}
-if (_input_sid) {
-       g_source_remove(_input_sid);
-       _input_sid = 0;
-}
-
-/* Destroy the GIOChannel object. */
-if (_channel) {
-       g_io_channel_shutdown(_channel, FALSE, NULL);
-       g_io_channel_unref(_channel);
-       _channel = NULL;
-}
-
-/* Close the file descriptor. */
-if (fd != -1) {
-       close(fd);
-       fd = -1;
-}
-}
-
-/**
- * Connect to the receiver.
- * This method assumes that fd is -1 and _channel is NULL.  If unsure, call
- * rcvr_disconnect() first.
- * Since this is an idle function, this function returns whether or not it
- * should be called again, which is always FALSE.
- */
-gboolean 
-rcvr_connect_now()
-{
-if (!_rcvr_mac)
-       return FALSE;
-
-_rcvr_addr.rc_family = AF_BLUETOOTH;
-_rcvr_addr.rc_channel = 1;
-str2ba(_rcvr_mac, &_rcvr_addr.rc_bdaddr);
-
-#if 0
-_rcvr_addr.rc_channel = gconf_client_get_int(gconf_client, GCONF_KEY_RCVR_CHAN, NULL);
-if (_rcvr_addr.rc_channel < 1)
-       _rcvr_addr.rc_channel = 1;
-#endif
-
-if (_conn_state == RCVR_DOWN && _rcvr_mac) {
-#ifndef DEBUG_GPS
-       /* Create the file descriptor. */
-       if (*_rcvr_mac == '/')
-               fd = open(_rcvr_mac, O_RDONLY);
-       else
-               fd = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
-
-       /* If file descriptor creation failed, try again later.  Note that
-        * there is no need to call rcvr_disconnect() because the file
-        * descriptor creation is the first step, so if it fails, there's
-        * nothing to clean up. */
-       if (fd == -1) {
-               g_printf("Failed to create socket\n");
-               rcvr_connect_later();
-       } else {
-               /* Reset GPS read buffer */
-               _gps_read_buf_curr = _gps_read_buf;
-               *_gps_read_buf_curr = '\0';
-               _gps_read_buf_last = _gps_read_buf + GPS_READ_BUF_SIZE - 1;
-
-               /* Create channel and add watches. */
-               _channel = g_io_channel_unix_new(fd);
-               g_io_channel_set_encoding(_channel, NULL, NULL);
-               g_io_channel_set_flags(_channel, G_IO_FLAG_NONBLOCK, NULL);
-               _error_sid = g_io_add_watch_full(_channel, G_PRIORITY_HIGH_IDLE,
-                                       G_IO_ERR | G_IO_HUP, channel_cb_error, NULL, NULL);
-               _connect_sid = g_io_add_watch_full(_channel, G_PRIORITY_HIGH_IDLE,
-                                       G_IO_OUT, channel_cb_connect, NULL, NULL);
-               if (*_rcvr_mac != '/') {
-                       rcvr_connect_bt();
-               } else {
-                       g_printf("Using dev node: %s\n", _rcvr_mac);
-               }
-       }
-#else
-       /* We're in DEBUG mode, so instead of connecting, skip to FIXED. */
-       gps_conn_set_state(RCVR_FIXED);
-#endif
-}
-
-_clater_sid = 0;
-return FALSE;
-}
-
-/**
- * Place a request to connect about 1 second after the function is called.
- */
-void 
-rcvr_connect_later(void)
-{
-_clater_sid = g_timeout_add(1000, (GSourceFunc) rcvr_connect_now, NULL);
-}
-
 gboolean 
 scan_bluetooth_idle(ScanInfo * scan_info)
 {
index 97050f94392f29108c9f13f69d70809eee87fb65..e36d6bbb2fe711364a196e29c82ae327f25134b0 100644 (file)
 static guint errors;
 static gint fd;
 
-void rcvr_connect_later();     /* Forward declaration. */
-
-/*****************************************************************************/
-
-static gboolean
-channel_cb_connect(GIOChannel * src, GIOCondition condition, gpointer data)
-{
-_gps_read_buf_curr = _gps_read_buf;
-_gps_read_buf_last = _gps_read_buf + GPS_READ_BUF_SIZE - 1;
-gps_conn_set_state(RCVR_UP);
-_input_sid = g_io_add_watch_full(_channel, G_PRIORITY_HIGH_IDLE, G_IO_IN | G_IO_PRI, channel_cb_input, NULL, NULL);
-_connect_sid = 0;
-errors=0;
-return FALSE;
-}
-
-/**
- * Disconnect from the receiver.  This method cleans up any and everything
- * that might be associated with the receiver.
- */
-void 
-rcvr_disconnect()
-{
-GError *error = NULL;
-
-/* Remove watches. */
-if (_clater_sid) {
-       g_source_remove(_clater_sid);
-       _clater_sid = 0;
-}
-if (_error_sid) {
-       g_source_remove(_error_sid);
-       _error_sid = 0;
-}
-if (_connect_sid) {
-       g_source_remove(_connect_sid);
-       _connect_sid = 0;
-}
-if (_input_sid) {
-       g_source_remove(_input_sid);
-       _input_sid = 0;
-}
-
-/* Destroy the GIOChannel object. */
-if (_channel) {
-       g_io_channel_shutdown(_channel, FALSE, NULL);
-       g_io_channel_unref(_channel);
-       _channel = NULL;
-}
-
-/* Close the file descriptor. */
-if (fd != -1) {
-       close(fd);
-       fd = -1;
-}
-
-if (_rfcomm_req_proxy) {
-       dbus_g_proxy_call(_rfcomm_req_proxy,
-                       BTCOND_RFCOMM_CANCEL_CONNECT_REQ, &error,
-                       G_TYPE_STRING, _rcvr_mac, G_TYPE_STRING,
-                       "SPP", G_TYPE_INVALID, G_TYPE_INVALID);
-       error = NULL;
-       dbus_g_proxy_call(_rfcomm_req_proxy,
-                       BTCOND_RFCOMM_DISCONNECT_REQ, &error,
-                       G_TYPE_STRING, _rcvr_mac, G_TYPE_STRING,
-                       "SPP", G_TYPE_INVALID, G_TYPE_INVALID);
-}
-}
-
 void 
 rcvr_connect_fd(gchar *fdpath)
 {
@@ -216,15 +147,6 @@ _clater_sid = 0;
 return FALSE;
 }
 
-/**
- * Place a request to connect about 1 second after the function is called.
- */
-void 
-rcvr_connect_later()
-{
-_clater_sid = g_timeout_add(1000, (GSourceFunc)rcvr_connect_now, NULL);
-}
-
 /**
  * Bluetooth device scanning functions below
  */
@@ -259,8 +181,7 @@ if (NULL == (scan_info->sig_proxy = dbus_g_proxy_new_for_name(dbus_conn, BTSEARC
        return 2;
 }
 
-dbus_g_object_register_marshaller(_bt_maemo_VOID__STRING_STRING_POINTER_UCHAR_UINT,
-     G_TYPE_NONE, G_TYPE_STRING, G_TYPE_STRING, DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UCHAR, G_TYPE_UINT, G_TYPE_INVALID);
+dbus_g_object_register_marshaller(_bt_maemo_VOID__STRING_STRING_POINTER_UCHAR_UINT, G_TYPE_NONE, G_TYPE_STRING, G_TYPE_STRING, DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UCHAR, G_TYPE_UINT, G_TYPE_INVALID);
 
 dbus_g_proxy_add_signal(scan_info->sig_proxy, BTSEARCH_DEV_FOUND_SIG, G_TYPE_STRING, G_TYPE_STRING, DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UCHAR, G_TYPE_UINT, G_TYPE_INVALID);
 dbus_g_proxy_connect_signal(scan_info->sig_proxy, BTSEARCH_DEV_FOUND_SIG, G_CALLBACK(scan_cb_dev_found), scan_info, NULL);
index e6f817812b1e78a2b40552f0256d52f41cb6c259..57b8703bff3a8201bc49e42e9f99f34873a333ae 100644 (file)
@@ -47,7 +47,7 @@
 
 #include "utils.h"
 #include "mapper-types.h"
-#include "bt.h"
+#include "bluetooth-scan.h"
 
 /**
  * Scan for all bluetooth devices.  This method can take a few seconds,
index 5f0b874477a07d1d038b5d8731a22399be13b7cb..6a37a1e2bb39fe80b150ad8b989b874fb032b47d 100644 (file)
@@ -46,7 +46,6 @@ static GtkWidget *fix_banner = NULL;
 #include "settings.h"
 #include "gps.h"
 #include "map.h"
-#include "bt.h"
 #include "ui-common.h"
 #include "gps-conn.h"
 
@@ -54,9 +53,9 @@ static GtkWidget *fix_banner = NULL;
  * Set the connection state. This function controls all connection-related banners.
  */
 void 
-gps_conn_set_state(ConnState new_conn_state)
+gps_conn_set_state(Gps *gps, GpsConnState new_conn_state)
 {
-switch (_conn_state = new_conn_state) {
+switch (gps->io.conn=new_conn_state) {
        case RCVR_OFF:
        case RCVR_FIXED:
                if (connect_banner) {
@@ -93,7 +92,7 @@ switch (_conn_state = new_conn_state) {
 }
 
 void
-gps_conn_set_progress(gdouble fix)
+gps_conn_set_progress(Gps *gps, gdouble fix)
 {
 #ifdef WITH_HILDON
 hildon_banner_set_fraction(fix_banner, fix);
index 4067421766b55b329eec4afe02fc2a68eae58e19..f4dc4d4323a4a086cc9fcafc7f24fe88dcca1ff6 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef _MAPPER_GPS_CONN_H
 #define _MAPPER_GPS_CONN_H
 
-void gps_conn_set_state(ConnState new_conn_state);
-void gps_conn_set_progress(gdouble fix);
+void gps_conn_set_state(Gps *gps, GpsConnState new_conn_state);
+void gps_conn_set_progress(Gps *gps, gdouble fix);
 
 #endif
index 195014d5de9568345dc05edef12075cf57c3ea1d..2971ee2e782714159090410d068f2c1e85de5e7d 100644 (file)
@@ -39,7 +39,6 @@
 #include <libxml/parser.h>
 
 #include "utils.h"
-#include "bt.h"
 #include "gps.h"
 #include "mapper-types.h"
 #include "ui-common.h"
 #include "gtkgps.h"
 #include "gtkcompass.h"
 
-gboolean
-channel_cb_error(GIOChannel *src, GIOCondition condition, gpointer data)
-{
-/* An error has occurred - re-connect(). */
-rcvr_disconnect();
-track_add(NULL, FALSE);
-_speed_excess = FALSE;
-
-if (_conn_state > RCVR_OFF) {
-       gps_conn_set_state(RCVR_DOWN);
-       rcvr_connect_later();
-}
-return FALSE;
-}
-
 static void
-channel_parse_rmc(gchar * sentence)
+gps_nmea_parse_rmc(Gps *gps, gchar * sentence)
 {
        /* Recommended Minimum Navigation Information C
         *  1) UTC Time
@@ -102,14 +86,14 @@ channel_parse_rmc(gchar * sentence)
        /* Token is now Status. */
        if (token && *token == 'A') {
                /* Data is valid. */
-               if (_conn_state != RCVR_FIXED) {
+               if (gps->io.conn != RCVR_FIXED) {
                        newly_fixed = TRUE;
-                       gps_conn_set_state(RCVR_FIXED);
+                       gps_conn_set_state(gps, RCVR_FIXED);
                }
        } else {
                /* Data is invalid - not enough satellites?. */
-               if (_conn_state != RCVR_UP) {
-                       gps_conn_set_state(RCVR_UP);
+               if (gps->io.conn != RCVR_UP) {
+                       gps_conn_set_state(gps, RCVR_UP);
                        track_add(NULL, FALSE);
                }
        }
@@ -123,13 +107,13 @@ channel_parse_rmc(gchar * sentence)
                MACRO_PARSE_FLOAT(tmpd, dpoint - 2);
                dpoint[-2] = '\0';
                MACRO_PARSE_INT(tmpi, token);
-               _gps->lat = tmpi + (tmpd * (1.0 / 60.0));
+               gps->data.lat = tmpi + (tmpd * (1.0 / 60.0));
        }
 
        /* Parse N or S. */
        token = strsep(&sentence, DELIM);
        if (token && *token == 'S')
-               _gps->lat = -_gps->lat;
+               gps->data.lat = -gps->data.lat;
 
        /* Parse the longitude. */
        token = strsep(&sentence, DELIM);
@@ -140,27 +124,27 @@ channel_parse_rmc(gchar * sentence)
                MACRO_PARSE_FLOAT(tmpd, dpoint - 2);
                dpoint[-2] = '\0';
                MACRO_PARSE_INT(tmpi, token);
-               _gps->lon = tmpi + (tmpd * (1.0 / 60.0));
+               gps->data.lon = tmpi + (tmpd * (1.0 / 60.0));
        }
 
        /* Parse E or W. */
        token = strsep(&sentence, DELIM);
        if (token && *token == 'W')
-               _gps->lon = -_gps->lon;
+               gps->data.lon = -gps->data.lon;
 
        /* Parse speed over ground, knots. */
        token = strsep(&sentence, DELIM);
        if (token && *token) {
-               MACRO_PARSE_FLOAT(_gps->speed, token);
-               if (_gps->fix > FIX_NOFIX) {
-                       _gps->maxspeed=MAX(_gps->maxspeed, _gps->speed);
+               MACRO_PARSE_FLOAT(gps->data.speed, token);
+               if (gps->data.fix > FIX_NOFIX) {
+                       gps->data.maxspeed=MAX(gps->data.maxspeed, gps->data.speed);
                }
        }
 
        /* Parse heading, degrees from true north. */
        token = strsep(&sentence, DELIM);
        if (token && *token) {
-               MACRO_PARSE_FLOAT(_gps->heading, token);
+               MACRO_PARSE_FLOAT(gps->data.heading, token);
        }
 
        /* Parse date. */
@@ -170,25 +154,25 @@ channel_parse_rmc(gchar * sentence)
                gpsdate[6] = '\0';      /* Make sure time is 6 chars long. */
                strcat(gpsdate, token);
                strptime(gpsdate, "%H%M%S%d%m%y", &time);
-               _gps->time = mktime(&time) + _gmtoffset;
+               gps->data.time = mktime(&time) + _gmtoffset;
        } else
-               _gps->time = time(NULL);
+               gps->data.time = time(NULL);
 
        /* Add new data to track only if we have a fix */
        _track_store=TRUE;
 
-       gps_integerize_data(_gps);
-       gps_display_data_speed(info_banner.speed, _gps->speed);
+       gps_data_integerize(&gps->data);
+       gps_display_data_speed(info_banner.speed, gps->data.speed);
 
-       if ((_conn_state==RCVR_FIXED) && (_track_store==TRUE) && filter_check(&filter, _gps, &map_loc)==TRUE) {
+       if ((gps->io.conn==RCVR_FIXED) && (_track_store==TRUE) && filter_check(&filter, &gps->data, &map_loc)==TRUE) {
                track_add(_gps, newly_fixed);
-               _gps->lheading=_gps->heading;
+               gps->data.lheading=gps->data.heading;
                map_refresh_mark();
        }
 }
 
 static void
-channel_parse_gga(gchar * sentence)
+gps_nmea_parse_gga(Gps *gps, gchar * sentence)
 {
        /* GGA          Global Positioning System Fix Data
           1. Fix Time
@@ -235,7 +219,7 @@ channel_parse_gga(gchar * sentence)
        /* Parse Fix quality */
        token = strsep(&sentence, DELIM);
        if (token && *token)
-               MACRO_PARSE_INT(_gps->fixquality, token);
+               MACRO_PARSE_INT(gps->data.fixquality, token);
 
        /* Skip number of satellites */
        token = strsep(&sentence, DELIM);
@@ -243,18 +227,18 @@ channel_parse_gga(gchar * sentence)
        /* Parse Horizontal dilution of position */
        token = strsep(&sentence, DELIM);
        if (token && *token)
-               MACRO_PARSE_INT(_gps->hdop, token);
+               MACRO_PARSE_INT(gps->data.hdop, token);
 
        /* Altitude */
        token = strsep(&sentence, DELIM);
        if (token && *token) {
-               MACRO_PARSE_FLOAT(_gps->altitude, token);
+               MACRO_PARSE_FLOAT(gps->data.altitude, token);
        } else
-               _gps->altitude = NAN;
+               gps->data.altitude = NAN;
 }
 
 static void
-channel_parse_gsa(gchar * sentence)
+gps_nmea_parse_gsa(Gps *gps, gchar * sentence)
 {
        /* GPS DOP and active satellites
         *  1) Auto selection of 2D or 3D fix (M = manual)
@@ -270,7 +254,7 @@ channel_parse_gsa(gchar * sentence)
        guint i,si;
        gint satforfix[12];
 
-       vprintf("%s(): %s\n", __PRETTY_FUNCTION__, sentence);
+       g_debug("%s(): %s\n", __PRETTY_FUNCTION__, sentence);
 
 #define DELIM ","
 
@@ -280,9 +264,9 @@ channel_parse_gsa(gchar * sentence)
        /* 3D fix. */
        token = strsep(&sentence, DELIM);
        if (token && *token)
-               MACRO_PARSE_INT(_gps->fix, token);
+               MACRO_PARSE_INT(gps->data.fix, token);
 
-       _gps->satinuse = 0;
+       gps->data.satinuse = 0;
        for (i = 0; i < 12; i++) {
                gint fprn;
                token = strsep(&sentence, DELIM);
@@ -291,33 +275,33 @@ channel_parse_gsa(gchar * sentence)
                else
                        fprn=-1;
                satforfix[i]=fprn;
-               _gps->sat[i].fix=FALSE;
+               gps->data.sat[i].fix=FALSE;
        }
 
        for (i=0;i<12;i++)
                for (si=0;si<12;si++) {
-                       if (_gps->sat[i].prn==satforfix[si])
-                               _gps->sat[i].fix=TRUE;
+                       if (gps->data.sat[i].prn==satforfix[si])
+                               gps->data.sat[i].fix=TRUE;
        }
 
        /* PDOP */
        token = strsep(&sentence, DELIM);
        if (token && *token)
-               MACRO_PARSE_FLOAT(_gps->pdop, token);
+               MACRO_PARSE_FLOAT(gps->data.pdop, token);
 
        /* HDOP */
        token = strsep(&sentence, DELIM);
        if (token && *token)
-               MACRO_PARSE_FLOAT(_gps->hdop, token);
+               MACRO_PARSE_FLOAT(gps->data.hdop, token);
 
        /* VDOP */
        token = strsep(&sentence, DELIM);
        if (token && *token)
-               MACRO_PARSE_FLOAT(_gps->vdop, token);
+               MACRO_PARSE_FLOAT(gps->data.vdop, token);
 }
 
 static void
-channel_parse_gsv(gchar * sentence)
+gps_nmea_parse_gsv(Gps *gps, gchar * sentence)
 {
        /* Must be GSV - Satellites in view
         *  1) total number of messages
@@ -350,9 +334,9 @@ channel_parse_gsv(gchar * sentence)
        /* Parse number of satellites in view. */
        token = strsep(&sentence, DELIM);
        if (token && *token) {
-               MACRO_PARSE_INT(_gps->satinview, token);
-               if (_gps->satinview > 12)       /* Handle buggy NMEA. */
-                       _gps->satinview = 12;
+               MACRO_PARSE_INT(gps->data.satinview, token);
+               if (gps->data.satinview > 12)   /* Handle buggy NMEA. */
+                       gps->data.satinview = 12;
        }
 
        /* Loop until there are no more satellites to parse. */
@@ -360,23 +344,23 @@ channel_parse_gsv(gchar * sentence)
                /* Get token for Satellite Number. */
                token = strsep(&sentence, DELIM);
                if (token && *token)
-                       _gps->sat[satcnt].prn = atoi(token);
+                       gps->data.sat[satcnt].prn = atoi(token);
 
                /* Get token for elevation in degrees (0-90). */
                token = strsep(&sentence, DELIM);
                if (token && *token)
-                       _gps->sat[satcnt].elevation = atoi(token);
+                       gps->data.sat[satcnt].elevation = atoi(token);
 
                /* Get token for azimuth in degrees to true north (0-359). */
                token = strsep(&sentence, DELIM);
                if (token && *token)
-                       _gps->sat[satcnt].azimuth = atoi(token);
+                       gps->data.sat[satcnt].azimuth = atoi(token);
 
                /* Get token for SNR. */
                token = strsep(&sentence, DELIM);
-               if (token && *token && (_gps->sat[satcnt].snr = atoi(token))) {
+               if (token && *token && (gps->data.sat[satcnt].snr = atoi(token))) {
                        /* SNR is non-zero - add to total and count as used. */
-                       running_total += _gps->sat[satcnt].snr;
+                       running_total += gps->data.sat[satcnt].snr;
                        num_sats_used++;
                }
                satcnt++;
@@ -385,13 +369,13 @@ channel_parse_gsv(gchar * sentence)
        if (msgcnt == nummsgs) {
                /*  This is the last message. Calculate signal strength. */
                if (num_sats_used) {
-                       if (_conn_state == RCVR_UP) {
+                       if (gps->io.conn==RCVR_UP) {
                                gdouble fraction = running_total * sqrt(num_sats_used) / num_sats_used / 100.0;
                                BOUND(fraction, 0.0, 1.0);
-                               gps_conn_set_progress(fraction);
+                               gps_conn_set_progress(gps, fraction);
                        }
-                       running_total = 0;
-                       num_sats_used = 0;
+                       running_total=0;
+                       num_sats_used=0;
                }
                satcnt = 0;
 
@@ -400,100 +384,28 @@ channel_parse_gsv(gchar * sentence)
        }
 }
 
-static gboolean
-channel_parse_buffer(gpointer data)
+gboolean
+gps_nmea_parse(gchar *data)
 {
-gchar *buf=(gchar *)data;
-
-if (!strncmp(buf + 3, "GSV", 3)) {
-       if (_conn_state == RCVR_UP)
-               channel_parse_gsv(buf + 7);
-} else if (!strncmp(buf + 3, "RMC", 3))
-       channel_parse_rmc(buf + 7);
-else if (!strncmp(buf + 3, "GGA", 3))
-       channel_parse_gga(buf + 7);
-else if (!strncmp(buf + 3, "GSA", 3))
-       channel_parse_gsa(buf + 7);
-else g_print("Unknown NMEA: [%s]\n", buf);
-
-g_free(buf);
+Gps *gps=_gps;
+
+if (!strncmp(data + 3, "GSV", 3)) {
+       if (gps->io.conn==RCVR_UP)
+               gps_nmea_parse_gsv(gps, data + 7);
+} else if (!strncmp(data + 3, "RMC", 3))
+       gps_nmea_parse_rmc(gps, data + 7);
+else if (!strncmp(data + 3, "GGA", 3))
+       gps_nmea_parse_gga(gps, data + 7);
+else if (!strncmp(data + 3, "GSA", 3))
+       gps_nmea_parse_gsa(gps, data + 7);
+else g_debug("Unknown NMEA: [%s]\n", data);
+g_free(data);
 
 if (_gps_info)
-       gps_display_data(_gps);
+       gps_display_data(&gps->data);
 
 if (_satdetails_on)
-       gps_display_details(_gps);
+       gps_display_details(&gps->data);
 
 return FALSE;
 }
-
-gboolean
-channel_cb_input(GIOChannel *src, GIOCondition condition, gpointer data)
-{
-gsize bytes_read;
-GIOStatus status;
-gchar *eol;
-
-vprintf("%s(%d)\n", __PRETTY_FUNCTION__, condition);
-
-status=g_io_channel_read_chars(_channel, _gps_read_buf_curr, _gps_read_buf_last - _gps_read_buf_curr, &bytes_read, NULL);
-
-switch (status) {
-       case G_IO_STATUS_NORMAL:
-       _gps_read_buf_curr += bytes_read;
-       *_gps_read_buf_curr = '\0';     /* append a \0 so we can read as string */
-       while ((eol = strchr(_gps_read_buf, '\n'))) {
-               gchar *sptr = _gps_read_buf + 1;        /* Skip the $ */
-               guint csum = 0;
-               if (*_gps_read_buf == '$') {
-                       /* This is the beginning of a sentence; okay to parse. */
-                       *eol = '\0';    /* overwrite \n with \0 */
-                       while (*sptr && *sptr != '*')
-                               csum ^= *sptr++;
-
-                       /* If we're at a \0 (meaning there is no checksum), or if the
-                        * checksum is good, then parse the sentence. */
-                       if (!*sptr || csum == strtol(sptr + 1, NULL, 16)) {
-                               gchar *data;
-
-                               if (*sptr)
-                                       *sptr = '\0';   /* take checksum out of the buffer. */
-
-                               data=g_strdup(_gps_read_buf);
-                               g_idle_add_full(G_PRIORITY_HIGH_IDLE, (GSourceFunc)channel_parse_buffer, data, NULL);
-                       } else {
-                               /* There was a checksum, and it was bad. */
-                               g_printerr("%s: Bad checksum in NMEA sentence:\n%s\n", __PRETTY_FUNCTION__, _gps_read_buf);
-                       }
-               }
-
-               /* If eol is at or after (_gps_read_buf_curr - 1) */
-               if (eol >= (_gps_read_buf_curr - 1)) {
-                       /* Last read was a newline - reset read buffer */
-                       _gps_read_buf_curr = _gps_read_buf;
-                       *_gps_read_buf_curr = '\0';
-               } else {
-                       /* Move the next line to the front of the buffer. */
-                       memmove(_gps_read_buf, eol + 1, _gps_read_buf_curr - eol);      /* include terminating 0 */
-                       /* Subtract _curr so that it's pointing at the new \0. */
-                       _gps_read_buf_curr -= (eol - _gps_read_buf + 1);
-               }
-       }
-       break;
-       case G_IO_STATUS_ERROR:
-       case G_IO_STATUS_EOF:
-               rcvr_disconnect();
-               rcvr_connect_later();
-               return FALSE;
-       break;
-       case G_IO_STATUS_AGAIN:
-               return TRUE;
-       break;
-       default:
-               g_assert_not_reached();
-       break;
-}
-
-vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-return TRUE;
-}
index 4c9e63dc79ffbb06ff292b1124d4bc03a56c93da..098b17b8d7866ea14664ed62b5a15c4121239ad8 100644 (file)
--- a/src/gps.c
+++ b/src/gps.c
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
+#include "config.h"
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <stddef.h>
+#include <libintl.h>
+#include <locale.h>
+#include <math.h>
+#include <errno.h>
+#include <sys/wait.h>
+#include <glib/gstdio.h>
+#include <fcntl.h>
+
 #include "gps.h"
 #include "latlon.h"
 #include "map.h"
+#include "gps-nmea-parse.h"
+#include "track.h"
+
+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);
+static gboolean gps_connect_socket(Gps *gps);
 
-GpsData *
-gps_init(void)
+/**
+ * Init GPS structure
+ */
+Gps *
+gps_new(void)
 {
-GpsData *gps;
+Gps *gps;
 
-gps=g_slice_new0(GpsData);
-gps->fix=FIX_NOFIX;
-gps_integerize_data(gps);
+gps=g_slice_new0(Gps);
+gps->data.fix=FIX_NOFIX;
+gps->io.fd=-1;
+gps->io.conn=RCVR_OFF;
+gps_data_integerize(&gps->data);
 return gps;
 }
 
 /**
  * Convert the float lat/lon/speed/heading data into integer units.
+ * Also calculate offsets.
  */
 void 
-gps_integerize_data(GpsData *gps)
+gps_data_integerize(GpsData *gpsdata)
 {
 gdouble tmp;
 
-tmp=(gps->heading*(1.f/180.f))*G_PI;
-latlon2unit(gps->lat, gps->lon, gps->unitx, gps->unity);
-gps->vel_offsetx=(gint)(floor(gps->speed*sin(tmp)+0.5f));
-gps->vel_offsety=-(gint)(floor(gps->speed*cos(tmp)+0.5f));
+tmp=(gpsdata->heading*(1.f/180.f))*G_PI;
+latlon2unit(gpsdata->lat, gpsdata->lon, gpsdata->unitx, gpsdata->unity);
+gpsdata->vel_offsetx=(gint)(floor(gpsdata->speed*sin(tmp)+0.5f));
+gpsdata->vel_offsety=-(gint)(floor(gpsdata->speed*cos(tmp)+0.5f));
+}
+
+/**
+ * Place a request to connect about 1 second after the function is called.
+ */
+void 
+gps_connect_later(Gps *gps)
+{
+g_assert(gps);
+g_assert(gps->io.clater_sid!=0);
+gps->io.clater_sid=g_timeout_add(1000, (GSourceFunc)gps_connect_now, gps);
+}
+
+gboolean
+gps_connect(Gps *gps)
+{
+switch (gps->io.type) {
+       case GPS_IO_FILE:
+               return TRUE;
+       break;
+       case GPS_IO_RFCOMM:
+       case GPS_IO_TCP:
+       case GPS_IO_GPSD:
+               gps_connect_socket(gps);
+       break;
+       case GPS_IO_GYPSY:
+               return FALSE;
+       break;
+       default:
+       break;
+}
+return FALSE;
+}
+
+static gboolean 
+gps_connect_socket(Gps *gps)
+{
+gint r, e;
+switch (gps->io.type) {
+#ifdef WITH_BLUEZ
+       case GPS_IO_RFCOMM:
+               r=connect(gps->io.fd, (struct sockaddr *)&gps->io.rcvr_addr_rc, sizeof(gps->io.rcvr_addr_rc));
+       break;
+#endif
+       case GPS_IO_TCP:
+       case GPS_IO_GPSD:
+               r=connect(gps->io.fd, (struct sockaddr *)&gps->io.rcvr_addr_in, sizeof(gps->io.rcvr_addr_in));
+       break;
+       default:
+               return FALSE;
+}
+e=errno;
+
+/* The socket is non blocking so handle it */
+if (r != 0) {
+       switch (e) {
+       case EAGAIN:
+       case EBUSY:
+       case EINPROGRESS:
+       case EALREADY:
+               g_printf("*** Connection in progress... %d %d\n", e, r);
+               perror("INFO: ");
+               return TRUE;
+       break;
+       case EHOSTUNREACH:
+               g_printf("*** Bluetooth/GPS device not found.\n");
+               gps_disconnect(gps);
+#if 0
+        set_action_activate("gps_enable", FALSE);
+        popup_error(_window, _("No bluetooth or GPS device found."));
+#endif
+               return FALSE;
+       break;
+       default:
+               /* Connection failed.  Disconnect and try again later. */
+               g_printf("### Connect failed, retrying... %d %d\n", e, r);
+               perror("ERROR: ");
+               gps_disconnect(gps);
+               gps_connect_later(gps);
+               return FALSE;
+       break;
+       }
 }
+return TRUE;
+}
+
+void 
+gps_disconnect(Gps *gps)
+{
+g_assert(gps);
+
+/* Remove watches. */
+if (gps->io.clater_sid) {
+       g_source_remove(gps->io.clater_sid);
+       gps->io.clater_sid=0;
+}
+if (gps->io.error_sid) {
+       g_source_remove(gps->io.error_sid);
+       gps->io.error_sid=0;
+}
+if (gps->io.connect_sid) {
+       g_source_remove(gps->io.connect_sid);
+       gps->io.connect_sid=0;
+}
+if (gps->io.input_sid) {
+       g_source_remove(gps->io.input_sid);
+       gps->io.input_sid=0;
+}
+
+/* Destroy the GIOChannel object. */
+if (gps->io.channel) {
+       g_io_channel_shutdown(gps->io.channel, FALSE, NULL);
+       g_io_channel_unref(gps->io.channel);
+       gps->io.channel=NULL;
+}
+
+/* Close the file descriptor. */
+if (gps->io.fd!=-1) {
+       close(gps->io.fd);
+       gps->io.fd=-1;
+}
+
+#ifdef WITH_HILDON_DBUS_BT
+if (gps->io.type==GPS_IO_HILDON_DBUS && gps->io.rfcomm_req_proxy) {
+               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);
+       }
+}
+#endif
+
+}
+
+/**
+ * Connect to the receiver.
+ * This method assumes that fd is -1 and _channel is NULL.  If unsure, call
+ * gps_disconnect() first.
+ * Since this is an idle function, this function returns whether or not it
+ * should be called again, which is always FALSE.
+ */
+gboolean 
+gps_connect_now(Gps *gps)
+{
+gint fd;
+
+g_assert(gps);
+
+switch (gps->io.type) {
+       case GPS_IO_FILE:
+               if (*gps->io.address=='/')
+                       gps->io.fd=open(gps->io.address, O_RDONLY);
+               else
+                       return FALSE;
+       break;
+       case GPS_IO_TCP:
+       case GPS_IO_GPSD:
+               if (gps->io.conn==RCVR_DOWN && gps->io.address) {
+                       fd=socket(AF_INET, SOCK_STREAM, 0);
+                       if (fd==-1) {
+                               g_debug("Failed to create socket\n");
+                               gps_connect_later(gps);
+                               return FALSE;
+                       }
+                       memcpy(&gps->io.rcvr_addr_in.sin_addr.s_addr, gps->io.address, strlen(gps->io.address));
+                       gps->io.rcvr_addr_in.sin_family = AF_INET;
+                       gps->io.rcvr_addr_in.sin_port = htons(gps->io.port);
+                       gps->io.fd=fd;
+               } else {
+                       return FALSE;
+               }
+       break;
+       case GPS_IO_RFCOMM:
+#ifdef WITH_BLUEZ
+               if (!gps->io.address)
+                       return FALSE;
+
+               if (gps->io.conn==RCVR_DOWN && gps->io.address) {
+                       fd=socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
+
+                       /* If file descriptor creation failed, try again later.  Note that
+                        * there is no need to call rcvr_disconnect() because the file
+                        * descriptor creation is the first step, so if it fails, there's
+                        * nothing to clean up. */
+                       if (fd==-1) {
+                               g_debug("Failed to create socket\n");
+                               gps_connect_later(gps);
+                               return FALSE;
+                       }
+                       gps->io.fd=fd;
+                       gps->io.rcvr_addr_rc.rc_family=AF_BLUETOOTH;
+                       gps->io.rcvr_addr_rc.rc_channel=1;
+                       str2ba(gps->io.address, &gps->io.rcvr_addr_rc.rc_bdaddr);
+               }
+#endif
+               return FALSE;
+       break;
+       default:
+               return FALSE;
+       break;
+}
+
+/* Reset GPS read buffer */
+gps->io.curr=gps->io.buffer;
+*gps->io.curr = '\0';
+gps->io.last=gps->io.buffer+GPS_READ_BUF_SIZE-1;
+
+/* Create channel and add watches. */
+gps->io.channel=g_io_channel_unix_new(gps->io.fd);
+g_io_channel_set_encoding(gps->io.channel, NULL, NULL);
+g_io_channel_set_flags(gps->io.channel, G_IO_FLAG_NONBLOCK, NULL);
+gps->io.error_sid=g_io_add_watch_full(gps->io.channel, G_PRIORITY_HIGH_IDLE, G_IO_ERR | G_IO_HUP, gps_channel_cb_error, NULL, NULL);
+gps->io.connect_sid=g_io_add_watch_full(gps->io.channel, G_PRIORITY_HIGH_IDLE, G_IO_OUT, gps_channel_cb_connect, NULL, NULL);
+gps->io.clater_sid=0;
+gps_connect(gps);
+return FALSE;
+}
+
+/**
+ * Connection callback
+ */
+static gboolean
+gps_channel_cb_connect(GIOChannel * src, GIOCondition condition, gpointer data)
+{
+gint error, size = sizeof(error);
+Gps *gps=(Gps *)data;
+
+g_assert(data);
+
+gps->io.curr=gps->io.buffer;
+gps->io.last=gps->io.buffer+GPS_READ_BUF_SIZE-1;
+
+switch (gps->io.type) {
+       case GPS_IO_TCP:
+       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");
+                       gps_disconnect(gps);
+                       gps_connect_later(gps);
+                       gps->io.connect_sid=0;
+                       return FALSE;
+               }
+       break;
+       case GPS_IO_FILE:
+
+       break;
+       default:
+               return FALSE;
+       break;
+}
+
+g_printf("Connected to receiver!\n");
+gps_conn_set_state(gps, RCVR_UP);
+gps->io.input_sid=g_io_add_watch_full(gps->io.channel, G_PRIORITY_HIGH_IDLE, G_IO_IN | G_IO_PRI, gps_channel_cb_input, gps, NULL);
+gps->io.errors=0;
+gps->io.connect_sid=0;
+return FALSE;
+}
+
+static gboolean
+gps_channel_cb_error(GIOChannel *src, GIOCondition condition, gpointer data)
+{
+Gps *gps=(Gps *)data;
+
+g_assert(data);
+/* An error has occurred - re-connect(). */
+gps_disconnect(gps);
+track_add(NULL, FALSE);
+/* _speed_excess = FALSE; */
+
+if (gps->io.conn > RCVR_OFF) {
+       gps_conn_set_state(gps, RCVR_DOWN);
+       gps_connect_later(gps);
+}
+return FALSE;
+}
+
+static gboolean
+gps_channel_cb_input(GIOChannel *src, GIOCondition condition, gpointer data)
+{
+gsize bytes_read;
+GIOStatus status;
+gchar *eol;
+Gps *gps=(Gps *)data;
+
+g_debug("%s(%d)\n", __PRETTY_FUNCTION__, condition);
+g_assert(data);
+
+status=g_io_channel_read_chars(gps->io.channel, gps->io.curr, gps->io.last-gps->io.curr, &bytes_read, NULL);
+switch (status) {
+       case G_IO_STATUS_NORMAL:
+       gps->io.curr += bytes_read;
+       *gps->io.curr = '\0';   /* append a \0 so we can read as string */
+       while ((eol = strchr(gps->io.buffer, '\n'))) {
+               gchar *sptr = gps->io.buffer + 1;       /* Skip the $ */
+               guint csum = 0;
+               if (*gps->io.buffer=='$') {
+                       /* This is the beginning of a sentence; okay to parse. */
+                       *eol = '\0';    /* overwrite \n with \0 */
+                       while (*sptr && *sptr != '*')
+                               csum ^= *sptr++;
+
+                       /* If we're at a \0 (meaning there is no checksum), or if the
+                        * checksum is good, then parse the sentence. */
+                       if (!*sptr || csum == strtol(sptr + 1, NULL, 16)) {
+                               gchar *data;
+
+                               if (*sptr)
+                                       *sptr = '\0';   /* take checksum out of the buffer. */
+
+                               data=g_strdup(gps->io.buffer);
+                               g_idle_add_full(G_PRIORITY_HIGH_IDLE, (GSourceFunc)gps_nmea_parse, data, NULL);
+                       } else {
+                               /* There was a checksum, and it was bad. */
+                               g_printerr("%s: Bad checksum in NMEA sentence:\n%s\n", __PRETTY_FUNCTION__, gps->io.buffer);
+                       }
+               }
+
+               /* If eol is at or after (_gps_read_buf_curr - 1) */
+               if (eol >= (gps->io.curr - 1)) {
+                       /* Last read was a newline - reset read buffer */
+                       gps->io.curr = gps->io.buffer;
+                       *gps->io.curr = '\0';
+               } else {
+                       /* Move the next line to the front of the buffer. */
+                       memmove(gps->io.buffer, eol + 1, gps->io.curr - eol);   /* include terminating 0 */
+                       /* Subtract _curr so that it's pointing at the new \0. */
+                       gps->io.curr -= (eol - gps->io.buffer + 1);
+               }
+       }
+       break;
+       case G_IO_STATUS_ERROR:
+       case G_IO_STATUS_EOF:
+               gps_disconnect(gps);
+               gps_connect_later(gps);
+               return FALSE;
+       break;
+       case G_IO_STATUS_AGAIN:
+               return TRUE;
+       break;
+       default:
+               g_assert_not_reached();
+       break;
+}
+
+return TRUE;
+}
+
index ddcaf7626c115359abecaef2a4b75c6ff8e308d1..db0592ad59247dcf0228fe0146818b3abae8a6f6 100644 (file)
--- a/src/gps.h
+++ b/src/gps.h
 #include <glib/gstdio.h>
 #include <gtk/gtk.h>
 #include <dbus/dbus-glib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/ip.h> 
+
+#ifdef WITH_BLUEZ
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/hci.h>
+#include <bluetooth/hci_lib.h>
+#include <bluetooth/rfcomm.h>
+#endif
 
 #include "path.h"
 #include "utils.h"
 #include "mapper-types.h"
 #include "gpsdata.h"
 
-#define GPS_READ_BUF_SIZE 1024
+#define GPS_READ_BUF_SIZE      (1024)
 
 /**
  * Types of GPS data sources
  */
 typedef enum {
-        GPS_IO_DIRECT=1,
-        GPS_IO_FILE,
-        GPS_IO_TCP,
-        GPS_IO_GPSD,
-               GPS_IO_GYPSY
+       GPS_IO_RFCOMM=1,        /* Bluetooth rfcomm socket */
+       GPS_IO_HILDON_DBUS,     /* Request rfcomm using hildon bluetooth D-Bus */
+       GPS_IO_BLUEZ_DBUS,      /* Request rfcomm using bluez bluetooth D-Bus*/
+       GPS_IO_FILE,            /* File or (serial) device node */
+       GPS_IO_TCP,                     /* TCP */
+       GPS_IO_GPSD,            /* TCP connection to gpsd (as TCP, but will send a request for NMEA mode */
+       GPS_IO_GYPSY,           /* Gypsy events */
+       GPS_IO_SIMULATION       /* Random movement */
 } GpsIOSourceType;
 
+/** This enumerated type defines the possible connection states. */
+typedef enum {
+       RCVR_OFF,
+       RCVR_DOWN,
+       RCVR_UP,
+       RCVR_FIXED
+} GpsConnState;
+
 /**
- * GPS IO variables
+ * GPS IO struct
  *
  */
 typedef struct _GpsIO GpsIO;
 struct _GpsIO {
        gint fd;
+       gchar *address; /* BT MAC, File path or IP */
+       guint port;
+       GpsIOSourceType type;
+       GpsConnState conn;
        GIOChannel *channel;
        DBusGProxy *rfcomm_req_proxy;
-       GpsIOSourceType src_type;
+#ifdef WITH_BLUEZ
+       struct sockaddr_rc rcvr_addr_rc;
+#endif
+       struct sockaddr_in rcvr_addr_in;
        guint connect_sid;
        guint error_sid;
        guint input_sid;
        guint clater_sid;
-       gchar buf[GPS_READ_BUF_SIZE];
+       guint errors;
+       gchar buffer[GPS_READ_BUF_SIZE];
        gchar *curr;
        gchar *last;
+       gchar *nmea;
 };
 
-GpsIO gpsio;
-GpsData *_gps;
+/**
+ * Gps 
+ */
+typedef struct _Gps Gps;
+struct _Gps {
+       gchar *name;    /* Name of the connection */
+       GpsIO io;
+       GpsData data;
+};
 
-gchar _gps_read_buf[GPS_READ_BUF_SIZE];
-gchar *_gps_read_buf_curr;
-gchar *_gps_read_buf_last;
+Gps *_gps;
+gint _gmtoffset;
 
 DBusGProxy *_rfcomm_req_proxy;
 
-GIOChannel *_channel;
-guint _connect_sid;
-guint _error_sid;
-guint _input_sid;
-guint _clater_sid;
-
-gint _gmtoffset;
-
-GpsData *gps_init(void);
-void gps_integerize_data(GpsData *gps);
+Gps *gps_new(void);
+void gps_data_integerize(GpsData *gpsdata);
 
-gboolean channel_cb_error(GIOChannel * src, GIOCondition condition, gpointer data);
-gboolean channel_cb_input(GIOChannel * src, GIOCondition condition, gpointer data);
+gboolean gps_connect(Gps *gps);
+gboolean gps_connect_now(Gps *gps);
+void gps_connect_later(Gps *gps);
+void gps_disconnect(Gps *gps);
 
 #endif
index 203cd88903d3245d6c57358bf70e006fc2ea5202..97d16b05c26ebffd3d6bf8f705ff39d2170f3fda 100644 (file)
@@ -44,7 +44,6 @@
 #include "map-download.h"
 #include "route.h"
 #include "mapper-types.h"
-#include "bt.h"
 #include "gps.h"
 #include "settings-gconf.h"
 #include "settings.h"
@@ -70,11 +69,11 @@ if (state->system_inactivity_ind) {
        if (_must_save_data)
                _must_save_data = FALSE;
        else {
-               if (_conn_state > RCVR_OFF) {
+               if (_gps->io.conn > RCVR_OFF) {
                        if (gconf_client_get_bool(gconf_client, GCONF_KEY_DISCONNECT_ON_COVER, NULL)) {
                                gconf_client_clear_cache(gconf_client);
-                               gps_conn_set_state(RCVR_OFF);
-                               rcvr_disconnect();
+                               gps_conn_set_state(_gps, RCVR_OFF);
+                               gps_disconnect(_gps);
                                track_add(0, FALSE);
                                /* Pretend autoroute is in progress to avoid download. */
                                if (_autoroute_data.enabled)
@@ -92,9 +91,9 @@ if (state->system_inactivity_ind) {
 } else if (state->memory_low_ind) {
        poi_icon_hash_clear();
 } else {
-       if (_conn_state == RCVR_OFF && _enable_gps) {
-               gps_conn_set_state(RCVR_DOWN);
-               rcvr_connect_later();
+       if (_gps->io.conn == RCVR_OFF && _enable_gps) {
+               gps_conn_set_state(gps, RCVR_DOWN);
+               gps_connect_later(gps);
                if (_autoroute_data.enabled)
                        _autoroute_data.in_progress = TRUE;
        }
index f1cac2baa6385ccb8b9d81daa53fd5c13affc38c..0b272d694784c54bf1772458a80b77873180be8d 100644 (file)
@@ -50,7 +50,6 @@
 #include "poi.h"
 #include "route.h"
 #include "gps.h"
-#include "bt.h"
 #include "mapper-types.h"
 #include "ui-common.h"
 #include "settings.h"
index 9ba59e6096b47f4c701287261a3d2534b15b8fcc..0a22759412dd3f2343c8d013e3d8415b75f804fb 100644 (file)
@@ -1171,9 +1171,9 @@ gboolean menu_cb_mapman(GtkAction * action)
        /* Initialize fields.  Do no use g_ascii_formatd; these strings will be
         * output (and parsed) as locale-dependent. */
 
-       g_snprintf(buffer, sizeof(buffer), "%.06f", _gps->lat);
+       g_snprintf(buffer, sizeof(buffer), "%.06f", _gps->data.lat);
        gtk_label_set_text(GTK_LABEL(lbl_gps_lat), buffer);
-       g_snprintf(buffer, sizeof(buffer), "%.06f", _gps->lon);
+       g_snprintf(buffer, sizeof(buffer), "%.06f", _gps->data.lon);
        gtk_label_set_text(GTK_LABEL(lbl_gps_lon), buffer);
 
        unit2latlon(_center.unitx, _center.unity, lat, lon);
index e1223c6e82f54a95f786529b1111b8576bdda2b6..0a375891cd14d914a3cb9e9dcb41690f40c706ce 100644 (file)
--- a/src/map.c
+++ b/src/map.c
@@ -50,7 +50,6 @@
 #include "route.h"
 #include "track.h"
 #include "gps.h"
-#include "bt.h"
 #include "mapper-types.h"
 #include "ui-common.h"
 #include "settings.h"
@@ -218,11 +217,11 @@ return TRUE;
  * _map_widget.  This method does not queue the draw area.
  */
 static void 
-map_draw_mark(void)
+map_draw_mark(Gps *gps)
 {
-gdk_draw_arc(_map_widget->window, _conn_state == RCVR_FIXED ? _gc[COLORABLE_MARK] : _gc[COLORABLE_MARK_OLD], FALSE,
+gdk_draw_arc(_map_widget->window, gps->io.conn == RCVR_FIXED ? _gc[COLORABLE_MARK] : _gc[COLORABLE_MARK_OLD], FALSE,
      mark_x1 - _draw_width, mark_y1 - _draw_width, 2 * _draw_width, 2 * _draw_width, 0, 360 * 64);
-gdk_draw_line(_map_widget->window, _conn_state == RCVR_FIXED ? (_show_velvec ? _gc[COLORABLE_MARK_VELOCITY] : _gc[COLORABLE_MARK]) : _gc[COLORABLE_MARK_OLD],
+gdk_draw_line(_map_widget->window, gps->io.conn == RCVR_FIXED ? (_show_velvec ? _gc[COLORABLE_MARK_VELOCITY] : _gc[COLORABLE_MARK]) : _gc[COLORABLE_MARK_OLD],
       mark_x1, mark_y1, mark_x2, mark_y2);
 }
 
@@ -231,12 +230,12 @@ gdk_draw_line(_map_widget->window, _conn_state == RCVR_FIXED ? (_show_velvec ? _
  * units in preparation for drawing the mark with map_draw_mark().
  */
 void 
-map_set_mark(void)
+map_set_mark(GpsData *gps)
 {
-mark_x1 = unit2x(_gps->unitx);
-mark_y1 = unit2y(_gps->unity);
-mark_x2 = mark_x1 + (_show_velvec ? _gps->vel_offsetx : 0);
-mark_y2 = mark_y1 + (_show_velvec ? _gps->vel_offsety : 0);
+mark_x1 = unit2x(gps->unitx);
+mark_y1 = unit2y(gps->unity);
+mark_x2 = mark_x1 + (_show_velvec ? gps->vel_offsetx : 0);
+mark_y2 = mark_y1 + (_show_velvec ? gps->vel_offsety : 0);
 mark_minx = MIN(mark_x1, mark_x2) - (2 * _draw_width);
 mark_miny = MIN(mark_y1, mark_y2) - (2 * _draw_width);
 mark_width = abs(mark_x1 - mark_x2) + (4 * _draw_width);
@@ -458,7 +457,7 @@ _zoom = new_zoom / _curr_repo->view_zoom_steps * _curr_repo->view_zoom_steps;
 _world_size_tiles = unit2tile(WORLD_SIZE_UNITS);
 
 /* If we're leading, update the center to reflect new zoom level. */
-MACRO_RECALC_CENTER(_center.unitx, _center.unity);
+MACRO_RECALC_CENTER(_gps->data, _center.unitx, _center.unity);
 
 /* Update center bounds to reflect new zoom level. */
 _min_center.unitx = pixel2unit(grid2pixel(_screen_grids_halfwidth));
@@ -478,7 +477,7 @@ MACRO_RECALC_OFFSET();
 MACRO_RECALC_FOCUS_BASE();
 MACRO_RECALC_FOCUS_SIZE();
 
-map_set_mark();
+map_set_mark(&_gps->data);
 map_force_redraw();
 }
 
@@ -565,7 +564,7 @@ if (new_base_tilex != _base_tilex || new_base_tiley != _base_tiley) {
 MACRO_RECALC_OFFSET();
 MACRO_RECALC_FOCUS_BASE();
 
-map_set_mark();
+map_set_mark(&_gps->data);
 MACRO_QUEUE_DRAW_AREA();
 }
 
@@ -605,7 +604,7 @@ if (pos->valid==FALSE)
 
 _center_mode=CENTER_MANUAL;
 map_center_latlon(pos->lat, pos->lon);
-map_set_autozoom(FALSE);
+map_set_autozoom(FALSE, 0);
 g_idle_add_full(G_PRIORITY_HIGH_IDLE,(GSourceFunc)map_update_location_from_center, NULL, NULL);
 return TRUE;
 }
@@ -624,7 +623,7 @@ gtk_widget_queue_draw_area(_map_widget,
                   mark_minx<0 ? 0 : mark_minx,
                   mark_miny<0 ? 0 : mark_miny, 
                   mark_width, mark_height);
-map_set_mark();
+map_set_mark(&_gps->data);
 gtk_widget_queue_draw_area(_map_widget,
                   mark_minx<0 ? 0 : mark_minx,
                   mark_miny<0 ? 0 : mark_miny, 
@@ -632,9 +631,9 @@ gtk_widget_queue_draw_area(_map_widget,
 }
 
 gboolean
-map_update_location_from_gps(void)
+map_update_location_from_gps(Gps *gps)
 {
-map_update_location(_gps->lat, _gps->lon, FALSE);
+map_update_location(gps->data.lat, gps->data.lon, FALSE);
 return FALSE;
 }
 
@@ -645,11 +644,13 @@ gdouble lat, lon;
 /* Force re-validation of place if user is clicking around */
 map_loc.valid=FALSE;
 /* XXX: hmm, not the right place for this */
+#if 0
 if (_gps->fix==FIX_NOFIX) {
-       _gps->unitx=_center.unitx;
-       _gps->unity=_center.unity;
-       unit2latlon(_gps->unitx, _gps->unity, _gps->lat, _gps->lon);
+       _gps->data.unitx=_center.unitx;
+       _gps->data.unity=_center.unity;
+       unit2latlon(_gps->data.unitx, _gps->data.unity, _gps->data.lat, _gps->data.lon);
 }
+#endif
 unit2latlon(_center.unitx, _center.unity, lat, lon);
 map_update_location(lat, lon, TRUE);
 return FALSE;
@@ -708,7 +709,7 @@ map_refresh_mark(void)
 guint new_center_unitx;
 guint new_center_unity;
 
-MACRO_RECALC_CENTER(new_center_unitx, new_center_unity);
+MACRO_RECALC_CENTER(_gps->data, new_center_unitx, new_center_unity);
 
 if ((new_center_unitx - _focus.unitx) < _focus_unitwidth && (new_center_unity - _focus.unity) < _focus_unitheight)
        /* We're not changing the view - just move the mark. */
@@ -905,7 +906,7 @@ GdkGC *gc;
 gfloat cur_speed;
 gchar *buffer;
 
-cur_speed = _gps->speed * UNITS_CONVERT[_units];
+cur_speed = _gps->data.speed * UNITS_CONVERT[_units];
 gc=(cur_speed > _speed_limit) ? speed_gc1 : speed_gc2;
 buffer = g_strdup_printf("%0.0f", cur_speed);
 map_information_text(10, 10, gc, buffer);
@@ -996,7 +997,7 @@ gdk_draw_drawable(GDK_DRAWABLE(_map_widget->window),
                event->area.x + _offsetx, event->area.y + _offsety,
                event->area.x, event->area.y,
                event->area.width, event->area.height);
-map_draw_mark();
+map_draw_mark(_gps);
 
 /* Draw scale, if necessary. */
 if (_show_scale)
@@ -1046,11 +1047,11 @@ gint iz;
 if (zoom_timeout_sid==0)
        return FALSE;
 
-z=(z+_gps->speed+1)/5;
+z=(z+_gps->data.speed+1)/5;
 if (z>5) z=5.0; else if (z<1) z=1.0;
 iz=(gint)roundf(z);
 #ifdef DEBUG
-g_printf("Setting autozoom to: %f %d S:%f\n", z, iz, _gps->speed);
+g_printf("Setting autozoom to: %f %d S:%f\n", z, iz, _gps->data.speed);
 #endif
 if (iz>last) 
        iz=last+1; 
@@ -1063,11 +1064,11 @@ return TRUE;
 }
 
 void
-map_set_autozoom(gboolean az)
+map_set_autozoom(gboolean az, gfloat speed)
 {
 if (az==TRUE) {
        MACRO_BANNER_SHOW_INFO(_window, "Autozoom enabled");
-       zoom_timeout_sid=g_timeout_add(_gps->speed<5 ? 2000 : 5000, (GSourceFunc) map_autozoomer, NULL);
+       zoom_timeout_sid=g_timeout_add(speed<5 ? 2000 : 5000, (GSourceFunc) map_autozoomer, NULL);
        return;
 } else {
        if (zoom_timeout_sid) {
@@ -1089,11 +1090,11 @@ cmenu_route_add_way(x, y);
 static void 
 map_draw_track(gint x, gint y)
 {
-_gps->unitx=x2unit((gint) (x + 0.5));
-_gps->unity=y2unit((gint) (y + 0.5));
-unit2latlon(_gps->unitx, _gps->unity, _gps->lat, _gps->lon);
-_gps->speed=20.f;
-gps_integerize_data(_gps);
+_gps->data.unitx=x2unit((gint) (x + 0.5));
+_gps->data.unity=y2unit((gint) (y + 0.5));
+unit2latlon(_gps->data.unitx, _gps->data.unity, _gps->data.lat, _gps->data.lon);
+_gps->data.speed=20.f;
+gps_data_integerize(&_gps->data);
 track_add(time(NULL), FALSE);
 map_refresh_mark();
 }
@@ -1193,8 +1194,8 @@ inp=TRUE;
 ilat=lat2mp_int(lat);
 ilon=lon2mp_int(lon);
 
-if (_gps->fix>1 && !force)
-       osm_set_way_range_from_speed(_gps->speed);
+if (_gps->data.fix>1 && !force)
+       osm_set_way_range_from_speed(_gps->data.speed);
 else
        osm_set_way_range(OSM_RANGE_WAY/4);
 
index 7b77afd01d9bb61283cb570aa6b45d83fb7a5376..f1c1539091e12cf52e4e5ee91644636cb4d5f066 100644 (file)
--- a/src/map.h
+++ b/src/map.h
 #define unit2y(unit) (unit2pixel(unit) - tile2pixel(_base_tiley) - _offsety)
 #define y2unit(y) (pixel2unit(y + _offsety) + tile2unit(_base_tiley))
 
-#define leadx2unit() (_gps->unitx + (_lead_ratio) * pixel2unit(_gps->vel_offsetx))
-#define leady2unit() (_gps->unity + (0.6f*_lead_ratio)*pixel2unit(_gps->vel_offsety))
+#define leadx2unit(mgps) (mgps.unitx + (_lead_ratio) * pixel2unit(mgps.vel_offsetx))
+#define leady2unit(mgps) (mgps.unity + (0.6f*_lead_ratio)*pixel2unit(mgps.vel_offsety))
 
 /* Pans are done two "grids" at a time, or 64 pixels. */
 #define PAN_UNITS (grid2unit(2))
 
-#define MACRO_RECALC_CENTER(center_unitx, center_unity) { \
+#define MACRO_RECALC_CENTER(mgps, center_unitx, center_unity) { \
     switch(_center_mode) \
     { \
         case CENTER_LEAD: \
-            center_unitx = leadx2unit(); \
-            center_unity = leady2unit(); \
+            center_unitx = leadx2unit(mgps); \
+            center_unity = leady2unit(mgps); \
             break; \
         case CENTER_LATLON: \
-            center_unitx = _gps->unitx; \
-            center_unity = _gps->unity; \
+            center_unitx = mgps.unitx; \
+            center_unity = mgps.unity; \
             break; \
         default: \
              center_unitx = _center.unitx; \
@@ -186,11 +186,11 @@ gboolean map_key_zoom_timeout();
 int map_zoom(gint zdir);
 gboolean map_zoom_in(void);
 gboolean map_zoom_out(void);
-void map_set_autozoom(gboolean az);
+void map_set_autozoom(gboolean az, gfloat speed);
 void map_render_path(Path * path, GdkGC ** gc);
 void map_pan(gint delta_unitx, gint delta_unity);
 void map_move_mark(void);
-void map_set_mark(void);
+void map_set_mark(GpsData *gps);
 void map_render_data(void);
 
 void map_render_tile(guint tilex, guint tiley, guint destx, guint desty, gboolean fast_fail);
index dc0a4e459a86dcea39fb35a8e43bf3d5305d8e2c..ae3599dae05b1647954b5b1c663a524434e321c6 100644 (file)
@@ -61,7 +61,6 @@
 #include "map.h"
 #include "route.h"
 #include "track.h"
-#include "bt.h"
 #include "ui-common.h"
 #include "db.h"
 #include "osm-db.h"
@@ -122,7 +121,7 @@ mapper_destroy(void)
 {
 config_save();
 config_save_repo();
-rcvr_disconnect();
+gps_disconnect(_gps);
 map_download_deinit();
 #if defined (WITH_GST) && defined (WITH_ESPEAK)
 speak_deinit();
@@ -200,10 +199,17 @@ gchar *w="Starting";
 
 switch (mis) {
        case MAPPER_INIT_START:
-               _conn_state = RCVR_OFF;
                curl_global_init(CURL_GLOBAL_NOTHING);
                gnome_vfs_init();
-               _gps=gps_init();
+               _gps=gps_new();
+               _gps->io.type=GPS_IO_SIMULATION;
+#ifdef WITH_BLUEZ
+               _gps->io.type=GPS_IO_RFCOMM;
+#endif
+#ifdef WITH_HILDON_DBUS_BT
+               _gps->io.type=GPS_IO_HILDON_DBUS;
+#endif
+               _gps->io.conn = RCVR_OFF;
                timezone_init();
                gpx_init();
                variables_init();
@@ -292,6 +298,8 @@ switch (mis) {
        break;
        case MAPPER_INIT_DONE:
                progress_dialog_remove(init_dialog);
+               if (_enable_gps)   
+               gps_connect_now(_gps);
                return FALSE;
        break;
 }
index 566b25d6e934ea989bc1ee58e9ab4414c639b263..be7537f00b1f5f34fbb1cddacbce9f42c7e87e27 100644 (file)
@@ -908,7 +908,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->heading-map_loc->heading)>10.0)) {
+       if ( (dist>(gdouble)way_dist_range) || (fabs(_gps->data.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 +951,8 @@ 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->heading;
-       map_loc->speed=_gps->speed;
+       map_loc->heading=_gps->data.heading;
+       map_loc->speed=_gps->data.speed;
 }
 
 #if 0
index 43dcfed456f165716955e75fad3b457a916cf154..e52df7a10d3f9630db7df0f3ff2e14b8d54f3cc7 100644 (file)
@@ -138,8 +138,8 @@ if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toggle))) {
                gchar buffer[80];
                gchar strlat[32];
                gchar strlon[32];
-               g_ascii_formatd(strlat, 32, "%.06f", _gps->lat);
-               g_ascii_formatd(strlon, 32, "%.06f", _gps->lon);
+               g_ascii_formatd(strlat, 32, "%.06f", _gps->data.lat);
+               g_ascii_formatd(strlon, 32, "%.06f", _gps->data.lon);
                g_snprintf(buffer, sizeof(buffer), "%s, %s", strlat, strlon);
                gtk_entry_set_text(GTK_ENTRY(oti->txt_from), buffer);
        } else if (toggle == oti->rad_use_route) {
@@ -218,8 +218,8 @@ auto_route_dl_idle()
 {
 gchar latstr[32], lonstr[32], *latlonstr;
 
-g_ascii_dtostr(latstr, 32, _gps->lat);
-g_ascii_dtostr(lonstr, 32, _gps->lon);
+g_ascii_dtostr(latstr, 32, _gps->data.lat);
+g_ascii_dtostr(lonstr, 32, _gps->data.lon);
 latlonstr = g_strdup_printf("%s,%s", latstr, lonstr);
 _autoroute_data.src_str =
     g_strdup_printf(_route_dl_url, latlonstr, _autoroute_data.dest);
@@ -537,14 +537,14 @@ if (_next_way) {
        /* First, set near_dist_squared with the new distance from
         * _near_point. */
        near = _near_point;
-       near_dist_squared = DISTANCE_SQUARED(*_gps, *near);
+       near_dist_squared = DISTANCE_SQUARED(_gps->data, *near);
 
        /* Now, search _route for a closer point.  If quick is TRUE, then we'll
         * only search forward, only as long as we keep finding closer points.
         */
        for (curr = _near_point; curr++ != _route.tail;) {
                if (curr->unity) {
-                       guint dist_squared = DISTANCE_SQUARED(*_gps, *curr);
+                       guint dist_squared = DISTANCE_SQUARED(_gps->data, *curr);
                        if (dist_squared <= near_dist_squared) {
                                near = curr;
                                near_dist_squared = dist_squared;
@@ -559,8 +559,8 @@ if (_next_way) {
 
        for (wnext = wcurr = _next_way; wcurr != _route.wtail; wcurr++) {
                if (wcurr->point < near || (wcurr->point == near && quick 
-                               && (_next_wpt && (DISTANCE_SQUARED(*_gps, *near) > _next_way_dist_squared
-                               && DISTANCE_SQUARED(*_gps, *_next_wpt) < _next_wpt_dist_squared))))
+                               && (_next_wpt && (DISTANCE_SQUARED(_gps->data, *near) > _next_way_dist_squared
+                               && DISTANCE_SQUARED(_gps->data, *_next_wpt) < _next_wpt_dist_squared))))
                    /* Okay, this else if expression warrants explanation.  If the
                     * nearest track point happens to be a waypoint, then we want to
                     * check if we have "passed" that waypoint.  To check this, we
@@ -575,8 +575,8 @@ if (_next_way) {
        }
 
        if (wnext == _route.wtail && (wnext->point < near || (wnext->point == near && quick
-                                         && (_next_wpt && (DISTANCE_SQUARED (*_gps, *near) > _next_way_dist_squared
-                                              && DISTANCE_SQUARED(*_gps, *_next_wpt) < _next_wpt_dist_squared)))))
+                                         && (_next_wpt && (DISTANCE_SQUARED (_gps->data, *near) > _next_way_dist_squared
+                                              && DISTANCE_SQUARED(_gps->data, *_next_wpt) < _next_wpt_dist_squared)))))
        {
                _next_way = NULL;
                _next_wpt = NULL;
@@ -602,9 +602,9 @@ if (_next_way) {
                        }
                        ret = TRUE;
                }
-               _next_way_dist_squared = DISTANCE_SQUARED(*_gps, *wnext->point);
+               _next_way_dist_squared = DISTANCE_SQUARED(_gps->data, *wnext->point);
                if (_next_wpt)
-                       _next_wpt_dist_squared = DISTANCE_SQUARED(*_gps, *_next_wpt);
+                       _next_wpt_dist_squared = DISTANCE_SQUARED(_gps->data, *_next_wpt);
        }
 }
 return ret;
@@ -658,7 +658,7 @@ if (point == NULL && _next_way)
 if (point == NULL)
        return FALSE;
 
-unit2latlon(_gps->unitx, _gps->unity, lat1, lon1);
+unit2latlon(_gps->data.unitx, _gps->data.unity, lat1, lon1);
 if (point > _near_point) {
        Point *curr;
        /* Skip _near_point in case we have already passed it. */
index 14caacb6b86ec1eefd3d70d5948434dd6b70f031..50ea67afa930cda839be99f92c598d52c4edb573 100644 (file)
 #include "map.h"
 #include "mapper-types.h"
 #include "latlon.h"
-#include "bt.h"
 #include "ui-common.h"
 #include "settings.h"
 #include "db.h"
-
+#include "bluetooth-scan.h"
 #include "hildon-wrappers.h"
 
 #include "help.h"
@@ -564,11 +563,8 @@ settings_dialog(void)
        g_signal_connect(G_OBJECT(btn_browsedb), "clicked", G_CALLBACK(settings_dialog_browse_forfile), &browse_info);
 
        /* Initialize fields. */
-       if (_rcvr_mac)
-               gtk_entry_set_text(GTK_ENTRY(txt_rcvr_mac), _rcvr_mac);
-
-       if (_mapper_db)
-               gtk_entry_set_text(GTK_ENTRY(txt_mapper_db), _mapper_db);
+       gtk_entry_set_text(GTK_ENTRY(txt_rcvr_mac), _gps->io.address ? _gps->io.address : "");
+       gtk_entry_set_text(GTK_ENTRY(txt_mapper_db), _mapper_db ? _mapper_db : "");
 
        hildon_number_editor_set_value(HILDON_NUMBER_EDITOR(num_poi_zoom), _poi_zoom);
        hildon_controlbar_set_value(HILDON_CONTROLBAR(num_center_ratio), _center_ratio);
@@ -592,9 +588,9 @@ settings_dialog(void)
                /* Set _rcvr_mac if necessary. */
                if (!*gtk_entry_get_text(GTK_ENTRY(txt_rcvr_mac))) {
                        /* User specified no rcvr mac - set _rcvr_mac to NULL. */
-                       if (_rcvr_mac) {
-                               g_free(_rcvr_mac);
-                               _rcvr_mac = NULL;
+                       if (_gps->io.address) {
+                               g_free(_gps->io.address);
+                               _gps->io.address = NULL;
                                rcvr_changed = TRUE;
                                set_action_sensitive("gps_details", FALSE);
                        }
@@ -604,10 +600,10 @@ settings_dialog(void)
                                rcvr_changed = TRUE;
                                set_action_sensitive("gps_details", FALSE);
                        }
-               } else if (!_rcvr_mac || strcmp(_rcvr_mac, gtk_entry_get_text(GTK_ENTRY(txt_rcvr_mac)))) {
+               } else if (!_gps->io.address || strcmp(_gps->io.address, gtk_entry_get_text(GTK_ENTRY(txt_rcvr_mac)))) {
                        /* User specified a new rcvr mac. */
-                       g_free(_rcvr_mac);
-                       _rcvr_mac = g_strdup(gtk_entry_get_text(GTK_ENTRY(txt_rcvr_mac)));
+                       g_free(_gps->io.address);
+                       _gps->io.address = g_strdup(gtk_entry_get_text(GTK_ENTRY(txt_rcvr_mac)));
                        rcvr_changed = TRUE;
                }
 
index b55a5ffaeb9f5f9fe2695d1d02e3662197e5dbad..8d1de743a231be6671c820959e44b935d214d157 100644 (file)
@@ -8,7 +8,6 @@
 #include "settings-gconf.h"
 
 /** CONFIGURATION INFORMATION. */
-gchar *_rcvr_mac;
 gchar *_route_dir_uri;
 gchar *_track_file_uri;
 gchar *_route_dl_url;
index 3764143cb0fd095528999de29509daffac2734ea..b8284d09b915fff65845cefd195cd11492df4c8b 100644 (file)
@@ -58,7 +58,7 @@ track_calculate_distance_from(Point *point)
 gdouble lat1, lon1, lat2, lon2;
 gdouble sum = 0.0;
 Point *curr;
-unit2latlon(_gps->unitx, _gps->unity, lat1, lon1);
+unit2latlon(_gps->data.unitx, _gps->data.unity, lat1, lon1);
 
 /* Skip _track.tail because that should be _gps. */
 for (curr = _track.tail; curr > point; --curr) {
@@ -298,7 +298,7 @@ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), table = gtk_table_new(2, 2
 gtk_table_attach(GTK_TABLE(table), label = gtk_label_new(_("Lat, Lon")), 0, 1, 0, 1, GTK_FILL, 0, 2, 4);
 gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
 
-unit2latlon(_gps->unitx, _gps->unity, lat, lon);
+unit2latlon(_gps->data.unitx, _gps->data.unity, lat, lon);
 lat_format(_degformat, lat, tmp1);
 lon_format(_degformat, lon, tmp2);
 p_latlon = g_strdup_printf("%s, %s", tmp1, tmp2);
index 3c8a094cb7c3903d664e36c17884051291c8a07d..90bfa385d6673cd093171e13b41d2418b7afb5a3 100644 (file)
@@ -28,7 +28,6 @@
 #include "gps.h"
 #include "map.h"
 #include "mapper-types.h"
-#include "bt.h"
 #include "ui-common.h"
 #include "db.h"
 
@@ -389,7 +388,7 @@ static gint done_here = 0;
 
 if (!been_here++) {
        /* Set connection state first, to avoid going into this if twice. */
-       if (!_rcvr_mac && _enable_gps) {
+       if (!_gps->io.address && _enable_gps) {
                GtkWidget *confirm;
 
                gtk_window_present(GTK_WINDOW(_window));
@@ -416,9 +415,6 @@ if (!been_here++) {
                        gtk_main_quit();
                }
        }
-       /* Connect to receiver. */
-       if (_enable_gps && _rcvr_mac)
-               rcvr_connect_now();
 
        done_here++;    /* Don't ask... */
 }
@@ -427,9 +423,9 @@ if (done_here) {
 
        /* Re-enable any banners that might have been up. */
        {
-               ConnState old_state = _conn_state;
-               gps_conn_set_state(RCVR_OFF);
-               gps_conn_set_state(old_state);
+               GpsConnState old_state = _gps->io.conn;
+               gps_conn_set_state(_gps, RCVR_OFF);
+               gps_conn_set_state(_gps, old_state);
        }
 }
 
@@ -747,16 +743,16 @@ gtk_paned_add2(GTK_PANED(hbox), _map_widget);
 /* GPS Tab */
 vbox = gtk_vbox_new(FALSE, 0);
 label = gtk_label_new("Gps");
-_gps_sat_view = gtk_gps_new(GTK_GPS_MODE_SKY, _gps);
+_gps_sat_view = gtk_gps_new(GTK_GPS_MODE_SKY, &_gps->data);
 gtk_box_pack_start(GTK_BOX(vbox), _gps_sat_view, TRUE, TRUE, 0);
-_gps_sat_view = gtk_gps_new(GTK_GPS_MODE_SIGNAL, _gps);
+_gps_sat_view = gtk_gps_new(GTK_GPS_MODE_SIGNAL, &_gps->data);
 gtk_box_pack_start(GTK_BOX(vbox), _gps_sat_view, TRUE, TRUE, 0);
 ui_notebook.gps=gtk_notebook_append_page(notebook, vbox, label);
 
 /* Heading Tab */
 vbox = gtk_vbox_new(FALSE, 0);
 label = gtk_label_new("Heading");
-_tab_compass = gtk_compass_new(_gps);
+_tab_compass = gtk_compass_new(&_gps->data);
 gtk_box_pack_start(GTK_BOX(vbox), _tab_compass, TRUE, TRUE, 0);
 ui_notebook.heading=gtk_notebook_append_page(notebook, vbox, label);