You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

packet.c 76KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619
  1. /****************************************************************************
  2. NAME:
  3. packet.c -- a packet-sniffing engine for reading from GPS devices
  4. DESCRIPTION:
  5. Initial conditions of the problem:
  6. 1. We have a file descriptor open for (possibly non-blocking) read. The device
  7. on the other end is sending packets at us.
  8. 2. It may require more than one read to gather a packet. Reads may span packet
  9. boundaries.
  10. 3. There may be leading garbage before the first packet. After the first
  11. start-of-packet, the input should be well-formed.
  12. The problem: how do we recognize which kind of packet we're getting?
  13. No need to handle Garmin USB binary, we know that type by the fact we're
  14. connected to the Garmin kernel driver. But we need to be able to tell the
  15. others apart and distinguish them from baud barf.
  16. PERMISSIONS
  17. This file is Copyright (c) 2010-2018 by the GPSD project
  18. SPDX-License-Identifier: BSD-2-clause
  19. ***************************************************************************/
  20. #include "gpsd_config.h" /* must be before all includes */
  21. #include <sys/types.h>
  22. #include <stdio.h>
  23. #include <stdbool.h>
  24. #include <ctype.h>
  25. #include <string.h>
  26. #include <errno.h>
  27. #include <netinet/in.h>
  28. #include <arpa/inet.h> /* for htons() */
  29. #include <unistd.h>
  30. #include "bits.h"
  31. #include "driver_greis.h"
  32. #include "gpsd.h"
  33. #include "crc24q.h"
  34. #include "strfuncs.h"
  35. /*
  36. * The packet-recognition state machine. This takes an incoming byte stream
  37. * and tries to segment it into packets. There are four types of packets:
  38. *
  39. * 1) Comments. These begin with # and end with \r\n.
  40. *
  41. * 2) NMEA lines. These begin with $, and with \r\n, and have a checksum.
  42. *
  43. * 3) Checksummed binary packets. These begin with some fixed leader
  44. * character(s), have a length embedded in them, and end with a
  45. * checksum (and possibly some fixed trailing bytes).
  46. *
  47. * 4) ISGPS packets. The input may be a bitstream containing IS-GPS-200
  48. * packets. Each includes a fixed leader byte, a length, and check bits.
  49. * In this case, it is not guaranted that packet starts begin on byte
  50. * bounaries; the recognizer has to run a separate state machine against
  51. * each byte just to achieve synchronization lock with the bitstream.
  52. *
  53. * 5) Un-checksummed binary packets. Like case 3, but without
  54. * a checksum it's much easier to get a false match from garbage.
  55. * The packet recognizer gives checksummed types higher priority.
  56. *
  57. * Adding support for a new GPS protocol typically reqires adding state
  58. * transitions to support whatever binary packet structure it has. The
  59. * goal is for the lexer to be able to cope with arbitrarily mixed packet
  60. * types on the input stream. This is a requirement because (1) sometimes
  61. * gpsd wants to switch a device that supports both NMEA and a binary
  62. * packet protocol to the latter for more detailed reporting, and (b) in
  63. * the presence of device hotplugging, the type of GPS report coming
  64. * in is subject to change at any time.
  65. *
  66. * Caller should consume a packet when it sees one of the *_RECOGNIZED
  67. * states. It's good practice to follow the _RECOGNIZED transition
  68. * with one that recognizes a leader of the same packet type rather
  69. * than dropping back to ground state -- this for example will prevent
  70. * the state machine from hopping between recognizing TSIP and
  71. * EverMore packets that both start with a DLE.
  72. *
  73. * Error handling is brutally simple; any time we see an unexpected
  74. * character, go to GROUND_STATE and reset the machine (except that a
  75. * $ in an NMEA payload only resets back to NMEA_DOLLAR state). Because
  76. * another good packet will usually be along in less than a second
  77. * repeating the same data, Boyer-Moore-like attempts to do parallel
  78. * recognition beyond the headers would make no sense in this
  79. * application, they'd just add complexity.
  80. *
  81. * The NMEA portion of the state machine allows the following talker IDs:
  82. * $BD -- Beidou
  83. * $EC -- Electronic Chart Display & Information System (ECDIS)
  84. * $GA -- Galileo
  85. * $GB -- Beidou
  86. * $GL -- GLONASS, according to IEIC 61162-1
  87. * $GN -- Mixed GPS and GLONASS data, according to IEIC 61162-1
  88. * $GP -- Global Positioning System.
  89. * $HC -- Heading/compass (Airmar PB200).
  90. * $II -- Integrated Instrumentation (Raytheon's SeaTalk system).
  91. * $IN -- Integrated Navigation (Garmin uses this).
  92. * $P -- Vendor-specific sentence
  93. * $QZ -- QZSS GPS augmentation system
  94. * $SD -- Depth Sounder
  95. * $ST -- $STI, Skytraq Debug Output
  96. * $TI -- Turn indicator (Airmar PB200).
  97. * $WI -- Weather instrument (Airmar PB200, Radio Ocean ROWIND, Vaisala WXT520).
  98. * $YX -- Transducer (used by some Airmar equipment including PB100)
  99. *
  100. * !AB -- NMEA 4.0 Base AIS station
  101. * !AD -- MMEA 4.0 Dependent AIS Base Station
  102. * !AI -- Mobile AIS station
  103. * !AN -- NMEA 4.0 Aid to Navigation AIS station
  104. * !AR -- NMEA 4.0 AIS Receiving Station
  105. * !AX -- NMEA 4.0 Repeater AIS station
  106. * !AS -- NMEA 4.0 Limited Base Station
  107. * !AT -- NMEA 4.0 AIS Transmitting Station
  108. * !BS -- Base AIS station (deprecated in NMEA 4.0)
  109. * !SA -- NMEA 4.0 Physical Shore AIS Station
  110. */
  111. enum
  112. {
  113. #include "packet_states.h"
  114. };
  115. static char *state_table[] = {
  116. #include "packet_names.h"
  117. };
  118. #define SOH (unsigned char)0x01
  119. #define DLE (unsigned char)0x10
  120. #define STX (unsigned char)0x02
  121. #define ETX (unsigned char)0x03
  122. #if defined(TSIP_ENABLE)
  123. /* Maximum length a TSIP packet can be */
  124. #define TSIP_MAX_PACKET 255
  125. #endif
  126. #ifdef ONCORE_ENABLE
  127. static size_t oncore_payload_cksum_length(unsigned char id1, unsigned char id2)
  128. {
  129. size_t l;
  130. /* For the packet sniffer to not terminate the message due to
  131. * payload data looking like a trailer, the known payload lengths
  132. * including the checksum are given. Return -1 for unknown IDs.
  133. */
  134. #define ONCTYPE(id2,id3) ((((unsigned int)id2)<<8)|(id3))
  135. /* *INDENT-OFF* */
  136. switch (ONCTYPE(id1,id2)) {
  137. case ONCTYPE('A','b'): l = 10; break; /* GMT offset */
  138. case ONCTYPE('A','w'): l = 8; break; /* time mode */
  139. case ONCTYPE('A','c'): l = 11; break; /* date */
  140. case ONCTYPE('A','a'): l = 10; break; /* time of day */
  141. case ONCTYPE('A','d'): l = 11; break; /* latitude */
  142. case ONCTYPE('A','e'): l = 11; break; /* longitude */
  143. case ONCTYPE('A','f'): l = 15; break; /* height */
  144. case ONCTYPE('E','a'): l = 76; break; /* position/status/data */
  145. case ONCTYPE('A','g'): l = 8; break; /* satellite mask angle */
  146. case ONCTYPE('B','b'): l = 92; break; /* visible satellites status */
  147. case ONCTYPE('B','j'): l = 8; break; /* leap seconds pending */
  148. case ONCTYPE('A','q'): l = 8; break; /* atmospheric correction mode */
  149. case ONCTYPE('A','p'): l = 25; break; /* set user datum / select datum */
  150. /* Command "Ao" gives "Ap" response (select datum) */
  151. case ONCTYPE('C','h'): l = 9; break; /* almanac input ("Cb" response) */
  152. case ONCTYPE('C','b'): l = 33; break; /* almanac output ("Be" response) */
  153. case ONCTYPE('S','z'): l = 8; break; /* system power-on failure */
  154. case ONCTYPE('C','j'): l = 294; break; /* receiver ID */
  155. case ONCTYPE('F','a'): l = 9; break; /* self-test */
  156. case ONCTYPE('C','f'): l = 7; break; /* set-to-defaults */
  157. case ONCTYPE('E','q'): l = 96; break; /* ASCII position */
  158. case ONCTYPE('A','u'): l = 12; break; /* altitide hold height */
  159. case ONCTYPE('A','v'): l = 8; break; /* altitude hold mode */
  160. case ONCTYPE('A','N'): l = 8; break; /* velocity filter */
  161. case ONCTYPE('A','O'): l = 8; break; /* RTCM report mode */
  162. case ONCTYPE('C','c'): l = 80; break; /* ephemeris data input ("Bf") */
  163. case ONCTYPE('C','k'): l = 7; break; /* pseudorng correction inp. ("Ce")*/
  164. /* Command "Ci" (switch to NMEA, GT versions only) has no response */
  165. case ONCTYPE('B','o'): l = 8; break; /* UTC offset status */
  166. case ONCTYPE('A','z'): l = 11; break; /* 1PPS cable delay */
  167. case ONCTYPE('A','y'): l = 11; break; /* 1PPS offset */
  168. case ONCTYPE('A','P'): l = 8; break; /* pulse mode */
  169. case ONCTYPE('A','s'): l = 20; break; /* position-hold position */
  170. case ONCTYPE('A','t'): l = 8; break; /* position-hold mode */
  171. case ONCTYPE('E','n'): l = 69; break; /* time RAIM setup and status */
  172. default:
  173. return 0;
  174. }
  175. /* *INDENT-ON* */
  176. return l - 6; /* Subtract header and trailer. */
  177. }
  178. #endif /* ONCORE_ENABLE */
  179. #ifdef GREIS_ENABLE
  180. static unsigned long greis_hex2bin(char c)
  181. /* Convert hex char to binary form. Requires that c be a hex char. */
  182. {
  183. if ((c >= 'a') && (c <= 'f'))
  184. c = c + 10 - 'a';
  185. else if ((c >= 'A') && (c <= 'F'))
  186. c = c + 10 - 'A';
  187. else if ((c >= '0') && (c <= '9'))
  188. c -= '0';
  189. return c;
  190. }
  191. #endif /* GREIS_ENABLE */
  192. static bool character_pushback(struct gps_lexer_t *lexer, unsigned int newstate)
  193. /* push back the last character grabbed, setting a specified state */
  194. {
  195. --lexer->inbufptr;
  196. --lexer->char_counter;
  197. lexer->state = newstate;
  198. if (lexer->errout.debug >= LOG_RAW + 2)
  199. {
  200. unsigned char c = *lexer->inbufptr;
  201. GPSD_LOG(LOG_RAW + 2, &lexer->errout,
  202. "%08ld: character '%c' [%02x] pushed back, state set to %s\n",
  203. lexer->char_counter,
  204. (isprint((int)c) ? c : '.'), c,
  205. state_table[lexer->state]);
  206. }
  207. return false;
  208. }
  209. static void character_discard(struct gps_lexer_t *lexer)
  210. /* shift the input buffer to discard one character and reread data */
  211. {
  212. memmove(lexer->inbuffer, lexer->inbuffer + 1, (size_t)-- lexer->inbuflen);
  213. lexer->inbufptr = lexer->inbuffer;
  214. if (lexer->errout.debug >= LOG_RAW + 1) {
  215. char scratchbuf[MAX_PACKET_LENGTH*4+1];
  216. GPSD_LOG(LOG_RAW + 1, &lexer->errout,
  217. "Character discarded, buffer %zu chars = %s\n",
  218. lexer->inbuflen,
  219. gpsd_packetdump(scratchbuf, sizeof(scratchbuf),
  220. (char *)lexer->inbuffer, lexer->inbuflen));
  221. }
  222. }
  223. static bool nextstate(struct gps_lexer_t *lexer, unsigned char c)
  224. {
  225. static int n = 0;
  226. #ifdef RTCM104V2_ENABLE
  227. enum isgpsstat_t isgpsstat;
  228. #endif /* RTCM104V2_ENABLE */
  229. #ifdef SUPERSTAR2_ENABLE
  230. static unsigned char ctmp;
  231. #endif /* SUPERSTAR2_ENABLE */
  232. n++;
  233. switch (lexer->state) {
  234. case GROUND_STATE:
  235. n = 0;
  236. #ifdef STASH_ENABLE
  237. lexer->stashbuflen = 0;
  238. #endif
  239. if (c == '#') {
  240. lexer->state = COMMENT_BODY;
  241. break;
  242. }
  243. #ifdef NMEA0183_ENABLE
  244. if (c == '$') {
  245. lexer->state = NMEA_DOLLAR;
  246. break;
  247. }
  248. if (c == '!') {
  249. lexer->state = NMEA_BANG;
  250. break;
  251. }
  252. #endif /* NMEA0183_ENABLE */
  253. #if defined(TNT_ENABLE) || defined(GARMINTXT_ENABLE) || defined(ONCORE_ENABLE)
  254. if (c == '@') {
  255. #ifdef RTCM104V2_ENABLE
  256. if (rtcm2_decode(lexer, c) == ISGPS_MESSAGE) {
  257. lexer->state = RTCM2_RECOGNIZED;
  258. break;
  259. }
  260. #endif /* RTCM104V2_ENABLE */
  261. lexer->state = AT1_LEADER;
  262. break;
  263. }
  264. #endif
  265. #if defined(SIRF_ENABLE) || defined(SKYTRAQ_ENABLE)
  266. if (c == 0xa0) {
  267. lexer->state = SIRF_LEADER_1;
  268. break;
  269. }
  270. #endif /* SIRF_ENABLE || SKYTRAQ_ENABLE */
  271. #ifdef SUPERSTAR2_ENABLE
  272. if (c == SOH) {
  273. lexer->state = SUPERSTAR2_LEADER;
  274. break;
  275. }
  276. #endif /* SUPERSTAR2_ENABLE */
  277. #if defined(TSIP_ENABLE) || defined(EVERMORE_ENABLE) || defined(GARMIN_ENABLE)
  278. if (c == DLE) {
  279. lexer->state = DLE_LEADER;
  280. break;
  281. }
  282. #endif /* TSIP_ENABLE || EVERMORE_ENABLE || GARMIN_ENABLE */
  283. #ifdef TRIPMATE_ENABLE
  284. if (c == 'A') {
  285. #ifdef RTCM104V2_ENABLE
  286. if (rtcm2_decode(lexer, c) == ISGPS_MESSAGE) {
  287. lexer->state = RTCM2_RECOGNIZED;
  288. break;
  289. }
  290. #endif /* RTCM104V2_ENABLE */
  291. lexer->state = ASTRAL_1;
  292. break;
  293. }
  294. #endif /* TRIPMATE_ENABLE */
  295. #ifdef EARTHMATE_ENABLE
  296. if (c == 'E') {
  297. #ifdef RTCM104V2_ENABLE
  298. if (rtcm2_decode(lexer, c) == ISGPS_MESSAGE) {
  299. lexer->state = RTCM2_RECOGNIZED;
  300. break;
  301. }
  302. #endif /* RTCM104V2_ENABLE */
  303. lexer->state = EARTHA_1;
  304. break;
  305. }
  306. #endif /* EARTHMATE_ENABLE */
  307. #ifdef ZODIAC_ENABLE
  308. if (c == 0xff) {
  309. lexer->state = ZODIAC_LEADER_1;
  310. break;
  311. }
  312. #endif /* ZODIAC_ENABLE */
  313. #ifdef UBLOX_ENABLE
  314. if (c == 0xb5) {
  315. lexer->state = UBX_LEADER_1;
  316. break;
  317. }
  318. #endif /* UBLOX_ENABLE */
  319. #ifdef ITRAX_ENABLE
  320. if (c == '<') {
  321. lexer->state = ITALK_LEADER_1;
  322. break;
  323. }
  324. #endif /* ITRAX_ENABLE */
  325. #ifdef NAVCOM_ENABLE
  326. if (c == 0x02) {
  327. lexer->state = NAVCOM_LEADER_1;
  328. break;
  329. }
  330. #endif /* NAVCOM_ENABLE */
  331. #ifdef GEOSTAR_ENABLE
  332. if (c == 'P') {
  333. lexer->state = GEOSTAR_LEADER_1;
  334. break;
  335. }
  336. #endif /* GEOSTAR_ENABLE */
  337. #ifdef GREIS_ENABLE
  338. if (c == 'R') {
  339. lexer->state = GREIS_REPLY_1;
  340. break;
  341. }
  342. /* Not the only possibility, but it is a distinctive cycle starter. */
  343. if (c == '~') {
  344. lexer->state = GREIS_ID_1;
  345. break;
  346. }
  347. #endif /* GREIS_ENABLE */
  348. #ifdef RTCM104V2_ENABLE
  349. if ((isgpsstat = rtcm2_decode(lexer, c)) == ISGPS_SYNC) {
  350. lexer->state = RTCM2_SYNC_STATE;
  351. break;
  352. } else if (isgpsstat == ISGPS_MESSAGE) {
  353. lexer->state = RTCM2_RECOGNIZED;
  354. break;
  355. }
  356. #endif /* RTCM104V2_ENABLE */
  357. #ifdef RTCM104V3_ENABLE
  358. if (c == 0xD3) {
  359. lexer->state = RTCM3_LEADER_1;
  360. break;
  361. }
  362. #endif /* RTCM104V3_ENABLE */
  363. #ifdef PASSTHROUGH_ENABLE
  364. if (c == '{')
  365. return character_pushback(lexer, JSON_LEADER);
  366. #endif /* PASSTHROUGH_ENABLE */
  367. break;
  368. case COMMENT_BODY:
  369. if (c == '\n')
  370. lexer->state = COMMENT_RECOGNIZED;
  371. else if (!isprint(c))
  372. return character_pushback(lexer, GROUND_STATE);
  373. break;
  374. #ifdef NMEA0183_ENABLE
  375. case NMEA_DOLLAR:
  376. if (c == 'G')
  377. lexer->state = NMEA_PUB_LEAD;
  378. else if (c == 'P') /* vendor sentence */
  379. lexer->state = NMEA_VENDOR_LEAD;
  380. else if (c == 'I') /* Seatalk */
  381. lexer->state = SEATALK_LEAD_1;
  382. else if (c == 'W') /* Weather instrument */
  383. lexer->state = WEATHER_LEAD_1;
  384. else if (c == 'H') /* Heading/compass */
  385. lexer->state = HEADCOMP_LEAD_1;
  386. else if (c == 'T') /* Turn indicator */
  387. lexer->state = TURN_LEAD_1;
  388. else if (c == 'A') /* SiRF Ack */
  389. lexer->state = SIRF_ACK_LEAD_1;
  390. else if (c == 'E') /* ECDIS */
  391. lexer->state = ECDIS_LEAD_1;
  392. else if (c == 'S')
  393. lexer->state = SOUNDER_LEAD_1;
  394. else if (c == 'Y')
  395. lexer->state = TRANSDUCER_LEAD_1;
  396. else if (c == 'B')
  397. lexer->state = BEIDOU_LEAD_1;
  398. else if (c == 'Q') {
  399. lexer->state = QZSS_LEAD_1;
  400. #ifdef OCEANSERVER_ENABLE
  401. } else if (c == 'C') {
  402. // is this ever used?
  403. lexer->state = NMEA_LEADER_END;
  404. } else if (c == 'O') {
  405. // for $OHPR
  406. lexer->state = NMEA_LEADER_END;
  407. #endif /* OCEANSERVER_ENABLE */
  408. } else {
  409. (void) character_pushback(lexer, GROUND_STATE);
  410. }
  411. break;
  412. case NMEA_PUB_LEAD:
  413. /*
  414. * $GP == GPS, $GL = GLONASS only, $GN = mixed GPS and GLONASS,
  415. * according to NMEA (IEIC 61162-1) DRAFT 02/06/2009.
  416. * We have a log from China with a Beidou device using $GB
  417. * rather than $BD.
  418. */
  419. if (c == 'B' || c == 'P' || c == 'N' || c == 'L' || c == 'A')
  420. lexer->state = NMEA_LEADER_END;
  421. else
  422. (void) character_pushback(lexer, GROUND_STATE);
  423. break;
  424. case NMEA_VENDOR_LEAD:
  425. if (c == 'A')
  426. lexer->state = NMEA_PASHR_A;
  427. else if (isalpha(c))
  428. lexer->state = NMEA_LEADER_END;
  429. else
  430. (void) character_pushback(lexer, GROUND_STATE);
  431. break;
  432. /*
  433. * Without the following six states, DLE in a $PASHR can fool the
  434. * sniffer into thinking it sees a TSIP packet. Hilarity ensues.
  435. */
  436. case NMEA_PASHR_A:
  437. if (c == 'S')
  438. lexer->state = NMEA_PASHR_S;
  439. else if (isalpha(c))
  440. lexer->state = NMEA_LEADER_END;
  441. else
  442. (void) character_pushback(lexer, GROUND_STATE);
  443. break;
  444. case NMEA_PASHR_S:
  445. if (c == 'H')
  446. lexer->state = NMEA_PASHR_H;
  447. else if (isalpha(c))
  448. lexer->state = NMEA_LEADER_END;
  449. else
  450. (void) character_pushback(lexer, GROUND_STATE);
  451. break;
  452. case NMEA_PASHR_H:
  453. if (c == 'R')
  454. lexer->state = NMEA_BINARY_BODY;
  455. else if (isalpha(c))
  456. lexer->state = NMEA_LEADER_END;
  457. else
  458. (void) character_pushback(lexer, GROUND_STATE);
  459. break;
  460. case NMEA_BINARY_BODY:
  461. if (c == '\r')
  462. lexer->state = NMEA_BINARY_CR;
  463. break;
  464. case NMEA_BINARY_CR:
  465. if (c == '\n')
  466. lexer->state = NMEA_BINARY_NL;
  467. else
  468. lexer->state = NMEA_BINARY_BODY;
  469. break;
  470. case NMEA_BINARY_NL:
  471. if (c == '$')
  472. (void) character_pushback(lexer, NMEA_RECOGNIZED);
  473. else
  474. lexer->state = NMEA_BINARY_BODY;
  475. break;
  476. case NMEA_BANG:
  477. if (c == 'A')
  478. lexer->state = AIS_LEAD_1;
  479. else if (c == 'B')
  480. lexer->state = AIS_LEAD_ALT1;
  481. else if (c == 'S')
  482. lexer->state = AIS_LEAD_ALT3;
  483. else
  484. return character_pushback(lexer, GROUND_STATE);
  485. break;
  486. case AIS_LEAD_1:
  487. if (strchr("BDINRSTX", c) != NULL)
  488. lexer->state = AIS_LEAD_2;
  489. else
  490. return character_pushback(lexer, GROUND_STATE);
  491. break;
  492. case AIS_LEAD_2:
  493. if (isalpha(c))
  494. lexer->state = NMEA_LEADER_END;
  495. else
  496. return character_pushback(lexer, GROUND_STATE);
  497. break;
  498. case AIS_LEAD_ALT1:
  499. if (c == 'S')
  500. lexer->state = AIS_LEAD_ALT2;
  501. else
  502. return character_pushback(lexer, GROUND_STATE);
  503. break;
  504. case AIS_LEAD_ALT2:
  505. if (isalpha(c))
  506. lexer->state = NMEA_LEADER_END;
  507. else
  508. return character_pushback(lexer, GROUND_STATE);
  509. break;
  510. case AIS_LEAD_ALT3:
  511. if (c == 'A')
  512. lexer->state = AIS_LEAD_ALT4;
  513. else
  514. return character_pushback(lexer, GROUND_STATE);
  515. break;
  516. case AIS_LEAD_ALT4:
  517. if (isalpha(c))
  518. lexer->state = NMEA_LEADER_END;
  519. else
  520. return character_pushback(lexer, GROUND_STATE);
  521. break;
  522. #if defined(TNT_ENABLE) || defined(GARMINTXT_ENABLE) || defined(ONCORE_ENABLE)
  523. case AT1_LEADER:
  524. switch (c) {
  525. #ifdef ONCORE_ENABLE
  526. case '@':
  527. lexer->state = ONCORE_AT2;
  528. break;
  529. #endif /* ONCORE_ENABLE */
  530. #ifdef TNT_ENABLE
  531. case '*':
  532. /*
  533. * TNT has similar structure to NMEA packet, '*' before
  534. * optional checksum ends the packet. Since '*' cannot be
  535. * received from GARMIN working in TEXT mode, use this
  536. * difference to tell that this is not GARMIN TEXT packet,
  537. * could be TNT.
  538. */
  539. lexer->state = NMEA_LEADER_END;
  540. break;
  541. #endif /* TNT_ENABLE */
  542. #if defined(GARMINTXT_ENABLE)
  543. case '\r':
  544. /* stay in this state, next character should be '\n' */
  545. /* in the theory we can stop search here and don't wait for '\n' */
  546. lexer->state = AT1_LEADER;
  547. break;
  548. case '\n':
  549. /* end of packet found */
  550. lexer->state = GTXT_RECOGNIZED;
  551. break;
  552. #endif /* GARMINTXT_ENABLE */
  553. default:
  554. if (!isprint(c))
  555. return character_pushback(lexer, GROUND_STATE);
  556. }
  557. break;
  558. #endif /* defined(TNT_ENABLE) || defined(GARMINTXT_ENABLE) || defined(ONCORE_ENABLE) */
  559. case NMEA_LEADER_END:
  560. if (c == '\r')
  561. lexer->state = NMEA_CR;
  562. else if (c == '\n')
  563. /* not strictly correct, but helps for interpreting logfiles */
  564. lexer->state = NMEA_RECOGNIZED;
  565. else if (c == '$') {
  566. #ifdef STASH_ENABLE
  567. (void) character_pushback(lexer, STASH_RECOGNIZED);
  568. #else
  569. (void) character_pushback(lexer, GROUND_STATE);
  570. #endif
  571. } else if (!isprint(c))
  572. (void) character_pushback(lexer, GROUND_STATE);
  573. break;
  574. case NMEA_CR:
  575. if (c == '\n')
  576. lexer->state = NMEA_RECOGNIZED;
  577. /*
  578. * There's a GPS called a Jackson Labs Firefly-1a that emits \r\r\n
  579. * at the end of each sentence. Don't be confused by this.
  580. */
  581. else if (c == '\r')
  582. lexer->state = NMEA_CR;
  583. else
  584. (void) character_pushback(lexer, GROUND_STATE);
  585. break;
  586. case NMEA_RECOGNIZED:
  587. if (c == '#')
  588. lexer->state = COMMENT_BODY;
  589. else if (c == '$')
  590. lexer->state = NMEA_DOLLAR;
  591. else if (c == '!')
  592. lexer->state = NMEA_BANG;
  593. #ifdef UBLOX_ENABLE
  594. else if (c == 0xb5) /* LEA-5H can and will output NMEA and UBX back to back */
  595. lexer->state = UBX_LEADER_1;
  596. #endif
  597. #ifdef PASSTHROUGH_ENABLE
  598. else if (c == '{')
  599. return character_pushback(lexer, JSON_LEADER);
  600. #endif /* PASSTHROUGH_ENABLE */
  601. else
  602. return character_pushback(lexer, GROUND_STATE);
  603. break;
  604. case SEATALK_LEAD_1:
  605. if (c == 'I' || c == 'N') /* II or IN are accepted */
  606. lexer->state = NMEA_LEADER_END;
  607. else
  608. return character_pushback(lexer, GROUND_STATE);
  609. break;
  610. case WEATHER_LEAD_1:
  611. if (c == 'I') /* Weather instrument leader accepted */
  612. lexer->state = NMEA_LEADER_END;
  613. else
  614. return character_pushback(lexer, GROUND_STATE);
  615. break;
  616. case HEADCOMP_LEAD_1:
  617. if (c == 'C') /* Heading/compass leader accepted */
  618. lexer->state = NMEA_LEADER_END;
  619. else
  620. return character_pushback(lexer, GROUND_STATE);
  621. break;
  622. case TURN_LEAD_1:
  623. if (c == 'I') /* Turn indicator leader accepted */
  624. lexer->state = NMEA_LEADER_END;
  625. else
  626. return character_pushback(lexer, GROUND_STATE);
  627. break;
  628. case ECDIS_LEAD_1:
  629. if (c == 'C') /* ECDIS leader accepted */
  630. lexer->state = NMEA_LEADER_END;
  631. else
  632. return character_pushback(lexer, GROUND_STATE);
  633. break;
  634. case SOUNDER_LEAD_1:
  635. if (c == 'D') /* Depth-sounder leader accepted */
  636. lexer->state = NMEA_LEADER_END;
  637. #ifdef SKYTRAQ_ENABLE
  638. else if (c == 'T') /* $ST leader accepted, to $STI */
  639. lexer->state = NMEA_LEADER_END;
  640. #endif /* SKYTRAQ_ENABLE */
  641. else
  642. return character_pushback(lexer, GROUND_STATE);
  643. break;
  644. case TRANSDUCER_LEAD_1:
  645. if (c == 'X') /* Transducer leader accepted */
  646. lexer->state = NMEA_LEADER_END;
  647. else
  648. return character_pushback(lexer, GROUND_STATE);
  649. break;
  650. case BEIDOU_LEAD_1:
  651. if (c == 'D') /* Beidou leader accepted */
  652. lexer->state = NMEA_LEADER_END;
  653. else
  654. return character_pushback(lexer, GROUND_STATE);
  655. break;
  656. case QZSS_LEAD_1:
  657. if (c == 'Z') /* QZSS leader accepted */
  658. lexer->state = NMEA_LEADER_END;
  659. else
  660. return character_pushback(lexer, GROUND_STATE);
  661. break;
  662. #ifdef TRIPMATE_ENABLE
  663. case ASTRAL_1:
  664. if (c == 'S') {
  665. #ifdef RTCM104V2_ENABLE
  666. if ((isgpsstat = rtcm2_decode(lexer, c)) == ISGPS_SYNC) {
  667. lexer->state = RTCM2_SYNC_STATE;
  668. break;
  669. } else if (isgpsstat == ISGPS_MESSAGE) {
  670. lexer->state = RTCM2_RECOGNIZED;
  671. break;
  672. }
  673. #endif /* RTCM104V2_ENABLE */
  674. lexer->state = ASTRAL_2;
  675. } else
  676. (void) character_pushback(lexer, GROUND_STATE);
  677. break;
  678. case ASTRAL_2:
  679. if (c == 'T') {
  680. #ifdef RTCM104V2_ENABLE
  681. if ((isgpsstat = rtcm2_decode(lexer, c)) == ISGPS_SYNC) {
  682. lexer->state = RTCM2_SYNC_STATE;
  683. break;
  684. } else if (isgpsstat == ISGPS_MESSAGE) {
  685. lexer->state = RTCM2_RECOGNIZED;
  686. break;
  687. }
  688. #endif /* RTCM104V2_ENABLE */
  689. lexer->state = ASTRAL_3;
  690. } else
  691. (void) character_pushback(lexer, GROUND_STATE);
  692. break;
  693. case ASTRAL_3:
  694. if (c == 'R') {
  695. #ifdef RTCM104V2_ENABLE
  696. if ((isgpsstat = rtcm2_decode(lexer, c)) == ISGPS_SYNC) {
  697. lexer->state = RTCM2_SYNC_STATE;
  698. break;
  699. } else if (isgpsstat == ISGPS_MESSAGE) {
  700. lexer->state = RTCM2_RECOGNIZED;
  701. break;
  702. }
  703. #endif /* RTCM104V2_ENABLE */
  704. lexer->state = ASTRAL_5;
  705. } else
  706. (void) character_pushback(lexer, GROUND_STATE);
  707. break;
  708. case ASTRAL_4:
  709. if (c == 'A') {
  710. #ifdef RTCM104V2_ENABLE
  711. if ((isgpsstat = rtcm2_decode(lexer, c)) == ISGPS_SYNC) {
  712. lexer->state = RTCM2_SYNC_STATE;
  713. break;
  714. } else if (isgpsstat == ISGPS_MESSAGE) {
  715. lexer->state = RTCM2_RECOGNIZED;
  716. break;
  717. }
  718. #endif /* RTCM104V2_ENABLE */
  719. lexer->state = ASTRAL_2;
  720. } else
  721. (void) character_pushback(lexer, GROUND_STATE);
  722. break;
  723. case ASTRAL_5:
  724. if (c == 'L') {
  725. #ifdef RTCM104V2_ENABLE
  726. if ((isgpsstat = rtcm2_decode(lexer, c)) == ISGPS_SYNC) {
  727. lexer->state = RTCM2_SYNC_STATE;
  728. break;
  729. } else if (isgpsstat == ISGPS_MESSAGE) {
  730. lexer->state = RTCM2_RECOGNIZED;
  731. break;
  732. }
  733. #endif /* RTCM104V2_ENABLE */
  734. lexer->state = NMEA_RECOGNIZED;
  735. } else
  736. (void) character_pushback(lexer, GROUND_STATE);
  737. break;
  738. #endif /* TRIPMATE_ENABLE */
  739. #ifdef EARTHMATE_ENABLE
  740. case EARTHA_1:
  741. if (c == 'A') {
  742. #ifdef RTCM104V2_ENABLE
  743. if ((isgpsstat = rtcm2_decode(lexer, c)) == ISGPS_SYNC) {
  744. lexer->state = RTCM2_SYNC_STATE;
  745. break;
  746. } else if (isgpsstat == ISGPS_MESSAGE) {
  747. lexer->state = RTCM2_RECOGNIZED;
  748. break;
  749. }
  750. #endif /* RTCM104V2_ENABLE */
  751. lexer->state = EARTHA_2;
  752. } else
  753. (void) character_pushback(lexer, GROUND_STATE);
  754. break;
  755. case EARTHA_2:
  756. if (c == 'R') {
  757. #ifdef RTCM104V2_ENABLE
  758. if ((isgpsstat = rtcm2_decode(lexer, c)) == ISGPS_SYNC) {
  759. lexer->state = RTCM2_SYNC_STATE;
  760. break;
  761. } else if (isgpsstat == ISGPS_MESSAGE) {
  762. lexer->state = RTCM2_RECOGNIZED;
  763. break;
  764. }
  765. #endif /* RTCM104V2_ENABLE */
  766. lexer->state = EARTHA_3;
  767. } else
  768. (void) character_pushback(lexer, GROUND_STATE);
  769. break;
  770. case EARTHA_3:
  771. if (c == 'T') {
  772. #ifdef RTCM104V2_ENABLE
  773. if ((isgpsstat = rtcm2_decode(lexer, c)) == ISGPS_SYNC) {
  774. lexer->state = RTCM2_SYNC_STATE;
  775. break;
  776. } else if (isgpsstat == ISGPS_MESSAGE) {
  777. lexer->state = RTCM2_RECOGNIZED;
  778. break;
  779. }
  780. #endif /* RTCM104V2_ENABLE */
  781. lexer->state = EARTHA_4;
  782. } else
  783. (void) character_pushback(lexer, GROUND_STATE);
  784. break;
  785. case EARTHA_4:
  786. if (c == 'H') {
  787. #ifdef RTCM104V2_ENABLE
  788. if ((isgpsstat = rtcm2_decode(lexer, c)) == ISGPS_SYNC) {
  789. lexer->state = RTCM2_SYNC_STATE;
  790. break;
  791. } else if (isgpsstat == ISGPS_MESSAGE) {
  792. lexer->state = RTCM2_RECOGNIZED;
  793. break;
  794. }
  795. #endif /* RTCM104V2_ENABLE */
  796. lexer->state = EARTHA_5;
  797. } else
  798. (void) character_pushback(lexer, GROUND_STATE);
  799. break;
  800. case EARTHA_5:
  801. if (c == 'A') {
  802. #ifdef RTCM104V2_ENABLE
  803. if ((isgpsstat = rtcm2_decode(lexer, c)) == ISGPS_SYNC) {
  804. lexer->state = RTCM2_SYNC_STATE;
  805. break;
  806. } else if (isgpsstat == ISGPS_MESSAGE) {
  807. lexer->state = RTCM2_RECOGNIZED;
  808. break;
  809. }
  810. #endif /* RTCM104V2_ENABLE */
  811. lexer->state = NMEA_RECOGNIZED;
  812. } else
  813. (void) character_pushback(lexer, GROUND_STATE);
  814. break;
  815. #endif /* EARTHMATE_ENABLE */
  816. case SIRF_ACK_LEAD_1:
  817. if (c == 'c')
  818. lexer->state = SIRF_ACK_LEAD_2;
  819. else if (c == 'I')
  820. lexer->state = AIS_LEAD_2;
  821. else
  822. return character_pushback(lexer, GROUND_STATE);
  823. break;
  824. case SIRF_ACK_LEAD_2:
  825. if (c == 'k')
  826. lexer->state = NMEA_LEADER_END;
  827. else
  828. return character_pushback(lexer, GROUND_STATE);
  829. break;
  830. #endif /* NMEA0183_ENABLE */
  831. #if defined(SIRF_ENABLE) || defined(SKYTRAQ_ENABLE)
  832. case SIRF_LEADER_1:
  833. # ifdef SIRF_ENABLE
  834. /* SIRF leads with 0xA0,0xA2 */
  835. if (c == 0xa2)
  836. lexer->state = SIRF_LEADER_2;
  837. else
  838. # endif /* SIRF_ENABLE */
  839. # ifdef SKYTRAQ_ENABLE
  840. /* Skytraq leads with 0xA0,0xA1 */
  841. if (c == 0xa1)
  842. lexer->state = SKY_LEADER_2;
  843. else
  844. # endif /* SKYTRAQ_ENABLE */
  845. return character_pushback(lexer, GROUND_STATE);
  846. break;
  847. #endif /* SIRF_ENABLE || SKYTRAQ_ENABLE */
  848. #ifdef SIRF_ENABLE
  849. case SIRF_LEADER_2:
  850. lexer->length = (size_t) (c << 8);
  851. lexer->state = SIRF_LENGTH_1;
  852. break;
  853. case SIRF_LENGTH_1:
  854. lexer->length += c + 2;
  855. if (lexer->length <= MAX_PACKET_LENGTH)
  856. lexer->state = SIRF_PAYLOAD;
  857. else
  858. return character_pushback(lexer, GROUND_STATE);
  859. break;
  860. case SIRF_PAYLOAD:
  861. if (--lexer->length == 0)
  862. lexer->state = SIRF_DELIVERED;
  863. break;
  864. case SIRF_DELIVERED:
  865. if (c == 0xb0)
  866. lexer->state = SIRF_TRAILER_1;
  867. else
  868. return character_pushback(lexer, GROUND_STATE);
  869. break;
  870. case SIRF_TRAILER_1:
  871. if (c == 0xb3)
  872. lexer->state = SIRF_RECOGNIZED;
  873. else
  874. return character_pushback(lexer, GROUND_STATE);
  875. break;
  876. case SIRF_RECOGNIZED:
  877. if (c == 0xa0)
  878. lexer->state = SIRF_LEADER_1;
  879. else
  880. return character_pushback(lexer, GROUND_STATE);
  881. break;
  882. #endif /* SIRF_ENABLE */
  883. #ifdef SKYTRAQ_ENABLE
  884. case SKY_LEADER_2:
  885. /* MSB of length is first */
  886. lexer->length = (size_t) (c << 8);
  887. lexer->state = SKY_LENGTH_1;
  888. break;
  889. case SKY_LENGTH_1:
  890. /* Skytraq length can be any 16 bit number, except 0 */
  891. lexer->length += c;
  892. if ( 0 == lexer->length )
  893. return character_pushback(lexer, GROUND_STATE);
  894. if (lexer->length > MAX_PACKET_LENGTH)
  895. return character_pushback(lexer, GROUND_STATE);
  896. lexer->state = SKY_PAYLOAD;
  897. break;
  898. case SKY_PAYLOAD:
  899. if ( 00 == --lexer->length)
  900. lexer->state = SKY_DELIVERED;
  901. break;
  902. case SKY_DELIVERED:
  903. if ( lexer->errout.debug >= LOG_RAW + 1) {
  904. char scratchbuf[MAX_PACKET_LENGTH*4+1];
  905. GPSD_LOG(LOG_RAW + 1, &lexer->errout,
  906. "Skytraq = %s\n",
  907. gpsd_packetdump(scratchbuf, sizeof(scratchbuf),
  908. (char *)lexer->inbuffer,
  909. lexer->inbufptr - (unsigned char *)lexer->inbuffer));
  910. }
  911. {
  912. unsigned char csum = 0;
  913. for (n = 4;
  914. (unsigned char *)(lexer->inbuffer + n) < lexer->inbufptr - 1;
  915. n++)
  916. csum ^= lexer->inbuffer[n];
  917. if (csum != c) {
  918. GPSD_LOG(LOG_IO, &lexer->errout,
  919. "Skytraq bad checksum 0x%hhx, expecting 0x%x\n",
  920. csum, c);
  921. lexer->state = GROUND_STATE;
  922. break;
  923. }
  924. }
  925. lexer->state = SKY_CSUM;
  926. break;
  927. case SKY_CSUM:
  928. if ( 0x0d != c)
  929. return character_pushback(lexer, GROUND_STATE);
  930. lexer->state = SKY_TRAILER_1;
  931. break;
  932. case SKY_TRAILER_1:
  933. if ( 0x0a != c)
  934. return character_pushback(lexer, GROUND_STATE);
  935. lexer->state = SKY_RECOGNIZED;
  936. break;
  937. case SKY_RECOGNIZED:
  938. if ( 0xa0 != c)
  939. return character_pushback(lexer, GROUND_STATE);
  940. lexer->state = SIRF_LEADER_1;
  941. break;
  942. #endif /* SKYTRAQ */
  943. #ifdef SUPERSTAR2_ENABLE
  944. case SUPERSTAR2_LEADER:
  945. ctmp = c;
  946. lexer->state = SUPERSTAR2_ID1;
  947. break;
  948. case SUPERSTAR2_ID1:
  949. if ((ctmp ^ 0xff) == c)
  950. lexer->state = SUPERSTAR2_ID2;
  951. else
  952. return character_pushback(lexer, GROUND_STATE);
  953. break;
  954. case SUPERSTAR2_ID2:
  955. lexer->length = (size_t) c; /* how many data bytes follow this byte */
  956. if (lexer->length)
  957. lexer->state = SUPERSTAR2_PAYLOAD;
  958. else
  959. lexer->state = SUPERSTAR2_CKSUM1; /* no data, jump to checksum */
  960. break;
  961. case SUPERSTAR2_PAYLOAD:
  962. if (--lexer->length == 0)
  963. lexer->state = SUPERSTAR2_CKSUM1;
  964. break;
  965. case SUPERSTAR2_CKSUM1:
  966. lexer->state = SUPERSTAR2_CKSUM2;
  967. break;
  968. case SUPERSTAR2_CKSUM2:
  969. lexer->state = SUPERSTAR2_RECOGNIZED;
  970. break;
  971. case SUPERSTAR2_RECOGNIZED:
  972. if (c == SOH)
  973. lexer->state = SUPERSTAR2_LEADER;
  974. else
  975. return character_pushback(lexer, GROUND_STATE);
  976. break;
  977. #endif /* SUPERSTAR2_ENABLE */
  978. #ifdef ONCORE_ENABLE
  979. case ONCORE_AT2:
  980. if (isupper(c)) {
  981. lexer->length = (size_t) c;
  982. lexer->state = ONCORE_ID1;
  983. } else
  984. return character_pushback(lexer, GROUND_STATE);
  985. break;
  986. case ONCORE_ID1:
  987. if (isalpha(c)) {
  988. lexer->length =
  989. oncore_payload_cksum_length((unsigned char)lexer->length, c);
  990. if (lexer->length != 0) {
  991. lexer->state = ONCORE_PAYLOAD;
  992. break;
  993. }
  994. } else
  995. return character_pushback(lexer, GROUND_STATE);
  996. break;
  997. case ONCORE_PAYLOAD:
  998. if (--lexer->length == 0)
  999. lexer->state = ONCORE_CHECKSUM;
  1000. break;
  1001. case ONCORE_CHECKSUM:
  1002. if (c != '\r')
  1003. return character_pushback(lexer, GROUND_STATE);
  1004. else
  1005. lexer->state = ONCORE_CR;
  1006. break;
  1007. case ONCORE_CR:
  1008. if (c == '\n')
  1009. lexer->state = ONCORE_RECOGNIZED;
  1010. else
  1011. lexer->state = ONCORE_PAYLOAD;
  1012. break;
  1013. case ONCORE_RECOGNIZED:
  1014. if (c == '@')
  1015. lexer->state = AT1_LEADER;
  1016. else
  1017. return character_pushback(lexer, GROUND_STATE);
  1018. break;
  1019. #endif /* ONCORE_ENABLE */
  1020. #if defined(TSIP_ENABLE) || defined(EVERMORE_ENABLE) || defined(GARMIN_ENABLE)
  1021. case DLE_LEADER:
  1022. #ifdef EVERMORE_ENABLE
  1023. if (c == STX) {
  1024. lexer->state = EVERMORE_LEADER_2;
  1025. break;
  1026. }
  1027. #endif /* EVERMORE_ENABLE */
  1028. #if defined(TSIP_ENABLE) || defined(GARMIN_ENABLE) || defined(NAVCOM_ENABLE)
  1029. /* garmin is special case of TSIP */
  1030. /* check last because there's no checksum */
  1031. #if defined(TSIP_ENABLE)
  1032. if (c >= 0x13) {
  1033. lexer->length = TSIP_MAX_PACKET;
  1034. lexer->state = TSIP_PAYLOAD;
  1035. break;
  1036. }
  1037. #endif /* TSIP_ENABLE */
  1038. if (c == DLE) {
  1039. lexer->state = GROUND_STATE;
  1040. break;
  1041. }
  1042. /* give up */
  1043. lexer->state = GROUND_STATE;
  1044. break;
  1045. #endif /* TSIP_ENABLE */
  1046. #ifdef NAVCOM_ENABLE
  1047. case NAVCOM_LEADER_1:
  1048. if (c == 0x99)
  1049. lexer->state = NAVCOM_LEADER_2;
  1050. else
  1051. return character_pushback(lexer, GROUND_STATE);
  1052. break;
  1053. case NAVCOM_LEADER_2:
  1054. if (c == 0x66)
  1055. lexer->state = NAVCOM_LEADER_3;
  1056. else
  1057. return character_pushback(lexer, GROUND_STATE);
  1058. break;
  1059. case NAVCOM_LEADER_3:
  1060. lexer->state = NAVCOM_ID;
  1061. break;
  1062. case NAVCOM_ID:
  1063. lexer->length = (size_t) c - 4;
  1064. lexer->state = NAVCOM_LENGTH_1;
  1065. break;
  1066. case NAVCOM_LENGTH_1:
  1067. lexer->length += (c << 8);
  1068. lexer->state = NAVCOM_LENGTH_2;
  1069. break;
  1070. case NAVCOM_LENGTH_2:
  1071. if (--lexer->length == 0)
  1072. lexer->state = NAVCOM_PAYLOAD;
  1073. break;
  1074. case NAVCOM_PAYLOAD:
  1075. {
  1076. unsigned char csum = lexer->inbuffer[3];
  1077. for (n = 4;
  1078. (unsigned char *)(lexer->inbuffer + n) < lexer->inbufptr - 1;
  1079. n++)
  1080. csum ^= lexer->inbuffer[n];
  1081. if (csum != c) {
  1082. GPSD_LOG(LOG_IO, &lexer->errout,
  1083. "Navcom packet type 0x%hhx bad checksum 0x%hhx, "
  1084. "expecting 0x%x\n",
  1085. lexer->inbuffer[3], csum, c);
  1086. lexer->state = GROUND_STATE;
  1087. break;
  1088. }
  1089. }
  1090. lexer->state = NAVCOM_CSUM;
  1091. break;
  1092. case NAVCOM_CSUM:
  1093. if (c == 0x03)
  1094. lexer->state = NAVCOM_RECOGNIZED;
  1095. else
  1096. return character_pushback(lexer, GROUND_STATE);
  1097. break;
  1098. case NAVCOM_RECOGNIZED:
  1099. if (c == 0x02)
  1100. lexer->state = NAVCOM_LEADER_1;
  1101. else
  1102. return character_pushback(lexer, GROUND_STATE);
  1103. break;
  1104. #endif /* NAVCOM_ENABLE */
  1105. #endif /* TSIP_ENABLE || EVERMORE_ENABLE || GARMIN_ENABLE */
  1106. #ifdef RTCM104V3_ENABLE
  1107. case RTCM3_LEADER_1:
  1108. /* high 6 bits must be zero, low 2 bits are MSB of a 10-bit length */
  1109. if ((c & 0xFC) == 0) {
  1110. lexer->length = (size_t) (c << 8);
  1111. lexer->state = RTCM3_LEADER_2;
  1112. } else
  1113. return character_pushback(lexer, GROUND_STATE);
  1114. break;
  1115. case RTCM3_LEADER_2:
  1116. /* third byte is the low 8 bits of the RTCM3 packet length */
  1117. lexer->length |= c;
  1118. lexer->length += 3; /* to get the three checksum bytes */
  1119. lexer->state = RTCM3_PAYLOAD;
  1120. break;
  1121. case RTCM3_PAYLOAD:
  1122. if (--lexer->length == 0)
  1123. lexer->state = RTCM3_RECOGNIZED;
  1124. break;
  1125. #endif /* RTCM104V3_ENABLE */
  1126. #ifdef ZODIAC_ENABLE
  1127. case ZODIAC_EXPECTED:
  1128. case ZODIAC_RECOGNIZED:
  1129. if (c == 0xff)
  1130. lexer->state = ZODIAC_LEADER_1;
  1131. else
  1132. return character_pushback(lexer, GROUND_STATE);
  1133. break;
  1134. case ZODIAC_LEADER_1:
  1135. if (c == 0x81)
  1136. lexer->state = ZODIAC_LEADER_2;
  1137. else
  1138. (void) character_pushback(lexer, GROUND_STATE);
  1139. break;
  1140. case ZODIAC_LEADER_2:
  1141. lexer->state = ZODIAC_ID_1;
  1142. break;
  1143. case ZODIAC_ID_1:
  1144. lexer->state = ZODIAC_ID_2;
  1145. break;
  1146. case ZODIAC_ID_2:
  1147. lexer->length = (size_t) c;
  1148. lexer->state = ZODIAC_LENGTH_1;
  1149. break;
  1150. case ZODIAC_LENGTH_1:
  1151. lexer->length += (c << 8);
  1152. lexer->state = ZODIAC_LENGTH_2;
  1153. break;
  1154. case ZODIAC_LENGTH_2:
  1155. lexer->state = ZODIAC_FLAGS_1;
  1156. break;
  1157. case ZODIAC_FLAGS_1:
  1158. lexer->state = ZODIAC_FLAGS_2;
  1159. break;
  1160. case ZODIAC_FLAGS_2:
  1161. lexer->state = ZODIAC_HSUM_1;
  1162. break;
  1163. case ZODIAC_HSUM_1:
  1164. {
  1165. #define getword(i) (short)(lexer->inbuffer[2*(i)] | (lexer->inbuffer[2*(i)+1] << 8))
  1166. short sum = getword(0) + getword(1) + getword(2) + getword(3);
  1167. sum *= -1;
  1168. if (sum != getword(4)) {
  1169. GPSD_LOG(LOG_IO, &lexer->errout,
  1170. "Zodiac Header checksum 0x%hx expecting 0x%hx\n",
  1171. sum, getword(4));
  1172. lexer->state = GROUND_STATE;
  1173. break;
  1174. }
  1175. }
  1176. GPSD_LOG(LOG_RAW + 1, &lexer->errout,
  1177. "Zodiac header id=%hd len=%hd flags=%hx\n",
  1178. getword(1), getword(2), getword(3));
  1179. #undef getword
  1180. if (lexer->length == 0) {
  1181. lexer->state = ZODIAC_RECOGNIZED;
  1182. break;
  1183. }
  1184. lexer->length *= 2; /* word count to byte count */
  1185. lexer->length += 2; /* checksum */
  1186. /* 10 bytes is the length of the Zodiac header */
  1187. if (lexer->length <= MAX_PACKET_LENGTH - 10)
  1188. lexer->state = ZODIAC_PAYLOAD;
  1189. else
  1190. return character_pushback(lexer, GROUND_STATE);
  1191. break;
  1192. case ZODIAC_PAYLOAD:
  1193. if (--lexer->length == 0)
  1194. lexer->state = ZODIAC_RECOGNIZED;
  1195. break;
  1196. #endif /* ZODIAC_ENABLE */
  1197. #ifdef UBLOX_ENABLE
  1198. case UBX_LEADER_1:
  1199. if (c == 0x62)
  1200. lexer->state = UBX_LEADER_2;
  1201. else
  1202. return character_pushback(lexer, GROUND_STATE);
  1203. break;
  1204. case UBX_LEADER_2:
  1205. lexer->state = UBX_CLASS_ID;
  1206. break;
  1207. case UBX_CLASS_ID:
  1208. lexer->state = UBX_MESSAGE_ID;
  1209. break;
  1210. case UBX_MESSAGE_ID:
  1211. lexer->length = (size_t) c;
  1212. lexer->state = UBX_LENGTH_1;
  1213. break;
  1214. case UBX_LENGTH_1:
  1215. lexer->length += (c << 8);
  1216. if (lexer->length <= MAX_PACKET_LENGTH)
  1217. lexer->state = UBX_LENGTH_2;
  1218. else
  1219. return character_pushback(lexer, GROUND_STATE);
  1220. break;
  1221. case UBX_LENGTH_2:
  1222. lexer->state = UBX_PAYLOAD;
  1223. break;
  1224. case UBX_PAYLOAD:
  1225. if (--lexer->length == 0)
  1226. lexer->state = UBX_CHECKSUM_A;
  1227. /* else stay in payload state */
  1228. break;
  1229. case UBX_CHECKSUM_A:
  1230. lexer->state = UBX_RECOGNIZED;
  1231. break;
  1232. case UBX_RECOGNIZED:
  1233. if (c == 0xb5)
  1234. lexer->state = UBX_LEADER_1;
  1235. #ifdef NMEA0183_ENABLE
  1236. else if (c == '$') /* LEA-5H can and will output NMEA and UBX back to back */
  1237. lexer->state = NMEA_DOLLAR;
  1238. #endif /* NMEA0183_ENABLE */
  1239. #ifdef PASSTHROUGH_ENABLE
  1240. else if (c == '{')
  1241. return character_pushback(lexer, JSON_LEADER);
  1242. #endif /* PASSTHROUGH_ENABLE */
  1243. else
  1244. return character_pushback(lexer, GROUND_STATE);
  1245. break;
  1246. #endif /* UBLOX_ENABLE */
  1247. #ifdef EVERMORE_ENABLE
  1248. case EVERMORE_LEADER_1:
  1249. if (c == STX)
  1250. lexer->state = EVERMORE_LEADER_2;
  1251. else
  1252. return character_pushback(lexer, GROUND_STATE);
  1253. break;
  1254. case EVERMORE_LEADER_2:
  1255. lexer->length = (size_t) c;
  1256. if (c == DLE)
  1257. lexer->state = EVERMORE_PAYLOAD_DLE;
  1258. else
  1259. lexer->state = EVERMORE_PAYLOAD;
  1260. break;
  1261. case EVERMORE_PAYLOAD:
  1262. if (c == DLE)
  1263. lexer->state = EVERMORE_PAYLOAD_DLE;
  1264. else if (--lexer->length == 0)
  1265. return character_pushback(lexer, GROUND_STATE);
  1266. break;
  1267. case EVERMORE_PAYLOAD_DLE:
  1268. switch (c) {
  1269. case DLE:
  1270. lexer->state = EVERMORE_PAYLOAD;
  1271. break;
  1272. case ETX:
  1273. lexer->state = EVERMORE_RECOGNIZED;
  1274. break;
  1275. default:
  1276. lexer->state = GROUND_STATE;
  1277. }
  1278. break;
  1279. case EVERMORE_RECOGNIZED:
  1280. if (c == DLE)
  1281. lexer->state = EVERMORE_LEADER_1;
  1282. else
  1283. return character_pushback(lexer, GROUND_STATE);
  1284. break;
  1285. #endif /* EVERMORE_ENABLE */
  1286. #ifdef ITRAX_ENABLE
  1287. case ITALK_LEADER_1:
  1288. if (c == '!')
  1289. lexer->state = ITALK_LEADER_2;
  1290. else
  1291. return character_pushback(lexer, GROUND_STATE);
  1292. break;
  1293. case ITALK_LEADER_2:
  1294. lexer->length = (size_t) (lexer->inbuffer[6] & 0xff);
  1295. lexer->state = ITALK_LENGTH;
  1296. break;
  1297. case ITALK_LENGTH:
  1298. lexer->length += 1; /* fix number of words in payload */
  1299. lexer->length *= 2; /* convert to number of bytes */
  1300. lexer->length += 3; /* add trailer length */
  1301. lexer->state = ITALK_PAYLOAD;
  1302. break;
  1303. case ITALK_PAYLOAD:
  1304. /* lookahead for "<!" because sometimes packets are short but valid */
  1305. if ((c == '>') && (lexer->inbufptr[0] == '<') &&
  1306. (lexer->inbufptr[1] == '!')) {
  1307. lexer->state = ITALK_RECOGNIZED;
  1308. GPSD_LOG(LOG_IO, &lexer->errout,
  1309. "ITALK: trying to process runt packet\n");
  1310. break;
  1311. } else if (--lexer->length == 0)
  1312. lexer->state = ITALK_DELIVERED;
  1313. break;
  1314. case ITALK_DELIVERED:
  1315. if (c == '>')
  1316. lexer->state = ITALK_RECOGNIZED;
  1317. else
  1318. return character_pushback(lexer, GROUND_STATE);
  1319. break;
  1320. case ITALK_RECOGNIZED:
  1321. if (c == '<')
  1322. lexer->state = ITALK_LEADER_1;
  1323. else
  1324. return character_pushback(lexer, GROUND_STATE);
  1325. break;
  1326. #endif /* ITRAX_ENABLE */
  1327. #ifdef GEOSTAR_ENABLE
  1328. case GEOSTAR_LEADER_1:
  1329. if (c == 'S')
  1330. lexer->state = GEOSTAR_LEADER_2;
  1331. else
  1332. return character_pushback(lexer, GROUND_STATE);
  1333. break;
  1334. case GEOSTAR_LEADER_2:
  1335. if (c == 'G')
  1336. lexer->state = GEOSTAR_LEADER_3;
  1337. else
  1338. return character_pushback(lexer, GROUND_STATE);
  1339. break;
  1340. case GEOSTAR_LEADER_3:
  1341. if (c == 'G')
  1342. lexer->state = GEOSTAR_LEADER_4;
  1343. else
  1344. return character_pushback(lexer, GROUND_STATE);
  1345. break;
  1346. case GEOSTAR_LEADER_4:
  1347. lexer->state = GEOSTAR_MESSAGE_ID_1;
  1348. break;
  1349. case GEOSTAR_MESSAGE_ID_1:
  1350. lexer->state = GEOSTAR_MESSAGE_ID_2;
  1351. break;
  1352. case GEOSTAR_MESSAGE_ID_2:
  1353. lexer->length = (size_t)(c * 4);
  1354. lexer->state = GEOSTAR_LENGTH_1;
  1355. break;
  1356. case GEOSTAR_LENGTH_1:
  1357. lexer->length += (c << 8) * 4;
  1358. if (lexer->length <= MAX_PACKET_LENGTH)
  1359. lexer->state = GEOSTAR_LENGTH_2;
  1360. else
  1361. return character_pushback(lexer, GROUND_STATE);
  1362. break;
  1363. case GEOSTAR_LENGTH_2:
  1364. lexer->state = GEOSTAR_PAYLOAD;
  1365. break;
  1366. case GEOSTAR_PAYLOAD:
  1367. if (--lexer->length == 0)
  1368. lexer->state = GEOSTAR_CHECKSUM_A;
  1369. /* else stay in payload state */
  1370. break;
  1371. case GEOSTAR_CHECKSUM_A:
  1372. lexer->state = GEOSTAR_CHECKSUM_B;
  1373. break;
  1374. case GEOSTAR_CHECKSUM_B:
  1375. lexer->state = GEOSTAR_CHECKSUM_C;
  1376. break;
  1377. case GEOSTAR_CHECKSUM_C:
  1378. lexer->state = GEOSTAR_RECOGNIZED;
  1379. break;
  1380. case GEOSTAR_RECOGNIZED:
  1381. if (c == 'P')
  1382. lexer->state = GEOSTAR_LEADER_1;
  1383. else
  1384. return character_pushback(lexer, GROUND_STATE);
  1385. break;
  1386. #endif /* GEOSTAR_ENABLE */
  1387. #ifdef GREIS_ENABLE
  1388. case GREIS_EXPECTED:
  1389. case GREIS_RECOGNIZED:
  1390. if (!isascii(c)) {
  1391. return character_pushback(lexer, GROUND_STATE);
  1392. } else if (c == '#') {
  1393. /* Probably a comment used by the testsuite */
  1394. lexer->state = COMMENT_BODY;
  1395. } else if (c == '\r' || c == '\n') {
  1396. /* Arbitrary CR/LF allowed here, so continue to expect GREIS */
  1397. lexer->state = GREIS_EXPECTED;
  1398. character_discard(lexer);
  1399. } else {
  1400. lexer->state = GREIS_ID_1;
  1401. }
  1402. break;
  1403. case GREIS_REPLY_1:
  1404. if (c != 'E')
  1405. return character_pushback(lexer, GROUND_STATE);
  1406. lexer->state = GREIS_REPLY_2;
  1407. break;
  1408. case GREIS_ID_1:
  1409. if (!isascii(c))
  1410. return character_pushback(lexer, GROUND_STATE);
  1411. lexer->state = GREIS_ID_2;
  1412. break;
  1413. case GREIS_REPLY_2:
  1414. case GREIS_ID_2:
  1415. if (!isxdigit(c))
  1416. return character_pushback(lexer, GROUND_STATE);
  1417. lexer->length = greis_hex2bin(c) << 8;
  1418. lexer->state = GREIS_LENGTH_1;
  1419. break;
  1420. case GREIS_LENGTH_1:
  1421. if (!isxdigit(c))
  1422. return character_pushback(lexer, GROUND_STATE);
  1423. lexer->length += greis_hex2bin(c) << 4;
  1424. lexer->state = GREIS_LENGTH_2;
  1425. break;
  1426. case GREIS_LENGTH_2:
  1427. if (!isxdigit(c))
  1428. return character_pushback(lexer, GROUND_STATE);
  1429. lexer->length += greis_hex2bin(c);
  1430. lexer->state = GREIS_PAYLOAD;
  1431. break;
  1432. case GREIS_PAYLOAD:
  1433. if (--lexer->length == 0)
  1434. lexer->state = GREIS_RECOGNIZED;
  1435. /* else stay in payload state */
  1436. break;
  1437. #endif /* GREIS_ENABLE */
  1438. #ifdef TSIP_ENABLE
  1439. case TSIP_LEADER:
  1440. /* unused case */
  1441. if (c >= 0x13) {
  1442. lexer->length = TSIP_MAX_PACKET;
  1443. lexer->state = TSIP_PAYLOAD;
  1444. } else
  1445. return character_pushback(lexer, GROUND_STATE);
  1446. break;
  1447. case TSIP_PAYLOAD:
  1448. if (c == DLE)
  1449. lexer->state = TSIP_DLE;
  1450. if ( 0 == --lexer->length ) {
  1451. /* uh, oh, packet too long, probably was never TSIP */
  1452. /* note lexer->length is unsigned */
  1453. lexer->state = GROUND_STATE;
  1454. }
  1455. break;
  1456. case TSIP_DLE:
  1457. switch (c) {
  1458. case ETX:
  1459. lexer->state = TSIP_RECOGNIZED;
  1460. break;
  1461. case DLE:
  1462. lexer->length = TSIP_MAX_PACKET;
  1463. lexer->state = TSIP_PAYLOAD;
  1464. break;
  1465. default:
  1466. lexer->state = GROUND_STATE;
  1467. break;
  1468. }
  1469. break;
  1470. case TSIP_RECOGNIZED:
  1471. if (c == DLE)
  1472. /*
  1473. * Don't go to TSIP_LEADER state -- TSIP packets aren't
  1474. * checksummed, so false positives are easy. We might be
  1475. * looking at another DLE-stuffed protocol like EverMore
  1476. * or Garmin streaming binary.
  1477. */
  1478. lexer->state = DLE_LEADER;
  1479. else
  1480. return character_pushback(lexer, GROUND_STATE);
  1481. break;
  1482. #endif /* TSIP_ENABLE */
  1483. #ifdef RTCM104V2_ENABLE
  1484. case RTCM2_SYNC_STATE:
  1485. case RTCM2_SKIP_STATE:
  1486. if ((isgpsstat = rtcm2_decode(lexer, c)) == ISGPS_MESSAGE) {
  1487. lexer->state = RTCM2_RECOGNIZED;
  1488. break;
  1489. } else if (isgpsstat == ISGPS_NO_SYNC)
  1490. lexer->state = GROUND_STATE;
  1491. break;
  1492. case RTCM2_RECOGNIZED:
  1493. if (c == '#')
  1494. /*
  1495. * There's a remote possibility this could fire when # =
  1496. * 0x23 is legitimate in-stream RTCM2 data. No help for
  1497. * it, the test framework needs this case so it can inject
  1498. * # EOF and we'll miss a packet.
  1499. */
  1500. return character_pushback(lexer, GROUND_STATE);
  1501. else if (rtcm2_decode(lexer, c) == ISGPS_SYNC) {
  1502. lexer->state = RTCM2_SYNC_STATE;
  1503. break;
  1504. } else
  1505. lexer->state = GROUND_STATE;
  1506. break;
  1507. #endif /* RTCM104V2_ENABLE */
  1508. #ifdef PASSTHROUGH_ENABLE
  1509. case JSON_LEADER:
  1510. if (c == '{' || c == '[') {
  1511. lexer->json_depth++;
  1512. } else if (c == '}' || c == ']') {
  1513. if (--lexer->json_depth == 0)
  1514. lexer->state = JSON_RECOGNIZED;
  1515. } else if (isspace(c) || c == ',')
  1516. break;
  1517. else if (c == '"') {
  1518. lexer->state = JSON_STRINGLITERAL;
  1519. lexer->json_after = JSON_END_ATTRIBUTE;
  1520. } else {
  1521. GPSD_LOG(LOG_RAW + 1, &lexer->errout,
  1522. "%08ld: missing attribute start after header\n",
  1523. lexer->char_counter);
  1524. lexer->state = GROUND_STATE;
  1525. }
  1526. break;
  1527. case JSON_STRINGLITERAL:
  1528. if (c == '\\')
  1529. lexer->state = JSON_STRING_SOLIDUS;
  1530. else if (c == '"')
  1531. lexer->state = lexer->json_after;
  1532. break;
  1533. case JSON_STRING_SOLIDUS:
  1534. lexer->state = JSON_STRINGLITERAL;
  1535. break;
  1536. case JSON_END_ATTRIBUTE:
  1537. if (isspace(c))
  1538. break;
  1539. else if (c == ':')
  1540. lexer->state = JSON_EXPECT_VALUE;
  1541. else
  1542. /* saw something other than value start after colon */
  1543. return character_pushback(lexer, GROUND_STATE);
  1544. break;
  1545. case JSON_EXPECT_VALUE:
  1546. if (isspace(c))
  1547. break;
  1548. else if (c == '"') {
  1549. lexer->state = JSON_STRINGLITERAL;
  1550. lexer->json_after = JSON_END_VALUE;
  1551. } else if (c == '{' || c == '[') {
  1552. return character_pushback(lexer, JSON_LEADER);
  1553. } else if (strchr("-0123456789", c) != NULL) {
  1554. lexer->state = JSON_NUMBER;
  1555. } else if (c == 't' || c == 'f' || c == 'n')
  1556. /*
  1557. * This is a bit more permissive than strictly necessary, as
  1558. * GPSD JSON does not include the null token. Still, it's
  1559. * futureproofing.
  1560. */
  1561. lexer->state = JSON_SPECIAL;
  1562. else
  1563. /* couldn't recognize start of value literal */
  1564. return character_pushback(lexer, GROUND_STATE);
  1565. break;
  1566. case JSON_NUMBER:
  1567. /*
  1568. * Will recognize some ill-formed numeric literals.
  1569. * Should be OK as we're already three stages deep inside
  1570. * JSON recognition; odds that we'll actually see an
  1571. * ill-formed literal are quite low. and the worst
  1572. * possible result if it happens is our JSON parser will
  1573. * quietly chuck out the object.
  1574. */
  1575. if (strchr("1234567890.eE+-", c) == NULL) {
  1576. return character_pushback(lexer, JSON_END_VALUE);
  1577. }
  1578. break;
  1579. case JSON_SPECIAL:
  1580. if (strchr("truefalsnil", c) == NULL)
  1581. return character_pushback(lexer, JSON_END_VALUE);
  1582. break;
  1583. case JSON_END_VALUE:
  1584. if (isspace(c))
  1585. break;
  1586. else if (c == ',')
  1587. lexer->state = JSON_LEADER;
  1588. else if (c == '}' || c == ']')
  1589. return character_pushback(lexer, JSON_LEADER);
  1590. else
  1591. /* trailing garbage after JSON value */
  1592. return character_pushback(lexer, GROUND_STATE);
  1593. break;
  1594. #endif /* PASSTHROUGH_ENABLE */
  1595. #ifdef STASH_ENABLE
  1596. case STASH_RECOGNIZED:
  1597. if (c == '$')
  1598. lexer->state = NMEA_DOLLAR;
  1599. else
  1600. return character_pushback(lexer, GROUND_STATE);
  1601. break;
  1602. #endif /* STASH_ENABLE */
  1603. }
  1604. return true; /* no pushback */
  1605. }
  1606. static void packet_accept(struct gps_lexer_t *lexer, int packet_type)
  1607. /* packet grab succeeded, move to output buffer */
  1608. {
  1609. size_t packetlen = lexer->inbufptr - lexer->inbuffer;
  1610. if (packetlen < sizeof(lexer->outbuffer)) {
  1611. memcpy(lexer->outbuffer, lexer->inbuffer, packetlen);
  1612. lexer->outbuflen = packetlen;
  1613. lexer->outbuffer[packetlen] = '\0';
  1614. lexer->type = packet_type;
  1615. if (lexer->errout.debug >= LOG_RAW + 1) {
  1616. char scratchbuf[MAX_PACKET_LENGTH*4+1];
  1617. GPSD_LOG(LOG_RAW + 1, &lexer->errout,
  1618. "Packet type %d accepted %zu = %s\n",
  1619. packet_type, packetlen,
  1620. gpsd_packetdump(scratchbuf, sizeof(scratchbuf),
  1621. (char *)lexer->outbuffer,
  1622. lexer->outbuflen));
  1623. }
  1624. } else {
  1625. GPSD_LOG(LOG_ERROR, &lexer->errout,
  1626. "Rejected too long packet type %d len %zu\n",
  1627. packet_type, packetlen);
  1628. }
  1629. }
  1630. static void packet_discard(struct gps_lexer_t *lexer)
  1631. /* shift the input buffer to discard all data up to current input pointer */
  1632. {
  1633. size_t discard = lexer->inbufptr - lexer->inbuffer;
  1634. size_t remaining = lexer->inbuflen - discard;
  1635. lexer->inbufptr = memmove(lexer->inbuffer, lexer->inbufptr, remaining);
  1636. lexer->inbuflen = remaining;
  1637. if (lexer->errout.debug >= LOG_RAW + 1) {
  1638. char scratchbuf[MAX_PACKET_LENGTH*4+1];
  1639. GPSD_LOG(LOG_RAW + 1, &lexer->errout,
  1640. "Packet discard of %zu, chars remaining is %zu = %s\n",
  1641. discard, remaining,
  1642. gpsd_packetdump(scratchbuf, sizeof(scratchbuf),
  1643. (char *)lexer->inbuffer, lexer->inbuflen));
  1644. }
  1645. }
  1646. #ifdef STASH_ENABLE
  1647. static void packet_stash(struct gps_lexer_t *lexer)
  1648. /* stash the input buffer up to current input pointer */
  1649. {
  1650. size_t stashlen = lexer->inbufptr - lexer->inbuffer;
  1651. memcpy(lexer->stashbuffer, lexer->inbuffer, stashlen);
  1652. lexer->stashbuflen = stashlen;
  1653. if (lexer->errout.debug >= LOG_RAW+1) {
  1654. char scratchbuf[MAX_PACKET_LENGTH*4+1];
  1655. GPSD_LOG(LOG_RAW + 1, &lexer->errout,
  1656. "Packet stash of %zu = %s\n",
  1657. stashlen,
  1658. gpsd_packetdump(scratchbuf, sizeof(scratchbuf),
  1659. (char *)lexer->stashbuffer,
  1660. lexer->stashbuflen));
  1661. }
  1662. }
  1663. static void packet_unstash(struct gps_lexer_t *lexer)
  1664. /* return stash to start of input buffer */
  1665. {
  1666. size_t available = sizeof(lexer->inbuffer) - lexer->inbuflen;
  1667. size_t stashlen = lexer->stashbuflen;
  1668. if (stashlen <= available) {
  1669. memmove(lexer->inbuffer + stashlen, lexer->inbuffer, lexer->inbuflen);
  1670. memcpy(lexer->inbuffer, lexer->stashbuffer, stashlen);
  1671. lexer->inbuflen += stashlen;
  1672. lexer->stashbuflen = 0;
  1673. if (lexer->errout.debug >= LOG_RAW+1) {
  1674. char scratchbuf[MAX_PACKET_LENGTH*4+1];
  1675. GPSD_LOG(LOG_RAW + 1, &lexer->errout,
  1676. "Packet unstash of %zu, reconstructed is %zu = %s\n",
  1677. stashlen, lexer->inbuflen,
  1678. gpsd_packetdump(scratchbuf, sizeof(scratchbuf),
  1679. (char *)lexer->inbuffer, lexer->inbuflen));
  1680. }
  1681. } else {
  1682. GPSD_LOG(LOG_ERROR, &lexer->errout,
  1683. "Rejected too long unstash of %zu\n", stashlen);
  1684. lexer->stashbuflen = 0;
  1685. }
  1686. }
  1687. #endif /* STASH_ENABLE */
  1688. /* get 0-origin big-endian words relative to start of packet buffer */
  1689. #define getword(i) (short)(lexer->inbuffer[2*(i)] | (lexer->inbuffer[2*(i)+1] << 8))
  1690. /* entry points begin here */
  1691. void lexer_init(struct gps_lexer_t *lexer)
  1692. {
  1693. lexer->char_counter = 0;
  1694. lexer->retry_counter = 0;
  1695. #ifdef PASSTHROUGH_ENABLE
  1696. lexer->json_depth = 0;
  1697. #endif /* PASSTHROUGH_ENABLE */
  1698. lexer->start_time.tv_sec = 0;
  1699. lexer->start_time.tv_nsec = 0;
  1700. packet_reset(lexer);
  1701. errout_reset(&lexer->errout);
  1702. }
  1703. void packet_parse(struct gps_lexer_t *lexer)
  1704. /* grab a packet from the input buffer */
  1705. {
  1706. lexer->outbuflen = 0;
  1707. while (packet_buffered_input(lexer) > 0) {
  1708. unsigned char c = *lexer->inbufptr++;
  1709. unsigned int oldstate = lexer->state;
  1710. if (!nextstate(lexer, c))
  1711. continue;
  1712. GPSD_LOG(LOG_RAW + 2, &lexer->errout,
  1713. "%08ld: character '%c' [%02x], %s -> %s\n",
  1714. lexer->char_counter, (isprint(c) ? c : '.'), c,
  1715. state_table[oldstate], state_table[lexer->state]);
  1716. lexer->char_counter++;
  1717. if (lexer->state == GROUND_STATE) {
  1718. character_discard(lexer);
  1719. } else if (lexer->state == COMMENT_RECOGNIZED) {
  1720. packet_accept(lexer, COMMENT_PACKET);
  1721. packet_discard(lexer);
  1722. lexer->state = GROUND_STATE;
  1723. break;
  1724. }
  1725. #ifdef NMEA0183_ENABLE
  1726. else if (lexer->state == NMEA_RECOGNIZED) {
  1727. /*
  1728. * $PASHR packets have no checksum. Avoid the possibility
  1729. * that random garbage might make it look like they do.
  1730. */
  1731. if (!str_starts_with((const char *)lexer->inbuffer, "$PASHR,"))
  1732. {
  1733. bool checksum_ok = true;
  1734. char csum[3] = { '0', '0', '0' };
  1735. char *end;
  1736. /*
  1737. * Back up past any whitespace. Need to do this because
  1738. * at least one GPS (the Firefly 1a) emits \r\r\n
  1739. */
  1740. for (end = (char *)lexer->inbufptr - 1; isspace((unsigned char) *end); end--)
  1741. continue;
  1742. while (strchr("0123456789ABCDEF", *end))
  1743. --end;
  1744. if (*end == '*') {
  1745. unsigned int n, crc = 0;
  1746. for (n = 1; (char *)lexer->inbuffer + n < end; n++)
  1747. crc ^= lexer->inbuffer[n];
  1748. (void)snprintf(csum, sizeof(csum), "%02X", crc);
  1749. checksum_ok = (csum[0] == toupper((unsigned char) end[1])
  1750. && csum[1] == toupper((unsigned char) end[2]));
  1751. }
  1752. if (!checksum_ok) {
  1753. GPSD_LOG(LOG_WARN, &lexer->errout,
  1754. "bad checksum in NMEA packet; expected %s.\n",
  1755. csum);
  1756. packet_accept(lexer, BAD_PACKET);
  1757. lexer->state = GROUND_STATE;
  1758. packet_discard(lexer);
  1759. break; /* exit case */
  1760. }
  1761. }
  1762. /* checksum passed or not present */
  1763. #ifdef AIVDM_ENABLE
  1764. /* !ABVDx - NMEA 4.0 Base AIS station
  1765. * !ADVDx - MMEA 4.0 Dependent AIS Base Station
  1766. * !AIVDx - Mobile AIS station
  1767. * !ANVDx - NMEA 4.0 Aid to Navigation AIS station
  1768. * !ARVDx - NMEA 4.0 AIS Receiving Station
  1769. * !ASVDx - NMEA 4.0 Limited Base Station
  1770. * !ATVDx - NMEA 4.0 AIS Transmitting Station
  1771. * !AXVDx - NMEA 4.0 Repeater AIS station
  1772. * !BSVDx - Base AIS station (deprecated in NMEA 4.0)
  1773. * !SAVDx - NMEA 4.0 Physical Shore AIS Station
  1774. *
  1775. * where x is:
  1776. * M -- from other ships
  1777. * O -- from your own ship
  1778. */
  1779. /* make some simple char tests first to stop wasting cycles
  1780. * on a lot of strncmp()s */
  1781. if ('!' == lexer->inbuffer[0] &&
  1782. 'V' == lexer->inbuffer[3] &&
  1783. 'D' == lexer->inbuffer[4] &&
  1784. ',' == lexer->inbuffer[6] &&
  1785. (str_starts_with((char *)lexer->inbuffer, "!ABVDM,") ||
  1786. str_starts_with((char *)lexer->inbuffer, "!ABVDO,") ||
  1787. str_starts_with((char *)lexer->inbuffer, "!ADVDM,") ||
  1788. str_starts_with((char *)lexer->inbuffer, "!ADVDO,") ||
  1789. str_starts_with((char *)lexer->inbuffer, "!AIVDM,") ||
  1790. str_starts_with((char *)lexer->inbuffer, "!AIVDO,") ||
  1791. str_starts_with((char *)lexer->inbuffer, "!ANVDM,") ||
  1792. str_starts_with((char *)lexer->inbuffer, "!ANVDO,") ||
  1793. str_starts_with((char *)lexer->inbuffer, "!ARVDM,") ||
  1794. str_starts_with((char *)lexer->inbuffer, "!ARVDO,") ||
  1795. str_starts_with((char *)lexer->inbuffer, "!ASVDM,") ||
  1796. str_starts_with((char *)lexer->inbuffer, "!ASVDO,") ||
  1797. str_starts_with((char *)lexer->inbuffer, "!ATVDM,") ||
  1798. str_starts_with((char *)lexer->inbuffer, "!ATVDO,") ||
  1799. str_starts_with((char *)lexer->inbuffer, "!AXVDM,") ||
  1800. str_starts_with((char *)lexer->inbuffer, "!AXVDO,") ||
  1801. str_starts_with((char *)lexer->inbuffer, "!BSVDM,") ||
  1802. str_starts_with((char *)lexer->inbuffer, "!BSVDO,") ||
  1803. str_starts_with((char *)lexer->inbuffer, "!SAVDM,") ||
  1804. str_starts_with((char *)lexer->inbuffer, "!SAVDO,"))) {
  1805. packet_accept(lexer, AIVDM_PACKET);
  1806. } else
  1807. #endif /* AIVDM_ENABLE */
  1808. packet_accept(lexer, NMEA_PACKET);
  1809. packet_discard(lexer);
  1810. #ifdef STASH_ENABLE
  1811. if (lexer->stashbuflen)
  1812. packet_unstash(lexer);
  1813. #endif /* STASH_ENABLE */
  1814. break;
  1815. }
  1816. #endif /* NMEA0183_ENABLE */
  1817. #ifdef SIRF_ENABLE
  1818. else if (lexer->state == SIRF_RECOGNIZED) {
  1819. unsigned char *trailer = lexer->inbufptr - 4;
  1820. unsigned int checksum =
  1821. (unsigned)((trailer[0] << 8) | trailer[1]);
  1822. unsigned int n, crc = 0;
  1823. for (n = 4; n < (unsigned)(trailer - lexer->inbuffer); n++)
  1824. crc += (int)lexer->inbuffer[n];
  1825. crc &= 0x7fff;
  1826. if (checksum == crc)
  1827. packet_accept(lexer, SIRF_PACKET);
  1828. else {
  1829. packet_accept(lexer, BAD_PACKET);
  1830. lexer->state = GROUND_STATE;
  1831. }
  1832. packet_discard(lexer);
  1833. break;
  1834. }
  1835. #endif /* SIRF_ENABLE */
  1836. #ifdef SKYTRAQ_ENABLE
  1837. else if (lexer->state == SKY_RECOGNIZED) {
  1838. packet_accept(lexer, SKY_PACKET);
  1839. packet_discard(lexer);
  1840. break;
  1841. }
  1842. #endif /* SKYTRAQ_ENABLE */
  1843. #ifdef SUPERSTAR2_ENABLE
  1844. else if (lexer->state == SUPERSTAR2_RECOGNIZED) {
  1845. unsigned a = 0, b;
  1846. size_t n;
  1847. lexer->length = 4 + (size_t) lexer->inbuffer[3] + 2;
  1848. for (n = 0; n < lexer->length - 2; n++)
  1849. a += (unsigned)lexer->inbuffer[n];
  1850. b = (unsigned)getleu16(lexer->inbuffer, lexer->length - 2);
  1851. GPSD_LOG(LOG_IO, &lexer->errout,
  1852. "SuperStarII pkt dump: type %u len %u\n",
  1853. lexer->inbuffer[1], (unsigned int)lexer->length);
  1854. if (a != b) {
  1855. GPSD_LOG(LOG_IO, &lexer->errout,
  1856. "REJECT SuperStarII packet type 0x%02x"
  1857. "%zd bad checksum 0x%04x, expecting 0x%04x\n",
  1858. lexer->inbuffer[1], lexer->length, a, b);
  1859. packet_accept(lexer, BAD_PACKET);
  1860. lexer->state = GROUND_STATE;
  1861. } else {
  1862. packet_accept(lexer, SUPERSTAR2_PACKET);
  1863. }
  1864. packet_discard(lexer);
  1865. break;
  1866. }
  1867. #endif /* SUPERSTAR2_ENABLE */
  1868. #ifdef ONCORE_ENABLE
  1869. else if (lexer->state == ONCORE_RECOGNIZED) {
  1870. char a, b;
  1871. int i, len;
  1872. len = lexer->inbufptr - lexer->inbuffer;
  1873. a = (char)(lexer->inbuffer[len - 3]);
  1874. b = '\0';
  1875. for (i = 2; i < len - 3; i++)
  1876. b ^= lexer->inbuffer[i];
  1877. if (a == b) {
  1878. GPSD_LOG(LOG_IO, &lexer->errout,
  1879. "Accept OnCore packet @@%c%c len %d\n",
  1880. lexer->inbuffer[2], lexer->inbuffer[3], len);
  1881. packet_accept(lexer, ONCORE_PACKET);
  1882. } else {
  1883. GPSD_LOG(LOG_IO, &lexer->errout,
  1884. "REJECT OnCore packet @@%c%c len %d\n",
  1885. lexer->inbuffer[2], lexer->inbuffer[3], len);
  1886. packet_accept(lexer, BAD_PACKET);
  1887. lexer->state = GROUND_STATE;
  1888. }
  1889. packet_discard(lexer);
  1890. break;
  1891. }
  1892. #endif /* ONCORE_ENABLE */
  1893. #if defined(TSIP_ENABLE) || defined(GARMIN_ENABLE)
  1894. else if (lexer->state == TSIP_RECOGNIZED) {
  1895. size_t packetlen = lexer->inbufptr - lexer->inbuffer;
  1896. #ifdef TSIP_ENABLE
  1897. unsigned int pos, dlecnt;
  1898. /* don't count stuffed DLEs in the length */
  1899. dlecnt = 0;
  1900. for (pos = 0; pos < (unsigned int)packetlen; pos++)
  1901. if (lexer->inbuffer[pos] == DLE)
  1902. dlecnt++;
  1903. if (dlecnt > 2) {
  1904. dlecnt -= 2;
  1905. dlecnt /= 2;
  1906. GPSD_LOG(LOG_RAW + 1, &lexer->errout,
  1907. "Unstuffed %d DLEs\n", dlecnt);
  1908. packetlen -= dlecnt;
  1909. }
  1910. #endif /* TSIP_ENABLE */
  1911. if (packetlen < 5) {
  1912. lexer->state = GROUND_STATE;
  1913. } else {
  1914. unsigned int pkt_id;
  1915. #ifdef GARMIN_ENABLE
  1916. unsigned int len;
  1917. size_t n;
  1918. unsigned int ch, chksum;
  1919. n = 0;
  1920. #ifdef TSIP_ENABLE
  1921. /* shortcut garmin */
  1922. if (TSIP_PACKET == lexer->type)
  1923. goto not_garmin;
  1924. #endif /* TSIP_ENABLE */
  1925. if (lexer->inbuffer[n++] != DLE)
  1926. goto not_garmin;
  1927. pkt_id = lexer->inbuffer[n++]; /* packet ID */
  1928. len = lexer->inbuffer[n++];
  1929. chksum = len + pkt_id;
  1930. if (len == DLE) {
  1931. if (lexer->inbuffer[n++] != DLE)
  1932. goto not_garmin;
  1933. }
  1934. for (; len > 0; len--) {
  1935. chksum += lexer->inbuffer[n];
  1936. if (lexer->inbuffer[n++] == DLE) {
  1937. if (lexer->inbuffer[n++] != DLE)
  1938. goto not_garmin;
  1939. }
  1940. }
  1941. /* check sum byte */
  1942. ch = lexer->inbuffer[n++];
  1943. chksum += ch;
  1944. if (ch == DLE) {
  1945. if (lexer->inbuffer[n++] != DLE)
  1946. goto not_garmin;
  1947. }
  1948. if (lexer->inbuffer[n++] != DLE)
  1949. goto not_garmin;
  1950. /* we used to say n++ here, but scan-build complains */
  1951. if (lexer->inbuffer[n] != ETX)
  1952. goto not_garmin;
  1953. chksum &= 0xff;
  1954. if (chksum) {
  1955. GPSD_LOG(LOG_IO, &lexer->errout,
  1956. "Garmin checksum failed: %02x!=0\n", chksum);
  1957. goto not_garmin;
  1958. }
  1959. packet_accept(lexer, GARMIN_PACKET);
  1960. packet_discard(lexer);
  1961. break;
  1962. not_garmin:;
  1963. GPSD_LOG(LOG_RAW + 1, &lexer->errout,
  1964. "Not a Garmin packet\n");
  1965. #endif /* GARMIN_ENABLE */
  1966. #ifdef TSIP_ENABLE
  1967. /* check for some common TSIP packet types:
  1968. * 0x13, TSIP Parsing Error Notification
  1969. * 0x1c, Hardware/Software Version Information
  1970. * 0x38, Request SV system data
  1971. * 0x40, Almanac
  1972. * 0x41, GPS time, data length 10
  1973. * 0x42, Single Precision Fix XYZ, data length 16
  1974. * 0x43, Velocity Fix XYZ, ECEF, data length 20
  1975. * 0x45, Software Version Information, data length 10
  1976. * 0x46, Health of Receiver, data length 2
  1977. * 0x47, Signal Level all Sats Tracked, data length 1+5*numSV
  1978. * 0x48, GPS System Messages, data length 22
  1979. * 0x49, Almanac Health Page, data length 32
  1980. * 0x4a, Single Precision Fix LLA, data length 20
  1981. * 0x4b, Machine Code Status, data length 3
  1982. * 0x4c, Operating Parameters Report, data length 17
  1983. * 0x4d, Oscillator Offset
  1984. * 0x4e, Response to set GPS time
  1985. * 0x54, One Satellite Bias, data length 12
  1986. * 0x55, I/O Options, data length 4
  1987. * 0x56, Velocity Fix ENU, data length 20
  1988. * 0x57, Last Computed Fix Report, data length 8
  1989. * 0x58, Satellite System Data
  1990. * 0x58-05, UTC
  1991. * 0x59, Satellite Health
  1992. * 0x5a, Raw Measurements
  1993. * 0x5b, Satellite Ephemeris Status, data length 16
  1994. * 0x5c, Satellite Tracking Status, data length 24
  1995. * 0x5d, Satellite Tracking Status (multi-gnss), data length 26
  1996. * 0x5e, Additional Fix Status Report
  1997. * 0x5f, Severe Failure Notification
  1998. * 0x5F-01-0B: Reset Error Codes
  1999. * 0x5F-02: Ascii text message
  2000. * 0x6c, Satellite Selection List, data length 18+numSV
  2001. * 0x6d, All-In-View Satellite Selection, data length 17+numSV
  2002. * 0x6f, Synced Measurement Packet
  2003. * 0x72, PV filter parameters
  2004. * 0x74, Altitude filter parameters
  2005. * 0x78, Max DGPS correction age
  2006. * 0x7b, NMEA message schedule
  2007. * 0x82, Differential Position Fix Mode, data length 1
  2008. * 0x83, Double Precision Fix XYZ, data length 36
  2009. * 0x84, Double Precision Fix LLA, data length 36
  2010. * 0x85, DGPS Correction status
  2011. * 0x8f, Superpackets
  2012. * 0x8f-01,
  2013. * 0x8f-02,
  2014. * 0x8f-03, port configration
  2015. * 0x8f-14, datum
  2016. * 0x8f-15, datum
  2017. * 0x8f-17, Single Precision UTM
  2018. * 0x8f-18, Double Precision UTM
  2019. * 0x8f-20, LLA & ENU
  2020. * 0x8f-26, SEEPROM write status
  2021. * 0x8f-40, TAIP Configuration
  2022. * 0xbb, GPS Navigation Configuration
  2023. * 0xbc, Receiver Port Configuration
  2024. *
  2025. * <DLE>[pkt id] [data] <DLE><ETX>
  2026. *
  2027. * The best description is in [TSIP], the Trimble Standard
  2028. * Interface Protocol manual; unless otherwise specified
  2029. * that is where these type/length notifications are from.
  2030. *
  2031. * Note that not all Trimble chips conform perfectly to this
  2032. * specification, nor does it cover every packet type we
  2033. * may see on the wire.
  2034. */
  2035. pkt_id = lexer->inbuffer[1]; /* packet ID */
  2036. /* *INDENT-OFF* */
  2037. if (!((0x13 == pkt_id) ||
  2038. (0x1c == pkt_id) ||
  2039. (0x38 == pkt_id) ||
  2040. ((0x41 <= pkt_id) && (0x4c >= pkt_id)) ||
  2041. ((0x54 <= pkt_id) && (0x57 >= pkt_id)) ||
  2042. ((0x5a <= pkt_id) && (0x5f >= pkt_id)) ||
  2043. (0x6c == pkt_id) ||
  2044. (0x6d == pkt_id) ||
  2045. ((0x82 <= pkt_id) && (0x84 >= pkt_id)) ||
  2046. (0x8f == pkt_id) ||
  2047. (0xbb == pkt_id) ||
  2048. (0xbc == pkt_id))) {
  2049. GPSD_LOG(LOG_IO, &lexer->errout,
  2050. "Packet ID 0x%02x out of range for TSIP\n",
  2051. pkt_id);
  2052. goto not_tsip;
  2053. }
  2054. /* *INDENT-ON* */
  2055. #define TSIP_ID_AND_LENGTH(id, len) ((id == pkt_id) && (len == packetlen-4))
  2056. if ((0x13 == pkt_id) && (1 <= packetlen))
  2057. /* pass */ ;
  2058. /*
  2059. * Not in [TSIP], Accutime Gold only. Variable length.
  2060. */
  2061. else if ((0x1c == pkt_id) && (11 <= packetlen))
  2062. /* pass */ ;
  2063. else if (TSIP_ID_AND_LENGTH(0x41, 10))
  2064. /* pass */ ;
  2065. else if (TSIP_ID_AND_LENGTH(0x42, 16))
  2066. /* pass */ ;
  2067. else if (TSIP_ID_AND_LENGTH(0x43, 20))
  2068. /* pass */ ;
  2069. else if (TSIP_ID_AND_LENGTH(0x45, 10))
  2070. /* pass */ ;
  2071. else if (TSIP_ID_AND_LENGTH(0x46, 2))
  2072. /* pass */ ;
  2073. else if ((0x47 == pkt_id) && ((packetlen % 5) == 0))
  2074. /*
  2075. * 0x47 data length 1+5*numSV, packetlen is 5+5*numSV
  2076. * FIXME, should be a proper length calculation
  2077. */
  2078. /* pass */ ;
  2079. else if (TSIP_ID_AND_LENGTH(0x48, 22))
  2080. /* pass */ ;
  2081. else if (TSIP_ID_AND_LENGTH(0x49, 32))
  2082. /* pass */ ;
  2083. else if (TSIP_ID_AND_LENGTH(0x4a, 20))
  2084. /* pass */ ;
  2085. else if (TSIP_ID_AND_LENGTH(0x4b, 3))
  2086. /* pass */ ;
  2087. else if (TSIP_ID_AND_LENGTH(0x4c, 17))
  2088. /* pass */ ;
  2089. else if (TSIP_ID_AND_LENGTH(0x54, 12))
  2090. /* pass */ ;
  2091. else if (TSIP_ID_AND_LENGTH(0x55, 4))
  2092. /* pass */ ;
  2093. else if (TSIP_ID_AND_LENGTH(0x56, 20))
  2094. /* pass */ ;
  2095. else if (TSIP_ID_AND_LENGTH(0x57, 8))
  2096. /* pass */ ;
  2097. else if (TSIP_ID_AND_LENGTH(0x5a, 25))
  2098. /* pass */ ;
  2099. else if (TSIP_ID_AND_LENGTH(0x5b, 16))
  2100. /* pass */ ;
  2101. else if (TSIP_ID_AND_LENGTH(0x5c, 24))
  2102. /* pass */ ;
  2103. else if (TSIP_ID_AND_LENGTH(0x5d, 26))
  2104. /* pass */ ;
  2105. else if (TSIP_ID_AND_LENGTH(0x5e, 2))
  2106. /* pass */ ;
  2107. /*
  2108. * Not in [TSIP]. the TSIP driver doesn't use type 0x5f.
  2109. * but we test for it so as to avoid setting packet not_tsip
  2110. */
  2111. else if (TSIP_ID_AND_LENGTH(0x5f, 66))
  2112. /*
  2113. * 0x6c data length 18+numSV, total packetlen is 22+numSV
  2114. * numSV up to 224
  2115. */
  2116. /* pass */ ;
  2117. else if ((0x6c == pkt_id)
  2118. && ((22 <= packetlen) && (246 >= packetlen)))
  2119. /*
  2120. * 0x6d data length 17+numSV, total packetlen is 21+numSV
  2121. * numSV up to 32
  2122. */
  2123. /* pass */ ;
  2124. else if ((0x6d == pkt_id)
  2125. && ((21 <= packetlen) && (53 >= packetlen)))
  2126. /* pass */ ;
  2127. else if (TSIP_ID_AND_LENGTH(0x82, 1))
  2128. /* pass */ ;
  2129. else if (TSIP_ID_AND_LENGTH(0x83, 36))
  2130. /* pass */ ;
  2131. else if (TSIP_ID_AND_LENGTH(0x84, 36))
  2132. /* pass */ ;
  2133. /* super packets, variable length */
  2134. else if (0x8f == pkt_id)
  2135. /* pass */ ;
  2136. /*
  2137. * This is according to [TSIP].
  2138. */
  2139. else if (TSIP_ID_AND_LENGTH(0xbb, 40))
  2140. /* pass */ ;
  2141. /*
  2142. * The Accutime Gold ships a version of this packet with a
  2143. * 43-byte payload. We only use the first 21 bytes, and
  2144. * parts after byte 27 are padding.
  2145. */
  2146. else if (TSIP_ID_AND_LENGTH(0xbb, 43))
  2147. /* pass */ ;
  2148. else {
  2149. /* pass */ ;
  2150. GPSD_LOG(LOG_IO, &lexer->errout,
  2151. "TSIP REJECT pkt_id = %#02x, packetlen= %zu\n",
  2152. pkt_id, packetlen);
  2153. goto not_tsip;
  2154. }
  2155. #undef TSIP_ID_AND_LENGTH
  2156. /* Debug */
  2157. GPSD_LOG(LOG_RAW, &lexer->errout,
  2158. "TSIP pkt_id = %#02x, packetlen= %zu\n",
  2159. pkt_id, packetlen);
  2160. packet_accept(lexer, TSIP_PACKET);
  2161. packet_discard(lexer);
  2162. break;
  2163. not_tsip:
  2164. GPSD_LOG(LOG_RAW + 1, &lexer->errout, "Not a TSIP packet\n");
  2165. /*
  2166. * More attempts to recognize ambiguous TSIP-like
  2167. * packet types could go here.
  2168. */
  2169. packet_accept(lexer, BAD_PACKET);
  2170. lexer->state = GROUND_STATE;
  2171. packet_discard(lexer);
  2172. break;
  2173. #endif /* TSIP_ENABLE */
  2174. }
  2175. }
  2176. #endif /* TSIP_ENABLE || GARMIN_ENABLE */
  2177. #ifdef RTCM104V3_ENABLE
  2178. else if (lexer->state == RTCM3_RECOGNIZED) {
  2179. if (crc24q_check(lexer->inbuffer,
  2180. lexer->inbufptr - lexer->inbuffer)) {
  2181. packet_accept(lexer, RTCM3_PACKET);
  2182. } else {
  2183. GPSD_LOG(LOG_IO, &lexer->errout,
  2184. "RTCM3 data checksum failure, "
  2185. "%0x against %02x %02x %02x\n",
  2186. crc24q_hash(lexer->inbuffer,
  2187. lexer->inbufptr - lexer->inbuffer -
  2188. 3), lexer->inbufptr[-3],
  2189. lexer->inbufptr[-2], lexer->inbufptr[-1]);
  2190. packet_accept(lexer, BAD_PACKET);
  2191. }
  2192. packet_discard(lexer);
  2193. lexer->state = GROUND_STATE;
  2194. break;
  2195. }
  2196. #endif /* RTCM104V3_ENABLE */
  2197. #ifdef ZODIAC_ENABLE
  2198. else if (lexer->state == ZODIAC_RECOGNIZED) {
  2199. short len, n, sum;
  2200. len = getword(2);
  2201. for (n = sum = 0; n < len; n++)
  2202. sum += getword(5 + n);
  2203. sum *= -1;
  2204. if (len == 0 || sum == getword(5 + len)) {
  2205. packet_accept(lexer, ZODIAC_PACKET);
  2206. } else {
  2207. GPSD_LOG(LOG_IO, &lexer->errout,
  2208. "Zodiac data checksum 0x%hx over length %hd, expecting 0x%hx\n",
  2209. sum, len, getword(5 + len));
  2210. packet_accept(lexer, BAD_PACKET);
  2211. lexer->state = GROUND_STATE;
  2212. }
  2213. packet_discard(lexer);
  2214. break;
  2215. }
  2216. #endif /* ZODIAC_ENABLE */
  2217. #ifdef UBLOX_ENABLE
  2218. else if (lexer->state == UBX_RECOGNIZED) {
  2219. /* UBX use a TCP like checksum */
  2220. int n, len;
  2221. unsigned char ck_a = (unsigned char)0;
  2222. unsigned char ck_b = (unsigned char)0;
  2223. len = lexer->inbufptr - lexer->inbuffer;
  2224. GPSD_LOG(LOG_IO, &lexer->errout, "UBX: len %d\n", len);
  2225. for (n = 2; n < (len - 2); n++) {
  2226. ck_a += lexer->inbuffer[n];
  2227. ck_b += ck_a;
  2228. }
  2229. if (ck_a == lexer->inbuffer[len - 2] &&
  2230. ck_b == lexer->inbuffer[len - 1])
  2231. packet_accept(lexer, UBX_PACKET);
  2232. else {
  2233. GPSD_LOG(LOG_IO, &lexer->errout,
  2234. "UBX checksum 0x%02hhx%02hhx over length %d,"
  2235. " expecting 0x%02hhx%02hhx (type 0x%02hhx%02hhx)\n",
  2236. ck_a,
  2237. ck_b,
  2238. len,
  2239. lexer->inbuffer[len - 2],
  2240. lexer->inbuffer[len - 1],
  2241. lexer->inbuffer[2], lexer->inbuffer[3]);
  2242. packet_accept(lexer, BAD_PACKET);
  2243. lexer->state = GROUND_STATE;
  2244. }
  2245. packet_discard(lexer);
  2246. break;
  2247. }
  2248. #endif /* UBLOX_ENABLE */
  2249. #ifdef EVERMORE_ENABLE
  2250. else if (lexer->state == EVERMORE_RECOGNIZED) {
  2251. unsigned int n, crc, checksum, len;
  2252. n = 0;
  2253. if (lexer->inbuffer[n++] != DLE)
  2254. goto not_evermore;
  2255. if (lexer->inbuffer[n++] != STX)
  2256. goto not_evermore;
  2257. len = lexer->inbuffer[n++];
  2258. if (len == DLE) {
  2259. if (lexer->inbuffer[n++] != DLE)
  2260. goto not_evermore;
  2261. }
  2262. len -= 2;
  2263. crc = 0;
  2264. for (; len > 0; len--) {
  2265. crc += lexer->inbuffer[n];
  2266. if (lexer->inbuffer[n++] == DLE) {
  2267. if (lexer->inbuffer[n++] != DLE)
  2268. goto not_evermore;
  2269. }
  2270. }
  2271. checksum = lexer->inbuffer[n++];
  2272. if (checksum == DLE) {
  2273. if (lexer->inbuffer[n++] != DLE)
  2274. goto not_evermore;
  2275. }
  2276. if (lexer->inbuffer[n++] != DLE)
  2277. goto not_evermore;
  2278. /* we used to say n++ here, but scan-build complains */
  2279. if (lexer->inbuffer[n] != ETX)
  2280. goto not_evermore;
  2281. crc &= 0xff;
  2282. if (crc != checksum) {
  2283. GPSD_LOG(LOG_IO, &lexer->errout,
  2284. "EverMore checksum failed: %02x != %02x\n",
  2285. crc, checksum);
  2286. goto not_evermore;
  2287. }
  2288. packet_accept(lexer, EVERMORE_PACKET);
  2289. packet_discard(lexer);
  2290. break;
  2291. not_evermore:
  2292. packet_accept(lexer, BAD_PACKET);
  2293. lexer->state = GROUND_STATE;
  2294. packet_discard(lexer);
  2295. break;
  2296. }
  2297. #endif /* EVERMORE_ENABLE */
  2298. /* XXX CSK */
  2299. #ifdef ITRAX_ENABLE
  2300. #define getib(j) ((uint8_t)lexer->inbuffer[(j)])
  2301. #define getiw(i) ((uint16_t)(((uint16_t)getib((i)+1) << 8) | (uint16_t)getib((i))))
  2302. else if (lexer->state == ITALK_RECOGNIZED) {
  2303. volatile uint16_t len, n, csum, xsum;
  2304. /* number of words */
  2305. len = (uint16_t) (lexer->inbuffer[6] & 0xff);
  2306. /* expected checksum */
  2307. xsum = getiw(7 + 2 * len);
  2308. csum = 0;
  2309. for (n = 0; n < len; n++) {
  2310. volatile uint16_t tmpw = getiw(7 + 2 * n);
  2311. volatile uint32_t tmpdw = (csum + 1) * (tmpw + n);
  2312. csum ^= (tmpdw & 0xffff) ^ ((tmpdw >> 16) & 0xffff);
  2313. }
  2314. if (len == 0 || csum == xsum)
  2315. packet_accept(lexer, ITALK_PACKET);
  2316. else {
  2317. GPSD_LOG(LOG_IO, &lexer->errout,
  2318. "ITALK: checksum failed - "
  2319. "type 0x%02x expected 0x%04x got 0x%04x\n",
  2320. lexer->inbuffer[4], xsum, csum);
  2321. packet_accept(lexer, BAD_PACKET);
  2322. lexer->state = GROUND_STATE;
  2323. }
  2324. packet_discard(lexer);
  2325. break;
  2326. }
  2327. #undef getiw
  2328. #undef getib
  2329. #endif /* ITRAX_ENABLE */
  2330. #ifdef NAVCOM_ENABLE
  2331. else if (lexer->state == NAVCOM_RECOGNIZED) {
  2332. /* By the time we got here we know checksum is OK */
  2333. packet_accept(lexer, NAVCOM_PACKET);
  2334. packet_discard(lexer);
  2335. break;
  2336. }
  2337. #endif /* NAVCOM_ENABLE */
  2338. #ifdef GEOSTAR_ENABLE
  2339. else if (lexer->state == GEOSTAR_RECOGNIZED) {
  2340. /* GeoStar uses a XOR 32bit checksum */
  2341. int n, len;
  2342. unsigned int cs = 0L;
  2343. len = lexer->inbufptr - lexer->inbuffer;
  2344. /* Calculate checksum */
  2345. for (n = 0; n < len; n += 4) {
  2346. cs ^= getleu32(lexer->inbuffer, n);
  2347. }
  2348. if (cs == 0)
  2349. packet_accept(lexer, GEOSTAR_PACKET);
  2350. else {
  2351. GPSD_LOG(LOG_IO, &lexer->errout,
  2352. "GeoStar checksum failed 0x%x over length %d\n",
  2353. cs, len);
  2354. packet_accept(lexer, BAD_PACKET);
  2355. lexer->state = GROUND_STATE;
  2356. }
  2357. packet_discard(lexer);
  2358. break;
  2359. }
  2360. #endif /* GEOSTAR_ENABLE */
  2361. #ifdef GREIS_ENABLE
  2362. else if (lexer->state == GREIS_RECOGNIZED) {
  2363. int len = lexer->inbufptr - lexer->inbuffer;
  2364. if (lexer->inbuffer[0] == 'R' && lexer->inbuffer[1] == 'E') {
  2365. /* Replies don't have checksum */
  2366. GPSD_LOG(LOG_IO, &lexer->errout,
  2367. "Accept GREIS reply packet len %d\n", len);
  2368. packet_accept(lexer, GREIS_PACKET);
  2369. } else if (lexer->inbuffer[0] == 'E' && lexer->inbuffer[1] == 'R') {
  2370. /* Error messages don't have checksum */
  2371. GPSD_LOG(LOG_IO, &lexer->errout,
  2372. "Accept GREIS error packet len %d\n", len);
  2373. packet_accept(lexer, GREIS_PACKET);
  2374. } else {
  2375. unsigned char expected_cs = lexer->inbuffer[len - 1];
  2376. unsigned char cs = greis_checksum(lexer->inbuffer, len - 1);
  2377. if (cs == expected_cs) {
  2378. GPSD_LOG(LOG_IO, &lexer->errout,
  2379. "Accept GREIS packet type '%c%c' len %d\n",
  2380. lexer->inbuffer[0], lexer->inbuffer[1], len);
  2381. packet_accept(lexer, GREIS_PACKET);
  2382. } else {
  2383. /*
  2384. * Print hex instead of raw characters, since they might be
  2385. * unprintable. If \0, it will even mess up the log output.
  2386. */
  2387. GPSD_LOG(LOG_IO, &lexer->errout,
  2388. "REJECT GREIS len %d."
  2389. " Bad checksum %#02x, expecting %#02x."
  2390. " Packet type in hex: 0x%02x%02x",
  2391. len, cs, expected_cs, lexer->inbuffer[0],
  2392. lexer->inbuffer[1]);
  2393. packet_accept(lexer, BAD_PACKET);
  2394. /* got this far, fair to expect we will get more GREIS */
  2395. lexer->state = GREIS_EXPECTED;
  2396. }
  2397. }
  2398. packet_discard(lexer);
  2399. break;
  2400. }
  2401. #endif /* GREIS_ENABLE */
  2402. #ifdef RTCM104V2_ENABLE
  2403. else if (lexer->state == RTCM2_RECOGNIZED) {
  2404. /*
  2405. * RTCM packets don't have checksums. The six bits of parity
  2406. * per word and the preamble better be good enough.
  2407. */
  2408. packet_accept(lexer, RTCM2_PACKET);
  2409. packet_discard(lexer);
  2410. break;
  2411. }
  2412. #endif /* RTCM104V2_ENABLE */
  2413. #ifdef GARMINTXT_ENABLE
  2414. else if (lexer->state == GTXT_RECOGNIZED) {
  2415. size_t packetlen = lexer->inbufptr - lexer->inbuffer;
  2416. if (57 <= packetlen) {
  2417. packet_accept(lexer, GARMINTXT_PACKET);
  2418. packet_discard(lexer);
  2419. lexer->state = GROUND_STATE;
  2420. break;
  2421. } else {
  2422. packet_accept(lexer, BAD_PACKET);
  2423. lexer->state = GROUND_STATE;
  2424. }
  2425. }
  2426. #endif
  2427. #ifdef PASSTHROUGH_ENABLE
  2428. else if (lexer->state == JSON_RECOGNIZED) {
  2429. size_t packetlen = lexer->inbufptr - lexer->inbuffer;
  2430. if (packetlen >= 11)
  2431. /* {"class": } */
  2432. packet_accept(lexer, JSON_PACKET);
  2433. else
  2434. packet_accept(lexer, BAD_PACKET);
  2435. packet_discard(lexer);
  2436. lexer->state = GROUND_STATE;
  2437. break;
  2438. }
  2439. #endif /* PASSTHROUGH_ENABLE */
  2440. #ifdef STASH_ENABLE
  2441. else if (lexer->state == STASH_RECOGNIZED) {
  2442. packet_stash(lexer);
  2443. packet_discard(lexer);
  2444. }
  2445. #endif /* STASH_ENABLE */
  2446. } /* while */
  2447. }
  2448. #undef getword
  2449. ssize_t packet_get(int fd, struct gps_lexer_t *lexer)
  2450. /* grab a packet; return -1=>I/O error, 0=>EOF, or a length */
  2451. {
  2452. ssize_t recvd;
  2453. errno = 0;
  2454. /* O_NONBLOCK set, so this should not block.
  2455. * Best not to block on an unresponsive GNSS receiver */
  2456. recvd = read(fd, lexer->inbuffer + lexer->inbuflen,
  2457. sizeof(lexer->inbuffer) - (lexer->inbuflen));
  2458. if (recvd == -1) {
  2459. if ((errno == EAGAIN) || (errno == EINTR)) {
  2460. GPSD_LOG(LOG_RAW + 2, &lexer->errout, "no bytes ready\n");
  2461. recvd = 0;
  2462. /* fall through, input buffer may be nonempty */
  2463. } else {
  2464. GPSD_LOG(LOG_RAW + 2, &lexer->errout,
  2465. "errno: %s\n", strerror(errno));
  2466. return -1;
  2467. }
  2468. } else {
  2469. if (lexer->errout.debug >= LOG_RAW + 1) {
  2470. char scratchbuf[MAX_PACKET_LENGTH*4+1];
  2471. GPSD_LOG(LOG_RAW + 1, &lexer->errout,
  2472. "Read %zd chars to buffer offset %zd (total %zd): %s\n",
  2473. recvd, lexer->inbuflen, lexer->inbuflen + recvd,
  2474. gpsd_packetdump(scratchbuf, sizeof(scratchbuf),
  2475. (char *)lexer->inbufptr, (size_t) recvd));
  2476. }
  2477. lexer->inbuflen += recvd;
  2478. }
  2479. GPSD_LOG(LOG_SPIN, &lexer->errout,
  2480. "packet_get() fd %d -> %zd (%d)\n",
  2481. fd, recvd, errno);
  2482. /*
  2483. * Bail out, indicating no more input, only if we just received
  2484. * nothing from the device and there is nothing waiting in the
  2485. * packet input buffer.
  2486. */
  2487. if (recvd <= 0 && packet_buffered_input(lexer) <= 0)
  2488. return recvd;
  2489. /* Otherwise, consume from the packet input buffer */
  2490. /* coverity[tainted_data] */
  2491. packet_parse(lexer);
  2492. /* if input buffer is full, discard */
  2493. if (sizeof(lexer->inbuffer) == (lexer->inbuflen)) {
  2494. /* coverity[tainted_data] */
  2495. packet_discard(lexer);
  2496. lexer->state = GROUND_STATE;
  2497. }
  2498. /*
  2499. * If we gathered a packet, return its length; it will have been
  2500. * consumed out of the input buffer and moved to the output
  2501. * buffer. We don't care whether the read() returned 0 or -1 and
  2502. * gathered packet data was all buffered or whether it was partly
  2503. * just physically read.
  2504. *
  2505. * Note: this choice greatly simplifies life for callers of
  2506. * packet_get(), but means that they cannot tell when a nonzero
  2507. * return means there was a successful physical read. They will
  2508. * thus credit a data source that drops out with being alive
  2509. * slightly longer than it actually was. This is unlikely to
  2510. * matter as long as any policy timeouts are large compared to
  2511. * the time required to consume the greatest possible amount
  2512. * of buffered input, but if you hack this code you need to
  2513. * be aware of the issue. It might also slightly affect
  2514. * performance profiling.
  2515. */
  2516. if (lexer->outbuflen > 0)
  2517. return (ssize_t) lexer->outbuflen;
  2518. else
  2519. /*
  2520. * Otherwise recvd is the size of whatever packet fragment we got.
  2521. * It can still be 0 or -1 at this point even if buffer data
  2522. * was consumed.
  2523. */
  2524. return recvd;
  2525. }
  2526. void packet_reset(struct gps_lexer_t *lexer)
  2527. /* return the packet machine to the ground state */
  2528. {
  2529. lexer->type = BAD_PACKET;
  2530. lexer->state = GROUND_STATE;
  2531. lexer->inbuflen = 0;
  2532. lexer->inbufptr = lexer->inbuffer;
  2533. #ifdef BINARY_ENABLE
  2534. isgps_init(lexer);
  2535. #endif /* BINARY_ENABLE */
  2536. #ifdef STASH_ENABLE
  2537. lexer->stashbuflen = 0;
  2538. #endif /* STASH_ENABLE */
  2539. }
  2540. #ifdef __UNUSED__
  2541. void packet_pushback(struct gps_lexer_t *lexer)
  2542. /* push back the last packet grabbed */
  2543. {
  2544. if (lexer->outbuflen + lexer->inbuflen < MAX_PACKET_LENGTH) {
  2545. memmove(lexer->inbuffer + lexer->outbuflen,
  2546. lexer->inbuffer, lexer->inbuflen);
  2547. memmove(lexer->inbuffer, lexer->outbuffer, lexer->outbuflen);
  2548. lexer->inbuflen += lexer->outbuflen;
  2549. lexer->inbufptr += lexer->outbuflen;
  2550. lexer->outbuflen = 0;
  2551. }
  2552. }
  2553. #endif /* __UNUSED */