#include "icons/icons.h"
#include "babel.h"
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
-#include <glib.h>
+#include <glib/gstdio.h>
#include <glib/gprintf.h>
#include <glib/gi18n.h>
#ifdef VIK_CONFIG_REALTIME_GPS_TRACKING
static void vik_gps_layer_realize ( VikGpsLayer *val, VikTreeview *vt, GtkTreeIter *layer_iter );
static void vik_gps_layer_free ( VikGpsLayer *val );
static void vik_gps_layer_draw ( VikGpsLayer *val, gpointer data );
-VikGpsLayer *vik_gps_layer_new ();
+static VikGpsLayer *vik_gps_layer_new ( VikViewport *vp );
static void gps_layer_marshall( VikGpsLayer *val, guint8 **data, gint *len );
static VikGpsLayer *gps_layer_unmarshall( guint8 *data, gint len, VikViewport *vvp );
#else
static gchar * params_ports[] = {"/dev/ttyS0", "/dev/ttyS1", "/dev/ttyUSB0", "/dev/ttyUSB1", "usb:", NULL};
#endif
-#define NUM_PORTS (sizeof(params_ports)/sizeof(params_ports[0]) - 1)
+/* NUM_PORTS not actually used */
+/* #define NUM_PORTS (sizeof(params_ports)/sizeof(params_ports[0]) - 1) */
+/* Compatibility with previous versions */
+#ifdef WINDOWS
+static gchar * old_params_ports[] = {"com1", "usb:", NULL};
+#else
+static gchar * old_params_ports[] = {"/dev/ttyS0", "/dev/ttyS1", "/dev/ttyUSB0", "/dev/ttyUSB1", "usb:", NULL};
+#endif
+#define OLD_NUM_PORTS (sizeof(old_params_ports)/sizeof(old_params_ports[0]) - 1)
typedef enum {GPS_DOWN=0, GPS_UP} gps_dir;
typedef struct {
static VikLayerParam gps_layer_params[] = {
{ "gps_protocol", VIK_LAYER_PARAM_UINT, GROUP_DATA_MODE, N_("GPS Protocol:"), VIK_LAYER_WIDGET_COMBOBOX, params_protocols, NULL},
- { "gps_port", VIK_LAYER_PARAM_UINT, GROUP_DATA_MODE, N_("Serial Port:"), VIK_LAYER_WIDGET_COMBOBOX, params_ports, NULL},
+ { "gps_port", VIK_LAYER_PARAM_STRING, GROUP_DATA_MODE, N_("Serial Port:"), VIK_LAYER_WIDGET_COMBOBOX, params_ports, NULL},
#ifdef VIK_CONFIG_REALTIME_GPS_TRACKING
{ "record_tracking", VIK_LAYER_PARAM_BOOLEAN, GROUP_REALTIME_MODE, N_("Recording tracks"), VIK_LAYER_WIDGET_CHECKBUTTON},
params_groups,
sizeof(params_groups)/sizeof(params_groups[0]),
- VIK_MENU_ITEM_ALL & ~(VIK_MENU_ITEM_CUT|VIK_MENU_ITEM_COPY),
+ VIK_MENU_ITEM_ALL,
(VikLayerFuncCreate) vik_gps_layer_create,
(VikLayerFuncRealize) vik_gps_layer_realize,
GpsFix realtime_fix;
GpsFix last_fix;
- enum unit realtime_gpsd_unit;
-
VikTrack *realtime_track;
gchar *realtime_track_name;
guint vehicle_position;
#endif /* VIK_CONFIG_REALTIME_GPS_TRACKING */
guint protocol_id;
- guint serial_port_id;
+ gchar *serial_port;
};
GType vik_gps_layer_get_type ()
len -= sizeof(gint) + alm_size; \
data += sizeof(gint) + alm_size;
- VikGpsLayer *rv = vik_gps_layer_new();
+ VikGpsLayer *rv = vik_gps_layer_new(vvp);
VikLayer *child_layer;
gint i;
g_warning(_("Unknown GPS Protocol"));
break;
case PARAM_PORT:
- if (data.u < NUM_PORTS)
- vgl->serial_port_id = data.u;
+ if (data.s)
+{
+ g_free(vgl->serial_port);
+ /* Compat: previous version stored serial_port as an array index */
+ int index = data.s[0] - '0';
+ if (data.s[0] != '\0' &&
+ g_ascii_isdigit (data.s[0]) &&
+ data.s[1] == '\0' &&
+ index < OLD_NUM_PORTS)
+ /* It is a single digit: activate compatibility */
+ vgl->serial_port = g_strdup(old_params_ports[index]);
+ else
+ vgl->serial_port = g_strdup(data.s);
+ g_debug("%s: %s", __FUNCTION__, vgl->serial_port);
+}
else
g_warning(_("Unknown serial port device"));
break;
rv.u = vgl->protocol_id;
break;
case PARAM_PORT:
- rv.u = vgl->serial_port_id;
+ rv.s = vgl->serial_port;
+ g_debug("%s: %s", __FUNCTION__, rv.s);
break;
#ifdef VIK_CONFIG_REALTIME_GPS_TRACKING
case PARAM_GPSD_HOST:
vgl->realtime_track_pt1_gc = vik_viewport_new_gc ( vp, "red", 2 );
vgl->realtime_track_pt2_gc = vik_viewport_new_gc ( vp, "green", 2 );
vgl->realtime_track_pt_gc = vgl->realtime_track_pt1_gc;
- vgl->realtime_gpsd_unit = gpsd_units();
- // fprintf(stderr, "DEBUG: gpsd_unit = %d\n", vgl->realtime_gpsd_unit);
vgl->realtime_track = NULL;
/* Setting params here */
vgl->gpsd_retry_interval = 10;
#endif /* VIK_CONFIG_REALTIME_GPS_TRACKING */
vgl->protocol_id = 0;
- vgl->serial_port_id = 0;
+ vgl->serial_port = NULL;
+
+#ifndef WINDOWS
+ /* Attempt to auto set default USB serial port entry */
+ /* Ordered to make lowest device favourite if available */
+ if (g_access ("/dev/ttyUSB1", R_OK) == 0) {
+ if (vgl->serial_port != NULL)
+ g_free (vgl->serial_port);
+ vgl->serial_port = g_strdup ("/dev/ttyUSB1");
+ }
+ if (g_access ("/dev/ttyUSB0", R_OK) == 0) {
+ if (vgl->serial_port != NULL)
+ g_free (vgl->serial_port);
+ vgl->serial_port = g_strdup ("/dev/ttyUSB0");
+ }
+#endif
return vgl;
}
static void disconnect_layer_signal ( VikLayer *vl, VikGpsLayer *vgl )
{
- g_assert(DISCONNECT_UPDATE_SIGNAL(vl,vgl)==1);
+ guint number_handlers = DISCONNECT_UPDATE_SIGNAL(vl,vgl);
+ if ( number_handlers != 1 ) {
+ /*
+ NB It's not fatal if this gives 2 for example! Hence removal of the g_assert
+ This happens when copied GPS layer is deleted (not sure why the number_handlers would be 2)
+ I don't think there's any side effects and certainly better than the program just aborting
+ */
+ g_warning(_("Unexpected number of disconnected handlers: %d"), number_handlers);
+ }
}
static void vik_gps_layer_free ( VikGpsLayer *vgl )
}
g_strfreev(tokens);
}
+ /* eg: "Unit:\teTrex Legend HCx Software Version 2.90\n" */
+ if (strstr(line, "Unit:")) {
+ gchar **tokens = g_strsplit(line, "\t", 0);
+ int n_tokens = 0;
+ while (tokens[n_tokens])
+ n_tokens++;
+
+ if (n_tokens > 1) {
+ set_gps_info(tokens[1], sess);
+ }
+ g_strfreev(tokens);
+ }
if (strstr(line, "RECORD")) {
int lsb, msb, cnt;
{
VikGpsLayer *vgl = (VikGpsLayer *)layer_and_vlp[0];
VikTrwLayer *vtl = vgl->trw_children[TRW_UPLOAD];
- gps_comm(vtl, GPS_UP, vgl->protocol_id, params_ports[vgl->serial_port_id]);
+ gps_comm(vtl, GPS_UP, vgl->protocol_id, vgl->serial_port);
}
static void gps_download_cb( gpointer layer_and_vlp[2] )
{
VikGpsLayer *vgl = (VikGpsLayer *)layer_and_vlp[0];
VikTrwLayer *vtl = vgl->trw_children[TRW_DOWNLOAD];
- gps_comm(vtl, GPS_DOWN, vgl->protocol_id, params_ports[vgl->serial_port_id]);
+ gps_comm(vtl, GPS_DOWN, vgl->protocol_id, vgl->serial_port);
}
static void gps_empty_upload_cb( gpointer layer_and_vlp[2] )
vik_viewport_set_center_coord(vvp, &vehicle_coord);
update_all = TRUE;
}
- else {
+ else if (vgl->vehicle_position == VEHICLE_POSITION_ON_SCREEN) {
const int hdiv = 6;
const int vdiv = 6;
const int px = 20; /* adjust ment in pixels to make sure vehicle is inside the box */
static gboolean rt_gpsd_try_connect(gpointer *data)
{
VikGpsLayer *vgl = (VikGpsLayer *)data;
+#ifndef HAVE_GPS_OPEN_R
struct gps_data_t *gpsd = gps_open(vgl->gpsd_host, vgl->gpsd_port);
if (gpsd == NULL) {
+#else
+ vgl->vgpsd = g_malloc(sizeof(VglGpsd));
+
+ if (gps_open_r(vgl->gpsd_host, vgl->gpsd_port, /*(struct gps_data_t *)*/vgl->vgpsd) != 0) {
+#endif
g_warning("Failed to connect to gpsd at %s (port %s). Will retry in %d seconds",
vgl->gpsd_host, vgl->gpsd_port, vgl->gpsd_retry_interval);
return TRUE; /* keep timer running */
}
- vgl->vgpsd = g_realloc(gpsd, sizeof(VglGpsd));
+#ifndef HAVE_GPS_OPEN_R
+ vgl->vgpsd = realloc(gpsd, sizeof(VglGpsd));
+#endif
vgl->vgpsd->vgl = vgl;
vgl->realtime_fix.dirty = vgl->last_fix.dirty = FALSE;
vgl->realtime_io_channel = g_io_channel_unix_new(vgl->vgpsd->gpsd.gps_fd);
vgl->realtime_io_watch_id = g_io_add_watch( vgl->realtime_io_channel,
G_IO_IN | G_IO_ERR | G_IO_HUP, gpsd_data_available, vgl);
+#if HAVE_GPS_STREAM
+ gps_stream(&vgl->vgpsd->gpsd, WATCH_ENABLE, NULL);
+#else
gps_query(&vgl->vgpsd->gpsd, "w+x");
+#endif
return FALSE; /* no longer called by timeout */
}
}
if (vgl->vgpsd) {
gps_close(&vgl->vgpsd->gpsd);
+#ifdef HAVE_GPS_OPEN_R
+ g_free(vgl->vgpsd);
+#else
+ free(vgl->vgpsd);
+#endif
vgl->vgpsd = NULL;
}