summaryrefslogtreecommitdiff
path: root/driver_nmea.c
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>2009-03-16 07:04:58 +0000
committerEric S. Raymond <esr@thyrsus.com>2009-03-16 07:04:58 +0000
commit89291e5e1f0930298c4d62d0f91c5a15b3bdc3a6 (patch)
treec6cd149619a2ad2451b918f1b4505e0ef7eef17d /driver_nmea.c
parentaf9d3f3c0051ac14d47ab91852015d3c7c1ce00f (diff)
downloadgpsd-89291e5e1f0930298c4d62d0f91c5a15b3bdc3a6.tar.gz
Fix infinite-looping configuariuon bug reported by Andrew Mileski.
Diffstat (limited to 'driver_nmea.c')
-rw-r--r--driver_nmea.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/driver_nmea.c b/driver_nmea.c
index 1e0ba2b2..39564856 100644
--- a/driver_nmea.c
+++ b/driver_nmea.c
@@ -770,6 +770,24 @@ gps_mask_t nmea_parse(char *sentence, struct gps_device_t *session)
nmea_decoder decoder;
} nmea_phrase[] = {
/*@ -nullassign @*/
+ {"PGRMC", 0, NULL}, /* ignore Garmin Sensor Config */
+ {"PGRME", 7, processPGRME},
+ {"PGRMI", 0, NULL}, /* ignore Garmin Sensor Init */
+ {"PGRMO", 0, NULL}, /* ignore Garmin Sentence Enable */
+ /*
+ * Basic sentences must come after the PG* ones, otherwise
+ * Garmins can get stuck in a loop that looks like this:
+ *
+ * 1. A Garmin GPS in NMEA mode is detected.
+ *
+ * 2. PGRMC is sent to reconfigure to Garmin binary mode.
+ * If successful, the GPS echoes the phrase.
+ *
+ * 3. nmea_parse() sees the echo as RMC because the talker ID is
+ * ignored, and fails to recognize the echo as PGRMC and ignore it.
+ *
+ * 4. The mode is changed back to NMEA, resulting in an infinite loop.
+ */
{"RMC", 8, processGPRMC},
{"GGA", 13, processGPGGA},
{"GLL", 7, processGPGLL},
@@ -777,10 +795,6 @@ gps_mask_t nmea_parse(char *sentence, struct gps_device_t *session)
{"GSV", 0, processGPGSV},
{"VTG", 0, NULL}, /* ignore Velocity Track made Good */
{"ZDA", 7, processGPZDA},
- {"PGRMC", 0, NULL}, /* ignore Garmin Sensor Config */
- {"PGRME", 7, processPGRME},
- {"PGRMI", 0, NULL}, /* ignore Garmin Sensor Init */
- {"PGRMO", 0, NULL}, /* ignore Garmin Sentence Enable */
#ifdef TNT_ENABLE
{"PTNTHTM", 9, processTNTHTM},
#endif /* TNT_ENABLE */