packet.c 94 KB

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