diff options
author | Eric S. Raymond <esr@thyrsus.com> | 2010-05-06 10:39:05 -0400 |
---|---|---|
committer | Eric S. Raymond <esr@thyrsus.com> | 2010-05-06 10:39:05 -0400 |
commit | d70d87e260dd1d888e95011190d46eeb85419074 (patch) | |
tree | 65b3458c5fce6f26d9c3c86ad79187f9cdc34f0b /packet.c | |
parent | 43807e0b2622cfb1b15e28e2bef08c8f0a8aceb9 (diff) | |
download | gpsd-d70d87e260dd1d888e95011190d46eeb85419074.tar.gz |
Packetize Ashtech $PAHSRs correctly despite embedded binary content.
Diffstat (limited to 'packet.c')
-rw-r--r-- | packet.c | 58 |
1 files changed, 57 insertions, 1 deletions
@@ -111,6 +111,15 @@ enum #define STX (unsigned char)0x02 #define ETX (unsigned char)0x03 +static void character_pushback(struct gps_packet_t *lexer) +/* push back the last character grabbed */ +{ + --lexer->inbufptr; + --lexer->char_counter; + gpsd_report(LOG_RAW + 2, "%08ld: character pushed back\n", + lexer->char_counter); +} + static void nextstate(struct gps_packet_t *lexer, unsigned char c) { #ifdef RTCM104V2_ENABLE @@ -258,11 +267,58 @@ static void nextstate(struct gps_packet_t *lexer, unsigned char c) lexer->state = GROUND_STATE; break; case NMEA_VENDOR_LEAD: - if (isalpha(c)) + if (c == 'A') + lexer->state = NMEA_PASHR_A; + else if (isalpha(c)) + lexer->state = NMEA_LEADER_END; + else + lexer->state = GROUND_STATE; + break; + /* + * Without the following six states, DLE in a $PASHR can fool the + * sniffer into thinking it sees a TSIP packet. Hilarity ensues. + */ + case NMEA_PASHR_A: + if (c == 'S') + lexer->state = NMEA_PASHR_S; + else if (isalpha(c)) lexer->state = NMEA_LEADER_END; else lexer->state = GROUND_STATE; break; + case NMEA_PASHR_S: + if (c == 'H') + lexer->state = NMEA_PASHR_H; + else if (isalpha(c)) + lexer->state = NMEA_LEADER_END; + else + lexer->state = GROUND_STATE; + break; + case NMEA_PASHR_H: + if (c == 'R') + lexer->state = NMEA_BINARY_BODY; + else if (isalpha(c)) + lexer->state = NMEA_LEADER_END; + else + lexer->state = GROUND_STATE; + break; + case NMEA_BINARY_BODY: + if (c == '\r') + lexer->state = NMEA_BINARY_CR; + break; + case NMEA_BINARY_CR: + if (c == '\n') + lexer->state = NMEA_BINARY_NL; + else + lexer->state = NMEA_BINARY_BODY; + break; + case NMEA_BINARY_NL: + if (c == '$') { + character_pushback(lexer); + lexer->state = NMEA_RECOGNIZED; /* CRC will reject it */ + } else + lexer->state = NMEA_BINARY_BODY; + break; case NMEA_BANG: if (c == 'A') lexer->state = AIS_LEAD_1; |