summaryrefslogtreecommitdiff
path: root/libgpsd_core.c
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>2013-09-29 13:54:21 -0400
committerEric S. Raymond <esr@thyrsus.com>2013-09-29 13:56:34 -0400
commit9cfee07284fa5fafe6d19b87d9d053f9d2cac2ac (patch)
treefa1777f8d69d3847582d32a8d3cd09c74d55a5dd /libgpsd_core.c
parent9d40fb73cf953310d6b4457b6a54ee608f504341 (diff)
downloadgpsd-9cfee07284fa5fafe6d19b87d9d053f9d2cac2ac.tar.gz
Increase the resilience of the packet getter.
Fail hunt only if we get a second consecutive bad packet and the lexer is in ground state. We don't want to fail on a first bad packet because the source might have a burst of leading garbage after open. We don't want to fail if the lexer is not in ground state, because that means the read might have picked up a valid partial packet - better to go back around the loop and pick up more data. This change also improves behavior if a read happens to end in mid-packet. All regression tests pass.
Diffstat (limited to 'libgpsd_core.c')
-rw-r--r--libgpsd_core.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/libgpsd_core.c b/libgpsd_core.c
index 97f16d4d..461b98f5 100644
--- a/libgpsd_core.c
+++ b/libgpsd_core.c
@@ -307,7 +307,7 @@ void gpsd_clear(struct gps_device_t *session)
session->gpsdata.separation = NAN;
session->mag_var = NAN;
session->releasetime = (timestamp_t)0;
- session->getcount = 0;
+ session->badcount = 0;
/* clear the private data union */
memset(&session->driver, '\0', sizeof(session->driver));
@@ -1096,8 +1096,18 @@ gps_mask_t gpsd_poll(struct gps_device_t *session)
}
}
/*@+nullderef@*/
+ session->badcount = 0;
/* FALL THROUGH */
- } else if (session->getcount++>1 && !gpsd_next_hunt_setting(session)) {
+ /*
+ * Fail hunt only if we get a second consecutive bad packet
+ * and the lexer is in ground state. We don't want to fail on
+ * a first bad packet because the source might have a burst of
+ * leading garbage after open. We don't want to fail if the
+ * lexer is not in ground state, because that means the read
+ * might have picked up a valid partial packet - better to go
+ * back around the loop and pick up more data.
+ */
+ } else if (session->badcount++>1 && !session->packet.state && !gpsd_next_hunt_setting(session)) {
gpsd_report(session->context->debug, LOG_INF,
"hunt on %s failed (%lf sec since data)\n",
session->gpsdata.dev.path,