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"])
--- /dev/null
+#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
+++ /dev/null
-#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
#include "gps.h"
#include "map.h"
#include "mapper-types.h"
-#include "bt.h"
#include "ui-common.h"
#include "db.h"
#include "latlon.h"
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;
}
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;
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);
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;
}
gboolean
cb_zoomin(GtkAction * action)
{
-map_set_autozoom(FALSE);
+map_set_autozoom(FALSE, 0);
g_idle_add((GSourceFunc)map_zoom_in, NULL);
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;
}
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;
}
set_action_sensitive("autocenter_lead", _enable_gps);
map_move_mark();
-gps_show_info(_gps);
+gps_show_info(&_gps->data);
return TRUE;
}
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();
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);
}
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);
}
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);
}
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);
}
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();
#include "db.h"
#include "poi.h"
#include "gps.h"
-#include "bt.h"
#include "ui-common.h"
#include "settings.h"
#include "gpx.h"
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);
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);
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);
_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;
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. */
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);
}
/* 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. */
{
#include "gps.h"
#include "map.h"
#include "mapper-types.h"
-#include "bt.h"
#include "ui-common.h"
#include "settings.h"
#include "filter.h"
#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)
{
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)
{
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
*/
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);
#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,
#include "settings.h"
#include "gps.h"
#include "map.h"
-#include "bt.h"
#include "ui-common.h"
#include "gps-conn.h"
* 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) {
}
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);
#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
#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
/* 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);
}
}
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);
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. */
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
/* 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);
/* 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)
guint i,si;
gint satforfix[12];
- vprintf("%s(): %s\n", __PRETTY_FUNCTION__, sentence);
+ g_debug("%s(): %s\n", __PRETTY_FUNCTION__, sentence);
#define DELIM ","
/* 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);
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
/* 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. */
/* 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++;
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;
}
}
-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;
-}
* 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;
+}
+
#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
#include "map-download.h"
#include "route.h"
#include "mapper-types.h"
-#include "bt.h"
#include "gps.h"
#include "settings-gconf.h"
#include "settings.h"
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)
} 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;
}
#include "poi.h"
#include "route.h"
#include "gps.h"
-#include "bt.h"
#include "mapper-types.h"
#include "ui-common.h"
#include "settings.h"
/* 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);
#include "route.h"
#include "track.h"
#include "gps.h"
-#include "bt.h"
#include "mapper-types.h"
#include "ui-common.h"
#include "settings.h"
* _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);
}
* 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);
_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));
MACRO_RECALC_FOCUS_BASE();
MACRO_RECALC_FOCUS_SIZE();
-map_set_mark();
+map_set_mark(&_gps->data);
map_force_redraw();
}
MACRO_RECALC_OFFSET();
MACRO_RECALC_FOCUS_BASE();
-map_set_mark();
+map_set_mark(&_gps->data);
MACRO_QUEUE_DRAW_AREA();
}
_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;
}
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,
}
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;
}
/* 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;
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. */
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);
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)
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;
}
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) {
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();
}
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);
#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; \
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);
#include "map.h"
#include "route.h"
#include "track.h"
-#include "bt.h"
#include "ui-common.h"
#include "db.h"
#include "osm-db.h"
{
config_save();
config_save_repo();
-rcvr_disconnect();
+gps_disconnect(_gps);
map_download_deinit();
#if defined (WITH_GST) && defined (WITH_ESPEAK)
speak_deinit();
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();
break;
case MAPPER_INIT_DONE:
progress_dialog_remove(init_dialog);
+ if (_enable_gps)
+ gps_connect_now(_gps);
return FALSE;
break;
}
/* 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);
}
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
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) {
{
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);
/* 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;
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
}
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;
}
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;
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. */
#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"
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);
/* 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);
}
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;
}
#include "settings-gconf.h"
/** CONFIGURATION INFORMATION. */
-gchar *_rcvr_mac;
gchar *_route_dir_uri;
gchar *_track_file_uri;
gchar *_route_dl_url;
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) {
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);
#include "gps.h"
#include "map.h"
#include "mapper-types.h"
-#include "bt.h"
#include "ui-common.h"
#include "db.h"
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));
gtk_main_quit();
}
}
- /* Connect to receiver. */
- if (_enable_gps && _rcvr_mac)
- rcvr_connect_now();
done_here++; /* Don't ask... */
}
/* 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);
}
}
/* 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);