summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>2013-11-19 04:19:17 -0500
committerEric S. Raymond <esr@thyrsus.com>2013-11-19 04:19:17 -0500
commitd1645133ee3aecb02f1f8f61a1e0854eb5c712da (patch)
treebb830c53d9bed842bfa0c3a2d74ebbd278266f0e
parent08198ac8b5d745cf678d0eb7c34e99deb0dc894d (diff)
downloadgpsd-d1645133ee3aecb02f1f8f61a1e0854eb5c712da.tar.gz
Add timeout on wait-for-ACK to SiRF driver.
Correct initialization observed oon SiRF-III. All regression tests pass.
-rw-r--r--TODO2
-rw-r--r--driver_sirf.c23
-rw-r--r--gpsd.h-tail3
-rw-r--r--gpsmon.c8
4 files changed, 28 insertions, 8 deletions
diff --git a/TODO b/TODO
index 13592e2e..d27e98c1 100644
--- a/TODO
+++ b/TODO
@@ -20,7 +20,7 @@ month is quite low.
**** In gpsmon's PPS Offset field
-Presently PPS Offset is displayed in direct mode for NMEA, SiRF, and
+resently PPS Offset is displayed in direct mode for NMEA, SiRF, and
UBX devices. Others should probably do likewise, notably the
Motorola Oncore and Garmin drivers.
diff --git a/driver_sirf.c b/driver_sirf.c
index 942915d2..d9bcbbd5 100644
--- a/driver_sirf.c
+++ b/driver_sirf.c
@@ -46,6 +46,12 @@
#define HI(n) ((n) >> 8)
#define LO(n) ((n) & 0xff)
+/*
+ * According to the protocol reference, if you don't get ACK/NACK in response
+ * to a control send withing 6 seconds, you should just retry.
+ */
+#define SIRF_RETRY_TIME 6
+
/*@ +charint @*/
/* Poll Software Version MID 132 */
static unsigned char versionprobe[] = {
@@ -237,7 +243,10 @@ static bool sirf_write(struct gps_device_t *session, unsigned char *msg)
* lower-powered processor that apparently has trouble keeping up.
* Now you have to wait for the ACK, otherwise chaos ensues.
*/
- if (session->driver.sirf.ack_await > 0) {
+ if (time(NULL) - session->driver.sirf.last_send > SIRF_RETRY_TIME)
+ session->driver.sirf.need_ack = false;
+ /* can also be false because ACK was received after last send */
+ if (session->driver.sirf.need_ack) {
gpsd_report(session->context->debug, LOG_WARN,
"SiRF: write of control type %02x failed, awaiting ACK.\n",
msg[4]);
@@ -260,7 +269,8 @@ static bool sirf_write(struct gps_device_t *session, unsigned char *msg)
"SiRF: Writing control type %02x:\n", msg[4]);
ok = (gpsd_write(session, (const char *)msg, len+8) == (ssize_t) (len+8));
- session->driver.sirf.ack_await++;
+ session->driver.sirf.need_ack = true;
+ session->driver.sirf.last_send = time(NULL);
return (ok);
}
@@ -1230,14 +1240,14 @@ gps_mask_t sirf_parse(struct gps_device_t * session, unsigned char *buf,
case 0x0b: /* Command Acknowledgement MID 11 */
gpsd_report(session->context->debug, LOG_PROG,
"SiRF: ACK 0x0b: %02x\n", getub(buf, 1));
- session->driver.sirf.ack_await--;
+ session->driver.sirf.need_ack = false;
return 0;
case 0x0c: /* Command NAcknowledgement MID 12 */
gpsd_report(session->context->debug, LOG_PROG,
"SiRF: NAK 0x0c: %02x\n", getub(buf, 1));
/* ugh -- there's no alternative but silent failure here */
- session->driver.sirf.ack_await--;
+ session->driver.sirf.need_ack = false;
return 0;
case 0x0d: /* Visible List MID 13 */
@@ -1391,7 +1401,10 @@ static void sirfbin_event_hook(struct gps_device_t *session, event_t event)
if (event == event_configure) {
/* might not be time for the next init string yet */
- if (session->driver.sirf.ack_await > 0)
+ if (time(NULL) - session->driver.sirf.last_send > SIRF_RETRY_TIME)
+ session->driver.sirf.need_ack = false;
+ /* can also be false because ACK was received after last send */
+ if (session->driver.sirf.need_ack)
return;
switch (session->driver.sirf.cfg_stage++) {
diff --git a/gpsd.h-tail b/gpsd.h-tail
index b9b1ea67..a2604d7b 100644
--- a/gpsd.h-tail
+++ b/gpsd.h-tail
@@ -545,7 +545,8 @@ struct gps_device_t {
#endif /* GEOSTAR_ENABLE */
#ifdef SIRF_ENABLE
struct {
- int ack_await; /* if NZ we're awaiting ACK */
+ bool need_ack; /* if NZ we're awaiting ACK */
+ time_t last_send; /* for tracking send timeouts */
unsigned int cfg_stage; /* configuration stage counter */
unsigned int driverstate; /* for private use */
#define SIRF_LT_231 0x01 /* SiRF at firmware rev < 231 */
diff --git a/gpsmon.c b/gpsmon.c
index 6eae3e5b..54bd0f59 100644
--- a/gpsmon.c
+++ b/gpsmon.c
@@ -1158,7 +1158,13 @@ int main(int argc, char **argv)
else
devicename = argv[optind];
- (void)strlcpy(session.gpsdata.dev.path, devicename,
+ /* backward compatibilty: accept a bare server name */
+ if (strchr(devicename, ':') == NULL && devicename[0] != '/')
+ (void) strlcpy(session.gpsdata.dev.path,
+ "tcp://", sizeof(session.gpsdata.dev.path));
+ else
+ session.gpsdata.dev.path[0] = '\0';
+ (void)strlcat(session.gpsdata.dev.path, devicename,
sizeof(session.gpsdata.dev.path));
if (gpsd_activate(&session, O_PROBEONLY) == -1) {