summaryrefslogtreecommitdiff
path: root/packet.c
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>2005-07-16 13:21:03 +0000
committerEric S. Raymond <esr@thyrsus.com>2005-07-16 13:21:03 +0000
commit5ac90117f32cd9c2d798b8f567269606aebb7033 (patch)
treea5b4ac61f177351462be7d0c03f4207ab3b57c80 /packet.c
parent2b86ce367a08bdfd69b4882fcc8ad7f07ee80648 (diff)
downloadgpsd-5ac90117f32cd9c2d798b8f567269606aebb7033.tar.gz
Break the packet tester code out into a separate program.
Fix the state table regenerator so it conditionalizes the token list.
Diffstat (limited to 'packet.c')
-rw-r--r--packet.c384
1 files changed, 111 insertions, 273 deletions
diff --git a/packet.c b/packet.c
index f8bb34ad..7d28ba84 100644
--- a/packet.c
+++ b/packet.c
@@ -32,29 +32,6 @@ distinguish them from baud barf.
#include "config.h"
#include "gpsd.h"
-#ifdef TESTMAIN
-#include <stdarg.h>
-
-static int verbose = 0;
-static int waiting;
-
-void gpsd_report(int errlevel, const char *fmt, ... )
-/* assemble command in printf(3) style, use stderr or syslog */
-{
- if (errlevel <= verbose) {
- char buf[BUFSIZ];
- va_list ap;
-
- buf[0] = '\0';
- va_start(ap, fmt) ;
- (void)vsnprintf(buf + strlen(buf), sizeof(buf)-strlen(buf), fmt, ap);
- va_end(ap);
-
- (void)fputs(buf, stderr);
- }
-}
-#endif /* TESTMAIN */
-
/*
* The packet-recognition state machine. It can be fooled by garbage
* that looks like the head of a binary packet followed by a NMEA
@@ -699,24 +676,9 @@ static void character_discard(struct gps_device_t *session)
#define getword(i) (short)(session->inbuffer[2*(i)] | (session->inbuffer[2*(i)+1] << 8))
-ssize_t packet_get(struct gps_device_t *session)
+ssize_t packet_parse(struct gps_device_t *session, size_t newdata)
/* grab a packet; returns ether BAD_PACKET or the length */
{
- int newdata;
-#ifndef TESTMAIN
- /*@ -modobserver @*/
- newdata = (int)read(session->gpsdata.gps_fd, session->inbufptr,
- sizeof(session->inbuffer)-(session->inbufptr-session->inbuffer));
- /*@ +modobserver @*/
-#else
- newdata = waiting;
-#endif /* TESTMAIN */
-
- if (newdata < 0 && errno != EAGAIN)
- return BAD_PACKET;
- else if (newdata == 0 || (newdata < 0 && errno == EAGAIN))
- return 0;
-
#ifdef STATE_DEBUG
gpsd_report(6, "Read %d chars to buffer offset %d (total %d): %s\n",
newdata,
@@ -732,66 +694,101 @@ ssize_t packet_get(struct gps_device_t *session)
unsigned char c = *session->inbufptr++;
/*@ +modobserver @*/
/* to regenerate this table, see statetable.el */
- /*%start%*/
- char *state_table[] = {
- "GROUND_STATE",
- "NMEA_DOLLAR",
- "NMEA_PUB_LEAD",
- "NMEA_LEADER_END",
- "NMEA_CR",
- "NMEA_RECOGNIZED",
- "SIRF_ACK_LEAD_1",
- "SIRF_ACK_LEAD_2",
- "SEATALK_LEAD_1",
- "DLE_LEADER",
- "ASTRAL_1",
- "ASTRAL_2",
- "ASTRAL_3",
- "ASTRAL_4",
- "ASTRAL_5",
- "EARTHA_1",
- "EARTHA_2",
- "EARTHA_3",
- "EARTHA_4",
- "EARTHA_5",
- "SIRF_LEADER_1",
- "SIRF_LEADER_2",
- "SIRF_LENGTH_1",
- "SIRF_PAYLOAD",
- "SIRF_DELIVERED",
- "SIRF_TRAILER_1",
- "SIRF_RECOGNIZED",
- "ZODIAC_EXPECTED",
- "ZODIAC_LEADER_1",
- "ZODIAC_LEADER_2",
- "ZODIAC_ID_1",
- "ZODIAC_ID_2",
- "ZODIAC_LENGTH_1",
- "ZODIAC_LENGTH_2",
- "ZODIAC_FLAGS_1",
- "ZODIAC_FLAGS_2",
- "ZODIAC_HSUM_1",
- "ZODIAC_PAYLOAD",
- "ZODIAC_RECOGNIZED",
- "EVERMORE_LEADER_1",
- "EVERMORE_LEADER_2",
- "EVERMORE_PAYLOAD",
- "EVERMORE_PAYLOAD_DLE",
- "EVERMORE_RECOGNIZED",
- "ITALK_LEADER_1",
- "ITALK_LEADER_2",
- "ITALK_LENGTH_1",
- "ITALK_LENGTH_2",
- "ITALK_DELIVERED",
- "ITALK_TRAILER_1",
- "ITALK_RECOGNIZED",
- "TSIP_LEADER",
- "TSIP_PAYLOAD",
- "TSIP_DLE",
- "TSIP_RECOGNIZED",
- "RTM_SYNC_STATE",
- "RTM_RECOGBIZED",
- };
+ /*%start%*/char *state_table[] = {
+ "GROUND_STATE", /* we don't know what packet type to expect */
+
+#ifdef NMEA_ENABLE
+ "NMEA_DOLLAR", /* we've seen first character of NMEA leader */
+ "NMEA_PUB_LEAD", /* seen second character of NMEA G leader */
+ "NMEA_LEADER_END", /* seen end char of NMEA leader, in body */
+ "NMEA_CR", /* seen terminating \r of NMEA packet */
+ "NMEA_RECOGNIZED", /* saw trailing \n of NMEA packet */
+
+ "SIRF_ACK_LEAD_1", /* seen A of possible SiRF Ack */
+ "SIRF_ACK_LEAD_2", /* seen c of possible SiRF Ack */
+
+ "SEATALK_LEAD_1", /* SeaTalk/Garmin packet leader 'I' */
+#endif /* NMEA_ENABLE */
+
+ "DLE_LEADER", /* we've seen the TSIP/Evermore leader (DLE) */
+
+#ifdef TRIPMATE_ENABLE
+ "ASTRAL_1", /* ASTRAL leader A */
+ "ASTRAL_2", /* ASTRAL leader S */
+ "ASTRAL_3", /* ASTRAL leader T */
+ "ASTRAL_4", /* ASTRAL leader R */
+ "ASTRAL_5", /* ASTRAL leader A */
+#endif /* TRIPMATE_ENABLE */
+
+#ifdef EARTHMATE_ENABLE
+ "EARTHA_1", /* EARTHA leader E */
+ "EARTHA_2", /* EARTHA leader A */
+ "EARTHA_3", /* EARTHA leader R */
+ "EARTHA_4", /* EARTHA leader T */
+ "EARTHA_5", /* EARTHA leader H */
+#endif /* EARTHMATE_ENABLE */
+
+#ifdef SIRFII_ENABLE
+ "SIRF_LEADER_1", /* we've seen first character of SiRF leader */
+ "SIRF_LEADER_2", /* seen second character of SiRF leader */
+ "SIRF_LENGTH_1", /* seen first byte of SiRF length */
+ "SIRF_PAYLOAD", /* we're in a SiRF payload part */
+ "SIRF_DELIVERED", /* saw last byte of SiRF payload/checksum */
+ "SIRF_TRAILER_1", /* saw first byte of SiRF trailer */
+ "SIRF_RECOGNIZED", /* saw second byte of SiRF trailer */
+#endif /* SIRFII_ENABLE */
+
+#ifdef ZODIAC_ENABLE
+ "ZODIAC_EXPECTED", /* expecting Zodiac packet */
+ "ZODIAC_LEADER_1", /* saw leading 0xff */
+ "ZODIAC_LEADER_2", /* saw leading 0x81 */
+ "ZODIAC_ID_1", /* saw first byte of ID */
+ "ZODIAC_ID_2", /* saw second byte of ID */
+ "ZODIAC_LENGTH_1", /* saw first byte of Zodiac packet length */
+ "ZODIAC_LENGTH_2", /* saw second byte of Zodiac packet length */
+ "ZODIAC_FLAGS_1", /* saw first byte of FLAGS */
+ "ZODIAC_FLAGS_2", /* saw second byte of FLAGS */
+ "ZODIAC_HSUM_1", /* saw first byte of Header sum */
+ "ZODIAC_PAYLOAD", /* we're in a Zodiac payload */
+ "ZODIAC_RECOGNIZED", /* found end of the Zodiac packet */
+#endif /* ZODIAC_ENABLE */
+
+#ifdef EVERMORE_ENABLE
+ "EVERMORE_LEADER_1", /* a DLE after having seen Evermore data */
+ "EVERMORE_LEADER_2", /* seen opening STX of Evermore packet */
+ "EVERMORE_PAYLOAD", /* in payload part of Evermore packet */
+ "EVERMORE_PAYLOAD_DLE", /* DLE in payload part of Evermore packet */
+ "EVERMORE_RECOGNIZED", /* found end of Evermore packet */
+#endif /* EVERMORE_ENABLE */
+
+#ifdef ITALK_ENABLE
+ "ITALK_LEADER_1", /* saw leading < of iTalk packet */
+ "ITALK_LEADER_2", /* saw leading * of iTalk packet */
+ "ITALK_LENGTH_1", /* saw MSB of packet length */
+ "ITALK_LENGTH_2", /* saw LSB of packet length */
+ "ITALK_DELIVERED", /* seen end of payload */
+ "ITALK_TRAILER_1", /* saw iTalk trailer byte */
+ "ITALK_RECOGNIZED", /* found end of the iTalk packet */
+#endif /* ITALK_ENABLE */
+
+/*
+ * Packet formats without checksums start here. We list them last so
+ * that if a format with a conflicting structure *and* a checksum can
+ * be recognized, that will be preferred.
+ */
+
+#ifdef TSIP_ENABLE
+ "TSIP_LEADER", /* a DLE after having seen TSIP data */
+ "TSIP_PAYLOAD", /* we're in TSIP payload */
+ "TSIP_DLE", /* we've seen a DLE in TSIP payload */
+ "TSIP_RECOGNIZED", /* found end of the TSIP packet */
+#endif /* TSIP_ENABLE */
+
+#ifdef RTCM104_ENABLE
+ "RTCM_SYNC_STATE", /* we have sync lock */
+ "RTCM_RECOGNIZED", /* we have an RTCM packet */
+#endif /* RTCM104_ENABLE */
+};
/*%end%*/
nexstate(session, c);
gpsd_report(7, "Character '%c' [%02X], new state: %s\n",
@@ -925,6 +922,21 @@ ssize_t packet_get(struct gps_device_t *session)
}
#undef getword
+ssize_t packet_get(struct gps_device_t *session)
+/* grab a packet; returns ether BAD_PACKET or the length */
+{
+ int newdata;
+ /*@ -modobserver @*/
+ newdata = (int)read(session->gpsdata.gps_fd, session->inbufptr,
+ sizeof(session->inbuffer)-(session->inbufptr-session->inbuffer));
+ /*@ +modobserver @*/
+ if (newdata < 0 && errno != EAGAIN)
+ return BAD_PACKET;
+ else if (newdata == 0 || (newdata < 0 && errno == EAGAIN))
+ return 0;
+ return packet_parse(session, newdata);
+}
+
void packet_reset(struct gps_device_t *session)
/* return the packet machine to the ground state */
{
@@ -950,177 +962,3 @@ void packet_pushback(struct gps_device_t *session)
}
}
#endif /* __UNUSED */
-
-#ifdef TESTMAIN
-/* To build a test main, compile with cc -DTESTMAIN -g packet.c -o packet */
-
-int main(int argc, char *argv[])
-{
- struct map {
- char *legend;
- unsigned char test[MAX_PACKET_LENGTH+1];
- int testlen;
- int garbage_offset;
- int type;
- int initstate;
- };
- struct map tests[] = {
- /* NMEA tests */
- {
- "NMEA packet with checksum (1)",
- "$GPVTG,308.74,T,,M,0.00,N,0.0,K*68\r\n",
- 36,
- 0,
- NMEA_PACKET,
- GROUND_STATE,
- },
- {
- "NMEA packet with checksum (2)",
- "$GPGGA,110534.994,4002.1425,N,07531.2585,W,0,00,50.0,172.7,M,-33.8,M,0.0,0000*7A\r\n",
- 82,
- 0,
- NMEA_PACKET,
- GROUND_STATE,
- },
- {
- "NMEA packet with checksum and 4 chars of leading garbage",
- "\xff\xbf\x00\xbf$GPVTG,308.74,T,,M,0.00,N,0.0,K*68\r\n",
- 40,
- 4,
- NMEA_PACKET,
- GROUND_STATE,
- },
- {
- "NMEA packet without checksum",
- "$PSRF105,1\r\n",
- 12,
- 0,
- NMEA_PACKET,
- GROUND_STATE,
- },
- {
- "NMEA packet with wrong checksum",
- "$GPVTG,308.74,T,,M,0.00,N,0.0,K*28\r\n",
- 36,
- 0,
- BAD_PACKET,
- GROUND_STATE,
- },
- /* SiRF tests */
- {
- "SiRF WAAS version ID",
- {
- 0xA0, 0xA2, 0x00, 0x15,
- 0x06, 0x06, 0x31, 0x2E, 0x32, 0x2E, 0x30, 0x44,
- 0x4B, 0x49, 0x54, 0x31, 0x31, 0x39, 0x20, 0x53,
- 0x4D, 0x00, 0x00, 0x00, 0x00,
- 0x03, 0x82, 0xB0, 0xB3},
- 29,
- 0,
- SIRF_PACKET,
- GROUND_STATE,
- },
- {
- "SiRF WAAS version ID with 3 chars of leading garbage",
- {
- 0xff, 0x00, 0xff,
- 0xA0, 0xA2, 0x00, 0x15,
- 0x06, 0x06, 0x31, 0x2E, 0x32, 0x2E, 0x30, 0x44,
- 0x4B, 0x49, 0x54, 0x31, 0x31, 0x39, 0x20, 0x53,
- 0x4D, 0x00, 0x00, 0x00, 0x00,
- 0x03, 0x82, 0xB0, 0xB3},
- 32,
- 3,
- SIRF_PACKET,
- GROUND_STATE,
- },
- {
- "SiRF WAAS version ID with wrong checksum",
- {
- 0xA0, 0xA2, 0x00, 0x15,
- 0x06, 0x06, 0x31, 0x2E, 0x32, 0x2E, 0x30, 0x44,
- 0x4B, 0x49, 0x54, 0x31, 0x31, 0x39, 0x20, 0x53,
- 0x4D, 0x00, 0x00, 0x00, 0x00,
- 0x03, 0x00, 0xB0, 0xB3},
- 29,
- 0,
- BAD_PACKET,
- GROUND_STATE,
- },
- {
- "SiRF WAAS version ID with bad length",
- {
- 0xA0, 0xA2, 0xff, 0x15,
- 0x06, 0x06, 0x31, 0x2E, 0x32, 0x2E, 0x30, 0x44,
- 0x4B, 0x49, 0x54, 0x31, 0x31, 0x39, 0x20, 0x53,
- 0x4D, 0x00, 0x00, 0x00, 0x00,
- 0x03, 0x82, 0xB0, 0xB3},
- 29,
- 0,
- BAD_PACKET,
- GROUND_STATE,
- },
- /* Zodiac tests */
- {
- "Zodiac binary 1000 Geodetic Status Output Message",
- {
- 0xff, 0x81, 0xe8, 0x03, 0x31, 0x00, 0x00, 0x00, 0xe8, 0x79,
- 0x74, 0x0e, 0x00, 0x00, 0x24, 0x00, 0x24, 0x00, 0x04, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x03, 0x23, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x06, 0x00,
- 0xcd, 0x07, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x7b, 0x0d,
- 0x00, 0x00, 0x12, 0x6b, 0xa7, 0x04, 0x41, 0x75, 0x32, 0xf8,
- 0x03, 0x1f, 0x00, 0x00, 0xe6, 0xf2, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x11, 0xf6, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x40,
- 0xd9, 0x12, 0x90, 0xd0, 0x03, 0x00, 0x00, 0xa3, 0xe1, 0x11,
- 0x10, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa3, 0xe1, 0x11,
- 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0x04, 0x00, 0x04, 0xaa},
- 110,
- 0,
- ZODIAC_PACKET,
- ZODIAC_EXPECTED,
- },
- };
-
- struct map *mp;
- struct gps_device_t state;
- int st;
- unsigned char *cp;
-
- if (argc > 1)
- verbose = atoi(argv[1]);
-
- for (mp = tests; mp < tests + sizeof(tests)/sizeof(tests[0]); mp++) {
- state.packet_type = BAD_PACKET;
- state.packet_state = mp->initstate;
- state.inbuflen = 0;
- memcpy(state.inbufptr = state.inbuffer, mp->test, mp->testlen);
- gpsd_report(2, "%s starts with state %d\n", mp->legend, mp->initstate);
- waiting = mp->testlen;
- st = packet_get(&state);
- if (state.packet_type != mp->type)
- printf("%s test FAILED (packet type %d wrong).\n", mp->legend, st);
- else if (memcmp(mp->test + mp->garbage_offset, state.outbuffer, state.outbuflen))
- printf("%s test FAILED (data garbled).\n", mp->legend);
- else
- printf("%s test succeeded.\n", mp->legend);
-#ifdef DUMPIT
- for (cp = state.outbuffer;
- cp < state.outbuffer + state.outbuflen;
- cp++) {
- if (st != NMEA_PACKET)
- (void)printf(" 0x%02x", *cp);
- else if (*cp == '\r')
- (void)fputs("\\r", stdout);
- else if (*cp == '\n')
- (void)fputs("\\n", stdout);
- else if (isprint(*cp))
- (void)putchar(*cp);
- else
- (void)printf("\\x%02x", *cp);
- }
- (void)putchar('\n');
-#endif /* DUMPIT */
- }
-}
-#endif /* TESTMAIN */