summaryrefslogtreecommitdiff
path: root/packet.c
diff options
context:
space:
mode:
Diffstat (limited to 'packet.c')
-rw-r--r--packet.c67
1 files changed, 58 insertions, 9 deletions
diff --git a/packet.c b/packet.c
index ff249614..710d0fe3 100644
--- a/packet.c
+++ b/packet.c
@@ -94,12 +94,12 @@ static void nextstate(struct gps_device_t *session, unsigned char c)
break;
}
#endif /* SIRF_ENABLE */
-#if defined(TSIP_ENABLE) || defined(EVERMORE_ENABLE)
+#if defined(TSIP_ENABLE) || defined(EVERMORE_ENABLE) || defined(GARMIN_ENABLE)
if (c == 0x10) {
session->packet_state = DLE_LEADER;
break;
}
-#endif /* defined(TSIP_ENABLE) || defined(EVERMORE_ENABLE) */
+#endif /* TSIP_ENABLE || EVERMORE_ENABLE || GARMIN_ENABLE */
#ifdef TRIPMATE_ENABLE
if (c == 'A') {
#ifdef RTCM104_ENABLE
@@ -340,14 +340,15 @@ static void nextstate(struct gps_device_t *session, unsigned char c)
session->packet_state = GROUND_STATE;
break;
#endif /* SIRF_ENABLE */
-#if defined(TSIP_ENABLE) || defined(EVERMORE_ENABLE)
+#if defined(TSIP_ENABLE) || defined(EVERMORE_ENABLE) || defined(GARMIN_ENABLE)
case DLE_LEADER:
#ifdef EVERMORE_ENABLE
if (c == 0x02)
session->packet_state = EVERMORE_LEADER_2;
else
#endif /* EVERMORE_ENABLE */
-#ifdef TSIP_ENABLE
+#if defined(TSIP_ENABLE) || defined(GARMIN_ENABLE)
+ /* garmin is special case of TSIP */
/* check last because there's no checksum */
if (c >= 0x13)
session->packet_state = TSIP_PAYLOAD;
@@ -355,7 +356,7 @@ static void nextstate(struct gps_device_t *session, unsigned char c)
#endif /* TSIP_ENABLE */
session->packet_state = GROUND_STATE;
break;
-#endif /* defined(TSIP_ENABLE) || defined(EVERMORE_ENABLE) */
+#endif /* TSIP_ENABLE || EVERMORE_ENABLE || GARMIN_ENABLE */
#ifdef ZODIAC_ENABLE
case ZODIAC_EXPECTED:
case ZODIAC_RECOGNIZED:
@@ -679,15 +680,63 @@ ssize_t packet_parse(struct gps_device_t *session, size_t fix)
packet_discard(session);
break;
#endif /* SIRF_ENABLE */
-#ifdef TSIP_ENABLE
+#if defined(TSIP_ENABLE) || defined(GARMIN_ENABLE)
} else if (session->packet_state == TSIP_RECOGNIZED) {
- if ((session->inbufptr - session->inbuffer) >= 4)
+ if ((session->inbufptr - session->inbuffer) >= 4) {
+#ifdef GARMIN_ENABLE
+ unsigned int n, chksum, c, len;
+ bool ok = false;
+
+ n = 0;
+ /*@ +charint */
+ do {
+
+ if (session->inbuffer[n++] != 0x10) break;
+ chksum = session->inbuffer[n++]; // skip pkt ID */
+ len = session->inbuffer[n++];
+ chksum += len;
+ if (len == 0x10) {
+ if (session->inbuffer[n++] != 0x10) break;
+ }
+ for (; len > 0; len--) {
+ chksum += session->inbuffer[n];
+ gpsd_report(4, "Garmin char : %02x\n",
+ session->inbuffer[n]);
+ if (session->inbuffer[n++] == 0x10) {
+ if (session->inbuffer[n++] != 0x10) break;
+ }
+ }
+ if (len > 0) break;
+ /* check sum byte */
+ c = session->inbuffer[n++];
+ chksum += c;
+ if (c == 0x10) {
+ if (session->inbuffer[n++] != 0x10) break;
+ }
+ if (session->inbuffer[n++] != 0x10) break;
+ if (session->inbuffer[n++] != 0x03) break;
+ chksum &= 0xff;
+
+ if ( chksum) {
+ gpsd_report(4, "Garmin checksum failed: %02x != 0\n"
+ , chksum);
+ break;
+ }
+ ok = true;
+ } while (0);
+ /*@ +charint */
+
+ gpsd_report(4, "Garmin n= %02x\n", n);
+ if (ok)
+ packet_accept(session, GARMIN_PACKET);
+ else
+#endif /* GARMIN_ENABLE */
packet_accept(session, TSIP_PACKET);
- else
+ } else
session->packet_state = GROUND_STATE;
packet_discard(session);
break;
-#endif /* TSIP_ENABLE */
+#endif /* TSIP_ENABLE || GARMIN_ENABLE */
#ifdef ZODIAC_ENABLE
} else if (session->packet_state == ZODIAC_RECOGNIZED) {
short len, n, sum;