1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620 |
- #include "gpsd_config.h"
- #include <sys/types.h>
- #include <stdio.h>
- #include <stdbool.h>
- #include <ctype.h>
- #include <string.h>
- #include <errno.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <unistd.h>
- #include "bits.h"
- #include "driver_greis.h"
- #include "gpsd.h"
- #include "crc24q.h"
- #include "strfuncs.h"
- enum
- {
- #include "packet_states.h"
- };
- static char *state_table[] = {
- #include "packet_names.h"
- };
- #define SOH (unsigned char)0x01
- #define DLE (unsigned char)0x10
- #define STX (unsigned char)0x02
- #define ETX (unsigned char)0x03
- #if defined(TSIP_ENABLE)
- #define TSIP_MAX_PACKET 255
- #endif
- #ifdef ONCORE_ENABLE
- static size_t oncore_payload_cksum_length(unsigned char id1, unsigned char id2)
- {
- size_t l;
-
- #define ONCTYPE(id2,id3) ((((unsigned int)id2)<<8)|(id3))
- /* *INDENT-OFF* */
- switch (ONCTYPE(id1,id2)) {
- case ONCTYPE('A','b'): l = 10; break; /* GMT offset */
- case ONCTYPE('A','w'): l = 8; break; /* time mode */
- case ONCTYPE('A','c'): l = 11; break; /* date */
- case ONCTYPE('A','a'): l = 10; break; /* time of day */
- case ONCTYPE('A','d'): l = 11; break; /* latitude */
- case ONCTYPE('A','e'): l = 11; break; /* longitude */
- case ONCTYPE('A','f'): l = 15; break; /* height */
- case ONCTYPE('E','a'): l = 76; break; /* position/status/data */
- case ONCTYPE('A','g'): l = 8; break; /* satellite mask angle */
- case ONCTYPE('B','b'): l = 92; break; /* visible satellites status */
- case ONCTYPE('B','j'): l = 8; break; /* leap seconds pending */
- case ONCTYPE('A','q'): l = 8; break; /* atmospheric correction mode */
- case ONCTYPE('A','p'): l = 25; break; /* set user datum / select datum */
- /* Command "Ao" gives "Ap" response (select datum) */
- case ONCTYPE('C','h'): l = 9; break; /* almanac input ("Cb" response) */
- case ONCTYPE('C','b'): l = 33; break; /* almanac output ("Be" response) */
- case ONCTYPE('S','z'): l = 8; break; /* system power-on failure */
- case ONCTYPE('C','j'): l = 294; break; /* receiver ID */
- case ONCTYPE('F','a'): l = 9; break; /* self-test */
- case ONCTYPE('C','f'): l = 7; break; /* set-to-defaults */
- case ONCTYPE('E','q'): l = 96; break; /* ASCII position */
- case ONCTYPE('A','u'): l = 12; break; /* altitide hold height */
- case ONCTYPE('A','v'): l = 8; break; /* altitude hold mode */
- case ONCTYPE('A','N'): l = 8; break; /* velocity filter */
- case ONCTYPE('A','O'): l = 8; break; /* RTCM report mode */
- case ONCTYPE('C','c'): l = 80; break; /* ephemeris data input ("Bf") */
- case ONCTYPE('C','k'): l = 7; break; /* pseudorng correction inp. ("Ce")*/
- /* Command "Ci" (switch to NMEA, GT versions only) has no response */
- case ONCTYPE('B','o'): l = 8; break; /* UTC offset status */
- case ONCTYPE('A','z'): l = 11; break; /* 1PPS cable delay */
- case ONCTYPE('A','y'): l = 11; break; /* 1PPS offset */
- case ONCTYPE('A','P'): l = 8; break; /* pulse mode */
- case ONCTYPE('A','s'): l = 20; break; /* position-hold position */
- case ONCTYPE('A','t'): l = 8; break; /* position-hold mode */
- case ONCTYPE('E','n'): l = 69; break; /* time RAIM setup and status */
- default:
- return 0;
- }
- /* *INDENT-ON* */
- return l - 6; /* Subtract header and trailer. */
- }
- #endif /* ONCORE_ENABLE */
- #ifdef GREIS_ENABLE
- static unsigned long greis_hex2bin(char c)
- /* Convert hex char to binary form. Requires that c be a hex char. */
- {
- if ((c >= 'a') && (c <= 'f'))
- c = c + 10 - 'a';
- else if ((c >= 'A') && (c <= 'F'))
- c = c + 10 - 'A';
- else if ((c >= '0') && (c <= '9'))
- c -= '0';
- return c;
- }
- #endif /* GREIS_ENABLE */
- static bool character_pushback(struct gps_lexer_t *lexer, unsigned int newstate)
- /* push back the last character grabbed, setting a specified state */
- {
- --lexer->inbufptr;
- --lexer->char_counter;
- lexer->state = newstate;
- if (lexer->errout.debug >= LOG_RAW + 2)
- {
- unsigned char c = *lexer->inbufptr;
- GPSD_LOG(LOG_RAW + 2, &lexer->errout,
- "%08ld: character '%c' [%02x] pushed back, state set to %s\n",
- lexer->char_counter,
- (isprint((int)c) ? c : '.'), c,
- state_table[lexer->state]);
- }
- return false;
- }
- static void character_discard(struct gps_lexer_t *lexer)
- {
- memmove(lexer->inbuffer, lexer->inbuffer + 1, (size_t)-- lexer->inbuflen);
- lexer->inbufptr = lexer->inbuffer;
- if (lexer->errout.debug >= LOG_RAW + 1) {
- char scratchbuf[MAX_PACKET_LENGTH*4+1];
- GPSD_LOG(LOG_RAW + 1, &lexer->errout,
- "Character discarded, buffer %zu chars = %s\n",
- lexer->inbuflen,
- gpsd_packetdump(scratchbuf, sizeof(scratchbuf),
- (char *)lexer->inbuffer, lexer->inbuflen));
- }
- }
- static bool nextstate(struct gps_lexer_t *lexer, unsigned char c)
- {
- static int n = 0;
- #ifdef RTCM104V2_ENABLE
- enum isgpsstat_t isgpsstat;
- #endif
- #ifdef SUPERSTAR2_ENABLE
- static unsigned char ctmp;
- #endif
- n++;
- switch (lexer->state) {
- case GROUND_STATE:
- n = 0;
- #ifdef STASH_ENABLE
- lexer->stashbuflen = 0;
- #endif
- if (c == '#') {
- lexer->state = COMMENT_BODY;
- break;
- }
- #ifdef NMEA0183_ENABLE
- if (c == '$') {
- lexer->state = NMEA_DOLLAR;
- break;
- }
- if (c == '!') {
- lexer->state = NMEA_BANG;
- break;
- }
- #endif
- #if defined(TNT_ENABLE) || defined(GARMINTXT_ENABLE) || defined(ONCORE_ENABLE)
- if (c == '@') {
- #ifdef RTCM104V2_ENABLE
- if (rtcm2_decode(lexer, c) == ISGPS_MESSAGE) {
- lexer->state = RTCM2_RECOGNIZED;
- break;
- }
- #endif
- lexer->state = AT1_LEADER;
- break;
- }
- #endif
- #if defined(SIRF_ENABLE) || defined(SKYTRAQ_ENABLE)
- if (c == 0xa0) {
- lexer->state = SIRF_LEADER_1;
- break;
- }
- #endif
- #ifdef SUPERSTAR2_ENABLE
- if (c == SOH) {
- lexer->state = SUPERSTAR2_LEADER;
- break;
- }
- #endif
- #if defined(TSIP_ENABLE) || defined(EVERMORE_ENABLE) || defined(GARMIN_ENABLE)
- if (c == DLE) {
- lexer->state = DLE_LEADER;
- break;
- }
- #endif
- #ifdef TRIPMATE_ENABLE
- if (c == 'A') {
- #ifdef RTCM104V2_ENABLE
- if (rtcm2_decode(lexer, c) == ISGPS_MESSAGE) {
- lexer->state = RTCM2_RECOGNIZED;
- break;
- }
- #endif
- lexer->state = ASTRAL_1;
- break;
- }
- #endif
- #ifdef EARTHMATE_ENABLE
- if (c == 'E') {
- #ifdef RTCM104V2_ENABLE
- if (rtcm2_decode(lexer, c) == ISGPS_MESSAGE) {
- lexer->state = RTCM2_RECOGNIZED;
- break;
- }
- #endif
- lexer->state = EARTHA_1;
- break;
- }
- #endif
- #ifdef ZODIAC_ENABLE
- if (c == 0xff) {
- lexer->state = ZODIAC_LEADER_1;
- break;
- }
- #endif
- #ifdef UBLOX_ENABLE
- if (c == 0xb5) {
- lexer->state = UBX_LEADER_1;
- break;
- }
- #endif
- #ifdef ITRAX_ENABLE
- if (c == '<') {
- lexer->state = ITALK_LEADER_1;
- break;
- }
- #endif
- #ifdef NAVCOM_ENABLE
- if (c == 0x02) {
- lexer->state = NAVCOM_LEADER_1;
- break;
- }
- #endif
- #ifdef GEOSTAR_ENABLE
- if (c == 'P') {
- lexer->state = GEOSTAR_LEADER_1;
- break;
- }
- #endif
- #ifdef GREIS_ENABLE
- if (c == 'R') {
- lexer->state = GREIS_REPLY_1;
- break;
- }
-
- if (c == '~') {
- lexer->state = GREIS_ID_1;
- break;
- }
- #endif
- #ifdef RTCM104V2_ENABLE
- if ((isgpsstat = rtcm2_decode(lexer, c)) == ISGPS_SYNC) {
- lexer->state = RTCM2_SYNC_STATE;
- break;
- } else if (isgpsstat == ISGPS_MESSAGE) {
- lexer->state = RTCM2_RECOGNIZED;
- break;
- }
- #endif
- #ifdef RTCM104V3_ENABLE
- if (c == 0xD3) {
- lexer->state = RTCM3_LEADER_1;
- break;
- }
- #endif
- #ifdef PASSTHROUGH_ENABLE
- if (c == '{')
- return character_pushback(lexer, JSON_LEADER);
- #endif
- break;
- case COMMENT_BODY:
- if (c == '\n')
- lexer->state = COMMENT_RECOGNIZED;
- else if (!isprint(c))
- return character_pushback(lexer, GROUND_STATE);
- break;
- #ifdef NMEA0183_ENABLE
- case NMEA_DOLLAR:
- if (c == 'G')
- lexer->state = NMEA_PUB_LEAD;
- else if (c == 'P')
- lexer->state = NMEA_VENDOR_LEAD;
- else if (c == 'I')
- lexer->state = SEATALK_LEAD_1;
- else if (c == 'W')
- lexer->state = WEATHER_LEAD_1;
- else if (c == 'H')
- lexer->state = HEADCOMP_LEAD_1;
- else if (c == 'T')
- lexer->state = TURN_LEAD_1;
- else if (c == 'A')
- lexer->state = SIRF_ACK_LEAD_1;
- else if (c == 'E')
- lexer->state = ECDIS_LEAD_1;
- else if (c == 'S')
- lexer->state = SOUNDER_LEAD_1;
- else if (c == 'Y')
- lexer->state = TRANSDUCER_LEAD_1;
- else if (c == 'B')
- lexer->state = BEIDOU_LEAD_1;
- else if (c == 'Q') {
- lexer->state = QZSS_LEAD_1;
- #ifdef OCEANSERVER_ENABLE
- } else if (c == 'C') {
-
- lexer->state = NMEA_LEADER_END;
- } else if (c == 'O') {
-
- lexer->state = NMEA_LEADER_END;
- #endif
- } else {
- (void) character_pushback(lexer, GROUND_STATE);
- }
- break;
- case NMEA_PUB_LEAD:
-
- if (c == 'B' || c == 'P' || c == 'N' || c == 'L' || c == 'A')
- lexer->state = NMEA_LEADER_END;
- else
- (void) character_pushback(lexer, GROUND_STATE);
- break;
- case NMEA_VENDOR_LEAD:
- if (c == 'A')
- lexer->state = NMEA_PASHR_A;
- else if (isalpha(c))
- lexer->state = NMEA_LEADER_END;
- else
- (void) character_pushback(lexer, GROUND_STATE);
- break;
-
- case NMEA_PASHR_A:
- if (c == 'S')
- lexer->state = NMEA_PASHR_S;
- else if (isalpha(c))
- lexer->state = NMEA_LEADER_END;
- else
- (void) character_pushback(lexer, GROUND_STATE);
- break;
- case NMEA_PASHR_S:
- if (c == 'H')
- lexer->state = NMEA_PASHR_H;
- else if (isalpha(c))
- lexer->state = NMEA_LEADER_END;
- else
- (void) character_pushback(lexer, GROUND_STATE);
- break;
- case NMEA_PASHR_H:
- if (c == 'R')
- lexer->state = NMEA_BINARY_BODY;
- else if (isalpha(c))
- lexer->state = NMEA_LEADER_END;
- else
- (void) character_pushback(lexer, GROUND_STATE);
- break;
- case NMEA_BINARY_BODY:
- if (c == '\r')
- lexer->state = NMEA_BINARY_CR;
- break;
- case NMEA_BINARY_CR:
- if (c == '\n')
- lexer->state = NMEA_BINARY_NL;
- else
- lexer->state = NMEA_BINARY_BODY;
- break;
- case NMEA_BINARY_NL:
- if (c == '$')
- (void) character_pushback(lexer, NMEA_RECOGNIZED);
- else
- lexer->state = NMEA_BINARY_BODY;
- break;
- case NMEA_BANG:
- if (c == 'A')
- lexer->state = AIS_LEAD_1;
- else if (c == 'B')
- lexer->state = AIS_LEAD_ALT1;
- else if (c == 'S')
- lexer->state = AIS_LEAD_ALT3;
- else
- return character_pushback(lexer, GROUND_STATE);
- break;
- case AIS_LEAD_1:
- if (strchr("BDINRSTX", c) != NULL)
- lexer->state = AIS_LEAD_2;
- else
- return character_pushback(lexer, GROUND_STATE);
- break;
- case AIS_LEAD_2:
- if (isalpha(c))
- lexer->state = NMEA_LEADER_END;
- else
- return character_pushback(lexer, GROUND_STATE);
- break;
- case AIS_LEAD_ALT1:
- if (c == 'S')
- lexer->state = AIS_LEAD_ALT2;
- else
- return character_pushback(lexer, GROUND_STATE);
- break;
- case AIS_LEAD_ALT2:
- if (isalpha(c))
- lexer->state = NMEA_LEADER_END;
- else
- return character_pushback(lexer, GROUND_STATE);
- break;
- case AIS_LEAD_ALT3:
- if (c == 'A')
- lexer->state = AIS_LEAD_ALT4;
- else
- return character_pushback(lexer, GROUND_STATE);
- break;
- case AIS_LEAD_ALT4:
- if (isalpha(c))
- lexer->state = NMEA_LEADER_END;
- else
- return character_pushback(lexer, GROUND_STATE);
- break;
- #if defined(TNT_ENABLE) || defined(GARMINTXT_ENABLE) || defined(ONCORE_ENABLE)
- case AT1_LEADER:
- switch (c) {
- #ifdef ONCORE_ENABLE
- case '@':
- lexer->state = ONCORE_AT2;
- break;
- #endif
- #ifdef TNT_ENABLE
- case '*':
-
- lexer->state = NMEA_LEADER_END;
- break;
- #endif
- #if defined(GARMINTXT_ENABLE)
- case '\r':
-
-
- lexer->state = AT1_LEADER;
- break;
- case '\n':
-
- lexer->state = GTXT_RECOGNIZED;
- break;
- #endif
- default:
- if (!isprint(c))
- return character_pushback(lexer, GROUND_STATE);
- }
- break;
- #endif
- case NMEA_LEADER_END:
- if (c == '\r')
- lexer->state = NMEA_CR;
- else if (c == '\n')
-
- lexer->state = NMEA_RECOGNIZED;
- else if (c == '$') {
- #ifdef STASH_ENABLE
- (void) character_pushback(lexer, STASH_RECOGNIZED);
- #else
- (void) character_pushback(lexer, GROUND_STATE);
- #endif
- } else if (!isprint(c))
- (void) character_pushback(lexer, GROUND_STATE);
- break;
- case NMEA_CR:
- if (c == '\n')
- lexer->state = NMEA_RECOGNIZED;
-
- else if (c == '\r')
- lexer->state = NMEA_CR;
- else
- (void) character_pushback(lexer, GROUND_STATE);
- break;
- case NMEA_RECOGNIZED:
- if (c == '#')
- lexer->state = COMMENT_BODY;
- else if (c == '$')
- lexer->state = NMEA_DOLLAR;
- else if (c == '!')
- lexer->state = NMEA_BANG;
- #ifdef UBLOX_ENABLE
- else if (c == 0xb5)
- lexer->state = UBX_LEADER_1;
- #endif
- #ifdef PASSTHROUGH_ENABLE
- else if (c == '{')
- return character_pushback(lexer, JSON_LEADER);
- #endif
- else
- return character_pushback(lexer, GROUND_STATE);
- break;
- case SEATALK_LEAD_1:
- if (c == 'I' || c == 'N')
- lexer->state = NMEA_LEADER_END;
- else
- return character_pushback(lexer, GROUND_STATE);
- break;
- case WEATHER_LEAD_1:
- if (c == 'I')
- lexer->state = NMEA_LEADER_END;
- else
- return character_pushback(lexer, GROUND_STATE);
- break;
- case HEADCOMP_LEAD_1:
- if (c == 'C')
- lexer->state = NMEA_LEADER_END;
- else
- return character_pushback(lexer, GROUND_STATE);
- break;
- case TURN_LEAD_1:
- if (c == 'I')
- lexer->state = NMEA_LEADER_END;
- else
- return character_pushback(lexer, GROUND_STATE);
- break;
- case ECDIS_LEAD_1:
- if (c == 'C')
- lexer->state = NMEA_LEADER_END;
- else
- return character_pushback(lexer, GROUND_STATE);
- break;
- case SOUNDER_LEAD_1:
- if (c == 'D')
- lexer->state = NMEA_LEADER_END;
- #ifdef SKYTRAQ_ENABLE
- else if (c == 'T')
- lexer->state = NMEA_LEADER_END;
- #endif
- else
- return character_pushback(lexer, GROUND_STATE);
- break;
- case TRANSDUCER_LEAD_1:
- if (c == 'X')
- lexer->state = NMEA_LEADER_END;
- else
- return character_pushback(lexer, GROUND_STATE);
- break;
- case BEIDOU_LEAD_1:
- if (c == 'D')
- lexer->state = NMEA_LEADER_END;
- else
- return character_pushback(lexer, GROUND_STATE);
- break;
- case QZSS_LEAD_1:
- if (c == 'Z')
- lexer->state = NMEA_LEADER_END;
- else
- return character_pushback(lexer, GROUND_STATE);
- break;
- #ifdef TRIPMATE_ENABLE
- case ASTRAL_1:
- if (c == 'S') {
- #ifdef RTCM104V2_ENABLE
- if ((isgpsstat = rtcm2_decode(lexer, c)) == ISGPS_SYNC) {
- lexer->state = RTCM2_SYNC_STATE;
- break;
- } else if (isgpsstat == ISGPS_MESSAGE) {
- lexer->state = RTCM2_RECOGNIZED;
- break;
- }
- #endif
- lexer->state = ASTRAL_2;
- } else
- (void) character_pushback(lexer, GROUND_STATE);
- break;
- case ASTRAL_2:
- if (c == 'T') {
- #ifdef RTCM104V2_ENABLE
- if ((isgpsstat = rtcm2_decode(lexer, c)) == ISGPS_SYNC) {
- lexer->state = RTCM2_SYNC_STATE;
- break;
- } else if (isgpsstat == ISGPS_MESSAGE) {
- lexer->state = RTCM2_RECOGNIZED;
- break;
- }
- #endif
- lexer->state = ASTRAL_3;
- } else
- (void) character_pushback(lexer, GROUND_STATE);
- break;
- case ASTRAL_3:
- if (c == 'R') {
- #ifdef RTCM104V2_ENABLE
- if ((isgpsstat = rtcm2_decode(lexer, c)) == ISGPS_SYNC) {
- lexer->state = RTCM2_SYNC_STATE;
- break;
- } else if (isgpsstat == ISGPS_MESSAGE) {
- lexer->state = RTCM2_RECOGNIZED;
- break;
- }
- #endif
- lexer->state = ASTRAL_5;
- } else
- (void) character_pushback(lexer, GROUND_STATE);
- break;
- case ASTRAL_4:
- if (c == 'A') {
- #ifdef RTCM104V2_ENABLE
- if ((isgpsstat = rtcm2_decode(lexer, c)) == ISGPS_SYNC) {
- lexer->state = RTCM2_SYNC_STATE;
- break;
- } else if (isgpsstat == ISGPS_MESSAGE) {
- lexer->state = RTCM2_RECOGNIZED;
- break;
- }
- #endif
- lexer->state = ASTRAL_2;
- } else
- (void) character_pushback(lexer, GROUND_STATE);
- break;
- case ASTRAL_5:
- if (c == 'L') {
- #ifdef RTCM104V2_ENABLE
- if ((isgpsstat = rtcm2_decode(lexer, c)) == ISGPS_SYNC) {
- lexer->state = RTCM2_SYNC_STATE;
- break;
- } else if (isgpsstat == ISGPS_MESSAGE) {
- lexer->state = RTCM2_RECOGNIZED;
- break;
- }
- #endif
- lexer->state = NMEA_RECOGNIZED;
- } else
- (void) character_pushback(lexer, GROUND_STATE);
- break;
- #endif
- #ifdef EARTHMATE_ENABLE
- case EARTHA_1:
- if (c == 'A') {
- #ifdef RTCM104V2_ENABLE
- if ((isgpsstat = rtcm2_decode(lexer, c)) == ISGPS_SYNC) {
- lexer->state = RTCM2_SYNC_STATE;
- break;
- } else if (isgpsstat == ISGPS_MESSAGE) {
- lexer->state = RTCM2_RECOGNIZED;
- break;
- }
- #endif
- lexer->state = EARTHA_2;
- } else
- (void) character_pushback(lexer, GROUND_STATE);
- break;
- case EARTHA_2:
- if (c == 'R') {
- #ifdef RTCM104V2_ENABLE
- if ((isgpsstat = rtcm2_decode(lexer, c)) == ISGPS_SYNC) {
- lexer->state = RTCM2_SYNC_STATE;
- break;
- } else if (isgpsstat == ISGPS_MESSAGE) {
- lexer->state = RTCM2_RECOGNIZED;
- break;
- }
- #endif
- lexer->state = EARTHA_3;
- } else
- (void) character_pushback(lexer, GROUND_STATE);
- break;
- case EARTHA_3:
- if (c == 'T') {
- #ifdef RTCM104V2_ENABLE
- if ((isgpsstat = rtcm2_decode(lexer, c)) == ISGPS_SYNC) {
- lexer->state = RTCM2_SYNC_STATE;
- break;
- } else if (isgpsstat == ISGPS_MESSAGE) {
- lexer->state = RTCM2_RECOGNIZED;
- break;
- }
- #endif
- lexer->state = EARTHA_4;
- } else
- (void) character_pushback(lexer, GROUND_STATE);
- break;
- case EARTHA_4:
- if (c == 'H') {
- #ifdef RTCM104V2_ENABLE
- if ((isgpsstat = rtcm2_decode(lexer, c)) == ISGPS_SYNC) {
- lexer->state = RTCM2_SYNC_STATE;
- break;
- } else if (isgpsstat == ISGPS_MESSAGE) {
- lexer->state = RTCM2_RECOGNIZED;
- break;
- }
- #endif
- lexer->state = EARTHA_5;
- } else
- (void) character_pushback(lexer, GROUND_STATE);
- break;
- case EARTHA_5:
- if (c == 'A') {
- #ifdef RTCM104V2_ENABLE
- if ((isgpsstat = rtcm2_decode(lexer, c)) == ISGPS_SYNC) {
- lexer->state = RTCM2_SYNC_STATE;
- break;
- } else if (isgpsstat == ISGPS_MESSAGE) {
- lexer->state = RTCM2_RECOGNIZED;
- break;
- }
- #endif
- lexer->state = NMEA_RECOGNIZED;
- } else
- (void) character_pushback(lexer, GROUND_STATE);
- break;
- #endif
- case SIRF_ACK_LEAD_1:
- if (c == 'c')
- lexer->state = SIRF_ACK_LEAD_2;
- else if (c == 'I')
- lexer->state = AIS_LEAD_2;
- else
- return character_pushback(lexer, GROUND_STATE);
- break;
- case SIRF_ACK_LEAD_2:
- if (c == 'k')
- lexer->state = NMEA_LEADER_END;
- else
- return character_pushback(lexer, GROUND_STATE);
- break;
- #endif
- #if defined(SIRF_ENABLE) || defined(SKYTRAQ_ENABLE)
- case SIRF_LEADER_1:
- # ifdef SIRF_ENABLE
-
- if (c == 0xa2)
- lexer->state = SIRF_LEADER_2;
- else
- # endif
- # ifdef SKYTRAQ_ENABLE
-
- if (c == 0xa1)
- lexer->state = SKY_LEADER_2;
- else
- # endif
- return character_pushback(lexer, GROUND_STATE);
- break;
- #endif
- #ifdef SIRF_ENABLE
- case SIRF_LEADER_2:
- lexer->length = (size_t) (c << 8);
- lexer->state = SIRF_LENGTH_1;
- break;
- case SIRF_LENGTH_1:
- lexer->length += c + 2;
- if (lexer->length <= MAX_PACKET_LENGTH)
- lexer->state = SIRF_PAYLOAD;
- else
- return character_pushback(lexer, GROUND_STATE);
- break;
- case SIRF_PAYLOAD:
- if (--lexer->length == 0)
- lexer->state = SIRF_DELIVERED;
- break;
- case SIRF_DELIVERED:
- if (c == 0xb0)
- lexer->state = SIRF_TRAILER_1;
- else
- return character_pushback(lexer, GROUND_STATE);
- break;
- case SIRF_TRAILER_1:
- if (c == 0xb3)
- lexer->state = SIRF_RECOGNIZED;
- else
- return character_pushback(lexer, GROUND_STATE);
- break;
- case SIRF_RECOGNIZED:
- if (c == 0xa0)
- lexer->state = SIRF_LEADER_1;
- else
- return character_pushback(lexer, GROUND_STATE);
- break;
- #endif
- #ifdef SKYTRAQ_ENABLE
- case SKY_LEADER_2:
-
- lexer->length = (size_t) (c << 8);
- lexer->state = SKY_LENGTH_1;
- break;
- case SKY_LENGTH_1:
-
- lexer->length += c;
- if ( 0 == lexer->length )
- return character_pushback(lexer, GROUND_STATE);
- if (lexer->length > MAX_PACKET_LENGTH)
- return character_pushback(lexer, GROUND_STATE);
- lexer->state = SKY_PAYLOAD;
- break;
- case SKY_PAYLOAD:
- if ( 00 == --lexer->length)
- lexer->state = SKY_DELIVERED;
- break;
- case SKY_DELIVERED:
- if ( lexer->errout.debug >= LOG_RAW + 1) {
- char scratchbuf[MAX_PACKET_LENGTH*4+1];
- GPSD_LOG(LOG_RAW + 1, &lexer->errout,
- "Skytraq = %s\n",
- gpsd_packetdump(scratchbuf, sizeof(scratchbuf),
- (char *)lexer->inbuffer,
- lexer->inbufptr - (unsigned char *)lexer->inbuffer));
- }
- {
- unsigned char csum = 0;
- for (n = 4;
- (unsigned char *)(lexer->inbuffer + n) < lexer->inbufptr - 1;
- n++)
- csum ^= lexer->inbuffer[n];
- if (csum != c) {
- GPSD_LOG(LOG_IO, &lexer->errout,
- "Skytraq bad checksum 0x%hhx, expecting 0x%x\n",
- csum, c);
- lexer->state = GROUND_STATE;
- break;
- }
- }
- lexer->state = SKY_CSUM;
- break;
- case SKY_CSUM:
- if ( 0x0d != c)
- return character_pushback(lexer, GROUND_STATE);
- lexer->state = SKY_TRAILER_1;
- break;
- case SKY_TRAILER_1:
- if ( 0x0a != c)
- return character_pushback(lexer, GROUND_STATE);
- lexer->state = SKY_RECOGNIZED;
- break;
- case SKY_RECOGNIZED:
- if ( 0xa0 != c)
- return character_pushback(lexer, GROUND_STATE);
- lexer->state = SIRF_LEADER_1;
- break;
- #endif
- #ifdef SUPERSTAR2_ENABLE
- case SUPERSTAR2_LEADER:
- ctmp = c;
- lexer->state = SUPERSTAR2_ID1;
- break;
- case SUPERSTAR2_ID1:
- if ((ctmp ^ 0xff) == c)
- lexer->state = SUPERSTAR2_ID2;
- else
- return character_pushback(lexer, GROUND_STATE);
- break;
- case SUPERSTAR2_ID2:
- lexer->length = (size_t) c;
- if (lexer->length)
- lexer->state = SUPERSTAR2_PAYLOAD;
- else
- lexer->state = SUPERSTAR2_CKSUM1;
- break;
- case SUPERSTAR2_PAYLOAD:
- if (--lexer->length == 0)
- lexer->state = SUPERSTAR2_CKSUM1;
- break;
- case SUPERSTAR2_CKSUM1:
- lexer->state = SUPERSTAR2_CKSUM2;
- break;
- case SUPERSTAR2_CKSUM2:
- lexer->state = SUPERSTAR2_RECOGNIZED;
- break;
- case SUPERSTAR2_RECOGNIZED:
- if (c == SOH)
- lexer->state = SUPERSTAR2_LEADER;
- else
- return character_pushback(lexer, GROUND_STATE);
- break;
- #endif
- #ifdef ONCORE_ENABLE
- case ONCORE_AT2:
- if (isupper(c)) {
- lexer->length = (size_t) c;
- lexer->state = ONCORE_ID1;
- } else
- return character_pushback(lexer, GROUND_STATE);
- break;
- case ONCORE_ID1:
- if (isalpha(c)) {
- lexer->length =
- oncore_payload_cksum_length((unsigned char)lexer->length, c);
- if (lexer->length != 0) {
- lexer->state = ONCORE_PAYLOAD;
- break;
- }
- } else
- return character_pushback(lexer, GROUND_STATE);
- break;
- case ONCORE_PAYLOAD:
- if (--lexer->length == 0)
- lexer->state = ONCORE_CHECKSUM;
- break;
- case ONCORE_CHECKSUM:
- if (c != '\r')
- return character_pushback(lexer, GROUND_STATE);
- else
- lexer->state = ONCORE_CR;
- break;
- case ONCORE_CR:
- if (c == '\n')
- lexer->state = ONCORE_RECOGNIZED;
- else
- lexer->state = ONCORE_PAYLOAD;
- break;
- case ONCORE_RECOGNIZED:
- if (c == '@')
- lexer->state = AT1_LEADER;
- else
- return character_pushback(lexer, GROUND_STATE);
- break;
- #endif
- #if defined(TSIP_ENABLE) || defined(EVERMORE_ENABLE) || defined(GARMIN_ENABLE)
- case DLE_LEADER:
- #ifdef EVERMORE_ENABLE
- if (c == STX) {
- lexer->state = EVERMORE_LEADER_2;
- break;
- }
- #endif
- #if defined(TSIP_ENABLE) || defined(GARMIN_ENABLE) || defined(NAVCOM_ENABLE)
-
-
- #if defined(TSIP_ENABLE)
- if (c >= 0x13) {
- lexer->length = TSIP_MAX_PACKET;
- lexer->state = TSIP_PAYLOAD;
- break;
- }
- #endif
- if (c == DLE) {
- lexer->state = GROUND_STATE;
- break;
- }
-
- lexer->state = GROUND_STATE;
- break;
- #endif
- #ifdef NAVCOM_ENABLE
- case NAVCOM_LEADER_1:
- if (c == 0x99)
- lexer->state = NAVCOM_LEADER_2;
- else
- return character_pushback(lexer, GROUND_STATE);
- break;
- case NAVCOM_LEADER_2:
- if (c == 0x66)
- lexer->state = NAVCOM_LEADER_3;
- else
- return character_pushback(lexer, GROUND_STATE);
- break;
- case NAVCOM_LEADER_3:
- lexer->state = NAVCOM_ID;
- break;
- case NAVCOM_ID:
- lexer->length = (size_t) c - 4;
- lexer->state = NAVCOM_LENGTH_1;
- break;
- case NAVCOM_LENGTH_1:
- lexer->length += (c << 8);
- lexer->state = NAVCOM_LENGTH_2;
- break;
- case NAVCOM_LENGTH_2:
- if (--lexer->length == 0)
- lexer->state = NAVCOM_PAYLOAD;
- break;
- case NAVCOM_PAYLOAD:
- {
- unsigned char csum = lexer->inbuffer[3];
- for (n = 4;
- (unsigned char *)(lexer->inbuffer + n) < lexer->inbufptr - 1;
- n++)
- csum ^= lexer->inbuffer[n];
- if (csum != c) {
- GPSD_LOG(LOG_IO, &lexer->errout,
- "Navcom packet type 0x%hhx bad checksum 0x%hhx, "
- "expecting 0x%x\n",
- lexer->inbuffer[3], csum, c);
- lexer->state = GROUND_STATE;
- break;
- }
- }
- lexer->state = NAVCOM_CSUM;
- break;
- case NAVCOM_CSUM:
- if (c == 0x03)
- lexer->state = NAVCOM_RECOGNIZED;
- else
- return character_pushback(lexer, GROUND_STATE);
- break;
- case NAVCOM_RECOGNIZED:
- if (c == 0x02)
- lexer->state = NAVCOM_LEADER_1;
- else
- return character_pushback(lexer, GROUND_STATE);
- break;
- #endif
- #endif
- #ifdef RTCM104V3_ENABLE
- case RTCM3_LEADER_1:
-
- if ((c & 0xFC) == 0) {
- lexer->length = (size_t) (c << 8);
- lexer->state = RTCM3_LEADER_2;
- } else
- return character_pushback(lexer, GROUND_STATE);
- break;
- case RTCM3_LEADER_2:
-
- lexer->length |= c;
- lexer->length += 3;
- lexer->state = RTCM3_PAYLOAD;
- break;
- case RTCM3_PAYLOAD:
- if (--lexer->length == 0)
- lexer->state = RTCM3_RECOGNIZED;
- break;
- #endif
- #ifdef ZODIAC_ENABLE
- case ZODIAC_EXPECTED:
- case ZODIAC_RECOGNIZED:
- if (c == 0xff)
- lexer->state = ZODIAC_LEADER_1;
- else
- return character_pushback(lexer, GROUND_STATE);
- break;
- case ZODIAC_LEADER_1:
- if (c == 0x81)
- lexer->state = ZODIAC_LEADER_2;
- else
- (void) character_pushback(lexer, GROUND_STATE);
- break;
- case ZODIAC_LEADER_2:
- lexer->state = ZODIAC_ID_1;
- break;
- case ZODIAC_ID_1:
- lexer->state = ZODIAC_ID_2;
- break;
- case ZODIAC_ID_2:
- lexer->length = (size_t) c;
- lexer->state = ZODIAC_LENGTH_1;
- break;
- case ZODIAC_LENGTH_1:
- lexer->length += (c << 8);
- lexer->state = ZODIAC_LENGTH_2;
- break;
- case ZODIAC_LENGTH_2:
- lexer->state = ZODIAC_FLAGS_1;
- break;
- case ZODIAC_FLAGS_1:
- lexer->state = ZODIAC_FLAGS_2;
- break;
- case ZODIAC_FLAGS_2:
- lexer->state = ZODIAC_HSUM_1;
- break;
- case ZODIAC_HSUM_1:
- {
- #define getword(i) (short)(lexer->inbuffer[2*(i)] | (lexer->inbuffer[2*(i)+1] << 8))
- short sum = getword(0) + getword(1) + getword(2) + getword(3);
- sum *= -1;
- if (sum != getword(4)) {
- GPSD_LOG(LOG_IO, &lexer->errout,
- "Zodiac Header checksum 0x%hx expecting 0x%hx\n",
- sum, getword(4));
- lexer->state = GROUND_STATE;
- break;
- }
- }
- GPSD_LOG(LOG_RAW + 1, &lexer->errout,
- "Zodiac header id=%hd len=%hd flags=%hx\n",
- getword(1), getword(2), getword(3));
- #undef getword
- if (lexer->length == 0) {
- lexer->state = ZODIAC_RECOGNIZED;
- break;
- }
- lexer->length *= 2;
- lexer->length += 2;
-
- if (lexer->length <= MAX_PACKET_LENGTH - 10)
- lexer->state = ZODIAC_PAYLOAD;
- else
- return character_pushback(lexer, GROUND_STATE);
- break;
- case ZODIAC_PAYLOAD:
- if (--lexer->length == 0)
- lexer->state = ZODIAC_RECOGNIZED;
- break;
- #endif
- #ifdef UBLOX_ENABLE
- case UBX_LEADER_1:
- if (c == 0x62)
- lexer->state = UBX_LEADER_2;
- else
- return character_pushback(lexer, GROUND_STATE);
- break;
- case UBX_LEADER_2:
- lexer->state = UBX_CLASS_ID;
- break;
- case UBX_CLASS_ID:
- lexer->state = UBX_MESSAGE_ID;
- break;
- case UBX_MESSAGE_ID:
- lexer->length = (size_t) c;
- lexer->state = UBX_LENGTH_1;
- break;
- case UBX_LENGTH_1:
- lexer->length += (c << 8);
- if (lexer->length <= MAX_PACKET_LENGTH)
- lexer->state = UBX_LENGTH_2;
- else
- return character_pushback(lexer, GROUND_STATE);
- break;
- case UBX_LENGTH_2:
- lexer->state = UBX_PAYLOAD;
- break;
- case UBX_PAYLOAD:
- if (--lexer->length == 0)
- lexer->state = UBX_CHECKSUM_A;
-
- break;
- case UBX_CHECKSUM_A:
- lexer->state = UBX_RECOGNIZED;
- break;
- case UBX_RECOGNIZED:
- if (c == 0xb5)
- lexer->state = UBX_LEADER_1;
- #ifdef NMEA0183_ENABLE
- else if (c == '$')
- lexer->state = NMEA_DOLLAR;
- #endif
- #ifdef PASSTHROUGH_ENABLE
- else if (c == '{')
- return character_pushback(lexer, JSON_LEADER);
- #endif
- else
- return character_pushback(lexer, GROUND_STATE);
- break;
- #endif
- #ifdef EVERMORE_ENABLE
- case EVERMORE_LEADER_1:
- if (c == STX)
- lexer->state = EVERMORE_LEADER_2;
- else
- return character_pushback(lexer, GROUND_STATE);
- break;
- case EVERMORE_LEADER_2:
- lexer->length = (size_t) c;
- if (c == DLE)
- lexer->state = EVERMORE_PAYLOAD_DLE;
- else
- lexer->state = EVERMORE_PAYLOAD;
- break;
- case EVERMORE_PAYLOAD:
- if (c == DLE)
- lexer->state = EVERMORE_PAYLOAD_DLE;
- else if (--lexer->length == 0)
- return character_pushback(lexer, GROUND_STATE);
- break;
- case EVERMORE_PAYLOAD_DLE:
- switch (c) {
- case DLE:
- lexer->state = EVERMORE_PAYLOAD;
- break;
- case ETX:
- lexer->state = EVERMORE_RECOGNIZED;
- break;
- default:
- lexer->state = GROUND_STATE;
- }
- break;
- case EVERMORE_RECOGNIZED:
- if (c == DLE)
- lexer->state = EVERMORE_LEADER_1;
- else
- return character_pushback(lexer, GROUND_STATE);
- break;
- #endif
- #ifdef ITRAX_ENABLE
- case ITALK_LEADER_1:
- if (c == '!')
- lexer->state = ITALK_LEADER_2;
- else
- return character_pushback(lexer, GROUND_STATE);
- break;
- case ITALK_LEADER_2:
- lexer->length = (size_t) (lexer->inbuffer[6] & 0xff);
- lexer->state = ITALK_LENGTH;
- break;
- case ITALK_LENGTH:
- lexer->length += 1;
- lexer->length *= 2;
- lexer->length += 3;
- lexer->state = ITALK_PAYLOAD;
- break;
- case ITALK_PAYLOAD:
-
- if ((c == '>') && (lexer->inbufptr[0] == '<') &&
- (lexer->inbufptr[1] == '!')) {
- lexer->state = ITALK_RECOGNIZED;
- GPSD_LOG(LOG_IO, &lexer->errout,
- "ITALK: trying to process runt packet\n");
- break;
- } else if (--lexer->length == 0)
- lexer->state = ITALK_DELIVERED;
- break;
- case ITALK_DELIVERED:
- if (c == '>')
- lexer->state = ITALK_RECOGNIZED;
- else
- return character_pushback(lexer, GROUND_STATE);
- break;
- case ITALK_RECOGNIZED:
- if (c == '<')
- lexer->state = ITALK_LEADER_1;
- else
- return character_pushback(lexer, GROUND_STATE);
- break;
- #endif
- #ifdef GEOSTAR_ENABLE
- case GEOSTAR_LEADER_1:
- if (c == 'S')
- lexer->state = GEOSTAR_LEADER_2;
- else
- return character_pushback(lexer, GROUND_STATE);
- break;
- case GEOSTAR_LEADER_2:
- if (c == 'G')
- lexer->state = GEOSTAR_LEADER_3;
- else
- return character_pushback(lexer, GROUND_STATE);
- break;
- case GEOSTAR_LEADER_3:
- if (c == 'G')
- lexer->state = GEOSTAR_LEADER_4;
- else
- return character_pushback(lexer, GROUND_STATE);
- break;
- case GEOSTAR_LEADER_4:
- lexer->state = GEOSTAR_MESSAGE_ID_1;
- break;
- case GEOSTAR_MESSAGE_ID_1:
- lexer->state = GEOSTAR_MESSAGE_ID_2;
- break;
- case GEOSTAR_MESSAGE_ID_2:
- lexer->length = (size_t)(c * 4);
- lexer->state = GEOSTAR_LENGTH_1;
- break;
- case GEOSTAR_LENGTH_1:
- lexer->length += (c << 8) * 4;
- if (lexer->length <= MAX_PACKET_LENGTH)
- lexer->state = GEOSTAR_LENGTH_2;
- else
- return character_pushback(lexer, GROUND_STATE);
- break;
- case GEOSTAR_LENGTH_2:
- lexer->state = GEOSTAR_PAYLOAD;
- break;
- case GEOSTAR_PAYLOAD:
- if (--lexer->length == 0)
- lexer->state = GEOSTAR_CHECKSUM_A;
-
- break;
- case GEOSTAR_CHECKSUM_A:
- lexer->state = GEOSTAR_CHECKSUM_B;
- break;
- case GEOSTAR_CHECKSUM_B:
- lexer->state = GEOSTAR_CHECKSUM_C;
- break;
- case GEOSTAR_CHECKSUM_C:
- lexer->state = GEOSTAR_RECOGNIZED;
- break;
- case GEOSTAR_RECOGNIZED:
- if (c == 'P')
- lexer->state = GEOSTAR_LEADER_1;
- else
- return character_pushback(lexer, GROUND_STATE);
- break;
- #endif
- #ifdef GREIS_ENABLE
- case GREIS_EXPECTED:
- case GREIS_RECOGNIZED:
- if (!isascii(c)) {
- return character_pushback(lexer, GROUND_STATE);
- } else if (c == '#') {
-
- lexer->state = COMMENT_BODY;
- } else if (c == '\r' || c == '\n') {
-
- lexer->state = GREIS_EXPECTED;
- character_discard(lexer);
- } else {
- lexer->state = GREIS_ID_1;
- }
- break;
- case GREIS_REPLY_1:
- if (c != 'E')
- return character_pushback(lexer, GROUND_STATE);
- lexer->state = GREIS_REPLY_2;
- break;
- case GREIS_ID_1:
- if (!isascii(c))
- return character_pushback(lexer, GROUND_STATE);
- lexer->state = GREIS_ID_2;
- break;
- case GREIS_REPLY_2:
- case GREIS_ID_2:
- if (!isxdigit(c))
- return character_pushback(lexer, GROUND_STATE);
- lexer->length = greis_hex2bin(c) << 8;
- lexer->state = GREIS_LENGTH_1;
- break;
- case GREIS_LENGTH_1:
- if (!isxdigit(c))
- return character_pushback(lexer, GROUND_STATE);
- lexer->length += greis_hex2bin(c) << 4;
- lexer->state = GREIS_LENGTH_2;
- break;
- case GREIS_LENGTH_2:
- if (!isxdigit(c))
- return character_pushback(lexer, GROUND_STATE);
- lexer->length += greis_hex2bin(c);
- lexer->state = GREIS_PAYLOAD;
- break;
- case GREIS_PAYLOAD:
- if (--lexer->length == 0)
- lexer->state = GREIS_RECOGNIZED;
-
- break;
- #endif
- #ifdef TSIP_ENABLE
- case TSIP_LEADER:
-
- if (c >= 0x13) {
- lexer->length = TSIP_MAX_PACKET;
- lexer->state = TSIP_PAYLOAD;
- } else
- return character_pushback(lexer, GROUND_STATE);
- break;
- case TSIP_PAYLOAD:
- if (c == DLE)
- lexer->state = TSIP_DLE;
- if ( 0 == --lexer->length ) {
-
-
- lexer->state = GROUND_STATE;
- }
- break;
- case TSIP_DLE:
- switch (c) {
- case ETX:
- lexer->state = TSIP_RECOGNIZED;
- break;
- case DLE:
- lexer->length = TSIP_MAX_PACKET;
- lexer->state = TSIP_PAYLOAD;
- break;
- default:
- lexer->state = GROUND_STATE;
- break;
- }
- break;
- case TSIP_RECOGNIZED:
- if (c == DLE)
-
- lexer->state = DLE_LEADER;
- else
- return character_pushback(lexer, GROUND_STATE);
- break;
- #endif
- #ifdef RTCM104V2_ENABLE
- case RTCM2_SYNC_STATE:
- case RTCM2_SKIP_STATE:
- if ((isgpsstat = rtcm2_decode(lexer, c)) == ISGPS_MESSAGE) {
- lexer->state = RTCM2_RECOGNIZED;
- break;
- } else if (isgpsstat == ISGPS_NO_SYNC)
- lexer->state = GROUND_STATE;
- break;
- case RTCM2_RECOGNIZED:
- if (c == '#')
-
- return character_pushback(lexer, GROUND_STATE);
- else if (rtcm2_decode(lexer, c) == ISGPS_SYNC) {
- lexer->state = RTCM2_SYNC_STATE;
- break;
- } else
- lexer->state = GROUND_STATE;
- break;
- #endif
- #ifdef PASSTHROUGH_ENABLE
- case JSON_LEADER:
- if (c == '{' || c == '[') {
- lexer->json_depth++;
- } else if (c == '}' || c == ']') {
- if (--lexer->json_depth == 0)
- lexer->state = JSON_RECOGNIZED;
- } else if (isspace(c) || c == ',')
- break;
- else if (c == '"') {
- lexer->state = JSON_STRINGLITERAL;
- lexer->json_after = JSON_END_ATTRIBUTE;
- } else {
- GPSD_LOG(LOG_RAW + 1, &lexer->errout,
- "%08ld: missing attribute start after header\n",
- lexer->char_counter);
- lexer->state = GROUND_STATE;
- }
- break;
- case JSON_STRINGLITERAL:
- if (c == '\\')
- lexer->state = JSON_STRING_SOLIDUS;
- else if (c == '"')
- lexer->state = lexer->json_after;
- break;
- case JSON_STRING_SOLIDUS:
- lexer->state = JSON_STRINGLITERAL;
- break;
- case JSON_END_ATTRIBUTE:
- if (isspace(c))
- break;
- else if (c == ':')
- lexer->state = JSON_EXPECT_VALUE;
- else
-
- return character_pushback(lexer, GROUND_STATE);
- break;
- case JSON_EXPECT_VALUE:
- if (isspace(c))
- break;
- else if (c == '"') {
- lexer->state = JSON_STRINGLITERAL;
- lexer->json_after = JSON_END_VALUE;
- } else if (c == '{' || c == '[') {
- return character_pushback(lexer, JSON_LEADER);
- } else if (strchr("-0123456789", c) != NULL) {
- lexer->state = JSON_NUMBER;
- } else if (c == 't' || c == 'f' || c == 'n')
-
- lexer->state = JSON_SPECIAL;
- else
-
- return character_pushback(lexer, GROUND_STATE);
- break;
- case JSON_NUMBER:
-
- if (strchr("1234567890.eE+-", c) == NULL) {
- return character_pushback(lexer, JSON_END_VALUE);
- }
- break;
- case JSON_SPECIAL:
- if (strchr("truefalsnil", c) == NULL)
- return character_pushback(lexer, JSON_END_VALUE);
- break;
- case JSON_END_VALUE:
- if (isspace(c))
- break;
- else if (c == ',')
- lexer->state = JSON_LEADER;
- else if (c == '}' || c == ']')
- return character_pushback(lexer, JSON_LEADER);
- else
-
- return character_pushback(lexer, GROUND_STATE);
- break;
- #endif
- #ifdef STASH_ENABLE
- case STASH_RECOGNIZED:
- if (c == '$')
- lexer->state = NMEA_DOLLAR;
- else
- return character_pushback(lexer, GROUND_STATE);
- break;
- #endif
- }
- return true;
- }
- static void packet_accept(struct gps_lexer_t *lexer, int packet_type)
- {
- size_t packetlen = lexer->inbufptr - lexer->inbuffer;
- if (packetlen < sizeof(lexer->outbuffer)) {
- memcpy(lexer->outbuffer, lexer->inbuffer, packetlen);
- lexer->outbuflen = packetlen;
- lexer->outbuffer[packetlen] = '\0';
- lexer->type = packet_type;
- if (lexer->errout.debug >= LOG_RAW + 1) {
- char scratchbuf[MAX_PACKET_LENGTH*4+1];
- GPSD_LOG(LOG_RAW + 1, &lexer->errout,
- "Packet type %d accepted %zu = %s\n",
- packet_type, packetlen,
- gpsd_packetdump(scratchbuf, sizeof(scratchbuf),
- (char *)lexer->outbuffer,
- lexer->outbuflen));
- }
- } else {
- GPSD_LOG(LOG_ERROR, &lexer->errout,
- "Rejected too long packet type %d len %zu\n",
- packet_type, packetlen);
- }
- }
- static void packet_discard(struct gps_lexer_t *lexer)
- {
- size_t discard = lexer->inbufptr - lexer->inbuffer;
- size_t remaining = lexer->inbuflen - discard;
- lexer->inbufptr = memmove(lexer->inbuffer, lexer->inbufptr, remaining);
- lexer->inbuflen = remaining;
- if (lexer->errout.debug >= LOG_RAW + 1) {
- char scratchbuf[MAX_PACKET_LENGTH*4+1];
- GPSD_LOG(LOG_RAW + 1, &lexer->errout,
- "Packet discard of %zu, chars remaining is %zu = %s\n",
- discard, remaining,
- gpsd_packetdump(scratchbuf, sizeof(scratchbuf),
- (char *)lexer->inbuffer, lexer->inbuflen));
- }
- }
- #ifdef STASH_ENABLE
- static void packet_stash(struct gps_lexer_t *lexer)
- {
- size_t stashlen = lexer->inbufptr - lexer->inbuffer;
- memcpy(lexer->stashbuffer, lexer->inbuffer, stashlen);
- lexer->stashbuflen = stashlen;
- if (lexer->errout.debug >= LOG_RAW+1) {
- char scratchbuf[MAX_PACKET_LENGTH*4+1];
- GPSD_LOG(LOG_RAW + 1, &lexer->errout,
- "Packet stash of %zu = %s\n",
- stashlen,
- gpsd_packetdump(scratchbuf, sizeof(scratchbuf),
- (char *)lexer->stashbuffer,
- lexer->stashbuflen));
- }
- }
- static void packet_unstash(struct gps_lexer_t *lexer)
- {
- size_t available = sizeof(lexer->inbuffer) - lexer->inbuflen;
- size_t stashlen = lexer->stashbuflen;
- if (stashlen <= available) {
- memmove(lexer->inbuffer + stashlen, lexer->inbuffer, lexer->inbuflen);
- memcpy(lexer->inbuffer, lexer->stashbuffer, stashlen);
- lexer->inbuflen += stashlen;
- lexer->stashbuflen = 0;
- if (lexer->errout.debug >= LOG_RAW+1) {
- char scratchbuf[MAX_PACKET_LENGTH*4+1];
- GPSD_LOG(LOG_RAW + 1, &lexer->errout,
- "Packet unstash of %zu, reconstructed is %zu = %s\n",
- stashlen, lexer->inbuflen,
- gpsd_packetdump(scratchbuf, sizeof(scratchbuf),
- (char *)lexer->inbuffer, lexer->inbuflen));
- }
- } else {
- GPSD_LOG(LOG_ERROR, &lexer->errout,
- "Rejected too long unstash of %zu\n", stashlen);
- lexer->stashbuflen = 0;
- }
- }
- #endif
- #define getword(i) (short)(lexer->inbuffer[2*(i)] | (lexer->inbuffer[2*(i)+1] << 8))
- /* entry points begin here */
- void lexer_init(struct gps_lexer_t *lexer)
- {
- lexer->char_counter = 0;
- lexer->retry_counter = 0;
- #ifdef PASSTHROUGH_ENABLE
- lexer->json_depth = 0;
- #endif
- lexer->start_time.tv_sec = 0;
- lexer->start_time.tv_nsec = 0;
- packet_reset(lexer);
- errout_reset(&lexer->errout);
- }
- void packet_parse(struct gps_lexer_t *lexer)
- {
- lexer->outbuflen = 0;
- while (packet_buffered_input(lexer) > 0) {
- unsigned char c = *lexer->inbufptr++;
- unsigned int oldstate = lexer->state;
- if (!nextstate(lexer, c))
- continue;
- GPSD_LOG(LOG_RAW + 2, &lexer->errout,
- "%08ld: character '%c' [%02x], %s -> %s\n",
- lexer->char_counter, (isprint(c) ? c : '.'), c,
- state_table[oldstate], state_table[lexer->state]);
- lexer->char_counter++;
- if (lexer->state == GROUND_STATE) {
- character_discard(lexer);
- } else if (lexer->state == COMMENT_RECOGNIZED) {
- packet_accept(lexer, COMMENT_PACKET);
- packet_discard(lexer);
- lexer->state = GROUND_STATE;
- break;
- }
- #ifdef NMEA0183_ENABLE
- else if (lexer->state == NMEA_RECOGNIZED) {
-
- if (!str_starts_with((const char *)lexer->inbuffer, "$PASHR,"))
- {
- bool checksum_ok = true;
- char csum[3] = { '0', '0', '0' };
- char *end;
-
- for (end = (char *)lexer->inbufptr - 1; isspace((unsigned char) *end); end--)
- continue;
- while (strchr("0123456789ABCDEF", *end))
- --end;
- if (*end == '*') {
- unsigned int n, crc = 0;
- for (n = 1; (char *)lexer->inbuffer + n < end; n++)
- crc ^= lexer->inbuffer[n];
- (void)snprintf(csum, sizeof(csum), "%02X", crc);
- checksum_ok = (csum[0] == toupper((unsigned char) end[1])
- && csum[1] == toupper((unsigned char) end[2]));
- }
- if (!checksum_ok) {
- GPSD_LOG(LOG_WARN, &lexer->errout,
- "bad checksum in NMEA packet; expected %s.\n",
- csum);
- packet_accept(lexer, BAD_PACKET);
- lexer->state = GROUND_STATE;
- packet_discard(lexer);
- break;
- }
- }
-
- #ifdef AIVDM_ENABLE
-
-
- if ('!' == lexer->inbuffer[0] &&
- 'V' == lexer->inbuffer[3] &&
- 'D' == lexer->inbuffer[4] &&
- ',' == lexer->inbuffer[6] &&
- (str_starts_with((char *)lexer->inbuffer, "!ABVDM,") ||
- str_starts_with((char *)lexer->inbuffer, "!ABVDO,") ||
- str_starts_with((char *)lexer->inbuffer, "!ADVDM,") ||
- str_starts_with((char *)lexer->inbuffer, "!ADVDO,") ||
- str_starts_with((char *)lexer->inbuffer, "!AIVDM,") ||
- str_starts_with((char *)lexer->inbuffer, "!AIVDO,") ||
- str_starts_with((char *)lexer->inbuffer, "!ANVDM,") ||
- str_starts_with((char *)lexer->inbuffer, "!ANVDO,") ||
- str_starts_with((char *)lexer->inbuffer, "!ARVDM,") ||
- str_starts_with((char *)lexer->inbuffer, "!ARVDO,") ||
- str_starts_with((char *)lexer->inbuffer, "!ASVDM,") ||
- str_starts_with((char *)lexer->inbuffer, "!ASVDO,") ||
- str_starts_with((char *)lexer->inbuffer, "!ATVDM,") ||
- str_starts_with((char *)lexer->inbuffer, "!ATVDO,") ||
- str_starts_with((char *)lexer->inbuffer, "!AXVDM,") ||
- str_starts_with((char *)lexer->inbuffer, "!AXVDO,") ||
- str_starts_with((char *)lexer->inbuffer, "!BSVDM,") ||
- str_starts_with((char *)lexer->inbuffer, "!BSVDO,") ||
- str_starts_with((char *)lexer->inbuffer, "!SAVDM,") ||
- str_starts_with((char *)lexer->inbuffer, "!SAVDO,"))) {
- packet_accept(lexer, AIVDM_PACKET);
- } else
- #endif
- packet_accept(lexer, NMEA_PACKET);
- packet_discard(lexer);
- #ifdef STASH_ENABLE
- if (lexer->stashbuflen)
- packet_unstash(lexer);
- #endif
- break;
- }
- #endif
- #ifdef SIRF_ENABLE
- else if (lexer->state == SIRF_RECOGNIZED) {
- unsigned char *trailer = lexer->inbufptr - 4;
- unsigned int checksum =
- (unsigned)((trailer[0] << 8) | trailer[1]);
- unsigned int n, crc = 0;
- for (n = 4; n < (unsigned)(trailer - lexer->inbuffer); n++)
- crc += (int)lexer->inbuffer[n];
- crc &= 0x7fff;
- if (checksum == crc)
- packet_accept(lexer, SIRF_PACKET);
- else {
- packet_accept(lexer, BAD_PACKET);
- lexer->state = GROUND_STATE;
- }
- packet_discard(lexer);
- break;
- }
- #endif
- #ifdef SKYTRAQ_ENABLE
- else if (lexer->state == SKY_RECOGNIZED) {
- packet_accept(lexer, SKY_PACKET);
- packet_discard(lexer);
- break;
- }
- #endif
- #ifdef SUPERSTAR2_ENABLE
- else if (lexer->state == SUPERSTAR2_RECOGNIZED) {
- unsigned a = 0, b;
- size_t n;
- lexer->length = 4 + (size_t) lexer->inbuffer[3] + 2;
- for (n = 0; n < lexer->length - 2; n++)
- a += (unsigned)lexer->inbuffer[n];
- b = (unsigned)getleu16(lexer->inbuffer, lexer->length - 2);
- GPSD_LOG(LOG_IO, &lexer->errout,
- "SuperStarII pkt dump: type %u len %u\n",
- lexer->inbuffer[1], (unsigned int)lexer->length);
- if (a != b) {
- GPSD_LOG(LOG_IO, &lexer->errout,
- "REJECT SuperStarII packet type 0x%02x"
- "%zd bad checksum 0x%04x, expecting 0x%04x\n",
- lexer->inbuffer[1], lexer->length, a, b);
- packet_accept(lexer, BAD_PACKET);
- lexer->state = GROUND_STATE;
- } else {
- packet_accept(lexer, SUPERSTAR2_PACKET);
- }
- packet_discard(lexer);
- break;
- }
- #endif
- #ifdef ONCORE_ENABLE
- else if (lexer->state == ONCORE_RECOGNIZED) {
- char a, b;
- int i, len;
- len = lexer->inbufptr - lexer->inbuffer;
- a = (char)(lexer->inbuffer[len - 3]);
- b = '\0';
- for (i = 2; i < len - 3; i++)
- b ^= lexer->inbuffer[i];
- if (a == b) {
- GPSD_LOG(LOG_IO, &lexer->errout,
- "Accept OnCore packet @@%c%c len %d\n",
- lexer->inbuffer[2], lexer->inbuffer[3], len);
- packet_accept(lexer, ONCORE_PACKET);
- } else {
- GPSD_LOG(LOG_IO, &lexer->errout,
- "REJECT OnCore packet @@%c%c len %d\n",
- lexer->inbuffer[2], lexer->inbuffer[3], len);
- packet_accept(lexer, BAD_PACKET);
- lexer->state = GROUND_STATE;
- }
- packet_discard(lexer);
- break;
- }
- #endif
- #if defined(TSIP_ENABLE) || defined(GARMIN_ENABLE)
- else if (lexer->state == TSIP_RECOGNIZED) {
- size_t packetlen = lexer->inbufptr - lexer->inbuffer;
- #ifdef TSIP_ENABLE
- unsigned int pos, dlecnt;
-
- dlecnt = 0;
- for (pos = 0; pos < (unsigned int)packetlen; pos++)
- if (lexer->inbuffer[pos] == DLE)
- dlecnt++;
- if (dlecnt > 2) {
- dlecnt -= 2;
- dlecnt /= 2;
- GPSD_LOG(LOG_RAW + 1, &lexer->errout,
- "Unstuffed %d DLEs\n", dlecnt);
- packetlen -= dlecnt;
- }
- #endif
- if (packetlen < 5) {
- lexer->state = GROUND_STATE;
- } else {
- unsigned int pkt_id;
- #ifdef GARMIN_ENABLE
- unsigned int len;
- size_t n;
- unsigned int ch, chksum;
- n = 0;
- #ifdef TSIP_ENABLE
-
- if (TSIP_PACKET == lexer->type)
- goto not_garmin;
- #endif
- if (lexer->inbuffer[n++] != DLE)
- goto not_garmin;
- pkt_id = lexer->inbuffer[n++];
- len = lexer->inbuffer[n++];
- chksum = len + pkt_id;
- if (len == DLE) {
- if (lexer->inbuffer[n++] != DLE)
- goto not_garmin;
- }
- for (; len > 0; len--) {
- chksum += lexer->inbuffer[n];
- if (lexer->inbuffer[n++] == DLE) {
- if (lexer->inbuffer[n++] != DLE)
- goto not_garmin;
- }
- }
-
- ch = lexer->inbuffer[n++];
- chksum += ch;
- if (ch == DLE) {
- if (lexer->inbuffer[n++] != DLE)
- goto not_garmin;
- }
- if (lexer->inbuffer[n++] != DLE)
- goto not_garmin;
-
- if (lexer->inbuffer[n] != ETX)
- goto not_garmin;
- chksum &= 0xff;
- if (chksum) {
- GPSD_LOG(LOG_IO, &lexer->errout,
- "Garmin checksum failed: %02x!=0\n", chksum);
- goto not_garmin;
- }
- packet_accept(lexer, GARMIN_PACKET);
- packet_discard(lexer);
- break;
- not_garmin:;
- GPSD_LOG(LOG_RAW + 1, &lexer->errout,
- "Not a Garmin packet\n");
- #endif
- #ifdef TSIP_ENABLE
-
- pkt_id = lexer->inbuffer[1];
-
- if (!((0x13 == pkt_id) ||
- (0x1c == pkt_id) ||
- (0x38 == pkt_id) ||
- ((0x41 <= pkt_id) && (0x4c >= pkt_id)) ||
- ((0x54 <= pkt_id) && (0x57 >= pkt_id)) ||
- ((0x5a <= pkt_id) && (0x5f >= pkt_id)) ||
- (0x6c == pkt_id) ||
- (0x6d == pkt_id) ||
- ((0x82 <= pkt_id) && (0x84 >= pkt_id)) ||
- (0x8f == pkt_id) ||
- (0xbb == pkt_id) ||
- (0xbc == pkt_id))) {
- GPSD_LOG(LOG_IO, &lexer->errout,
- "Packet ID 0x%02x out of range for TSIP\n",
- pkt_id);
- goto not_tsip;
- }
-
- #define TSIP_ID_AND_LENGTH(id, len) ((id == pkt_id) && (len == packetlen-4))
- if ((0x13 == pkt_id) && (1 <= packetlen))
- ;
-
- else if ((0x1c == pkt_id) && (11 <= packetlen))
- ;
- else if (TSIP_ID_AND_LENGTH(0x41, 10))
- ;
- else if (TSIP_ID_AND_LENGTH(0x42, 16))
- ;
- else if (TSIP_ID_AND_LENGTH(0x43, 20))
- ;
- else if (TSIP_ID_AND_LENGTH(0x45, 10))
- ;
- else if (TSIP_ID_AND_LENGTH(0x46, 2))
- ;
- else if ((0x47 == pkt_id) && ((packetlen % 5) == 0))
-
- ;
- else if (TSIP_ID_AND_LENGTH(0x48, 22))
- ;
- else if (TSIP_ID_AND_LENGTH(0x49, 32))
- ;
- else if (TSIP_ID_AND_LENGTH(0x4a, 20))
- ;
- else if (TSIP_ID_AND_LENGTH(0x4b, 3))
- ;
- else if (TSIP_ID_AND_LENGTH(0x4c, 17))
- ;
- else if (TSIP_ID_AND_LENGTH(0x54, 12))
- ;
- else if (TSIP_ID_AND_LENGTH(0x55, 4))
- ;
- else if (TSIP_ID_AND_LENGTH(0x56, 20))
- ;
- else if (TSIP_ID_AND_LENGTH(0x57, 8))
- ;
- else if (TSIP_ID_AND_LENGTH(0x5a, 25))
- ;
- else if (TSIP_ID_AND_LENGTH(0x5b, 16))
- ;
- else if (TSIP_ID_AND_LENGTH(0x5c, 24))
- ;
- else if (TSIP_ID_AND_LENGTH(0x5d, 26))
- ;
- else if (TSIP_ID_AND_LENGTH(0x5e, 2))
- ;
-
- else if (TSIP_ID_AND_LENGTH(0x5f, 66))
-
- ;
- else if ((0x6c == pkt_id)
- && ((22 <= packetlen) && (246 >= packetlen)))
-
- ;
- else if ((0x6d == pkt_id)
- && ((21 <= packetlen) && (53 >= packetlen)))
- ;
- else if (TSIP_ID_AND_LENGTH(0x82, 1))
- ;
- else if (TSIP_ID_AND_LENGTH(0x83, 36))
- ;
- else if (TSIP_ID_AND_LENGTH(0x84, 36))
- ;
-
- else if (0x8f == pkt_id)
- ;
-
- else if (TSIP_ID_AND_LENGTH(0xbb, 40))
- ;
-
- else if (TSIP_ID_AND_LENGTH(0xbb, 43))
- ;
- else {
- ;
- GPSD_LOG(LOG_IO, &lexer->errout,
- "TSIP REJECT pkt_id = %#02x, packetlen= %zu\n",
- pkt_id, packetlen);
- goto not_tsip;
- }
- #undef TSIP_ID_AND_LENGTH
-
- GPSD_LOG(LOG_RAW, &lexer->errout,
- "TSIP pkt_id = %#02x, packetlen= %zu\n",
- pkt_id, packetlen);
- packet_accept(lexer, TSIP_PACKET);
- packet_discard(lexer);
- break;
- not_tsip:
- GPSD_LOG(LOG_RAW + 1, &lexer->errout, "Not a TSIP packet\n");
-
- packet_accept(lexer, BAD_PACKET);
- lexer->state = GROUND_STATE;
- packet_discard(lexer);
- break;
- #endif
- }
- }
- #endif
- #ifdef RTCM104V3_ENABLE
- else if (lexer->state == RTCM3_RECOGNIZED) {
- if (crc24q_check(lexer->inbuffer,
- lexer->inbufptr - lexer->inbuffer)) {
- packet_accept(lexer, RTCM3_PACKET);
- } else {
- GPSD_LOG(LOG_IO, &lexer->errout,
- "RTCM3 data checksum failure, "
- "%0x against %02x %02x %02x\n",
- crc24q_hash(lexer->inbuffer,
- lexer->inbufptr - lexer->inbuffer -
- 3), lexer->inbufptr[-3],
- lexer->inbufptr[-2], lexer->inbufptr[-1]);
- packet_accept(lexer, BAD_PACKET);
- }
- packet_discard(lexer);
- lexer->state = GROUND_STATE;
- break;
- }
- #endif
- #ifdef ZODIAC_ENABLE
- else if (lexer->state == ZODIAC_RECOGNIZED) {
- short len, n, sum;
- len = getword(2);
- for (n = sum = 0; n < len; n++)
- sum += getword(5 + n);
- sum *= -1;
- if (len == 0 || sum == getword(5 + len)) {
- packet_accept(lexer, ZODIAC_PACKET);
- } else {
- GPSD_LOG(LOG_IO, &lexer->errout,
- "Zodiac data checksum 0x%hx over length %hd, expecting 0x%hx\n",
- sum, len, getword(5 + len));
- packet_accept(lexer, BAD_PACKET);
- lexer->state = GROUND_STATE;
- }
- packet_discard(lexer);
- break;
- }
- #endif
- #ifdef UBLOX_ENABLE
- else if (lexer->state == UBX_RECOGNIZED) {
-
- int n, len;
- unsigned char ck_a = (unsigned char)0;
- unsigned char ck_b = (unsigned char)0;
- len = lexer->inbufptr - lexer->inbuffer;
- GPSD_LOG(LOG_IO, &lexer->errout, "UBX: len %d\n", len);
- for (n = 2; n < (len - 2); n++) {
- ck_a += lexer->inbuffer[n];
- ck_b += ck_a;
- }
- if (ck_a == lexer->inbuffer[len - 2] &&
- ck_b == lexer->inbuffer[len - 1])
- packet_accept(lexer, UBX_PACKET);
- else {
- GPSD_LOG(LOG_IO, &lexer->errout,
- "UBX checksum 0x%02hhx%02hhx over length %d,"
- " expecting 0x%02hhx%02hhx (type 0x%02hhx%02hhx)\n",
- ck_a,
- ck_b,
- len,
- lexer->inbuffer[len - 2],
- lexer->inbuffer[len - 1],
- lexer->inbuffer[2], lexer->inbuffer[3]);
- packet_accept(lexer, BAD_PACKET);
- lexer->state = GROUND_STATE;
- }
- packet_discard(lexer);
- break;
- }
- #endif
- #ifdef EVERMORE_ENABLE
- else if (lexer->state == EVERMORE_RECOGNIZED) {
- unsigned int n, crc, checksum, len;
- n = 0;
- if (lexer->inbuffer[n++] != DLE)
- goto not_evermore;
- if (lexer->inbuffer[n++] != STX)
- goto not_evermore;
- len = lexer->inbuffer[n++];
- if (len == DLE) {
- if (lexer->inbuffer[n++] != DLE)
- goto not_evermore;
- }
- len -= 2;
- crc = 0;
- for (; len > 0; len--) {
- crc += lexer->inbuffer[n];
- if (lexer->inbuffer[n++] == DLE) {
- if (lexer->inbuffer[n++] != DLE)
- goto not_evermore;
- }
- }
- checksum = lexer->inbuffer[n++];
- if (checksum == DLE) {
- if (lexer->inbuffer[n++] != DLE)
- goto not_evermore;
- }
- if (lexer->inbuffer[n++] != DLE)
- goto not_evermore;
-
- if (lexer->inbuffer[n] != ETX)
- goto not_evermore;
- crc &= 0xff;
- if (crc != checksum) {
- GPSD_LOG(LOG_IO, &lexer->errout,
- "EverMore checksum failed: %02x != %02x\n",
- crc, checksum);
- goto not_evermore;
- }
- packet_accept(lexer, EVERMORE_PACKET);
- packet_discard(lexer);
- break;
- not_evermore:
- packet_accept(lexer, BAD_PACKET);
- lexer->state = GROUND_STATE;
- packet_discard(lexer);
- break;
- }
- #endif
- #ifdef ITRAX_ENABLE
- #define getib(j) ((uint8_t)lexer->inbuffer[(j)])
- #define getiw(i) ((uint16_t)(((uint16_t)getib((i)+1) << 8) | (uint16_t)getib((i))))
- else if (lexer->state == ITALK_RECOGNIZED) {
- volatile uint16_t len, n, csum, xsum;
-
- len = (uint16_t) (lexer->inbuffer[6] & 0xff);
-
- xsum = getiw(7 + 2 * len);
- csum = 0;
- for (n = 0; n < len; n++) {
- volatile uint16_t tmpw = getiw(7 + 2 * n);
- volatile uint32_t tmpdw = (csum + 1) * (tmpw + n);
- csum ^= (tmpdw & 0xffff) ^ ((tmpdw >> 16) & 0xffff);
- }
- if (len == 0 || csum == xsum)
- packet_accept(lexer, ITALK_PACKET);
- else {
- GPSD_LOG(LOG_IO, &lexer->errout,
- "ITALK: checksum failed - "
- "type 0x%02x expected 0x%04x got 0x%04x\n",
- lexer->inbuffer[4], xsum, csum);
- packet_accept(lexer, BAD_PACKET);
- lexer->state = GROUND_STATE;
- }
- packet_discard(lexer);
- break;
- }
- #undef getiw
- #undef getib
- #endif
- #ifdef NAVCOM_ENABLE
- else if (lexer->state == NAVCOM_RECOGNIZED) {
-
- packet_accept(lexer, NAVCOM_PACKET);
- packet_discard(lexer);
- break;
- }
- #endif
- #ifdef GEOSTAR_ENABLE
- else if (lexer->state == GEOSTAR_RECOGNIZED) {
-
- int n, len;
- unsigned int cs = 0L;
- len = lexer->inbufptr - lexer->inbuffer;
-
- for (n = 0; n < len; n += 4) {
- cs ^= getleu32(lexer->inbuffer, n);
- }
- if (cs == 0)
- packet_accept(lexer, GEOSTAR_PACKET);
- else {
- GPSD_LOG(LOG_IO, &lexer->errout,
- "GeoStar checksum failed 0x%x over length %d\n",
- cs, len);
- packet_accept(lexer, BAD_PACKET);
- lexer->state = GROUND_STATE;
- }
- packet_discard(lexer);
- break;
- }
- #endif
- #ifdef GREIS_ENABLE
- else if (lexer->state == GREIS_RECOGNIZED) {
- int len = lexer->inbufptr - lexer->inbuffer;
- if (lexer->inbuffer[0] == 'R' && lexer->inbuffer[1] == 'E') {
-
- GPSD_LOG(LOG_IO, &lexer->errout,
- "Accept GREIS reply packet len %d\n", len);
- packet_accept(lexer, GREIS_PACKET);
- } else if (lexer->inbuffer[0] == 'E' && lexer->inbuffer[1] == 'R') {
-
- GPSD_LOG(LOG_IO, &lexer->errout,
- "Accept GREIS error packet len %d\n", len);
- packet_accept(lexer, GREIS_PACKET);
- } else {
- unsigned char expected_cs = lexer->inbuffer[len - 1];
- unsigned char cs = greis_checksum(lexer->inbuffer, len - 1);
- if (cs == expected_cs) {
- GPSD_LOG(LOG_IO, &lexer->errout,
- "Accept GREIS packet type '%c%c' len %d\n",
- lexer->inbuffer[0], lexer->inbuffer[1], len);
- packet_accept(lexer, GREIS_PACKET);
- } else {
-
- GPSD_LOG(LOG_IO, &lexer->errout,
- "REJECT GREIS len %d."
- " Bad checksum %#02x, expecting %#02x."
- " Packet type in hex: 0x%02x%02x",
- len, cs, expected_cs, lexer->inbuffer[0],
- lexer->inbuffer[1]);
- packet_accept(lexer, BAD_PACKET);
-
- lexer->state = GREIS_EXPECTED;
- }
- }
- packet_discard(lexer);
- break;
- }
- #endif
- #ifdef RTCM104V2_ENABLE
- else if (lexer->state == RTCM2_RECOGNIZED) {
-
- packet_accept(lexer, RTCM2_PACKET);
- packet_discard(lexer);
- break;
- }
- #endif
- #ifdef GARMINTXT_ENABLE
- else if (lexer->state == GTXT_RECOGNIZED) {
- size_t packetlen = lexer->inbufptr - lexer->inbuffer;
- if (57 <= packetlen) {
- packet_accept(lexer, GARMINTXT_PACKET);
- packet_discard(lexer);
- lexer->state = GROUND_STATE;
- break;
- } else {
- packet_accept(lexer, BAD_PACKET);
- lexer->state = GROUND_STATE;
- }
- }
- #endif
- #ifdef PASSTHROUGH_ENABLE
- else if (lexer->state == JSON_RECOGNIZED) {
- size_t packetlen = lexer->inbufptr - lexer->inbuffer;
- if (packetlen >= 11)
-
- packet_accept(lexer, JSON_PACKET);
- else
- packet_accept(lexer, BAD_PACKET);
- packet_discard(lexer);
- lexer->state = GROUND_STATE;
- break;
- }
- #endif
- #ifdef STASH_ENABLE
- else if (lexer->state == STASH_RECOGNIZED) {
- packet_stash(lexer);
- packet_discard(lexer);
- }
- #endif
- }
- }
- #undef getword
- ssize_t packet_get(int fd, struct gps_lexer_t *lexer)
- {
- ssize_t recvd;
- errno = 0;
-
- recvd = read(fd, lexer->inbuffer + lexer->inbuflen,
- sizeof(lexer->inbuffer) - (lexer->inbuflen));
- if (recvd == -1) {
- if ((errno == EAGAIN) || (errno == EINTR)) {
- GPSD_LOG(LOG_RAW + 2, &lexer->errout, "no bytes ready\n");
- recvd = 0;
-
- } else {
- GPSD_LOG(LOG_RAW + 2, &lexer->errout,
- "errno: %s\n", strerror(errno));
- return -1;
- }
- } else {
- if (lexer->errout.debug >= LOG_RAW + 1) {
- char scratchbuf[MAX_PACKET_LENGTH*4+1];
- GPSD_LOG(LOG_RAW + 1, &lexer->errout,
- "Read %zd chars to buffer offset %zd (total %zd): %s\n",
- recvd, lexer->inbuflen, lexer->inbuflen + recvd,
- gpsd_packetdump(scratchbuf, sizeof(scratchbuf),
- (char *)lexer->inbufptr, (size_t) recvd));
- }
- lexer->inbuflen += recvd;
- }
- GPSD_LOG(LOG_SPIN, &lexer->errout,
- "packet_get() fd %d -> %zd (%d)\n",
- fd, recvd, errno);
-
- if (recvd <= 0 && packet_buffered_input(lexer) <= 0)
- return recvd;
-
-
- packet_parse(lexer);
-
- if (sizeof(lexer->inbuffer) == (lexer->inbuflen)) {
-
- packet_discard(lexer);
- lexer->state = GROUND_STATE;
- }
-
- if (lexer->outbuflen > 0)
- return (ssize_t) lexer->outbuflen;
- else
-
- return recvd;
- }
- void packet_reset(struct gps_lexer_t *lexer)
- {
- lexer->type = BAD_PACKET;
- lexer->state = GROUND_STATE;
- lexer->inbuflen = 0;
- lexer->inbufptr = lexer->inbuffer;
- #ifdef BINARY_ENABLE
- isgps_init(lexer);
- #endif
- #ifdef STASH_ENABLE
- lexer->stashbuflen = 0;
- #endif
- }
- #ifdef __UNUSED__
- void packet_pushback(struct gps_lexer_t *lexer)
- {
- if (lexer->outbuflen + lexer->inbuflen < MAX_PACKET_LENGTH) {
- memmove(lexer->inbuffer + lexer->outbuflen,
- lexer->inbuffer, lexer->inbuflen);
- memmove(lexer->inbuffer, lexer->outbuffer, lexer->outbuflen);
- lexer->inbuflen += lexer->outbuflen;
- lexer->inbufptr += lexer->outbuflen;
- lexer->outbuflen = 0;
- }
- }
- #endif
|