ubx.py 314 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007
  1. '''
  2. class ubx
  3. '''
  4. # This file is Copyright 2020 by the GPSD project
  5. # SPDX-License-Identifier: BSD-2-clause
  6. #
  7. # This code runs compatibly under Python 2 and 3.x for x >= 2.
  8. # Preserve this property!
  9. from __future__ import absolute_import, print_function, division
  10. import argparse # to parse CLI options
  11. import binascii # for binascii.hexlify()
  12. from functools import reduce # pylint: disable=redefined-builtin
  13. import operator # for or_
  14. import os # for os.environ
  15. import re # for regular expressions
  16. import socket # for socket.error
  17. import stat # for stat.S_ISBLK()
  18. import string # for string.printable
  19. import struct # for pack()
  20. import sys
  21. import time
  22. try:
  23. import gps
  24. except ImportError:
  25. # PEP8 says local imports last
  26. sys.stderr.write("%s: failed to import gps, check PYTHONPATH\n" %
  27. PROG_NAME)
  28. sys.exit(2)
  29. def erd_s(erd):
  30. """convert 6 bits of subframe 4, page 13 (NMCT) ERD to string"""
  31. if erd & 0x20:
  32. if erd == 0x20:
  33. return "n/a"
  34. # else
  35. erd = 1 - erd
  36. # else
  37. return "%3s" % erd
  38. # I'd like to use pypy module bitstring or bitarray, but
  39. # people complain when non stock python modules are used here.
  40. def unpack_s11(word, pos):
  41. """Grab a signed 11 bits from offset pos of word"""
  42. ubytes = bytearray(2)
  43. ubytes[0] = (word >> pos) & 0xff
  44. ubytes[1] = (word >> (pos + 8)) & 0x07
  45. if 0x04 & ubytes[1]:
  46. # extend the sign
  47. ubytes[1] |= 0xf8
  48. u = struct.unpack_from('<h', ubytes, 0)
  49. return u[0]
  50. def unpack_s11s(word):
  51. """Grab the weird split signed 11 bits from word"""
  52. newword = (word >> 22) & 0xff
  53. newword <<= 3
  54. newword |= (word >> 8) & 0x07
  55. return unpack_s11(newword, 0)
  56. def unpack_s14(word, pos):
  57. """Grab a signed 14 bits from offset pos of word"""
  58. ubytes = bytearray(2)
  59. ubytes[0] = (word >> pos) & 0xff
  60. ubytes[1] = (word >> (pos + 8)) & 0x3f
  61. if 0x20 & ubytes[1]:
  62. # extend the sign
  63. ubytes[1] |= 0xc0
  64. u = struct.unpack_from('<h', ubytes, 0)
  65. return u[0]
  66. def unpack_s16(word, pos):
  67. """Grab a signed two bytes from offset pos of word"""
  68. ubytes = bytearray(2)
  69. ubytes[0] = (word >> pos) & 0xff
  70. ubytes[1] = (word >> (pos + 8)) & 0xff
  71. u = struct.unpack_from('<h', ubytes, 0)
  72. return u[0]
  73. def unpack_u16(word, pos):
  74. """Grab a unsigned two bytes from offset pos of word"""
  75. ubytes = bytearray(2)
  76. ubytes[0] = (word >> pos) & 0xff
  77. ubytes[1] = (word >> (pos + 8)) & 0xff
  78. u = struct.unpack_from('<H', ubytes, 0)
  79. return u[0]
  80. def unpack_u17(word, pos):
  81. """Grab an unsigned 17 bits from offset pos of word"""
  82. return unpack_u24(word, pos) & 0x01ffff
  83. def unpack_s22(word, pos):
  84. """Grab a signed 22 bits from offset pos of word"""
  85. ubytes = bytearray(4)
  86. ubytes[0] = (word >> pos) & 0xff
  87. ubytes[1] = (word >> (pos + 8)) & 0xff
  88. ubytes[2] = (word >> (pos + 16)) & 0x3f
  89. ubytes[3] = 0
  90. if 0x20 & ubytes[2]:
  91. # extend the sign
  92. ubytes[2] |= 0xc0
  93. ubytes[3] = 0xff
  94. u = struct.unpack_from('<l', ubytes, 0)
  95. return u[0]
  96. def unpack_s24(word, pos):
  97. """Grab a signed 24 bits from offset pos of word"""
  98. ubytes = bytearray(4)
  99. ubytes[0] = (word >> pos) & 0xff
  100. ubytes[1] = (word >> (pos + 8)) & 0xff
  101. ubytes[2] = (word >> (pos + 16)) & 0xff
  102. ubytes[3] = 0
  103. if 0x80 & ubytes[2]:
  104. # extend the sign
  105. ubytes[3] = 0xff
  106. u = struct.unpack_from('<l', ubytes, 0)
  107. return u[0]
  108. def unpack_u24(word, pos):
  109. """Grab an unsigned 24 bits from offset pos of word"""
  110. ubytes = bytearray(4)
  111. ubytes[0] = (word >> pos) & 0xff
  112. ubytes[1] = (word >> (pos + 8)) & 0xff
  113. ubytes[2] = (word >> (pos + 16)) & 0xff
  114. ubytes[3] = 0
  115. u = struct.unpack_from('<L', ubytes, 0)
  116. return u[0]
  117. def unpack_s32s(word, word1):
  118. """Grab an signed 32 bits from weird split word, word1"""
  119. ubytes = bytearray(4)
  120. ubytes[0] = (word >> 6) & 0xff
  121. ubytes[1] = (word >> 14) & 0xff
  122. ubytes[2] = (word >> 22) & 0xff
  123. ubytes[3] = (word1 >> 6) & 0xff
  124. u = struct.unpack_from('<l', ubytes, 0)
  125. return u[0]
  126. def unpack_u32s(word, word1):
  127. """Grab an unsigned 32 bits from weird split word, word1"""
  128. ubytes = bytearray(4)
  129. ubytes[0] = (word >> 6) & 0xff
  130. ubytes[1] = (word >> 14) & 0xff
  131. ubytes[2] = (word >> 22) & 0xff
  132. ubytes[3] = (word1 >> 6) & 0xff
  133. u = struct.unpack_from('<L', ubytes, 0)
  134. return u[0]
  135. def unpack_s8(word, pos):
  136. """Grab a signed byte from offset pos of word"""
  137. ubytes = bytearray(1)
  138. ubytes[0] = (word >> pos) & 0xff
  139. u = struct.unpack_from('<b', ubytes, 0)
  140. return u[0]
  141. def unpack_u8(word, pos):
  142. """Grab an unsigned byte from offset pos of word"""
  143. ubytes = bytearray(1)
  144. ubytes[0] = (word >> pos) & 0xff
  145. u = struct.unpack_from('<B', ubytes, 0)
  146. return u[0]
  147. def flag_s(flag, descs):
  148. """Decode flag using descs, return a string. Ignores unknown bits."""
  149. s = ''
  150. for key, value in sorted(descs.items()):
  151. if key == (key & flag):
  152. s += value
  153. s += ' '
  154. return s.strip()
  155. def index_s(index, descs, nf="Unk"):
  156. """Decode flag using descs, return a string. Otherwise Unk"""
  157. if index in descs:
  158. s = descs[index]
  159. else:
  160. s = nf
  161. return s
  162. def timestamp(timestamp_opts):
  163. """Print current time as a timestamp.
  164. UNIX epoch for timestamp_opts == 1, UTC when timestamp_opts == 2
  165. """
  166. now = time.time()
  167. if 1 == timestamp_opts:
  168. print("%.4f" % now)
  169. elif 2 == timestamp_opts:
  170. print("%.4f %s" % (now, time.asctime(time.gmtime(now))))
  171. class ubx(object):
  172. """Class to hold u-blox stuff."""
  173. # expected statement identifier.
  174. expect_statement_identifier = False
  175. io_handle = None
  176. # when a statement identifier is received, it is stored here
  177. last_statement_identifier = None
  178. read_only = False
  179. protver = 10.0
  180. timestamp = None
  181. verbosity = gps.VERB_NONE
  182. def __init__(self):
  183. pass
  184. # allowable speeds
  185. speeds = (460800, 230400, 153600, 115200, 57600, 38400, 19200, 9600, 4800)
  186. # UBX Satellite Numbering
  187. gnss_id = {0: 'GPS',
  188. 1: 'SBAS',
  189. 2: 'Galileo',
  190. 3: 'BeiDou',
  191. 4: 'IMES',
  192. 5: 'QZSS',
  193. 6: 'GLONASS'}
  194. # Names for portID values in UBX-CFG-PRT, UBX-MON-IO, etc.
  195. port_ids = {0: 'DDC', # The license free name for i2c used in the spec
  196. 1: 'UART1',
  197. 2: 'UART2',
  198. 3: 'USB',
  199. 4: 'SPI',
  200. }
  201. port_id_map = dict([(v, k) for (k, v) in port_ids.items()])
  202. port_id_map['UART'] = port_id_map['UART1'] # Accept synonym
  203. port_ids[5] = 'Reserved' # Don't include this in port_id_map
  204. # Names for portID values in UBX-CFG-COMMS
  205. # the doc does not match what is seen
  206. port_ids1 = {0: 'DDC',
  207. 0x001: 'UART1', # as documented on ZED-M9
  208. 0x003: 'USB', # as documented on ZED-M9
  209. 0x004: 'SPI', # as documented on ZED-M9
  210. 0x100: 'UART1', # seen on ZED-M9, documented
  211. 0x101: 'UNKa', # seen on ZED-M9T, undocumented
  212. 0x102: 'UART2', # as documented on ZED-M9
  213. 0x200: 'UNKb', # seen on ZED-M9T, undocumented
  214. 0x201: 'UART2',
  215. 0x300: 'USB', # seen on ZED-M9, undocumented
  216. 0x400: 'SPI',
  217. }
  218. # u-blox 9 cfg items as a 5-tuple
  219. # 1 - Name
  220. # 2 - key id
  221. # 3 - value type
  222. # 4 - scale
  223. # 5 - Unit
  224. # 6 - Description
  225. cfgs = (
  226. # CFG--
  227. ("CFG", 0x1FFFFFFF, "", 0, "",
  228. "get all CFG"),
  229. # CFG-ANA-
  230. ("CFG-ANA", 0x1023FFFF, "", 0, "",
  231. "get all CFG-ANA"),
  232. ("CFG-ANA-USE_ANA", 0x10230001, "L", 1, "",
  233. "Use AssistNow Autonomous"),
  234. ("CFG-ANA-ORBMAXERR", 0x30230002, "U2", 1, "m",
  235. "Maximum acceptable (modeled) orbit error"),
  236. # CFG-BATCH-
  237. ("CFG-BATCH", 0x1026FFFF, "", 0, "",
  238. "get all CFG-BATCH"),
  239. ("CFG-BATCH-ENABLE", 0x10260013, "L", 1, "",
  240. "Enable the feature. Needs further configuration."),
  241. ("CFG-BATCH-PIOENABLE", 0x10260014, "L", 1, "",
  242. "Enable PIO notification when buffer fill level exceeds WARNTHRS."),
  243. ("CFG-BATCH-MAXENTRIES", 0x30260015, "U2", 1, "",
  244. "Size of buffer in number of epochs to store."),
  245. ("CFG-BATCH-WARNTHRS", 0x30260016, "U2", 1, "",
  246. "Fill level to trigger PIO notification, number of epochs stored."),
  247. ("CFG-BATCH-PIOACTIVELOW", 0x10260018, "L", 1, "",
  248. "Drive CFG-BATCH-PIOID low when buffer fill level reaches WARNTHRS"),
  249. ("CFG-BATCH-PIOPID", 0x20260019, "U1", 1, "",
  250. "PIO that is used for buffer fill level notification"),
  251. ("CFG-BATCH-EXTRAPVT", 0x1026001a, "L", 1, "",
  252. "Include additional PVT information in UBX-LOG-BATCH messages"),
  253. ("CFG-BATCH-EXTRAODO", 0x1026001b, "L", 1, "",
  254. "Include additional ODO information in UBX-LOG-BATCH messages"),
  255. # CFG-GEOFENCE-
  256. ("CFG-GEOFENCE", 0x2024FFFF, "", 0, "",
  257. "get all CFG-GEOFENCE"),
  258. ("CFG-GEOFENCE-CONFLVL", 0x20240011, "E1", 1, "",
  259. "Required confidence level for state evaluation"),
  260. ("CFG-GEOFENCE-USE_PIO", 0x10240012, "L", 1, "",
  261. "Use PIO combined fence state output"),
  262. ("CFG-GEOFENCE-PINPOL", 0x20240013, "E1", 1, "",
  263. "PIO pin polarity"),
  264. ("CFG-GEOFENCE-PIN", 0x20240014, "U1", 1, "",
  265. "PIO pin number"),
  266. ("CFG-GEOFENCE-USE_FENCE1", 0x10240020, "L", 1, "",
  267. "Use first geofence"),
  268. ("CFG-GEOFENCE-FENCE1_LAT", 0x40240021, "I4", 1e-7, "deg",
  269. "Latitude of the first geofence circle center"),
  270. ("CFG-GEOFENCE-FENCE1_LON", 0x40240022, "I4", 1e-7, "deg",
  271. "Longitude of the first geofence circle center"),
  272. ("CFG-GEOFENCE-FENCE1_RAD", 0x40240023, "U4", 0.01, "m",
  273. "Radius of the first geofence circle"),
  274. ("CFG-GEOFENCE-USE_FENCE2", 0x10240030, "L", 1, "",
  275. "Use second geofence"),
  276. ("CFG-GEOFENCE-FENCE2_LAT", 0x40240031, "I4", 1e-7, "deg",
  277. "Latitude of the second geofence circle center"),
  278. ("CFG-GEOFENCE-FENCE2_LON", 0x40240032, "I4", 1e-7, "deg",
  279. "Longitude of the second geofence circle center"),
  280. ("CFG-GEOFENCE-FENCE2_RAD", 0x40240033, "U4", 0.01, "m",
  281. "Radius of the second geofence circle"),
  282. ("CFG-GEOFENCE-USE_FENCE3", 0x10240040, "L", 1, "",
  283. "Use third geofence"),
  284. ("CFG-GEOFENCE-FENCE3_LAT", 0x40240041, "I4", 1e-7, "deg",
  285. "Latitude of the third geofence circle center"),
  286. ("CFG-GEOFENCE-FENCE3_LON", 0x40240042, "I4", 1e-7, "deg",
  287. "Longitude of the third geofence circle center"),
  288. ("CFG-GEOFENCE-FENCE3_RAD", 0x40240043, "U4", 0.01, "m",
  289. "Radius of the third geofence circle"),
  290. ("CFG-GEOFENCE-USE_FENCE4", 0x10240050, "L", 1, "",
  291. "Use fourth geofence"),
  292. ("CFG-GEOFENCE-FENCE4_LAT", 0x40240051, "I4", 1e-7, "deg",
  293. "Latitude of the fourth geofence circle center"),
  294. ("CFG-GEOFENCE-FENCE4_LON", 0x40240052, "I4", 1e-7, "deg",
  295. "Longitude of the fourth geofence circle center"),
  296. ("CFG-GEOFENCE-FENCE4_RAD", 0x40240053, "U4", 0.01, "m",
  297. "Radius of the fourth geofence circle"),
  298. # CFG-HW
  299. ("CFG-HW", 0x10a3FFFF, "", 0, "",
  300. "get all CFG-HW"),
  301. ("CFG-HW-ANT_CFG_VOLTCTRL", 0x10a3002e, "L", 1, "",
  302. "Active antenna voltage control flag"),
  303. ("CFG-HW-ANT_CFG_SHORTDET", 0x10a3002f, "L", 1, "",
  304. "Short antenna detection flag"),
  305. ("CFG-HW-ANT_CFG_SHORTDET_POL", 0x10a30030, "L", 1, "",
  306. "Short antenna detection polarity"),
  307. ("CFG-HW-ANT_CFG_OPENDET", 0x10a30031, "L", 1, "",
  308. "Open antenna detection flag"),
  309. ("CFG-HW-ANT_CFG_OPENDET_POL", 0x10a30032, "L", 1, "",
  310. "Open antenna detection polarity"),
  311. ("CFG-HW-ANT_CFG_PWRDOWN", 0x10a30033, "L", 1, "",
  312. "Power down antenna flag"),
  313. ("CFG-HW-ANT_CFG_PWRDOWN_POL", 0x10a30034, "L", 1, "",
  314. "Power down antenna logic polarity"),
  315. ("CFG-HW-ANT_CFG_RECOVER", 0x10a30035, "L", 1, "",
  316. "Automatic recovery from short state flag"),
  317. ("CFG-HW-ANT_SUP_SWITCH_PIN", 0x20a30036, "U1", 1, "",
  318. "ANT1 PIO number"),
  319. ("CFG-HW-ANT_SUP_SHORT_PIN", 0x20a30037, "U1", 1, "",
  320. "ANT0 PIO number"),
  321. ("CFG-HW-ANT_SUP_OPEN_PIN", 0x20a30038, "U1", 1, "",
  322. "ANT2 PIO number"),
  323. # CFG-I2C
  324. ("CFG-I2C", 0x2051ffff, "", 0, "",
  325. "get all CFG-I2C"),
  326. ("CFG-I2C-ADDRESS", 0x20510001, "U1", 1, "",
  327. "I2C slave address of the receiver"),
  328. ("CFG-I2C-EXTENDEDTIMEOUT", 0x10510002, "L", 1, "",
  329. "Flag to disable timeouting the interface after 1.5 s"),
  330. ("CFG-I2C-ENABLED", 0x10510003, "L", 1, "",
  331. "Flag to indicate if the I2C interface should be enabled"),
  332. # CFG-I2CINPROT
  333. ("CFG-I2CINPROT", 0x1071ffff, "", 0, "",
  334. "get all CFG-I2CINPROT"),
  335. ("CFG-I2CINPROT-UBX", 0x10710001, "L", 1, "",
  336. "Flag to indicate if UBX should be an input on I2C"),
  337. ("CFG-I2CINPROT-NMEA", 0x10710002, "L", 1, "",
  338. "Flag to indicate if NMEA should be an input on I2C"),
  339. ("CFG-I2CINPROT-RTCM2X", 0x10710003, "L", 1, "",
  340. "Flag to indicate if RTCM2X should be an input on I2C"),
  341. ("CFG-I2CINPROT-RTCM3X", 0x10710004, "L", 1, "",
  342. "Flag to indicate if RTCM3X should be input on I2C"),
  343. # CFG-I2COUTPROT
  344. ("CFG-I2COUTPROT", 0x1072ffff, "", 0, "",
  345. "get all CFG-I2COUTPROT"),
  346. ("CFG-I2COUTPROT-UBX", 0x10720001, "L", 1, "",
  347. "Flag to indicate if UBX should be an output on I2C"),
  348. ("CFG-I2COUTPROT-NMEA", 0x10720002, "L", 1, "",
  349. "Flag to indicate if NMEA should be an output on I2C"),
  350. ("CFG-I2COUTPROT-RTCM3X", 0x10720004, "L", 1, "",
  351. "Flag to indicate if RTCM3X should be an output on I2C"),
  352. # CFG-INFMSG-
  353. ("CFG-INFMSG", 0x2092ffff, "", 0, "",
  354. "get all CFG-INFMSG"),
  355. ("CFG-INFMSG-UBX_I2C", 0x20920001, "X1", 1, "",
  356. "Information message enable flags for UBX protocol on I2C"),
  357. ("CFG-INFMSG-UBX_UART1", 0x20920002, "X1", 1, "",
  358. "Information message enable flags for UBX protocol on UART1"),
  359. ("CFG-INFMSG-UBX_UART2", 0x20920003, "X1", 1, "",
  360. "Information message enable flags for UBX protocol on UART2"),
  361. ("CFG-INFMSG-UBX_USB", 0x20920004, "X1", 1, "",
  362. "Information message enable flags for UBX protocol on USB"),
  363. ("CFG-INFMSG-UBX_SPI", 0x20920005, "X1", 1, "",
  364. "Information message enable flags for UBX protocol on SPI"),
  365. ("CFG-INFMSG-NMEA_I2C", 0x20920006, "X1", 1, "",
  366. "Information message enable flags for NMEA protocol on I2C"),
  367. ("CFG-INFMSG-NMEA_UART1", 0x20920007, "X1", 1, "",
  368. "Information message enable flags for NMEA protocol on UART1"),
  369. ("CFG-INFMSG-NMEA_UART2", 0x20920008, "X1", 1, "",
  370. "Information message enable flags for NMEA protocol on UART2"),
  371. ("CFG-INFMSG-NMEA_USB", 0x20920009, "X1", 1, "",
  372. "Information message enable flags for NMEA protocol on USB"),
  373. ("CFG-INFMSG-NMEA_SPI", 0x2092000a, "X1", 1, "",
  374. "Information message enable flags for NMEA protocol on SPI"),
  375. # CFG-ITFM-
  376. ("CFG-ITFM", 0x2041ffff, "", 0, "",
  377. "get all CFG-ITFM"),
  378. ("CFG-ITFM-BBTHRESHOLD", 0x20410001, "U1", 1, "",
  379. "Broadband jamming detection threshold"),
  380. ("CFG-ITFM-CWTHRESHOLD", 0x20410002, "U1", 1, "",
  381. "CW jamming detection threshold"),
  382. ("CFG-ITFM-ENABLE", 0x1041000d, "L", 1, "",
  383. "Enable interference detection"),
  384. ("CFG-ITFM-ANTSETTING", 0x20410010, "E1", 1, "",
  385. "Antenna setting"),
  386. ("CFG-ITFM-ENABLE_AUX", 0x10410013, "L", 1, "",
  387. "Set to true to scan auxiliary bands"),
  388. # CFG-LOGFILTER-
  389. ("CFG-LOGFILTER", 0x10deffff, "", 0, "",
  390. "get all CFG-LOGFILTER"),
  391. ("CFG-LOGFILTER-RECORD_ENA", 0x10de0002, "L", 1, "",
  392. "Recording enabled"),
  393. ("CFG-LOGFILTER-ONCE_PER_WAKE_UP_ENA", 0x10de0003, "L", 1, "",
  394. "Once per wakeup"),
  395. ("CFG-LOGFILTER-APPLY_ALL_FILTERS", 0x10de0004, "L", 1, "",
  396. "Apply all filter settings"),
  397. ("CFG-LOGFILTER-MIN_INTERVAL", 0x30de0005, "U2", 1, "s",
  398. "Minimum time interval between logged positions"),
  399. ("CFG-LOGFILTER-TIME_THRS", 0x30de0006, "U2", 1, "s",
  400. "Time threshold"),
  401. ("CFG-LOGFILTER-SPEED_THRS", 0x30de0007, "U2", 1, "m/s",
  402. "Speed threshold"),
  403. ("CFG-LOGFILTER-POSITION_THRS", 0x40de0008, "U4", 1, "m",
  404. "Position threshold"),
  405. # CFG-MOT-
  406. ("CFG-MOT", 0x3025ffff, "", 0, "",
  407. "get all CFG-MOT"),
  408. ("CFG-MOT-GNSSSPEED_THRS", 0x20250038, "U1", 0.01, "m/s",
  409. "GNSS speed threshold below which platform is considered "
  410. "as stationary"),
  411. ("CFG-MOT-GNSSDIST_THRS", 0x3025003b, "U2", 1, "",
  412. "Distance above which GNSS-based stationary motion is exit"),
  413. # CFG-MSGOUT-NMEA
  414. ("CFG-MSGOUT", 0x2091ffff, "", 0, "",
  415. "get all CFG-MSGOUT"),
  416. ("CFG-MSGOUT-NMEA_ID_DTM_I2C", 0x209100a6, "U1", 1, "",
  417. "Output rate of the NMEA-GX-DTM message on port I2C"),
  418. ("CFG-MSGOUT-NMEA_ID_DTM_SPI", 0x209100aa, "U1", 1, "",
  419. "Output rate of the NMEA-GX-DTM message on port SPI"),
  420. ("CFG-MSGOUT-NMEA_ID_DTM_UART1", 0x209100a7, "U1", 1, "",
  421. "Output rate of the NMEA-GX-DTM message on port UART1"),
  422. ("CFG-MSGOUT-NMEA_ID_DTM_UART2", 0x209100a8, "U1", 1, "",
  423. "Output rate of the NMEA-GX-DTM message on port UART2"),
  424. ("CFG-MSGOUT-NMEA_ID_DTM_USB", 0x209100a9, "U1", 1, "",
  425. "Output rate of the NMEA-GX-DTM message on port USB"),
  426. ("CFG-MSGOUT-NMEA_ID_GBS_I2C", 0x209100dd, "U1", 1, "",
  427. "Output rate of the NMEA-GX-GBS message on port I2C"),
  428. ("CFG-MSGOUT-NMEA_ID_GBS_SPI", 0x209100e1, "U1", 1, "",
  429. "Output rate of the NMEA-GX-GBS message on port SPI"),
  430. ("CFG-MSGOUT-NMEA_ID_GBS_UART1", 0x209100de, "U1", 1, "",
  431. "Output rate of the NMEA-GX-GBS message on port UART1"),
  432. ("CFG-MSGOUT-NMEA_ID_GBS_UART2", 0x209100df, "U1", 1, "",
  433. "Output rate of the NMEA-GX-GBS message on port UART2"),
  434. ("CFG-MSGOUT-NMEA_ID_GBS_USB", 0x209100e0, "U1", 1, "",
  435. "Output rate of the NMEA-GX-GBS message on port USB"),
  436. ("CFG-MSGOUT-NMEA_ID_GGA_I2C", 0x209100ba, "U1", 1, "",
  437. "Output rate of the NMEA-GX-GGA message on port I2C"),
  438. ("CFG-MSGOUT-NMEA_ID_GGA_SPI", 0x209100be, "U1", 1, "",
  439. "Output rate of the NMEA-GX-GGA message on port SPI"),
  440. ("CFG-MSGOUT-NMEA_ID_GGA_UART1", 0x209100bb, "U1", 1, "",
  441. "Output rate of the NMEA-GX-GGA message on port UART1"),
  442. ("CFG-MSGOUT-NMEA_ID_GGA_UART2", 0x209100bc, "U1", 1, "",
  443. "Output rate of the NMEA-GX-GGA message on port UART2"),
  444. ("CFG-MSGOUT-NMEA_ID_GGA_USB", 0x209100bd, "U1", 1, "",
  445. "Output rate of the NMEA-GX-GGA message on port USB"),
  446. ("CFG-MSGOUT-NMEA_ID_GLL_I2C", 0x209100c9, "U1", 1, "",
  447. "Output rate of the NMEA-GX-GLL message on port I2C"),
  448. ("CFG-MSGOUT-NMEA_ID_GLL_SPI", 0x209100cd, "U1", 1, "",
  449. "Output rate of the NMEA-GX-GLL message on port SPI"),
  450. ("CFG-MSGOUT-NMEA_ID_GLL_UART1", 0x209100ca, "U1", 1, "",
  451. "Output rate of the NMEA-GX-GLL message on port UART1"),
  452. ("CFG-MSGOUT-NMEA_ID_GLL_UART2", 0x209100cb, "U1", 1, "",
  453. "Output rate of the NMEA-GX-GLL message on port UART2"),
  454. ("CFG-MSGOUT-NMEA_ID_GLL_USB", 0x209100cc, "U1", 1, "",
  455. "Output rate of the NMEA-GX-GLL message on port USB"),
  456. ("CFG-MSGOUT-NMEA_ID_GNS_I2C", 0x209100b5, "U1", 1, "",
  457. "Output rate of the NMEA-GX-GNS message on port I2C"),
  458. ("CFG-MSGOUT-NMEA_ID_GNS_SPI", 0x209100b9, "U1", 1, "",
  459. "Output rate of the NMEA-GX-GNS message on port SPI"),
  460. ("CFG-MSGOUT-NMEA_ID_GNS_UART1", 0x209100b6, "U1", 1, "",
  461. "Output rate of the NMEA-GX-GNS message on port UART1"),
  462. ("CFG-MSGOUT-NMEA_ID_GNS_UART2", 0x209100b7, "U1", 1, "",
  463. "Output rate of the NMEA-GX-GNS message on port UART2"),
  464. ("CFG-MSGOUT-NMEA_ID_GNS_USB", 0x209100b8, "U1", 1, "",
  465. "Output rate of the NMEA-GX-GNS message on port USB"),
  466. ("CFG-MSGOUT-NMEA_ID_GRS_I2C", 0x209100ce, "U1", 1, "",
  467. "Output rate of the NMEA-GX-GRS message on port I2C"),
  468. ("CFG-MSGOUT-NMEA_ID_GRS_SPI", 0x209100d2, "U1", 1, "",
  469. "Output rate of the NMEA-GX-GRS message on port SPI"),
  470. ("CFG-MSGOUT-NMEA_ID_GRS_UART1", 0x209100cf, "U1", 1, "",
  471. "Output rate of the NMEA-GX-GRS message on port UART1"),
  472. ("CFG-MSGOUT-NMEA_ID_GRS_UART2", 0x209100d0, "U1", 1, "",
  473. "Output rate of the NMEA-GX-GRS message on port UART2"),
  474. ("CFG-MSGOUT-NMEA_ID_GRS_USB", 0x209100d1, "U1", 1, "",
  475. "Output rate of the NMEA-GX-GRS message on port USB"),
  476. ("CFG-MSGOUT-NMEA_ID_GSA_I2C", 0x209100bf, "U1", 1, "",
  477. "Output rate of the NMEA-GX-GSA message on port I2C"),
  478. ("CFG-MSGOUT-NMEA_ID_GSA_SPI", 0x209100c3, "U1", 1, "",
  479. "Output rate of the NMEA-GX-GSA message on port SPI"),
  480. ("CFG-MSGOUT-NMEA_ID_GSA_UART1", 0x209100c0, "U1", 1, "",
  481. "Output rate of the NMEA-GX-GSA message on port UART1"),
  482. ("CFG-MSGOUT-NMEA_ID_GSA_UART2", 0x209100c1, "U1", 1, "",
  483. "Output rate of the NMEA-GX-GSA message on port UART2"),
  484. ("CFG-MSGOUT-NMEA_ID_GSA_USB", 0x209100c2, "U1", 1, "",
  485. "Output rate of the NMEA-GX-GSA message on port USB"),
  486. ("CFG-MSGOUT-NMEA_ID_GST_I2C", 0x209100d3, "U1", 1, "",
  487. "Output rate of the NMEA-GX-GST message on port I2C"),
  488. ("CFG-MSGOUT-NMEA_ID_GST_SPI", 0x209100d7, "U1", 1, "",
  489. "Output rate of the NMEA-GX-GST message on port SPI"),
  490. ("CFG-MSGOUT-NMEA_ID_GST_UART1", 0x209100d4, "U1", 1, "",
  491. "Output rate of the NMEA-GX-GST message on port UART1"),
  492. ("CFG-MSGOUT-NMEA_ID_GST_UART2", 0x209100d5, "U1", 1, "",
  493. "Output rate of the NMEA-GX-GST message on port UART2"),
  494. ("CFG-MSGOUT-NMEA_ID_GST_USB", 0x209100d6, "U1", 1, "",
  495. "Output rate of the NMEA-GX-GST message on port USB"),
  496. ("CFG-MSGOUT-NMEA_ID_GSV_I2C", 0x209100c4, "U1", 1, "",
  497. "Output rate of the NMEA-GX-GSV message on port I2C"),
  498. ("CFG-MSGOUT-NMEA_ID_GSV_SPI", 0x209100c8, "U1", 1, "",
  499. "Output rate of the NMEA-GX-GSV message on port SPI"),
  500. ("CFG-MSGOUT-NMEA_ID_GSV_UART1", 0x209100c5, "U1", 1, "",
  501. "Output rate of the NMEA-GX-GSV message on port UART1"),
  502. ("CFG-MSGOUT-NMEA_ID_GSV_UART2", 0x209100c6, "U1", 1, "",
  503. "Output rate of the NMEA-GX-GSV message on port UART"),
  504. ("CFG-MSGOUT-NMEA_ID_GSV_USB", 0x209100c7, "U1", 1, "",
  505. "Output rate of the NMEA-GX-GSV message on port USB"),
  506. ("CFG-MSGOUT-NMEA_ID_RLM_I2C", 0x20910400, "U1", 1, "",
  507. "Output rate of the NMEA-GX-RLM message on port I2C"),
  508. ("CFG-MSGOUT-NMEA_ID_RLM_SPI", 0x20910404, "U1", 1, "",
  509. "Output rate of the NMEA-GX-RLM message on port SPI"),
  510. ("CFG-MSGOUT-NMEA_ID_RLM_UART1", 0x20910401, "U1", 1, "",
  511. "Output rate of the NMEA-GX-RLM message on port UART1"),
  512. ("CFG-MSGOUT-NMEA_ID_RLM_UART2", 0x20910402, "U1", 1, "",
  513. "Output rate of the NMEA-GX-RLM message on port UART2"),
  514. ("CFG-MSGOUT-NMEA_ID_RLM_USB", 0x20910403, "U1", 1, "",
  515. "Output rate of the NMEA-GX-RLM message on port USB"),
  516. ("CFG-MSGOUT-NMEA_ID_RMC_I2C", 0x209100ab, "U1", 1, "",
  517. "Output rate of the NMEA-GX-RMC message on port I2C"),
  518. ("CFG-MSGOUT-NMEA_ID_RMC_SPI", 0x209100af, "U1", 1, "",
  519. "Output rate of the NMEA-GX-RMC message on port SPI"),
  520. ("CFG-MSGOUT-NMEA_ID_RMC_UART1", 0x209100ac, "U1", 1, "",
  521. "Output rate of the NMEA-GX-RMC message on port UART1"),
  522. ("CFG-MSGOUT-NMEA_ID_RMC_UART2", 0x209100ad, "U1", 1, "",
  523. "Output rate of the NMEA-GX-RMC message on port UART2"),
  524. ("CFG-MSGOUT-NMEA_ID_RMC_USB", 0x209100ae, "U1", 1, "",
  525. "Output rate of the NMEA-GX-RMC message on port USB"),
  526. ("CFG-MSGOUT-NMEA_ID_VLW_I2C", 0x209100e7, "U1", 1, "",
  527. "Output rate of the NMEA-GX-VLW message on port I2C"),
  528. ("CFG-MSGOUT-NMEA_ID_VLW_SPI", 0x209100eb, "U1", 1, "",
  529. "Output rate of the NMEA-GX-VLW message on port SPI"),
  530. ("CFG-MSGOUT-NMEA_ID_VLW_UART1", 0x209100e8, "U1", 1, "",
  531. "Output rate of the NMEA-GX-VLW message on port UART1"),
  532. ("CFG-MSGOUT-NMEA_ID_VLW_UART2", 0x209100e9, "U1", 1, "",
  533. "Output rate of the NMEA-GX-VLW message on port UART2"),
  534. ("CFG-MSGOUT-NMEA_ID_VLW_USB", 0x209100ea, "U1", 1, "",
  535. "Output rate of the NMEA-GX-VLW message on port USB"),
  536. ("CFG-MSGOUT-NMEA_ID_VTG_I2C", 0x209100b0, "U1", 1, "",
  537. "Output rate of the NMEA-GX-VTG message on port I2C"),
  538. ("CFG-MSGOUT-NMEA_ID_VTG_SPI", 0x209100b4, "U1", 1, "",
  539. "Output rate of the NMEA-GX-VTG message on port SPI"),
  540. ("CFG-MSGOUT-NMEA_ID_VTG_UART1", 0x209100b1, "U1", 1, "",
  541. "Output rate of the NMEA-GX-VTG message on port UART1"),
  542. ("CFG-MSGOUT-NMEA_ID_VTG_UART2", 0x209100b2, "U1", 1, "",
  543. "Output rate of the NMEA-GX-VTG message on port UART2"),
  544. ("CFG-MSGOUT-NMEA_ID_VTG_USB", 0x209100b3, "U1", 1, "",
  545. "Output rate of the NMEA-GX-VTG message on port USB"),
  546. ("CFG-MSGOUT-NMEA_ID_ZDA_I2C", 0x209100d8, "U1", 1, "",
  547. "Output rate of the NMEA-GX-ZDA message on port I2C"),
  548. ("CFG-MSGOUT-NMEA_ID_ZDA_SPI", 0x209100dc, "U1", 1, "",
  549. "Output rate of the NMEA-GX-ZDA message on port SPI"),
  550. ("CFG-MSGOUT-NMEA_ID_ZDA_UART1", 0x209100d9, "U1", 1, "",
  551. "Output rate of the NMEA-GX-ZDA message on port UART1"),
  552. ("CFG-MSGOUT-NMEA_ID_ZDA_UART2", 0x209100da, "U1", 1, "",
  553. "Output rate of the NMEA-GX-ZDA message on port UART2"),
  554. ("CFG-MSGOUT-NMEA_ID_ZDA_USB", 0x209100db, "U1", 1, "",
  555. "Output rate of the NMEA-GX-ZDA message on port USB"),
  556. # CFG-MSGOUT-PUBX
  557. ("CFG-MSGOUT-PUBX_ID_POLYP_I2C", 0x209100ec, "U1", 1, "",
  558. "Output rate of the NMEA-GX-PUBX00 message on port I2C"),
  559. ("CFG-MSGOUT-PUBX_ID_POLYP_SPI", 0x209100f0, "U1", 1, "",
  560. "Output rate of the NMEA-GX-PUBX00 message on port SPI"),
  561. ("CFG-MSGOUT-PUBX_ID_POLYP_UART1", 0x209100ed, "U1", 1, "",
  562. "Output rate of the NMEA-GX-PUBX00 message on port UART1"),
  563. ("CFG-MSGOUT-PUBX_ID_POLYP_UART2", 0x209100ee, "U1", 1, "",
  564. "Output rate of the NMEA-GX-PUBX00 message on port UART2"),
  565. ("CFG-MSGOUT-PUBX_ID_POLYP_USB", 0x209100ef, "U1", 1, "",
  566. "Output rate of the NMEA-GX-PUBX00 message on port USB"),
  567. ("CFG-MSGOUT-PUBX_ID_POLYS_I2C", 0x209100f1, "U1", 1, "",
  568. "Output rate of the NMEA-GX-PUBX03 message on port I2C"),
  569. ("CFG-MSGOUT-PUBX_ID_POLYS_SPI", 0x209100f5, "U1", 1, "",
  570. "Output rate of the NMEA-GX-PUBX03 message on port SPI"),
  571. ("CFG-MSGOUT-PUBX_ID_POLYS_UART1", 0x209100f2, "U1", 1, "",
  572. "Output rate of the NMEA-GX-PUBX03 message on port UART1"),
  573. ("CFG-MSGOUT-PUBX_ID_POLYS_UART2", 0x209100f3, "U1", 1, "",
  574. "Output rate of the NMEA-GX-PUBX03 message on port UART2"),
  575. ("CFG-MSGOUT-PUBX_ID_POLYS_USB", 0x209100f4, "U1", 1, "",
  576. "Output rate of the NMEA-GX-PUBX03 message on port USB"),
  577. ("CFG-MSGOUT-PUBX_ID_POLYT_I2C", 0x209100f6, "U1", 1, "",
  578. "Output rate of the NMEA-GX-PUBX04 message on port I2C"),
  579. ("CFG-MSGOUT-PUBX_ID_POLYT_SPI", 0x209100fa, "U1", 1, "",
  580. "Output rate of the NMEA-GX-PUBX04 message on port SPI"),
  581. ("CFG-MSGOUT-PUBX_ID_POLYT_UART1", 0x209100f7, "U1", 1, "",
  582. "Output rate of the NMEA-GX-PUBX04 message on port UART1"),
  583. ("CFG-MSGOUT-PUBX_ID_POLYT_UART2", 0x209100f8, "U1", 1, "",
  584. "Output rate of the NMEA-GX-PUBX04 message on port UART2"),
  585. ("CFG-MSGOUT-PUBX_ID_POLYT_USB", 0x209100f9, "U1", 1, "",
  586. "Output rate of the NMEA-GX-PUBX04 message on port USB"),
  587. # CFG-MSGOUT-RTCM_3X
  588. ("CFG-MSGOUT-RTCM_3X_TYPE1005_I2C", 0x209102bd, "U1", 1, "",
  589. "Output rate of the RTCM-3X-TYPE1005 message on port I2C"),
  590. ("CFG-MSGOUT-RTCM_3X_TYPE1005_SPI", 0x209102c1, "U1", 1, "",
  591. "Output rate of the RTCM-3X-TYPE1005 message on port SPI"),
  592. ("CFG-MSGOUT-RTCM_3X_TYPE1005_UART1", 0x209102be, "U1", 1, "",
  593. "Output rate of the RTCM-3X-TYPE1005 message on port UART1"),
  594. ("CFG-MSGOUT-RTCM_3X_TYPE1005_UART2", 0x209102bf, "U1", 1, "",
  595. "Output rate of the RTCM-3X-TYPE1005 message on port UART2"),
  596. ("CFG-MSGOUT-RTCM_3X_TYPE1005_USB", 0x209102c0, "U1", 1, "",
  597. "Output rate of the RTCM-3X-TYPE1005 message on port USB"),
  598. ("CFG-MSGOUT-RTCM_3X_TYPE1074_I2C", 0x2091035e, "U1", 1, "",
  599. "Output rate of the RTCM-3X-TYPE1074 message on port I2C"),
  600. ("CFG-MSGOUT-RTCM_3X_TYPE1074_SPI", 0x20910362, "U1", 1, "",
  601. "Output rate of the RTCM-3X-TYPE1074 message on port SPI"),
  602. ("CFG-MSGOUT-RTCM_3X_TYPE1074_UART1", 0x2091035f, "U1", 1, "",
  603. "Output rate of the RTCM-3X-TYPE1074 message on port UART1"),
  604. ("CFG-MSGOUT-RTCM_3X_TYPE1074_UART2", 0x20910360, "U1", 1, "",
  605. "Output rate of the RTCM-3X-TYPE1074 message on port UART2"),
  606. ("CFG-MSGOUT-RTCM_3X_TYPE1074_USB", 0x20910361, "U1", 1, "",
  607. "Output rate of the RTCM-3X-TYPE1074 message on port USB"),
  608. ("CFG-MSGOUT-RTCM_3X_TYPE1077_I2C", 0x209102cc, "U1", 1, "",
  609. "Output rate of the RTCM-3X-TYPE1077 message on port I2"),
  610. ("CFG-MSGOUT-RTCM_3X_TYPE1077_SPI", 0x209102d0, "U1", 1, "",
  611. "Output rate of the RTCM-3X-TYPE1077 message on port SPI"),
  612. ("CFG-MSGOUT-RTCM_3X_TYPE1077_UART1", 0x209102cd, "U1", 1, "",
  613. "Output rate of the RTCM-3X-TYPE1077 message on port UART1"),
  614. ("CFG-MSGOUT-RTCM_3X_TYPE1077_UART2", 0x209102ce, "U1", 1, "",
  615. "Output rate of the RTCM-3X-TYPE1077 message on port UART2"),
  616. ("CFG-MSGOUT-RTCM_3X_TYPE1077_USB", 0x209102cf, "U1", 1, "",
  617. "Output rate of the RTCM-3X-TYPE1077 message on port USB"),
  618. ("CFG-MSGOUT-RTCM_3X_TYPE1087_I2C", 0x209102d1, "U1", 1, "",
  619. "Output rate of the RTCM-3X-TYPE1087 message on port I2C"),
  620. ("CFG-MSGOUT-RTCM_3X_TYPE1084_SPI", 0x20910367, "U1", 1, "",
  621. "Output rate of the RTCM-3X-TYPE1084 message on port SPI"),
  622. ("CFG-MSGOUT-RTCM_3X_TYPE1084_UART1", 0x20910364, "U1", 1, "",
  623. "Output rate of the RTCM-3X-TYPE1084 message on port UART1"),
  624. ("CFG-MSGOUT-RTCM_3X_TYPE1084_UART2", 0x20910365, "U1", 1, "",
  625. "Output rate of the RTCM-3X-TYPE1084 message on port UART2"),
  626. ("CFG-MSGOUT-RTCM_3X_TYPE1084_USB", 0x20910366, "U1", 1, "",
  627. "Output rate of the RTCM-3X-TYPE1084 message on port USB"),
  628. ("CFG-MSGOUT-RTCM_3X_TYPE1087_SPI", 0x209102d5, "U1", 1, "",
  629. "Output rate of the RTCM-3X-TYPE1087 message on port SPI"),
  630. ("CFG-MSGOUT-RTCM_3X_TYPE1087_UART1", 0x209102d2, "U1", 1, "",
  631. "Output rate of the RTCM-3X-TYPE1087 message on port UART1"),
  632. ("CFG-MSGOUT-RTCM_3X_TYPE1087_UART2", 0x209102d3, "U1", 1, "",
  633. "Output rate of the RTCM-3X-TYPE1087 message on port UART2"),
  634. ("CFG-MSGOUT-RTCM_3X_TYPE1087_USB", 0x209102d4, "U1", 1, "",
  635. "Output rate of the RTCM-3X-TYPE1087 message on port USB"),
  636. ("CFG-MSGOUT-RTCM_3X_TYPE1094_I2C", 0x20910368, "U1", 1, "",
  637. "Output rate of the RTCM-3X-TYPE1094 message on port I2C"),
  638. ("CFG-MSGOUT-RTCM_3X_TYPE1094_SPI", 0x2091036c, "U1", 1, "",
  639. "Output rate of the RTCM-3X-TYPE1094 message on port SPI"),
  640. ("CFG-MSGOUT-RTCM_3X_TYPE1094_UART1", 0x20910369, "U1", 1, "",
  641. "Output rate of the RTCM-3X-TYPE1094 message on port UART1"),
  642. ("CFG-MSGOUT-RTCM_3X_TYPE1094_UART2", 0x2091036a, "U1", 1, "",
  643. "Output rate of the RTCM-3X-TYPE1094 message on port UART2"),
  644. ("CFG-MSGOUT-RTCM_3X_TYPE1094_USB", 0x2091036b, "U1", 1, "",
  645. "Output rate of the RTCM-3X-TYPE1094 message on port USB"),
  646. ("CFG-MSGOUT-RTCM_3X_TYPE1097_I2C", 0x20910318, "U1", 1, "",
  647. "Output rate of the RTCM-3X-TYPE1097 message on port I2C"),
  648. ("CFG-MSGOUT-RTCM_3X_TYPE1097_SPI", 0x2091031c, "U1", 1, "",
  649. "Output rate of the RTCM-3X-TYPE1097 message on port SPI"),
  650. ("CFG-MSGOUT-RTCM_3X_TYPE1097_UART1", 0x20910319, "U1", 1, "",
  651. "Output rate of the RTCM-3X-TYPE1097 message on port UART1"),
  652. ("CFG-MSGOUT-RTCM_3X_TYPE1097_UART2", 0x2091031a, "U1", 1, "",
  653. "Output rate of the RTCM-3X-TYPE1097 message on port UART2"),
  654. ("CFG-MSGOUT-RTCM_3X_TYPE1097_USB", 0x2091031b, "U1", 1, "",
  655. "Output rate of the RTCM-3X-TYPE1097 message on port USB"),
  656. ("CFG-MSGOUT-RTCM_3X_TYPE1124_I2C", 0x2091036d, "U1", 1, "",
  657. "Output rate of the RTCM-3X-TYPE1124 message on port I2C"),
  658. ("CFG-MSGOUT-RTCM_3X_TYPE1124_SPI", 0x20910371, "U1", 1, "",
  659. "Output rate of the RTCM-3X-TYPE1124 message on port SPI"),
  660. ("CFG-MSGOUT-RTCM_3X_TYPE1124_UART1", 0x2091036e, "U1", 1, "",
  661. "Output rate of the RTCM-3X-TYPE1124 message on port UART1"),
  662. ("CFG-MSGOUT-RTCM_3X_TYPE1124_UART2", 0x2091036f, "U1", 1, "",
  663. "Output rate of the RTCM-3X-TYPE1124 message on port UART2"),
  664. ("CFG-MSGOUT-RTCM_3X_TYPE1124_USB", 0x20910370, "U1", 1, "",
  665. "Output rate of the RTCM-3X-TYPE1124 message on port USB"),
  666. ("CFG-MSGOUT-RTCM_3X_TYPE1127_I2C", 0x209102d6, "U1", 1, "",
  667. "Output rate of the RTCM-3X-TYPE1127 message on port I2C"),
  668. ("CFG-MSGOUT-RTCM_3X_TYPE1127_SPI", 0x209102da, "U1", 1, "",
  669. "Output rate of the RTCM-3X-TYPE1127 message on port SPI"),
  670. ("CFG-MSGOUT-RTCM_3X_TYPE1127_UART1", 0x209102d7, "U1", 1, "",
  671. "Output rate of the RTCM-3X-TYPE1127 message on port UART1"),
  672. ("CFG-MSGOUT-RTCM_3X_TYPE1127_UART2", 0x209102d8, "U1", 1, "",
  673. "Output rate of the RTCM-3X-TYPE1127 message on port UART2"),
  674. ("CFG-MSGOUT-RTCM_3X_TYPE1127_USB", 0x209102d9, "U1", 1, "",
  675. "Output rate of the RTCM-3X-TYPE1127 message on port USB"),
  676. ("CFG-MSGOUT-RTCM_3X_TYPE1230_I2C", 0x20910303, "U1", 1, "",
  677. "Output rate of the RTCM-3X-TYPE1230 message on port I2C"),
  678. ("CFG-MSGOUT-RTCM_3X_TYPE1230_SPI", 0x20910307, "U1", 1, "",
  679. "Output rate of the RTCM-3X-TYPE1230 message on port SPI"),
  680. ("CFG-MSGOUT-RTCM_3X_TYPE1230_UART1", 0x20910304, "U1", 1, "",
  681. "Output rate of the RTCM-3X-TYPE1230 message on port UART1"),
  682. ("CFG-MSGOUT-RTCM_3X_TYPE1230_UART2", 0x20910305, "U1", 1, "",
  683. "Output rate of the RTCM-3X-TYPE1230 message on port UART2"),
  684. ("CFG-MSGOUT-RTCM_3X_TYPE1230_USB", 0x20910306, "U1", 1, "",
  685. "Output rate of the RTCM-3X-TYPE1230 message on port USB"),
  686. ("CFG-MSGOUT-RTCM_3X_TYPE4072_0_I2C", 0x209102fe, "U1", 1, "",
  687. "Output rate of the RTCM-3X-TYPE4072, sub-type 0 message "
  688. "on port I2C"),
  689. ("CFG-MSGOUT-RTCM_3X_TYPE4072_0_SPI", 0x20910302, "U1", 1, "",
  690. "Output rate of the RTCM-3X-TYPE4072, sub-type 0 message "
  691. "on port SPI"),
  692. ("CFG-MSGOUT-RTCM_3X_TYPE4072_0_UART1", 0x209102ff, "U1", 1, "",
  693. "Output rate of the RTCM-3X-TYPE4072, sub-type 0 message "
  694. "on port UART1"),
  695. ("CFG-MSGOUT-RTCM_3X_TYPE4072_0_UART2", 0x20910300, "U1", 1, "",
  696. "Output rate of the RTCM-3X-TYPE4072, sub-type 0 message "
  697. "on port UART2"),
  698. ("CFG-MSGOUT-RTCM_3X_TYPE4072_0_USB", 0x20910301, "U1", 1, "",
  699. "Output rate of the RTCM-3X-TYPE4072, sub-type 0 message "
  700. "on port USB"),
  701. ("CFG-MSGOUT-RTCM_3X_TYPE4072_1_I2C", 0x20910381, "U1", 1, "",
  702. "Output rate of the RTCM-3X-TYPE4072, sub-type 1 message on "
  703. "port I2C"),
  704. ("CFG-MSGOUT-RTCM_3X_TYPE4072_1_SPI", 0x20910385, "U1", 1, "",
  705. "Output rate of the RTCM-3X-TYPE4072, sub-type 1 message on "
  706. "port SPI"),
  707. ("CFG-MSGOUT-RTCM_3X_TYPE4072_1_UART1", 0x20910382, "U1", 1, "",
  708. "Output rate of the RTCM-3X-TYPE4072, sub-type 1 message on "
  709. "port UART1"),
  710. ("CFG-MSGOUT-RTCM_3X_TYPE4072_1_UART2", 0x20910383, "U1", 1, "",
  711. "Output rate of the RTCM-3X-TYPE4072, sub-type 1 message on "
  712. " port UART2"),
  713. ("CFG-MSGOUT-RTCM_3X_TYPE4072_1_USB", 0x20910384, "U1", 1, "",
  714. "Output rate of the RTCM-3X-TYPE4072, sub-type 1 message "
  715. "on port USB"),
  716. # CFG-MSGOUT-UBX_LOG
  717. ("CFG-MSGOUT-UBX_LOG_INFO_I2C", 0x20910259, "U1", 1, "",
  718. "Output rate of the UBX-LOG-INFO message on port I2C"),
  719. ("CFG-MSGOUT-UBX_LOG_INFO_SPI", 0x2091025d, "U1", 1, "",
  720. "Output rate of the UBX-LOG-INFO message on port SPI"),
  721. ("CFG-MSGOUT-UBX_LOG_INFO_UART1", 0x2091025a, "U1", 1, "",
  722. "Output rate of the UBX-LOG-INFO message on port UART1"),
  723. ("CFG-MSGOUT-UBX_LOG_INFO_UART2", 0x2091025b, "U1", 1, "",
  724. "Output rate of the UBX-LOG-INFO message on port UART2"),
  725. ("CFG-MSGOUT-UBX_LOG_INFO_USB", 0x2091025c, "U1", 1, "",
  726. "Output rate of the UBX-LOG-INFO message on port USB"),
  727. # CFG-MSGOUT-UBX_MON
  728. ("CFG-MSGOUT-UBX_MON_COMMS_I2C", 0x2091034f, "U1", 1, "",
  729. "Output rate of the UBX-MON-COMMS message on port I2C"),
  730. ("CFG-MSGOUT-UBX_MON_COMMS_SPI", 0x20910353, "U1", 1, "",
  731. "Output rate of the UBX-MON-COMMS message on port SPI"),
  732. ("CFG-MSGOUT-UBX_MON_COMMS_UART1", 0x20910350, "U1", 1, "",
  733. "Output rate of the UBX-MON-COMMS message on port UART1"),
  734. ("CFG-MSGOUT-UBX_MON_COMMS_UART2", 0x20910351, "U1", 1, "",
  735. "Output rate of the UBX-MON-COMMS message on port UART2"),
  736. ("CFG-MSGOUT-UBX_MON_COMMS_USB", 0x20910352, "U1", 1, "",
  737. "Output rate of the UBX-MON-COMMS message on port USB"),
  738. ("CFG-MSGOUT-UBX_MON_HW2_I2C", 0x209101b9, "U1", 1, "",
  739. "Output rate of the UBX-MON-HW2 message on port I2C"),
  740. ("CFG-MSGOUT-UBX_MON_HW2_SPI", 0x209101bd, "U1", 1, "",
  741. "Output rate of the UBX-MON-HW2 message on port SPI"),
  742. ("CFG-MSGOUT-UBX_MON_HW2_UART1", 0x209101ba, "U1", 1, "",
  743. "Output rate of the UBX-MON-HW2 message on port UART1"),
  744. ("CFG-MSGOUT-UBX_MON_HW2_UART2", 0x209101bb, "U1", 1, "",
  745. "Output rate of the UBX-MON-HW2 message on port UART2"),
  746. ("CFG-MSGOUT-UBX_MON_HW2_USB", 0x209101bc, "U1", 1, "",
  747. "Output rate of the UBX-MON-HW2 message on port USB"),
  748. ("CFG-MSGOUT-UBX_MON_HW3_I2C", 0x20910354, "U1", 1, "",
  749. "Output rate of the UBX-MON-HW3 message on port I2C"),
  750. ("CFG-MSGOUT-UBX_MON_HW3_SPI", 0x20910358, "U1", 1, "",
  751. "Output rate of the UBX-MON-HW3 message on port SPI"),
  752. ("CFG-MSGOUT-UBX_MON_HW3_UART1", 0x20910355, "U1", 1, "",
  753. "Output rate of the UBX-MON-HW3 message on port UART1"),
  754. ("CFG-MSGOUT-UBX_MON_HW3_UART2", 0x20910356, "U1", 1, "",
  755. "Output rate of the UBX-MON-HW3 message on port UART2"),
  756. ("CFG-MSGOUT-UBX_MON_HW3_USB", 0x20910357, "U1", 1, "",
  757. "Output rate of the UBX-MON-HW3 message on port USB"),
  758. ("CFG-MSGOUT-UBX_MON_HW_I2C", 0x209101b4, "U1", 1, "",
  759. "Output rate of the UBX-MON-HW message on port I2C"),
  760. ("CFG-MSGOUT-UBX_MON_HW_SPI", 0x209101b8, "U1", 1, "",
  761. "Output rate of the UBX-MON-HW message on port SPI"),
  762. ("CFG-MSGOUT-UBX_MON_HW_UART1", 0x209101b5, "U1", 1, "",
  763. "Output rate of the UBX-MON-HW message on port UART1"),
  764. ("CFG-MSGOUT-UBX_MON_HW_UART2", 0x209101b6, "U1", 1, "",
  765. "Output rate of the UBX-MON-HW message on port UART2"),
  766. ("CFG-MSGOUT-UBX_MON_HW_USB", 0x209101b7, "U1", 1, "",
  767. "Output rate of the UBX-MON-HW message on port USB"),
  768. ("CFG-MSGOUT-UBX_MON_IO_I2C", 0x209101a5, "U1", 1, "",
  769. "Output rate of the UBX-MON-IO message on port I2C"),
  770. ("CFG-MSGOUT-UBX_MON_IO_SPI", 0x209101a9, "U1", 1, "",
  771. "Output rate of the UBX-MON-IO message on port SPI"),
  772. ("CFG-MSGOUT-UBX_MON_IO_UART1", 0x209101a6, "U1", 1, "",
  773. "Output rate of the UBX-MON-IO message on port UART1"),
  774. ("CFG-MSGOUT-UBX_MON_IO_UART2", 0x209101a7, "U1", 1, "",
  775. "Output rate of the UBX-MON-IO message on port UART2"),
  776. ("CFG-MSGOUT-UBX_MON_IO_USB", 0x209101a8, "U1", 1, "",
  777. "Output rate of the UBX-MON-IO message on port USB"),
  778. ("CFG-MSGOUT-UBX_MON_MSGPP_I2C", 0x20910196, "U1", 1, "",
  779. "Output rate of the UBX-MON-MSGPP message on port I2C"),
  780. ("CFG-MSGOUT-UBX_MON_MSGPP_SPI", 0x2091019a, "U1", 1, "",
  781. "Output rate of the UBX-MON-MSGPP message on port SPI"),
  782. ("CFG-MSGOUT-UBX_MON_MSGPP_UART1", 0x20910197, "U1", 1, "",
  783. "Output rate of the UBX-MON-MSGPP message on port UART1"),
  784. ("CFG-MSGOUT-UBX_MON_MSGPP_UART2", 0x20910198, "U1", 1, "",
  785. "Output rate of the UBX-MON-MSGPP message on port UART2"),
  786. ("CFG-MSGOUT-UBX_MON_MSGPP_USB", 0x20910199, "U1", 1, "",
  787. "Output rate of the UBX-MON-MSGPP message on port USB"),
  788. ("CFG-MSGOUT-UBX_MON_RF_I2C", 0x20910359, "U1", 1, "",
  789. "Output rate of the UBX-MON-RF message on port I2C"),
  790. ("CFG-MSGOUT-UBX_MON_RF_SPI", 0x2091035d, "U1", 1, "",
  791. "Output rate of the UBX-MON-RF message on port SPI"),
  792. ("CFG-MSGOUT-UBX_MON_RF_UART1", 0x2091035a, "U1", 1, "",
  793. "Output rate of the UBX-MON-RF message on port UART1"),
  794. ("CFG-MSGOUT-UBX_MON_RF_UART2", 0x2091035b, "U1", 1, "",
  795. "Output rate of the UBX-MON-RF message on port UART2"),
  796. ("CFG-MSGOUT-UBX_MON_RF_USB", 0x2091035c, "U1", 1, "",
  797. "Output rate of the UBX-MON-RF message on port USB"),
  798. ("CFG-MSGOUT-UBX_NAV_TIMEQZSS_I2C", 0x20910386, "U1", 1, "",
  799. "Output rate of the UBX-NAV-TIMEQZSS message on port I2C"),
  800. ("CFG-MSGOUT-UBX_NAV_TIMEQZSS_SPI", 0x2091038a, "U1", 1, "",
  801. "Output rate of the UBX-NAV-TIMEQZSS message on port SPI"),
  802. ("CFG-MSGOUT-UBX_NAV_TIMEQZSS_USB", 0x20910387, "U1", 1, "",
  803. "Output rate of the UBX-NAV-TIMEQZSS message on port USB"),
  804. ("CFG-MSGOUT-UBX_NAV_TIMEQZSS_UART1", 0x20910388, "U1", 1, "",
  805. "Output rate of the UBX-NAV-TIMEQZSS message on port UART1"),
  806. ("CFG-MSGOUT-UBX_NAV_TIMEQZSS_UART2", 0x20910389, "U1", 1, "",
  807. "Output rate of the UBX-NAV-TIMEQZSS message on port UART2"),
  808. ("CFG-MSGOUT-UBX_MON_RXBUF_I2C", 0x209101a0, "U1", 1, "",
  809. "Output rate of the UBX-MON-RXBUF message on port I2C"),
  810. ("CFG-MSGOUT-UBX_MON_RXBUF_SPI", 0x209101a4, "U1", 1, "",
  811. "Output rate of the UBX-MON-RXBUF message on port SPI"),
  812. ("CFG-MSGOUT-UBX_MON_RXBUF_UART1", 0x209101a1, "U1", 1, "",
  813. "Output rate of the UBX-MON-RXBUF message on port UART1"),
  814. ("CFG-MSGOUT-UBX_MON_RXBUF_UART2", 0x209101a2, "U1", 1, "",
  815. "Output rate of the UBX-MON-RXBUF message on port UART2"),
  816. ("CFG-MSGOUT-UBX_MON_RXBUF_USB", 0x209101a3, "U1", 1, "",
  817. "Output rate of the UBX-MON-RXBUF message on port USB"),
  818. ("CFG-MSGOUT-UBX_MON_RXR_I2C", 0x20910187, "U1", 1, "",
  819. "Output rate of the UBX-MON-RXR message on port I2C"),
  820. ("CFG-MSGOUT-UBX_MON_RXR_SPI", 0x2091018b, "U1", 1, "",
  821. "Output rate of the UBX-MON-RXR message on port SPI"),
  822. ("CFG-MSGOUT-UBX_MON_RXR_UART1", 0x20910188, "U1", 1, "",
  823. "Output rate of the UBX-MON-RXR message on port UART1"),
  824. ("CFG-MSGOUT-UBX_MON_RXR_UART2", 0x20910189, "U1", 1, "",
  825. "Output rate of the UBX-MON-RXR message on port UART2"),
  826. ("CFG-MSGOUT-UBX_MON_RXR_USB", 0x2091018a, "U1", 1, "",
  827. "Output rate of the UBX-MON-RXR message on port USB"),
  828. ("CFG-MSGOUT-UBX_MON_SPAN_I2C", 0x2091038b, "U1", 1, "",
  829. "Output rate of the UBX-MON-SPAN message on port I2C"),
  830. ("CFG-MSGOUT-UBX_MON_SPAN_SPI", 0x2091038f, "U1", 1, "",
  831. "Output rate of the UBX-MON-SPAN message on port SPI"),
  832. ("CFG-MSGOUT-UBX_MON_SPAN_UART1", 0x2091038c, "U1", 1, "",
  833. "Output rate of the UBX-MON-SPAN message on port UART1"),
  834. ("CFG-MSGOUT-UBX_MON_SPAN_UART2", 0x2091038d, "U1", 1, "",
  835. "Output rate of the UBX-MON-SPAN message on port UART2"),
  836. ("CFG-MSGOUT-UBX_MON_SPAN_USB", 0x2091038e, "U1", 1, "",
  837. "Output rate of the UBX-MON-SPAN message on port USB"),
  838. ("CFG-MSGOUT-UBX_MON_TXBUF_I2C", 0x2091019b, "U1", 1, "",
  839. "Output rate of the UBX-MON-TXBUF message on port I2C"),
  840. ("CFG-MSGOUT-UBX_MON_TXBUF_SPI", 0x2091019f, "U1", 1, "",
  841. "Output rate of the UBX-MON-TXBUF message on port SPI"),
  842. ("CFG-MSGOUT-UBX_MON_TXBUF_UART1", 0x2091019c, "U1", 1, "",
  843. "Output rate of the UBX-MON-TXBUF message on port UART1"),
  844. ("CFG-MSGOUT-UBX_MON_TXBUF_UART2", 0x2091019d, "U1", 1, "",
  845. "Output rate of the UBX-MON-TXBUF message on port UART2"),
  846. ("CFG-MSGOUT-UBX_MON_TXBUF_USB", 0x2091019e, "U1", 1, "",
  847. "Output rate of the UBX-MON-TXBUF message on port USB"),
  848. ("CFG-MSGOUT-UBX_NAV_AOPSTATUS_I2C", 0x20910079, "U1", 1, "",
  849. "Output rate of the UBX-MON-AOPSTATUS message on port I2C"),
  850. ("CFG-MSGOUT-UBX_NAV_AOPSTATUS_SPI", 0x2091007d, "U1", 1, "",
  851. "Output rate of the UBX-MON-AOPSTATUS message on port SPI"),
  852. ("CFG-MSGOUT-UBX_NAV_AOPSTATUS_UART1", 0x2091007a, "U1", 1, "",
  853. "Output rate of the UBX-MON-AOPSTATUS message on port UART1"),
  854. ("CFG-MSGOUT-UBX_NAV_AOPSTATUS_UART2", 0x2091007b, "U1", 1, "",
  855. "Output rate of the UBX-MON-AOPSTATUS message on port UART2"),
  856. ("CFG-MSGOUT-UBX_NAV_AOPSTATUS_USB", 0x2091007c, "U1", 1, "",
  857. "Output rate of the UBX-MON-AOPSTATUS message on port USB"),
  858. ("CFG-MSGOUT-UBX_MON_TXBUF_I2C", 0x2091019b, "U1", 1, "",
  859. "Output rate of the UBX-MON-TXBUF message on port I2C"),
  860. ("CFG-MSGOUT-UBX_MON_TXBUF_SPI", 0x2091019f, "U1", 1, "",
  861. "Output rate of the UBX-MON-TXBUF message on port SPI"),
  862. ("CFG-MSGOUT-UBX_MON_TXBUF_UART1", 0x2091019c, "U1", 1, "",
  863. "Output rate of the UBX-MON-TXBUF message on port UART1"),
  864. ("CFG-MSGOUT-UBX_MON_TXBUF_UART2", 0x2091019d, "U1", 1, "",
  865. "Output rate of the UBX-MON-TXBUF message on port UART2"),
  866. ("CFG-MSGOUT-UBX_MON_TXBUF_USB", 0x2091019e, "U1", 1, "",
  867. "Output rate of the UBX-MON-TXBUF message on port USB"),
  868. # CFG-MSGOUT-UBX_NAV
  869. ("CFG-MSGOUT-UBX_NAV_CLOCK_I2C", 0x20910065, "U1", 1, "",
  870. "Output rate of the UBX-NAV-CLOCK message on port I2C"),
  871. ("CFG-MSGOUT-UBX_NAV_CLOCK_SPI", 0x20910069, "U1", 1, "",
  872. "Output rate of the UBX-NAV-CLOCK message on port SPI"),
  873. ("CFG-MSGOUT-UBX_NAV_CLOCK_UART1", 0x20910066, "U1", 1, "",
  874. "Output rate of the UBX-NAV-CLOCK message on port UART1"),
  875. ("CFG-MSGOUT-UBX_NAV_CLOCK_UART2", 0x20910067, "U1", 1, "",
  876. "Output rate of the UBX-NAV-CLOCK message on port UART2"),
  877. ("CFG-MSGOUT-UBX_NAV_CLOCK_USB", 0x20910068, "U1", 1, "",
  878. "Output rate of the UBX-NAV- CLOCK message on port USB"),
  879. ("CFG-MSGOUT-UBX_NAV_DOP_I2C", 0x20910038, "U1", 1, "",
  880. "Output rate of the UBX-NAV-DOP message on port I2C"),
  881. ("CFG-MSGOUT-UBX_NAV_DOP_SPI", 0x2091003c, "U1", 1, "",
  882. "Output rate of the UBX-NAV-DOP message on port SPI"),
  883. ("CFG-MSGOUT-UBX_NAV_DOP_UART1", 0x20910039, "U1", 1, "",
  884. "Output rate of the UBX-NAV-DOP message on port UART1"),
  885. ("CFG-MSGOUT-UBX_NAV_DOP_UART2", 0x2091003a, "U1", 1, "",
  886. "Output rate of the UBX-NAV-DOP message on port UART2"),
  887. ("CFG-MSGOUT-UBX_NAV_DOP_USB", 0x2091003b, "U1", 1, "",
  888. "Output rate of the UBX-NAV-DOP message on port USB"),
  889. ("CFG-MSGOUT-UBX_NAV_EOE_I2C", 0x2091015f, "U1", 1, "",
  890. "Output rate of the UBX-NAV-EOE message on port I2C"),
  891. ("CFG-MSGOUT-UBX_NAV_EOE_SPI", 0x20910163, "U1", 1, "",
  892. "Output rate of the UBX-NAV-EOE message on port SPI"),
  893. ("CFG-MSGOUT-UBX_NAV_EOE_UART1", 0x20910160, "U1", 1, "",
  894. "Output rate of the UBX-NAV-EOE message on port UART1"),
  895. ("CFG-MSGOUT-UBX_NAV_EOE_UART2", 0x20910161, "U1", 1, "",
  896. "Output rate of the UBX-NAV-EOE message on port UART2"),
  897. ("CFG-MSGOUT-UBX_NAV_EOE_USB", 0x20910162, "U1", 1, "",
  898. "Output rate of the UBX-NAV-EOE message on port USB"),
  899. ("CFG-MSGOUT-UBX_NAV_GEOFENCE_I2C", 0x209100a1, "U1", 1, "",
  900. "Output rate of the UBX-NAV-GEOFENCE message on port I2C"),
  901. ("CFG-MSGOUT-UBX_NAV_GEOFENCE_SPI", 0x209100a5, "U1", 1, "",
  902. "Output rate of the UBX-NAV-GEOFENCE message on port SPI"),
  903. ("CFG-MSGOUT-UBX_NAV_GEOFENCE_UART1", 0x209100a2, "U1", 1, "",
  904. "Output rate of the UBX-NAV-GEOFENCE message on port UART1"),
  905. ("CFG-MSGOUT-UBX_NAV_GEOFENCE_UART2", 0x209100a3, "U1", 1, "",
  906. "Output rate of the UBX-NAV-GEOFENCE message on port UART2"),
  907. ("CFG-MSGOUT-UBX_NAV_GEOFENCE_USB", 0x209100a4, "U1", 1, "",
  908. "Output rate of the UBX-NAV- GEOFENCE message on port USB"),
  909. ("CFG-MSGOUT-UBX_NAV_HPPOSECEF_I2C", 0x2091002e, "U1", 1, "",
  910. "Output rate of the UBX-NAV-HPPOSECEF message on port I2C"),
  911. ("CFG-MSGOUT-UBX_NAV_HPPOSECEF_SPI", 0x20910032, "U1", 1, "",
  912. "Output rate of the UBX-NAV-HPPOSECEF message on port SPI"),
  913. ("CFG-MSGOUT-UBX_NAV_HPPOSECEF_UART1", 0x2091002f, "U1", 1, "",
  914. "Output rate of the UBX-NAV-HPPOSECEF message on port UART1"),
  915. ("CFG-MSGOUT-UBX_NAV_HPPOSECEF_UART2", 0x20910030, "U1", 1, "",
  916. "Output rate of the UBX-NAV-HPPOSECEF message on port UART2"),
  917. ("CFG-MSGOUT-UBX_NAV_HPPOSECEF_USB", 0x20910031, "U1", 1, "",
  918. "Output rate of the UBX-NAV-HPPOSECEF message on port USB"),
  919. ("CFG-MSGOUT-UBX_NAV_HPPOSLLH_I2C", 0x20910033, "U1", 1, "",
  920. "Output rate of the UBX-NAV-HPPOSLLH message on port I2C"),
  921. ("CFG-MSGOUT-UBX_NAV_HPPOSLLH_SPI", 0x20910037, "U1", 1, "",
  922. "Output rate of the UBX-NAV-HPPOSLLH message on port SPI"),
  923. ("CFG-MSGOUT-UBX_NAV_HPPOSLLH_UART1", 0x20910034, "U1", 1, "",
  924. "Output rate of the UBX-NAV-HPPOSLLH message on port UART1"),
  925. ("CFG-MSGOUT-UBX_NAV_HPPOSLLH_UART2", 0x20910035, "U1", 1, "",
  926. "Output rate of the UBX-NAV-HPPOSLLH message on port UART2"),
  927. ("CFG-MSGOUT-UBX_NAV_HPPOSLLH_USB", 0x20910036, "U1", 1, "",
  928. "Output rate of the UBX-NAV-HPPOSLLH message on port USB"),
  929. ("CFG-MSGOUT-UBX_NAV_ODO_I2C", 0x2091007e, "U1", 1, "",
  930. "Output rate of the UBX-NAV-ODO message on port I2C"),
  931. ("CFG-MSGOUT-UBX_NAV_ODO_SPI", 0x20910082, "U1", 1, "",
  932. "Output rate of the UBX-NAV-ODO message on port SPI"),
  933. ("CFG-MSGOUT-UBX_NAV_ODO_UART1", 0x2091007f, "U1", 1, "",
  934. "Output rate of the UBX-NAV-ODO message on port UART1"),
  935. ("CFG-MSGOUT-UBX_NAV_ODO_UART2", 0x20910080, "U1", 1, "",
  936. "Output rate of the UBX-NAV-ODO message on port UART2"),
  937. ("CFG-MSGOUT-UBX_NAV_ODO_USB", 0x20910081, "U1", 1, "",
  938. "Output rate of the UBX-NAV-ODO message on port USB"),
  939. ("CFG-MSGOUT-UBX_NAV_ORB_I2C", 0x20910010, "U1", 1, "",
  940. "Output rate of the UBX-NAV-ORB message on port I2C"),
  941. ("CFG-MSGOUT-UBX_NAV_ORB_SPI", 0x20910014, "U1", 1, "",
  942. "Output rate of the UBX-NAV-ORB message on port SPI"),
  943. ("CFG-MSGOUT-UBX_NAV_ORB_UART1", 0x20910011, "U1", 1, "",
  944. "Output rate of the UBX-NAV-ORB message on port UART1"),
  945. ("CFG-MSGOUT-UBX_NAV_ORB_UART2", 0x20910012, "U1", 1, "",
  946. "Output rate of the UBX-NAV-ORB message on port UART2"),
  947. ("CFG-MSGOUT-UBX_NAV_ORB_USB", 0x20910013, "U1", 1, "",
  948. "Output rate of the UBX-NAV-ORB message on port USB"),
  949. ("CFG-MSGOUT-UBX_NAV_POSECEF_I2C", 0x20910024, "U1", 1, "",
  950. "Output rate of the UBX-NAV-POSECEF message on port I2C"),
  951. ("CFG-MSGOUT-UBX_NAV_POSECEF_SPI", 0x20910028, "U1", 1, "",
  952. "Output rate of the UBX-NAV-POSECEF message on port SPI"),
  953. ("CFG-MSGOUT-UBX_NAV_POSECEF_UART1", 0x20910025, "U1", 1, "",
  954. "Output rate of the UBX-NAV-POSECEF message on port UART1"),
  955. ("CFG-MSGOUT-UBX_NAV_POSECEF_UART2", 0x20910026, "U1", 1, "",
  956. "Output rate of the UBX-NAV-POSECEF message on port UART2"),
  957. ("CFG-MSGOUT-UBX_NAV_POSECEF_USB", 0x20910027, "U1", 1, "",
  958. "Output rate of the UBX-NAV-POSECEF message on port USB"),
  959. ("CFG-MSGOUT-UBX_NAV_POSLLH_I2C", 0x20910029, "U1", 1, "",
  960. "Output rate of the UBX-NAV-POSLLH message on port I2C"),
  961. ("CFG-MSGOUT-UBX_NAV_POSLLH_SPI", 0x2091002d, "U1", 1, "",
  962. "Output rate of the UBX-NAV-POSLLH message on port SPI"),
  963. ("CFG-MSGOUT-UBX_NAV_POSLLH_UART1", 0x2091002a, "U1", 1, "",
  964. "Output rate of the UBX-NAV-POSLLH message on port UART1"),
  965. ("CFG-MSGOUT-UBX_NAV_POSLLH_UART2", 0x2091002b, "U1", 1, "",
  966. "Output rate of the UBX-NAV-POSLLH message on port UART2"),
  967. ("CFG-MSGOUT-UBX_NAV_POSLLH_USB", 0x2091002c, "U1", 1, "",
  968. "Output rate of the UBX-NAV-POSLLH message on port USB"),
  969. ("CFG-MSGOUT-UBX_NAV_PVT_I2C", 0x20910006, "U1", 1, "",
  970. "Output rate of the UBX-NAV-PVT message on port I2C"),
  971. ("CFG-MSGOUT-UBX_NAV_PVT_SPI", 0x2091000a, "U1", 1, "",
  972. "Output rate of the UBX-NAV-PVT message on port SPI"),
  973. ("CFG-MSGOUT-UBX_NAV_PVT_UART1", 0x20910007, "U1", 1, "",
  974. "Output rate of the UBX-NAV-PVT message on port UART1"),
  975. ("CFG-MSGOUT-UBX_NAV_PVT_UART2", 0x20910008, "U1", 1, "",
  976. "Output rate of the UBX-NAV-PVT message on port UART2"),
  977. ("CFG-MSGOUT-UBX_NAV_PVT_USB", 0x20910009, "U1", 1, "",
  978. "Output rate of the UBX-NAV-PVT message on port USB"),
  979. ("CFG-MSGOUT-UBX_NAV_RELPOSNED_I2C", 0x2091008d, "U1", 1, "",
  980. "Output rate of the UBX-NAV-RELPOSNED message on port I2C"),
  981. ("CFG-MSGOUT-UBX_NAV_RELPOSNED_SPI", 0x20910091, "U1", 1, "",
  982. "Output rate of the UBX-NAV-RELPOSNED message on port SPI"),
  983. ("CFG-MSGOUT-UBX_NAV_RELPOSNED_UART1", 0x2091008e, "U1", 1, "",
  984. "Output rate of the UBX-NAV-RELPOSNED message on port UART1"),
  985. ("CFG-MSGOUT-UBX_NAV_RELPOSNED_UART2", 0x2091008f, "U1", 1, "",
  986. "Output rate of the UBX-NAV-RELPOSNED message on port UART2"),
  987. ("CFG-MSGOUT-UBX_NAV_RELPOSNED_USB", 0x20910090, "U1", 1, "",
  988. "Output rate of the UBX-NAV-RELPOSNED message on port USB"),
  989. ("CFG-MSGOUT-UBX_NAV_SAT_I2C", 0x20910015, "U1", 1, "",
  990. "Output rate of the UBX-NAV-SAT message on port I2C"),
  991. ("CFG-MSGOUT-UBX_NAV_SAT_SPI", 0x20910019, "U1", 1, "",
  992. "Output rate of the UBX-NAV-SAT message on port SPI"),
  993. ("CFG-MSGOUT-UBX_NAV_SAT_UART1", 0x20910016, "U1", 1, "",
  994. "Output rate of the UBX-NAV-SAT message on port UART1"),
  995. ("CFG-MSGOUT-UBX_NAV_SAT_UART2", 0x20910017, "U1", 1, "",
  996. "Output rate of the UBX-NAV-SAT message on port UART2"),
  997. ("CFG-MSGOUT-UBX_NAV_SAT_USB", 0x20910018, "U1", 1, "",
  998. "Output rate of the UBX-NAV-SAT message on port USB"),
  999. ("CFG-MSGOUT-UBX_NAV_SBAS_I2C", 0x2091006a, "U1", 1, "",
  1000. "Output rate of the UBX-NAV-SBAS message on port I2C"),
  1001. ("CFG-MSGOUT-UBX_NAV_SBAS_SPI", 0x2091006e, "U1", 1, "",
  1002. "Output rate of the UBX-NAV-SBAS message on port SPI"),
  1003. ("CFG-MSGOUT-UBX_NAV_SBAS_UART1", 0x2091006b, "U1", 1, "",
  1004. "Output rate of the UBX-NAV-SBAS message on port UART1"),
  1005. ("CFG-MSGOUT-UBX_NAV_SBAS_UART2", 0x2091006c, "U1", 1, "",
  1006. "Output rate of the UBX-NAV-SBAS message on port UART2"),
  1007. ("CFG-MSGOUT-UBX_NAV_SBAS_USB", 0x2091006d, "U1", 1, "",
  1008. "Output rate of the UBX-NAV-SBAS message on port USB"),
  1009. ("CFG-MSGOUT-UBX_NAV_SIG_I2C", 0x20910345, "U1", 1, "",
  1010. "Output rate of the UBX-NAV-SIG message on port I2C"),
  1011. ("CFG-MSGOUT-UBX_NAV_SIG_SPI", 0x20910349, "U1", 1, "",
  1012. "Output rate of the UBX-NAV-SIG message on port SPI"),
  1013. ("CFG-MSGOUT-UBX_NAV_SIG_UART1", 0x20910346, "U1", 1, "",
  1014. "Output rate of the UBX-NAV-SIG message on port UART1"),
  1015. ("CFG-MSGOUT-UBX_NAV_SIG_UART2", 0x20910347, "U1", 1, "",
  1016. "Output rate of the UBX-NAV-SIG message on port UART2"),
  1017. ("CFG-MSGOUT-UBX_NAV_SIG_USB", 0x20910348, "U1", 1, "",
  1018. "Output rate of the UBX-NAV-SIG message on port USB"),
  1019. ("CFG-MSGOUT-UBX_NAV_SLAS_I2C", 0x20910336, "U1", 1, "",
  1020. "Output rate of the UBX-NAV-SLAS message on port I2C"),
  1021. ("CFG-MSGOUT-UBX_NAV_SLAS_SPI", 0x2091033a, "U1", 1, "",
  1022. "Output rate of the UBX-NAV-SLAS message on port SPI"),
  1023. ("CFG-MSGOUT-UBX_NAV_SLAS_UART1", 0x20910338, "U1", 1, "",
  1024. "Output rate of the UBX-NAV-SLAS message on port UART1"),
  1025. ("CFG-MSGOUT-UBX_NAV_SLAS_UART2", 0x20910339, "U1", 1, "",
  1026. "Output rate of the UBX-NAV-SLAS message on port UART2"),
  1027. ("CFG-MSGOUT-UBX_NAV_SLAS_USB", 0x20910348, "U1", 1, "",
  1028. "Output rate of the UBX-NAV-SLAS message on port USB"),
  1029. ("CFG-MSGOUT-UBX_NAV_STATUS_I2C", 0x2091001a, "U1", 1, "",
  1030. "Output rate of the UBX-NAV-STATUS message on port I2C"),
  1031. ("CFG-MSGOUT-UBX_NAV_STATUS_SPI", 0x2091001e, "U1", 1, "",
  1032. "Output rate of the UBX-NAV-STATUS message on port SPI"),
  1033. ("CFG-MSGOUT-UBX_NAV_STATUS_UART1", 0x2091001b, "U1", 1, "",
  1034. "Output rate of the UBX-NAV-STATUS message on port UART1"),
  1035. ("CFG-MSGOUT-UBX_NAV_STATUS_UART2", 0x2091001c, "U1", 1, "",
  1036. "Output rate of the UBX-NAV-STATUS message on port UART2"),
  1037. ("CFG-MSGOUT-UBX_NAV_STATUS_USB", 0x2091001d, "U1", 1, "",
  1038. "Output rate of the UBX-NAV-STATUS message on port USB"),
  1039. ("CFG-MSGOUT-UBX_NAV_SVIN_I2C", 0x20910088, "U1", 1, "",
  1040. "Output rate of the UBX-NAV-SVIN message on port I2C"),
  1041. ("CFG-MSGOUT-UBX_NAV_SVIN_SPI", 0x2091008c, "U1", 1, "",
  1042. "Output rate of the UBX-NAV-SVIN message on port SPI"),
  1043. ("CFG-MSGOUT-UBX_NAV_SVIN_UART1", 0x20910089, "U1", 1, "",
  1044. "Output rate of the UBX-NAV-SVIN message on port UART1"),
  1045. ("CFG-MSGOUT-UBX_NAV_SVIN_UART2", 0x2091008a, "U1", 1, "",
  1046. "Output rate of the UBX-NAV-SVIN message on port UART2"),
  1047. ("CFG-MSGOUT-UBX_NAV_SVIN_USB", 0x2091008b, "U1", 1, "",
  1048. "Output rate of the UBX-NAV-SVIN message on port USB"),
  1049. ("CFG-MSGOUT-UBX_NAV_TIMEBDS_I2C", 0x20910051, "U1", 1, "",
  1050. "Output rate of the UBX-NAV-TIMEBDS message on port I2C"),
  1051. ("CFG-MSGOUT-UBX_NAV_TIMEBDS_SPI", 0x20910055, "U1", 1, "",
  1052. "Output rate of the UBX-NAV-TIMEBDS message on port SPI"),
  1053. ("CFG-MSGOUT-UBX_NAV_TIMEBDS_UART1", 0x20910052, "U1", 1, "",
  1054. "Output rate of the UBX-NAV-TIMEBDS message on port UART1"),
  1055. ("CFG-MSGOUT-UBX_NAV_TIMEBDS_UART2", 0x20910053, "U1", 1, "",
  1056. "Output rate of the UBX-NAV-TIMEBDS message on port UART2"),
  1057. ("CFG-MSGOUT-UBX_NAV_TIMEBDS_USB", 0x20910054, "U1", 1, "",
  1058. "Output rate of the UBX-NAV-TIMEBDS message on port USB"),
  1059. ("CFG-MSGOUT-UBX_NAV_TIMEGAL_I2C", 0x20910056, "U1", 1, "",
  1060. "Output rate of the UBX-NAV-TIMEGAL message on port I2C"),
  1061. ("CFG-MSGOUT-UBX_NAV_TIMEGAL_SPI", 0x2091005a, "U1", 1, "",
  1062. "Output rate of the UBX-NAV-TIMEGAL message on port SPI"),
  1063. ("CFG-MSGOUT-UBX_NAV_TIMEGAL_UART1", 0x20910057, "U1", 1, "",
  1064. "Output rate of the UBX-NAV-TIMEGAL message on port UART1"),
  1065. ("CFG-MSGOUT-UBX_NAV_TIMEGAL_UART2", 0x20910058, "U1", 1, "",
  1066. "Output rate of the UBX-NAV-TIMEGAL message on port UART2"),
  1067. ("CFG-MSGOUT-UBX_NAV_TIMEGAL_USB", 0x20910059, "U1", 1, "",
  1068. "Output rate of the UBX-NAV-TIMEGAL message on port USB"),
  1069. ("CFG-MSGOUT-UBX_NAV_TIMEGLO_I2C", 0x2091004c, "U1", 1, "",
  1070. "Output rate of the UBX-NAV-TIMEGLO message on port I2C"),
  1071. ("CFG-MSGOUT-UBX_NAV_TIMEGLO_SPI", 0x20910050, "U1", 1, "",
  1072. "Output rate of the UBX-NAV-TIMEGLO message on port SPI"),
  1073. ("CFG-MSGOUT-UBX_NAV_TIMEGLO_UART1", 0x2091004d, "U1", 1, "",
  1074. "Output rate of the UBX-NAV-TIMEGLO message on port UART1"),
  1075. ("CFG-MSGOUT-UBX_NAV_TIMEGLO_UART2", 0x2091004e, "U1", 1, "",
  1076. "Output rate of the UBX-NAV-TIMEGLO message on port UART2"),
  1077. ("CFG-MSGOUT-UBX_NAV_TIMEGLO_USB", 0x2091004f, "U1", 1, "",
  1078. "Output rate of the UBX-NAV-TIMEGLO message on port USB"),
  1079. ("CFG-MSGOUT-UBX_NAV_TIMEGPS_I2C", 0x20910047, "U1", 1, "",
  1080. "Output rate of the UBX-NAV-TIMEGPS message on port I2C"),
  1081. ("CFG-MSGOUT-UBX_NAV_TIMEGPS_SPI", 0x2091004b, "U1", 1, "",
  1082. "Output rate of the UBX-NAV-TIMEGPS message on port SPI"),
  1083. ("CFG-MSGOUT-UBX_NAV_TIMEGPS_UART1", 0x20910048, "U1", 1, "",
  1084. "Output rate of the UBX-NAV-TIMEGPS message on port UART1"),
  1085. ("CFG-MSGOUT-UBX_NAV_TIMEGPS_UART2", 0x20910049, "U1", 1, "",
  1086. "Output rate of the UBX-NAV-TIMEGPS message on port UART2"),
  1087. ("CFG-MSGOUT-UBX_NAV_TIMEGPS_USB", 0x2091004a, "U1", 1, "",
  1088. "Output rate of the UBX-NAV-TIMEGPS message on port USB"),
  1089. ("CFG-MSGOUT-UBX_NAV_TIMELS_I2C", 0x20910060, "U1", 1, "",
  1090. "Output rate of the UBX-NAV-TIMELS message on port I2C"),
  1091. ("CFG-MSGOUT-UBX_NAV_TIMELS_SPI", 0x20910064, "U1", 1, "",
  1092. "Output rate of the UBX-NAV-TIMELS message on port SPI"),
  1093. ("CFG-MSGOUT-UBX_NAV_TIMELS_UART1", 0x20910061, "U1", 1, "",
  1094. "Output rate of the UBX-NAV-TIMELS message on port UART1"),
  1095. ("CFG-MSGOUT-UBX_NAV_TIMELS_UART2", 0x20910062, "U1", 1, "",
  1096. "Output rate of the UBX-NAV-TIMELS message on port UART2"),
  1097. ("CFG-MSGOUT-UBX_NAV_TIMELS_USB", 0x20910063, "U1", 1, "",
  1098. "Output rate of the UBX-NAV-TIMELS message on port USB"),
  1099. ("CFG-MSGOUT-UBX_NAV_TIMEUTC_I2C", 0x2091005b, "U1", 1, "",
  1100. "Output rate of the UBX-NAV-TIMEUTC message on port I2C"),
  1101. ("CFG-MSGOUT-UBX_NAV_TIMEUTC_SPI", 0x2091005f, "U1", 1, "",
  1102. "Output rate of the UBX-NAV-TIMEUTC message on port S"),
  1103. ("CFG-MSGOUT-UBX_NAV_TIMEUTC_UART1", 0x2091005c, "U1", 1, "",
  1104. "Output rate of the UBX-NAV-TIMEUTC message on port UART1"),
  1105. ("CFG-MSGOUT-UBX_NAV_TIMEUTC_UART2", 0x2091005d, "U1", 1, "",
  1106. "Output rate of the UBX-NAV-TIMEUTC message on port UART2"),
  1107. ("CFG-MSGOUT-UBX_NAV_TIMEUTC_USB", 0x2091005e, "U1", 1, "",
  1108. "Output rate of the UBX-NAV- TIMEUTC message on port USB"),
  1109. ("CFG-MSGOUT-UBX_NAV_VELECEF_I2C", 0x2091003d, "U1", 1, "",
  1110. "Output rate of the UBX-NAV-VELECEF message on port I2C"),
  1111. ("CFG-MSGOUT-UBX_NAV_VELECEF_SPI", 0x20910041, "U1", 1, "",
  1112. "Output rate of the UBX-NAV-VELECEF message on port SPI"),
  1113. ("CFG-MSGOUT-UBX_NAV_VELECEF_UART1", 0x2091003e, "U1", 1, "",
  1114. "Output rate of the UBX-NAV-VELECEF message on port UART1"),
  1115. ("CFG-MSGOUT-UBX_NAV_VELECEF_UART2", 0x2091003f, "U1", 1, "",
  1116. "Output rate of the UBX-NAV-VELECEF message on port UART2"),
  1117. ("CFG-MSGOUT-UBX_NAV_VELECEF_USB", 0x20910040, "U1", 1, "",
  1118. "Output rate of the UBX-NAV-VELECEF message on port USB"),
  1119. ("CFG-MSGOUT-UBX_NAV_VELNED_I2C", 0x20910042, "U1", 1, "",
  1120. "Output rate of the UBX-NAV-VELNED message on port I2C"),
  1121. ("CFG-MSGOUT-UBX_NAV_VELNED_SPI", 0x20910046, "U1", 1, "",
  1122. "Output rate of the UBX-NAV-VELNED message on port SPI"),
  1123. ("CFG-MSGOUT-UBX_NAV_VELNED_UART1", 0x20910043, "U1", 1, "",
  1124. "Output rate of the UBX-NAV-VELNED message on port UART1"),
  1125. ("CFG-MSGOUT-UBX_NAV_VELNED_UART2", 0x20910044, "U1", 1, "",
  1126. "Output rate of the UBX-NAV-VELNED message on port UART2"),
  1127. ("CFG-MSGOUT-UBX_NAV_VELNED_USB", 0x20910045, "U1", 1, "",
  1128. "Output rate of the UBX-NAV-VELNED message on port USB"),
  1129. # CFG-MSGOUT-UBX_RXM
  1130. ("CFG-MSGOUT-UBX_RXM_MEASX_I2C", 0x20910204, "U1", 1, "",
  1131. "Output rate of the UBX-RXM-MEASX message on port I2C"),
  1132. ("CFG-MSGOUT-UBX_RXM_MEASX_SPI", 0x20910208, "U1", 1, "",
  1133. "Output rate of the UBX-RXM-MEASX message on port SPI"),
  1134. ("CFG-MSGOUT-UBX_RXM_MEASX_UART1", 0x20910205, "U1", 1, "",
  1135. "Output rate of the UBX-RXM-MEASX message on port UART1"),
  1136. ("CFG-MSGOUT-UBX_RXM_MEASX_UART2", 0x20910206, "U1", 1, "",
  1137. "Output rate of the UBX-RXM-MEASX message on port UART2"),
  1138. ("CFG-MSGOUT-UBX_RXM_MEASX_USB", 0x20910207, "U1", 1, "",
  1139. "Output rate of the UBX-RXM-MEASX message on port USB"),
  1140. ("CFG-MSGOUT-UBX_RXM_RAWX_I2C", 0x209102a4, "U1", 1, "",
  1141. "Output rate of the UBX-RXM-RAWX message on port I2C"),
  1142. ("CFG-MSGOUT-UBX_RXM_RAWX_SPI", 0x209102a8, "U1", 1, "",
  1143. "Output rate of the UBX-RXM-RAWX message on port SPI"),
  1144. ("CFG-MSGOUT-UBX_RXM_RAWX_UART1", 0x209102a5, "U1", 1, "",
  1145. "Output rate of the UBX-RXM-RAWX message on port UART1"),
  1146. ("CFG-MSGOUT-UBX_RXM_RAWX_UART2", 0x209102a6, "U1", 1, "",
  1147. "Output rate of the UBX-RXM-RAWX message on port UART2"),
  1148. ("CFG-MSGOUT-UBX_RXM_RAWX_USB", 0x209102a7, "U1", 1, "",
  1149. "Output rate of the UBX-RXM-RAWX message on port USB"),
  1150. ("CFG-MSGOUT-UBX_RXM_RLM_I2C", 0x2091025e, "U1", 1, "",
  1151. "Output rate of the UBX-RXM-RLM message on port I2C"),
  1152. ("CFG-MSGOUT-UBX_RXM_RLM_SPI", 0x20910262, "U1", 1, "",
  1153. "Output rate of the UBX-RXM-RLM message on port SPI"),
  1154. ("CFG-MSGOUT-UBX_RXM_RLM_UART1", 0x2091025f, "U1", 1, "",
  1155. "Output rate of the UBX-RXM-RLM message on port UART1"),
  1156. ("CFG-MSGOUT-UBX_RXM_RLM_UART2", 0x20910260, "U1", 1, "",
  1157. "Output rate of the UBX-RXM-RLM message on port UART2"),
  1158. ("CFG-MSGOUT-UBX_RXM_RLM_USB", 0x20910261, "U1", 1, "",
  1159. "Output rate of the UBX-RXM-RLM message on port USB"),
  1160. ("CFG-MSGOUT-UBX_RXM_RTCM_I2C", 0x20910268, "U1", 1, "",
  1161. "Output rate of the UBX-RXM-RTCM message on port I2C"),
  1162. ("CFG-MSGOUT-UBX_RXM_RTCM_SPI", 0x2091026c, "U1", 1, "",
  1163. "Output rate of the UBX-RXM-RTCM message on port SPI"),
  1164. ("CFG-MSGOUT-UBX_RXM_RTCM_UART1", 0x20910269, "U1", 1, "",
  1165. "Output rate of the UBX-RXM-RTCM message on port UART1"),
  1166. ("CFG-MSGOUT-UBX_RXM_RTCM_UART2", 0x2091026a, "U1", 1, "",
  1167. "Output rate of the UBX-RXM-RTCM message on port UART2"),
  1168. ("CFG-MSGOUT-UBX_RXM_RTCM_USB", 0x2091026b, "U1", 1, "",
  1169. "Output rate of the UBX-RXM-RTCM message on port USB"),
  1170. ("CFG-MSGOUT-UBX_RXM_SFRBX_I2C", 0x20910231, "U1", 1, "",
  1171. "Output rate of the UBX-RXM-SFRBX message on port I2C"),
  1172. ("CFG-MSGOUT-UBX_RXM_SFRBX_SPI", 0x20910235, "U1", 1, "",
  1173. "Output rate of the UBX-RXM-SFRBX message on port SPI"),
  1174. ("CFG-MSGOUT-UBX_RXM_SFRBX_UART1", 0x20910232, "U1", 1, "",
  1175. "Output rate of the UBX-RXM-SFRBX message on port UART1"),
  1176. ("CFG-MSGOUT-UBX_RXM_SFRBX_UART2", 0x20910233, "U1", 1, "",
  1177. "Output rate of the UBX-RXM-SFRBX message on port UART2"),
  1178. ("CFG-MSGOUT-UBX_RXM_SFRBX_USB", 0x20910234, "U1", 1, "",
  1179. "Output rate of the UBX-RXM-SFRBX message on port USB"),
  1180. # CFG-MSGOUT-UBX_TIM
  1181. ("CFG-MSGOUT-UBX_TIM_SVIN_I2C", 0x20910097, "U1", 1, "",
  1182. "Output rate of the UBX-TIM-SVIN message on port I2C"),
  1183. ("CFG-MSGOUT-UBX_TIM_SVIN_SPI", 0x2091009b, "U1", 1, "",
  1184. "Output rate of the UBX-TIM-SVIN message on port SPI"),
  1185. ("CFG-MSGOUT-UBX_TIM_SVIN_UART1", 0x20910098, "U1", 1, "",
  1186. "Output rate of the UBX-TIM-SVIN message on port UART1"),
  1187. ("CFG-MSGOUT-UBX_TIM_SVIN_UART2", 0x20910099, "U1", 1, "",
  1188. "Output rate of the UBX-TIM-SVIN message on port UART2"),
  1189. ("CFG-MSGOUT-UBX_TIM_SVIN_USB", 0x2091009a, "U1", 1, "",
  1190. "Output rate of the UBX-TIM-SVIN message on port USB"),
  1191. ("CFG-MSGOUT-UBX_TIM_TM2_I2C", 0x20910178, "U1", 1, "",
  1192. "Output rate of the UBX-TIM-TM2 message on port I2C"),
  1193. ("CFG-MSGOUT-UBX_TIM_TM2_SPI", 0x2091017c, "U1", 1, "",
  1194. "Output rate of the UBX-TIM-TM2 message on port SPI"),
  1195. ("CFG-MSGOUT-UBX_TIM_TM2_UART1", 0x20910179, "U1", 1, "",
  1196. "Output rate of the UBX-TIM-TM2 message on port UART1"),
  1197. ("CFG-MSGOUT-UBX_TIM_TM2_UART2", 0x2091017a, "U1", 1, "",
  1198. "Output rate of the UBX-TIM-TM2 message on port UART2"),
  1199. ("CFG-MSGOUT-UBX_TIM_TM2_USB", 0x2091017b, "U1", 1, "",
  1200. "Output rate of the UBX-TIM-TM2 message on port USB"),
  1201. ("CFG-MSGOUT-UBX_TIM_TP_I2C", 0x2091017d, "U1", 1, "",
  1202. "Output rate of the UBX-TIM-TP message on port I2C"),
  1203. ("CFG-MSGOUT-UBX_TIM_TP_SPI", 0x20910181, "U1", 1, "",
  1204. "Output rate of the UBX-TIM-TP message on port SPI"),
  1205. ("CFG-MSGOUT-UBX_TIM_TP_UART1", 0x2091017e, "U1", 1, "",
  1206. "Output rate of the UBX-TIM-TP message on port UART1"),
  1207. ("CFG-MSGOUT-UBX_TIM_TP_UART2", 0x2091017f, "U1", 1, "",
  1208. "Output rate of the UBX-TIM-TP message on port UART2"),
  1209. ("CFG-MSGOUT-UBX_TIM_TP_USB", 0x20910180, "U1", 1, "",
  1210. "Output rate of the UBX-TIM-TP message on port USB"),
  1211. ("CFG-MSGOUT-UBX_TIM_VRFY_I2C", 0x20910092, "U1", 1, "",
  1212. "Output rate of the UBX-TIM-VRFY message on port I2C"),
  1213. ("CFG-MSGOUT-UBX_TIM_VRFY_SPI", 0x20910096, "U1", 1, "",
  1214. "Output rate of the UBX-TIM-VRFY message on port SPI"),
  1215. ("CFG-MSGOUT-UBX_TIM_VRFY_UART1", 0x20910093, "U1", 1, "",
  1216. "Output rate of the UBX-TIM-VRFY message on port UART1"),
  1217. ("CFG-MSGOUT-UBX_TIM_VRFY_UART2", 0x20910094, "U1", 1, "",
  1218. "Output rate of the UBX-TIM-VRFY message on port UART2"),
  1219. ("CFG-MSGOUT-UBX_TIM_VRFY_USB", 0x20910095, "U1", 1, "",
  1220. "Output rate of the UBX-TIM-VRFY message on port USB"),
  1221. # CFG-NAVHPG-
  1222. ("CFG-NAVHPG", 0x2014ffff, "", 0, "",
  1223. "get all CFG-NAVHPG"),
  1224. ("CFG-NAVHPG-DGNSSMODE", 0x20140011, "E1", 1, "",
  1225. "Differential corrections mode"),
  1226. # CFG-NAVSPG-
  1227. ("CFG-NAVSPG", 0x2011ffff, "", 0, "",
  1228. "get all CFG-NAVSPG"),
  1229. ("CFG-NAVSPG-FIXMODE", 0x20110011, "E1", 1, "",
  1230. "Position fix mode"),
  1231. ("CFG-NAVSPG-INIFIX3D", 0x10110013, "L", 1, "",
  1232. "Initial fix must be a 3d fix"),
  1233. ("CFG-NAVSPG-WKNROLLOVER", 0x30110017, "U2", 1, "",
  1234. "GPS week rollover number"),
  1235. ("CFG-NAVSPG-USE_PPP", 0x10110019, "L", 1, "",
  1236. "Use Precise Point Positioning"),
  1237. ("CFG-NAVSPG-UTCSTANDARD", 0x2011001c, "E1", 1, "",
  1238. "UTC standard to be used"),
  1239. ("CFG-NAVSPG-DYNMODEL", 0x20110021, "E1", 1, "",
  1240. "Dynamic platform model"),
  1241. ("CFG-NAVSPG-ACKAIDING", 0x10110025, "L", 1, "",
  1242. "Acknowledge assistance input messages"),
  1243. ("CFG-NAVSPG-USE_USRDAT", 0x10110061, "L", 1, "",
  1244. "Use user geodetic datum"),
  1245. ("CFG-NAVSPG-USRDAT_MAJA", 0x50110062, "R8", 1, "m",
  1246. "Geodetic datum semi-major axis"),
  1247. ("CFG-NAVSPG-USRDAT_FLAT", 0x50110063, "R8", 1, "",
  1248. "Geodetic datum 1.0 / flattening"),
  1249. ("CFG-NAVSPG-USRDAT_DX", 0x40110064, "R4", 1, "m",
  1250. "Geodetic datum X axis shift at the origin"),
  1251. ("CFG-NAVSPG-USRDAT_DY", 0x40110065, "R4", 1, "m",
  1252. "Geodetic datum Y axis shift at the origin"),
  1253. ("CFG-NAVSPG-USRDAT_DZ", 0x40110066, "R4", 1, "m",
  1254. "Geodetic datum Z axis shift at the origin"),
  1255. ("CFG-NAVSPG-USRDAT_ROTX", 0x40110067, "R4", 1, "arcsec",
  1256. "Geodetic datum rotation about the X axis"),
  1257. ("CFG-NAVSPG-USRDAT_ROTY", 0x40110068, "R4", 1, "arcsec",
  1258. "Geodetic datum rotation about the Y axis ()"),
  1259. ("CFG-NAVSPG-USRDAT_ROTZ", 0x40110069, "R4", 1, "arcsec",
  1260. "Geodetic datum rotation about the Z axis"),
  1261. ("CFG-NAVSPG-USRDAT_SCALE", 0x4011006a, "R4", 1, "ppm",
  1262. "Geodetic datum scale factor"),
  1263. ("CFG-NAVSPG-INFIL_MINSVS", 0x201100a1, "U1", 1, "",
  1264. "Minimum number of satellites for navigation"),
  1265. ("CFG-NAVSPG-INFIL_MAXSVS", 0x201100a2, "U1", 1, "",
  1266. "Maximum number of satellites for navigation"),
  1267. ("CFG-NAVSPG-INFIL_MINCNO", 0x201100a3, "U1", 1, "dBHz",
  1268. "Minimum satellite signal level for navigation"),
  1269. ("CFG-NAVSPG-INFIL_MINELEV", 0x201100a4, "I1", 1, "deg",
  1270. "Minimum elevation for a GNSS satellite to be used in navigation"),
  1271. ("CFG-NAVSPG-INFIL_NCNOTHRS", 0x201100aa, "U1", 1, "",
  1272. "Number of satellites required to have C/N0 above "
  1273. "CFG-NAVSPG-INFIL_CNOTHRS for a fix to be attempted"),
  1274. ("CFG-NAVSPG-INFIL_CNOTHRS", 0x201100ab, "U1", 1, "",
  1275. "C/N0 threshold for deciding whether to attempt a fix"),
  1276. ("CFG-NAVSPG-OUTFIL_PDOP", 0x301100b1, "U2", 0.1, "",
  1277. "Output filter position DOP mask (threshold)"),
  1278. ("CFG-NAVSPG-OUTFIL_TDOP", 0x301100b2, "U2", 0.11, "",
  1279. "Output filter time DOP mask (threshold)"),
  1280. ("CFG-NAVSPG-OUTFIL_PACC", 0x301100b3, "U2", 1, "m",
  1281. "Output filter position accuracy mask (threshold)"),
  1282. ("CFG-NAVSPG-OUTFIL_TACC", 0x301100b4, "U2", 1, "m",
  1283. "Output filter time accuracy mask (threshold)"),
  1284. ("CFG-NAVSPG-OUTFIL_FACC", 0x301100b5, "U2", 0.01, "m/s",
  1285. "Output filter frequency accuracy mask (threshold)"),
  1286. ("CFG-NAVSPG-CONSTR_ALT", 0x401100c1, "I4", 0.01, "m",
  1287. "Fixed altitude (mean sea level) for 2D fix mode"),
  1288. ("CFG-NAVSPG-CONSTR_ALTVAR", 0x401100c2, "U4", 0.0001, "M^2",
  1289. "Fixed altitude variance for 2D mode"),
  1290. ("CFG-NAVSPG-CONSTR_DGNSSTO", 0x201100c4, "U1", 1, "s",
  1291. "DGNSS timeout"),
  1292. ("CFG-NAVSPG-SIGATTCOMP", 0x201100d6, "E1", 1, "",
  1293. "Permanently attenuated signal compensation mode"),
  1294. # CFG-NMEA-
  1295. ("CFG-NMEA", 0x2093ffff, "", 0, "",
  1296. "get all CFG-NMEA"),
  1297. ("CFG-NMEA-PROTVER", 0x20930001, "E1", 1, "",
  1298. "NMEA protocol version"),
  1299. ("CFG-NMEA-MAXSVS", 0x20930002, "E1", 1, "",
  1300. "Maximum number of SVs to report per Talker ID"),
  1301. ("CFG-NMEA-COMPAT", 0x10930003, "L", 1, "",
  1302. "Enable compatibility mode"),
  1303. ("CFG-NMEA-CONSIDER", 0x10930004, "L", 1, "",
  1304. "Enable considering mode"),
  1305. ("CFG-NMEA-LIMIT82", 0x10930005, "L", 1, "",
  1306. "Enable strict limit to 82 characters maximum NMEA message length"),
  1307. ("CFG-NMEA-HIGHPREC", 0x10930006, "L", 1, "",
  1308. "Enable high precision mode"),
  1309. ("CFG-NMEA-SVNUMBERING", 0x20930007, "E1", 1, "",
  1310. "Display configuration for SVs that have no value defined in NMEA"),
  1311. ("CFG-NMEA-FILT_GPS", 0x10930011, "L", 1, "",
  1312. "Disable reporting of GPS satellites"),
  1313. ("CFG-NMEA-FILT_SBAS", 0x10930012, "L", 1, "",
  1314. "Disable reporting of SBAS satellites"),
  1315. ("CFG-NMEA-FILT_GAL", 0x10930013, "L", 1, "",
  1316. "Disable reporting of GALILEO satellites"),
  1317. ("CFG-NMEA-FILT_QZSS", 0x10930015, "L", 1, "",
  1318. "Disable reporting of QZSS satellites"),
  1319. ("CFG-NMEA-FILT_GLO", 0x10930016, "L", 1, "",
  1320. "Disable reporting of GLONASS satellites"),
  1321. ("CFG-NMEA-FILT_BDS", 0x10930017, "L", 1, "",
  1322. "Disable reporting of BeiDou satellites"),
  1323. ("CFG-NMEA-OUT_INVFIX", 0x10930021, "L", 1, "",
  1324. "Enable position output for failed or invalid fixes"),
  1325. ("CFG-NMEA-OUT_MSKFIX", 0x10930022, "L", 1, "",
  1326. "Enable position output for invalid fixes"),
  1327. ("CFG-NMEA-OUT_INVTIME", 0x10930023, "L", 1, "",
  1328. "Enable time output for invalid times"),
  1329. ("CFG-NMEA-OUT_INVDATE", 0x10930024, "L", 1, "",
  1330. "Enable date output for invalid dates"),
  1331. ("CFG-NMEA-OUT_ONLYGPS", 0x10930025, "L", 1, "",
  1332. "Restrict output to GPS satellites only"),
  1333. ("CFG-NMEA-OUT_FROZENCOG", 0x10930026, "L", 1, "",
  1334. "Enable course over ground output even if it is frozen"),
  1335. ("CFG-NMEA-MAINTALKERID", 0x20930031, "E1", 1, "",
  1336. "Main Talker ID"),
  1337. ("CFG-NMEA-GSVTALKERID", 0x20930032, "E1", 1, "",
  1338. "Talker ID for GSV NMEA messages"),
  1339. ("CFG-NMEA-BDSTALKERID", 0x30930033, "U2", 1, "",
  1340. "BeiDou Talker ID"),
  1341. # CFG-ODO-
  1342. ("CFG-ODO", 0x1022ffff, "", 0, "",
  1343. "get all CFG-ODO"),
  1344. ("CFG-ODO-USE_ODO", 0x10220001, "L", 1, "",
  1345. "Use odometer"),
  1346. ("CFG-ODO-USE_COG", 0x10220002, "L", 1, "",
  1347. "Use low-speed course over ground filter"),
  1348. ("CFG-ODO-OUTLPVEL", 0x10220003, "L", 1, "",
  1349. "Output low-pass filtered velocity"),
  1350. ("CFG-ODO-OUTLPCOG", 0x10220004, "L", 1, "",
  1351. "Output low-pass filtered course over ground (heading)"),
  1352. ("CFG-ODO-PROFILE", 0x20220005, "E1", 1, "",
  1353. "Odometer profile configuration"),
  1354. ("CFG-ODO-COGMAXSPEED", 0x20220021, "U1", 1, "m/s",
  1355. "Upper speed limit for low-speed course over ground filter"),
  1356. ("CFG-ODO-COGMAXPOSACC", 0x20220022, "U1", 1, "",
  1357. "Maximum acceptable position accuracy for computing low-speed "
  1358. "filtered course over ground"),
  1359. ("CFG-ODO-COGLPGAIN", 0x20220032, "", 1, "",
  1360. "Course over ground low-pass filter level (at speed < 8 m/s)"),
  1361. ("CFG-ODO-VELLPGAIN", 0x20220031, "U1", 1, "",
  1362. "Velocity low-pass filter level"),
  1363. # CFG-PM-
  1364. ("CFG-PM", 0x20d0ffff, "", 0, "",
  1365. "get all CFG-PM, reciver power management"),
  1366. ("CFG-PM-OPERATEMODE", 0x20d00001, "L", 1, "",
  1367. "set PSMOO or PSMCT mode"),
  1368. ("CFG-PM-POSUPDATEPERIOD", 0x40d00002, "U4", 1, "",
  1369. "Position update period for PSMOO."),
  1370. ("CFG-PM-ACQPERIOD", 0x40d00003, "U4", 1, "s",
  1371. "Acquisition period if receiver fails to achieve a position fix"),
  1372. ("CFG-PM-GRIDOFFSET", 0x40d00004, "U4", 1, "s",
  1373. "Position update period grid offset relative to GPS start of week."),
  1374. ("CFG-PM-ONTIME", 0x30d00005, "U2", 1, "s",
  1375. "Time to stay in Tracking state."),
  1376. ("CFG-PM-MINACQTIME", 0x20d00006, "U1", 1, "s",
  1377. "Minimum time to spend in Acquisition state"),
  1378. ("CFG-PM-MAXACQTIME", 0x20d00007, "U1", 1, "s",
  1379. "Maximum time to spend in Acquisition state"),
  1380. ("CFG-PM-DONOTENTEROFF", 0x10d00008, "L", 1, "",
  1381. "Behavior when failure to achieve a position during update period."),
  1382. ("CFG-PM-WAITTIMEFIX", 0x10d00009, "L", 1, "",
  1383. "wait for time fix"),
  1384. ("CFG-PM-UPDATEEPH", 0x10d0000a, "L", 1, "",
  1385. "Update ephemeris regularly."),
  1386. ("CFG-PM-EXTINTSEL", 0x20d0000b, "E1", 1, "",
  1387. "EXTINT pin select."),
  1388. ("CFG-PM-EXTINTWAKE", 0x10d0000c, "L", 1, "",
  1389. "EXTINT pin control (Wake)"),
  1390. ("CFG-PM-EXTINTBACKUP", 0x10d0000d, "L", 1, "",
  1391. "EXTINT pin control (Backup)"),
  1392. ("CFG-PM-EXTINTINACTIVE", 0x10d0000e, "L", 1, "",
  1393. "EXTINT pin control (Inactive)"),
  1394. ("CFG-PM-UPDATEEPH", 0x10d0000d, "U4", 0.001, "s",
  1395. "Inactivity time out on EXTINT pin if enabled"),
  1396. ("CFG-PM-LIMITPEAKCURR", 0x10d00010, "L", 1, "",
  1397. "Limit peak current"),
  1398. # CFG-QZSS-
  1399. ("CFG-QZSS", 0x3037ffff, "", 0, "s",
  1400. "get all CFG-QZSS"),
  1401. ("CFG-QZSS-USE_SLAS_DGNSS", 0x10370005, "L", 0.001, "",
  1402. "Apply QZSS SLAS DGNSS corrections"),
  1403. ("CFG-QZSS-USE_TESTMODE", 0x10370006, "L", 0.001, "",
  1404. "Use QZSS SLAS data when it is in test mode"),
  1405. ("CFG-QZSS-USE_SLAS_RAIM_UNCORR", 0x10370007, "L", 0.001, "",
  1406. "Raim out measurements that are not corrected by QZSS SLAS"),
  1407. # CFG-RATE-
  1408. ("CFG-RATE", 0x3021ffff, "", 0, "s",
  1409. "get all CFG-RATE"),
  1410. ("CFG-RATE-MEAS", 0x30210001, "U2", 0.001, "s",
  1411. "Nominal time between GNSS measurements"),
  1412. ("CFG-RATE-NAV", 0x30210002, "U2", 1, "",
  1413. "Ratio of number of measurements to number of navigation solutions"),
  1414. ("CFG-RATE-TIMEREF", 0x20210003, "E1", 1, "",
  1415. "Time system to which measurements are aligned"),
  1416. # CFG-RINV-
  1417. ("CFG-RINV", 0x10c7ffff, "", 0, "",
  1418. "get all CFG-RINV"),
  1419. ("CFG-RINV-DUMP", 0x10c70001, "L", 1, "",
  1420. "Dump data at startup"),
  1421. ("CFG-RINV-BINARY", 0x10c70002, "L", 1, "",
  1422. "Data is binary"),
  1423. ("CFG-RINV-DATA_SIZE", 0x20c70003, "U1", 1, "",
  1424. "Size of data"),
  1425. ("CFG-RINV-CHUNK0", 0x50c70004, "X8", 1, "",
  1426. "Data bytes 1-8 (LSB)"),
  1427. ("CFG-RINV-CHUNK1", 0x50c70005, "X8", 1, "",
  1428. "Data bytes 9-16"),
  1429. ("CFG-RINV-CHUNK2", 0x50c70006, "X8", 1, "",
  1430. "Data bytes 17-24"),
  1431. ("CFG-RINV-CHUNK3", 0x50c70007, "X8", 1, "",
  1432. "Data bytes 25-30 (MSB)"),
  1433. # CFG-SBAS-
  1434. ("CFG-SBAS", 0x1036ffff, "", 0, "",
  1435. "get all CFG-SBAS"),
  1436. ("CFG-SBAS-USE_TESTMODE", 0x10360002, "L", 1, "",
  1437. "Use SBAS data when it is in test mode"),
  1438. ("CFG-SBAS-USE_RANGING", 0x10360003, "L", 1, "",
  1439. "Use SBAS GEOs as a ranging source (for navigation)"),
  1440. ("CFG-SBAS-USE_DIFFCORR", 0x10360004, "L", 1, "",
  1441. "Use SBAS differential corrections"),
  1442. ("CFG-SBAS-USE_INTEGRITY", 0x10360005, "L", 1, "",
  1443. "Use SBAS integrity information"),
  1444. ("CFG-SBAS-PRNSCANMASK", 0x50360006, "X8", 1, "",
  1445. "SBAS PRN search configuration"),
  1446. # CFG-SIGNAL-
  1447. ("CFG-SIGNAL", 0x1031ffff, "", 0, "",
  1448. "get all CFG-SIGNAL"),
  1449. ("CFG-SIGNAL-GPS_ENA", 0x1031001f, "L", 1, "",
  1450. "GPS enable"),
  1451. ("CFG-SIGNAL-GPS_L1CA_ENA", 0x10310001, "L", 1, "",
  1452. "GPS L1C/A"),
  1453. ("CFG-SIGNAL-GPS_L2C_ENA", 0x10310003, "L", 1, "",
  1454. "GPS L2C"),
  1455. ("CFG-SIGNAL-SBAS_ENA", 0x10310020, "L", 1, "",
  1456. "SBAS enable"),
  1457. ("CFG-SIGNAL-SBAS_L1CA_ENA", 0x10310005, "L", 1, "",
  1458. "SBAS L1C/A"),
  1459. ("CFG-SIGNAL-GAL_ENA", 0x10310021, "L", 1, "",
  1460. "Galileo enable"),
  1461. ("CFG-SIGNAL-GAL_E1_ENA", 0x10310007, "L", 1, "",
  1462. "Galileo E1"),
  1463. ("CFG-SIGNAL-GAL_E5B_ENA", 0x1031000a, "L", 1, "",
  1464. "Galileo E5b"),
  1465. ("CFG-SIGNAL-BDS_ENA", 0x10310022, "L", 1, "",
  1466. "BeiDou Enable"),
  1467. ("CFG-SIGNAL-BDS_B1_ENA", 0x1031000d, "L", 1, "",
  1468. "BeiDou B1I"),
  1469. ("CFG-SIGNAL-BDS_B2_ENA", 0x1031000e, "L", 1, "",
  1470. "BeiDou B2I"),
  1471. ("CFG-SIGNAL-QZSS_ENA", 0x10310024, "L", 1, "",
  1472. "QZSS enable"),
  1473. ("CFG-SIGNAL-QZSS_L1CA_ENA", 0x10310012, "L", 1, "",
  1474. "QZSS L1C/A"),
  1475. ("CFG-SIGNAL-QZSS_L1S_ENA", 0x10310014, "L", 1, "",
  1476. "QZSS L1S"),
  1477. ("CFG-SIGNAL-QZSS_L2C_ENA", 0x10310015, "L", 1, "",
  1478. "QZSS L2C"),
  1479. ("CFG-SIGNAL-GLO_ENA", 0x10310025, "L", 1, "",
  1480. "GLONASS enable"),
  1481. ("CFG-SIGNAL-GLO_L1_ENA", 0x10310018, "L", 1, "",
  1482. "GLONASS L1"),
  1483. ("CFG-SIGNAL-GLO_L2_ENA", 0x1031001a, "L", 1, "",
  1484. "GLONASS L2"),
  1485. # CFG-SPI-
  1486. ("CFG-SPI", 0x1064ffff, "", 0, "",
  1487. "get all CFG-SPI"),
  1488. ("CFG-SPI-MAXFF", 0x20640001, "U1", 1, "",
  1489. "Number of bytes containing 0xFF to receive before "
  1490. "switching off reception."),
  1491. ("CFG-SPI-CPOLARITY", 0x10640002, "L", 1, "",
  1492. "Clock polarity select"),
  1493. ("CFG-SPI-CPHASE", 0x10640003, "L", 1, "",
  1494. "Clock phase select"),
  1495. ("CFG-SPI-EXTENDEDTIMEOUT", 0x10640005, "L", 1, "",
  1496. "Flag to disable timeouting the interface after 1.5s"),
  1497. ("CFG-SPI-ENABLED", 0x10640006, "L", 1, "",
  1498. "Flag to indicate if the SPI interface should be enabled"),
  1499. # CFG-SPIINPROT-
  1500. ("CFG-SPIINPROT", 0x1079ffff, "", 0, "",
  1501. "get all CFG-SPIINPROT"),
  1502. ("CFG-SPIINPROT-UBX", 0x10790001, "L", 1, "",
  1503. "Flag to indicate if UBX should be an input protocol on SPI"),
  1504. ("CFG-SPIINPROT-NMEA", 0x10790002, "L", 1, "",
  1505. "Flag to indicate if NMEA should be an input protocol on SPI"),
  1506. ("CFG-SPIINPROT-RTCM2X", 0x10790003, "L", 1, "",
  1507. "Flag to indicate if RTCM2X should be an input protocol on SPI"),
  1508. ("CFG-SPIINPROT-RTCM3X", 0x10790004, "L", 1, "",
  1509. "Flag to indicate if RTCM3X should be an input protocol on SPI"),
  1510. # CFG-SPIOUTPROT-
  1511. ("CFG-SPIOUTPROT", 0x107affff, "", 0, "",
  1512. "get all CFG-SPIOUTPROT"),
  1513. ("CFG-SPIOUTPROT-UBX", 0x107a0001, "L", 1, "",
  1514. "Flag to indicate if UBX should be an output protocol on SPI"),
  1515. ("CFG-SPIOUTPROT-NMEA", 0x107a0002, "L", 1, "",
  1516. "Flag to indicate if NMEA should be an output protocol on SPI"),
  1517. ("CFG-SPIOUTPROT-RTCM3X", 0x107a0004, "L", 1, "",
  1518. "Flag to indicate if RTCM3X should be an output protocol on SPI"),
  1519. # CFG-TMODE-
  1520. ("CFG-TMODE", 0x2003ffff, "", 0, "",
  1521. "get all CFG-TMODE"),
  1522. ("CFG-TMODE-MODE", 0x20030001, "E1", 1, "",
  1523. "Receiver mode"),
  1524. ("CFG-TMODE-POS_TYPE", 0x20030002, "E1", 1, "",
  1525. "Determines whether the ARP position is given in ECEF or "
  1526. "LAT/LON/HEIGHT?"),
  1527. ("CFG-TMODE-ECEF_X", 0x40030003, "I4", 1, "cm",
  1528. "ECEF X coordinate of the ARP position."),
  1529. ("CFG-TMODE-ECEF_Y", 0x40030004, "I4", 1, "cm",
  1530. "ECEF Y coordinate of the ARP position."),
  1531. ("CFG-TMODE-ECEF_Z", 0x40030005, "I4", 1, "cm",
  1532. "ECEF Z coordinate of the ARP position."),
  1533. ("CFG-TMODE-ECEF_X_HP", 0x20030006, "I1", 0.1, "mm",
  1534. "High-precision ECEF X coordinate of the ARP position."),
  1535. ("CFG-TMODE-ECEF_Y_HP", 0x20030007, "I1", 0.1, "mm",
  1536. "High-precision ECEF Y coordinate of the ARP position."),
  1537. ("CFG-TMODE-ECEF_Z_HP", 0x20030008, "I1", 0.1, "mm",
  1538. "High-precision ECEF Z coordinate of the ARP position."),
  1539. ("CFG-TMODE-LAT", 0x40030009, "I4", 1e-7, "deg",
  1540. "Latitude of the ARP position."),
  1541. ("CFG-TMODE-LON", 0x4003000a, "I4", 1e-7, "deg",
  1542. "Longitude of the ARP position."),
  1543. ("CFG-TMODE-HEIGHT", 0x4003000b, "I4", 1, "cm",
  1544. "Height of the ARP position."),
  1545. ("CFG-TMODE-LAT_HP", 0x2003000c, "I1", 1e-9, "deg",
  1546. "High-precision latitude of the ARP position"),
  1547. ("CFG-TMODE-LON_HP", 0x2003000d, "I1", 1e-9, "deg",
  1548. "High-precision longitude of the ARP position."),
  1549. ("CFG-TMODE-HEIGHT_HP", 0x2003000e, "I1", 0.1, "mm",
  1550. "High-precision height of the ARP position."),
  1551. ("CFG-TMODE-FIXED_POS_ACC", 0x4003000f, "U4", 0.1, "mm",
  1552. "Fixed position 3D accuracy"),
  1553. ("CFG-TMODE-SVIN_MIN_DUR", 0x40030010, "U4", 1, "s",
  1554. "Survey-in minimum duration"),
  1555. ("CFG-TMODE-SVIN_ACC_LIMIT", 0x40030011, "U4", 0.1, "mm",
  1556. "Survey-in position accuracy limit"),
  1557. # CFG-TP-
  1558. ("CFG-TP", 0x3005ffff, "", 0, "",
  1559. "get all CFG-TP"),
  1560. ("CFG-TP-PULSE_DEF", 0x20050023, "E1", 1, "",
  1561. "Determines whether the time pulse is interpreted as frequency "
  1562. "or period?"),
  1563. ("CFG-TP-PULSE_LENGTH_DEF", 0x20050030, "E1", 1, "",
  1564. "Determines whether the time pulse length is interpreted as "
  1565. "length[us] or pulse ratio[%]?"),
  1566. ("CFG-TP-ANT_CABLEDELAY", 0x30050001, "I2", 0.000000001, "s",
  1567. "Antenna cable delay"),
  1568. ("CFG-TP-PERIOD_TP1", 0x40050002, "U4", 0.000001, "s",
  1569. "Time pulse period (TP1)"),
  1570. ("CFG-TP-PERIOD_LOCK_TP1", 0x40050003, "U4", 0.000001, "s",
  1571. "Time pulse period when locked to GNSS time (TP1)"),
  1572. ("CFG-TP-FREQ_TP1", 0x40050024, "U4", 1, "Hz",
  1573. "Time pulse frequency (TP1)"),
  1574. ("CFG-TP-FREQ_LOCK_TP1", 0x40050025, "U4", 1, "Hz",
  1575. "Time pulse frequency when locked to GNSS time (TP1)"),
  1576. ("CFG-TP-LEN_TP1", 0x40050004, "U4", 0.000001, "s",
  1577. "Time pulse length (TP1)"),
  1578. ("CFG-TP-LEN_LOCK_TP1", 0x40050005, "U4", 0.000001, "s",
  1579. "Time pulse length when locked to GNSS time (TP1)"),
  1580. ("CFG-TP-DUTY_TP1", 0x5005002a, "R8", 1, "%",
  1581. "Time pulse duty cycle (TP1)"),
  1582. ("CFG-TP-DUTY_LOCK_TP1", 0x5005002b, "R8", 1, "%",
  1583. "Time pulse duty cycle when locked to GNSS time (TP1)"),
  1584. ("CFG-TP-USER_DELAY_TP1", 0x40050006, "I4", 0.000000001, "s",
  1585. "User configurable time pulse delay (TP1)"),
  1586. ("CFG-TP-TP1_ENA", 0x10050007, "L", 1, "",
  1587. "Enable the first timepulse"),
  1588. ("CFG-TP-SYNC_GNSS_TP1", 0x10050008, "L", 1, "",
  1589. "Sync time pulse to GNSS time or local clock (TP1)"),
  1590. ("CFG-TP-USE_LOCKED_TP1", 0x10050009, "L", 1, "",
  1591. "Use locked parameters when possible (TP1)"),
  1592. ("CFG-TP-ALIGN_TO_TOW_TP1", 0x1005000a, "L", 1, "",
  1593. "Align time pulse to top of second (TP1)"),
  1594. ("CFG-TP-POL_TP1", 0x1005000b, "L", 1, "",
  1595. "Set time pulse polarity (TP1)"),
  1596. ("CFG-TP-TIMEGRID_TP1", 0x2005000c, "E1", 1, "",
  1597. "Time grid to use (TP1)"),
  1598. ("CFG-TP-PERIOD_TP2", 0x4005000d, "U4", 0.000001, "s",
  1599. "Time pulse period (TP2)"),
  1600. ("CFG-TP-PERIOD_LOCK_TP2", 0x4005000e, "U4", 0.000001, "s",
  1601. "Time pulse period when locked to GNSS time (TP2)"),
  1602. ("CFG-TP-FREQ_TP2", 0x40050026, "U4", 1, "Hz",
  1603. "Time pulse frequency (TP2)"),
  1604. ("CFG-TP-FREQ_LOCK_TP2", 0x40050027, "U4", 1, "Hz",
  1605. "Time pulse frequency when locked to GNSS time (TP2)"),
  1606. ("CFG-TP-LEN_TP2", 0x4005000f, "U4", 0.000001, "s",
  1607. "Time pulse length (TP2)"),
  1608. ("CFG-TP-LEN_LOCK_TP2", 0x40050010, "U4", 0.000001, "s",
  1609. "Time pulse length when locked to GNSS time (TP2)"),
  1610. ("CFG-TP-DUTY_TP2", 0x5005002c, "R8", 1, "%",
  1611. "Time pulse duty cycle (TP2)"),
  1612. ("CFG-TP-DUTY_LOCK_TP2", 0x5005002d, "R8", 1, "%",
  1613. "Time pulse duty cycle when locked to GNSS time (TP2)"),
  1614. ("CFG-TP-USER_DELAY_TP2", 0x40050011, "I4", 0.000000001, "s",
  1615. "User configurable time pulse delay (TP2)"),
  1616. ("CFG-TP-TP2_ENA", 0x10050012, "L", 1, "",
  1617. "Enable the second timepulse"),
  1618. ("CFG-TP-SYNC_GNSS_TP2", 0x10050013, "L", 1, "",
  1619. "Sync time pulse to GNSS time or local clock (TP2)"),
  1620. ("CFG-TP-USE_LOCKED_TP2", 0x10050014, "L", 1, "",
  1621. "Use locked parameters when possible (TP2)"),
  1622. ("CFG-TP-ALIGN_TO_TOW_TP2", 0x10050015, "L", 1, "",
  1623. "Align time pulse to top of second (TP2)"),
  1624. ("CFG-TP-POL_TP2", 0x10050016, "L", 1, "",
  1625. "Set time pulse polarity (TP2)"),
  1626. ("CFG-TP-TIMEGRID_TP2", 0x20050017, "E1", 1, "",
  1627. "Time grid to use (TP2)"),
  1628. # CFG-TXREADY-
  1629. ("CFG-TXREADY", 0x10a2ffff, "", 0, "",
  1630. "get all CFG-TXREADY"),
  1631. ("CFG-TXREADY-ENABLED", 0x10a20001, "L", 1, "",
  1632. "Flag to indicate if tx ready pin mechanism should be enabled"),
  1633. ("CFG-TXREADY-POLARITY", 0x10a20002, "L", 1, "",
  1634. "Polarity of the tx ready pin:false:high-active, true:low-active"),
  1635. ("CFG-TXREADY-PIN", 0x20a20003, "U1", 1, "",
  1636. "Pin number to use for the tx ready functionality"),
  1637. ("CFG-TXREADY-THRESHOLD", 0x30a20004, "U2", 1, "",
  1638. "Amount of data ready on interface before triggering tx ready pin"),
  1639. ("CFG-TXREADY-INTERFACE", 0x20a20005, "E1", 1, "",
  1640. "Interface where the tx ready feature should be linked to"),
  1641. # CFG-UART1-
  1642. ("CFG-UART1", 0x4052ffff, "", 0, "",
  1643. "get all CFG-UART1"),
  1644. ("CFG-UART1-BAUDRATE", 0x40520001, "U4", 1, "",
  1645. "The baud rate that should be configured on the UART1"),
  1646. ("CFG-UART1-STOPBITS", 0x20520002, "E1", 1, "",
  1647. "Number of stopbits that should be used on UART1"),
  1648. ("CFG-UART1-DATABITS", 0x20520003, "E1", 1, "",
  1649. "Number of databits that should be used on UART1"),
  1650. ("CFG-UART1-PARITY", 0x20520004, "E1", 1, "",
  1651. "Parity mode that should be used on UART1"),
  1652. ("CFG-UART1-ENABLED", 0x10520005, "L", 1, "",
  1653. "Flag to indicate if the UART1 should be enabled"),
  1654. # CFG-UART1INPROT
  1655. ("CFG-UART1INPROT", 0x1073ffff, "", 0, "",
  1656. "get all CFG-UART1INPROT"),
  1657. ("CFG-UART1INPROT-UBX", 0x10730001, "L", 1, "",
  1658. "Flag to indicate if UBX should be an input protocol on UART1"),
  1659. ("CFG-UART1INPROT-NMEA", 0x10730002, "L", 1, "",
  1660. "Flag to indicate if NMEA should be an input protocol on UART1"),
  1661. ("CFG-UART1INPROT-RTCM2X", 0x10730003, "L", 1, "",
  1662. "Flag to indicate if RTCM2X should be an input protocol on UART1"),
  1663. ("CFG-UART1INPROT-RTCM3X", 0x10730004, "L", 1, "",
  1664. "Flag to indicate if RTCM3X should be an input protocol on UART1"),
  1665. # CFG-UART1OUTPROT
  1666. ("CFG-UART1OUTPROT", 0x1074ffff, "", 0, "",
  1667. "get all CFG-UART1OUTPROT"),
  1668. ("CFG-UART1OUTPROT-UBX", 0x10740001, "L", 1, "",
  1669. "Flag to indicate if UBX should be an output protocol on UART1"),
  1670. ("CFG-UART1OUTPROT-NMEA", 0x10740002, "L", 1, "",
  1671. "Flag to indicate if NMEA should be an output protocol on UART1"),
  1672. ("CFG-UART1OUTPROT-RTCM3X", 0x10740004, "L", 1, "",
  1673. "Flag to indicate if RTCM3X should be an output protocol on UART1"),
  1674. # CFG-UART2-
  1675. ("CFG-UART2", 0x4053FFFF, "", 0, "",
  1676. "get all CFG-UART2"),
  1677. ("CFG-UART2-BAUDRATE", 0x40530001, "U4", 1, "",
  1678. "The baud rate that should be configured on the UART2"),
  1679. ("CFG-UART2-STOPBITS", 0x20530002, "E1", 1, "",
  1680. "Number of stopbits that should be used on UART2"),
  1681. ("CFG-UART2-DATABITS", 0x20530003, "E1", "1", "",
  1682. "Number of databits that should be used on UART2"),
  1683. ("CFG-UART2-PARITY", 0x20530004, "E1", "1", "",
  1684. "Parity mode that should be used on UART2"),
  1685. ("CFG-UART2-ENABLED", 0x10530005, "L", "1", "",
  1686. "Flag to indicate if the UART2 should be enabled"),
  1687. ("CFG-UART2-REMAP", 0x10530006, "L", "1", "",
  1688. "UART2 Remapping"),
  1689. # CFG-UART1INPROT
  1690. ("CFG-UART2INPROT", 0x1075ffff, "", 0, "",
  1691. "get all CFG-UART2INPROT"),
  1692. ("CFG-UART2INPROT-UBX", 0x10750001, "L", 1, "",
  1693. "Flag to indicate if UBX should be an input protocol on UART2"),
  1694. ("CFG-UART2INPROT-NMEA", 0x10750002, "L", 1, "",
  1695. "Flag to indicate if NMEA should be an input protocol on UART2"),
  1696. ("CFG-UART2INPROT-RTCM2X", 0x10750003, "L", 1, "",
  1697. "Flag to indicate if RTCM2X should be an input protocol on UART2"),
  1698. ("CFG-UART2INPROT-RTCM3X", 0x10750004, "L", 1, "",
  1699. "Flag to indicate if RTCM3X should be an input protocol on UART2"),
  1700. # CFG-UART2OUTPROT
  1701. ("CFG-UART2OUTPROT", 0x1076ffff, "", 0, "",
  1702. "get all CFG-UART2OUTPROT"),
  1703. ("CFG-UART2OUTPROT-UBX", 0x10760001, "L", 1, "",
  1704. "Flag to indicate if UBX should be an output protocol on UART2"),
  1705. ("CFG-UART2OUTPROT-NMEA", 0x10760002, "L", 1, "",
  1706. "Flag to indicate if NMEA should be an output protocol on UART2"),
  1707. ("CFG-UART2OUTPROT-RTCM3X", 0x10760004, "L", 1, "",
  1708. "Flag to indicate if RTCM3X should be an output protocol on UART2"),
  1709. # CFG-USB-
  1710. ("CFG-USB", 0x1065ffff, "", 0, "",
  1711. "get all CFG-USB"),
  1712. ("CFG-USB-ENABLED", 0x10650001, "L", 1, "",
  1713. "Flag to indicate if the USB interface should be enabled"),
  1714. ("CFG-USB-SELFPOW", 0x10650002, "L", 1, "",
  1715. "Self-Powered device"),
  1716. ("CFG-USB-VENDOR_ID", 0x3065000a, "U2", 1, "",
  1717. "Vendor ID"),
  1718. ("CFG-USB-PRODUCT_ID", 0x3065000b, "U2", 1, "",
  1719. "Product ID"),
  1720. ("CFG-USB-POWER", 0x3065000c, "U2", 1, "mA",
  1721. "Power consumption"),
  1722. ("CFG-USB-VENDOR_STR0", 0x5065000d, "X8", 1, "",
  1723. "Vendor string characters 0-7"),
  1724. ("CFG-USB-VENDOR_STR1", 0x5065000e, "X8", 1, "",
  1725. "Vendor string characters 8-15"),
  1726. ("CFG-USB-VENDOR_STR2", 0x5065000f, "X8", 1, "",
  1727. "Vendor string characters 16-23"),
  1728. ("CFG-USB-VENDOR_STR3", 0x50650010, "X8", 1, "",
  1729. "Vendor string characters 24-31"),
  1730. ("CFG-USB-PRODUCT_STR0", 0x50650011, "X8", 1, "",
  1731. "Product string characters 0-7"),
  1732. ("CFG-USB-PRODUCT_STR1", 0x50650012, "X8", 1, "",
  1733. "Product string characters 8-15"),
  1734. ("CFG-USB-PRODUCT_STR2", 0x50650013, "X8", 1, "",
  1735. "Product string characters 16-23"),
  1736. ("CFG-USB-PRODUCT_STR3", 0x50650014, "X8", 1, "",
  1737. "Product string characters 24-31"),
  1738. ("CFG-USB-SERIAL_NO_STR0", 0x50650015, "X8", 1, "",
  1739. "Serial number string characters 0-7"),
  1740. ("CFG-USB-SERIAL_NO_STR1", 0x50650016, "X8", 1, "",
  1741. "Serial number string characters 8-15"),
  1742. ("CFG-USB-SERIAL_NO_STR2", 0x50650017, "X8", 1, "",
  1743. "Serial number string characters 16-23"),
  1744. ("CFG-USB-SERIAL_NO_STR3", 0x50650018, "X8", 1, "",
  1745. "Serial number string characters 24-31"),
  1746. # CFG-USB-INPROT
  1747. ("CFG-USBINPROT", 0x1077ffff, "", 0, "",
  1748. "get all CFG-USBINPROT"),
  1749. ("CFG-USBINPROT-UBX", 0x10770001, "L", 1, "",
  1750. "Flag to indicate if UBX should be an input protocol on USB"),
  1751. ("CFG-USBINPROT-NMEA", 0x10770002, "L", 1, "",
  1752. "Flag to indicate if NMEA should be an input protocol on USB"),
  1753. ("CFG-USBINPROT-RTCM2X", 0x10770003, "L", 1, "",
  1754. "Flag to indicate if RTCM2X should be an input protocol on USB"),
  1755. ("CFG-USBINPROT-RTCM3X", 0x10770004, "L", 1, "",
  1756. "Flag to indicate if RTCM3X should be an input protocol on USB"),
  1757. # CFG-USB-OUTPROT
  1758. ("CFG-USBOUTPROT", 0x1078ffff, "", 0, "",
  1759. "get all CFG-USBOUTPROT"),
  1760. ("CFG-USBOUTPROT-UBX", 0x10780001, "L", 1, "",
  1761. "Flag to indicate if UBX should be an output protocol on USB"),
  1762. ("CFG-USBOUTPROT-NMEA", 0x10780002, "L", 1, "",
  1763. "Flag to indicate if NMEA should be an output protocol on USB"),
  1764. ("CFG-USBOUTPROT-RTCM3X", 0x10780004, "L", 1, "",
  1765. "Flag to indicate if RTCM3X should be an output protocol on USB"),
  1766. )
  1767. def item_to_type(self, item):
  1768. """Return (size, pack format, i/i/f) for item"""
  1769. # conversion of known types from known key
  1770. cfg_types = {
  1771. "E1": (1, "<B", "u"),
  1772. "E2": (2, "<H", "u"),
  1773. "E4": (4, "<L", "u"),
  1774. "I1": (1, "<b", "i"),
  1775. "I2": (2, "<h", "i"),
  1776. "I4": (4, "<l", "i"),
  1777. "I8": (8, "<q", "i"),
  1778. "L": (1, "<B", "u"),
  1779. "R4": (4, "<f", "f"),
  1780. "R8": (8, "<d", "f"),
  1781. "U1": (1, "<B", "u"),
  1782. "U2": (2, "<H", "u"),
  1783. "U4": (4, "<L", "u"),
  1784. "U8": (8, "<Q", "u"),
  1785. "X1": (1, "<B", "u"),
  1786. "X2": (2, "<H", "u"),
  1787. "X4": (4, "<L", "u"),
  1788. "X8": (8, "<Q", "u"),
  1789. }
  1790. # guess of known types from unknown key
  1791. key_map = {0: (1, "<B", "u"), # illegal
  1792. 1: (1, "<B", "u"), # one bit
  1793. 2: (1, "<B", "u"), # one byte
  1794. 3: (2, "<H", "u"), # two byte
  1795. 4: (4, "<L", "u"), # four byte
  1796. 5: (8, "<B", "u"), # eight byte
  1797. 6: (1, "<B", "u"), # illegal
  1798. 7: (1, "<B", "u"), # illegal
  1799. }
  1800. key = item[1]
  1801. val_type = item[2]
  1802. if val_type in cfg_types:
  1803. cfg_type = cfg_types[val_type]
  1804. else:
  1805. # unknown? get length correct
  1806. key_size = (key >> 28) & 0x07
  1807. cfg_type = key_map[key_size]
  1808. return cfg_type
  1809. cfg_by_key_group = {0x03: "TMODE",
  1810. 0x05: "TP",
  1811. 0x11: "NAVSPG",
  1812. 0x14: "NAVHPG",
  1813. 0x21: "RATE",
  1814. 0x22: "ODO",
  1815. 0x23: "ANA",
  1816. 0x24: "GEOFENCE",
  1817. 0x25: "MOT",
  1818. 0x26: "BATCH",
  1819. 0x31: "SIGNAL",
  1820. 0x37: "QZSS",
  1821. 0x41: "ITFM",
  1822. 0x51: "I2C",
  1823. 0x52: "UART1",
  1824. 0x53: "UART2",
  1825. 0x64: "SPI",
  1826. 0x65: "USB",
  1827. 0x71: "I2CINPROT",
  1828. 0x72: "I2COUTPROT",
  1829. 0x73: "UART1INPROT",
  1830. 0x74: "UART1OUTPROT",
  1831. 0x75: "UART2INPROT",
  1832. 0x76: "UART2OUTPROT",
  1833. 0x77: "USBOUTPROT",
  1834. 0x78: "USBOUTPROT",
  1835. 0x79: "SPIINPROT",
  1836. 0x7a: "SPIOUTPROT",
  1837. 0x91: "MSGOUT",
  1838. 0x92: "INFMSG",
  1839. 0x93: "NMEA",
  1840. 0xa2: "TXREADY",
  1841. 0xa3: "HW",
  1842. 0xc7: "RINV",
  1843. 0xd0: "PM",
  1844. 0xde: "LOGFILTER",
  1845. }
  1846. cfg_by_key_kmap = {0: "Z0",
  1847. 1: "L",
  1848. 2: "U1",
  1849. 3: "U2",
  1850. 4: "U4",
  1851. 5: "U8",
  1852. 6: "Z6",
  1853. 7: "Z7",
  1854. }
  1855. def cfg_by_key(self, key):
  1856. """Find a config item by key"""
  1857. for item in self.cfgs:
  1858. if item[1] == key:
  1859. return item
  1860. # not found, build a fake item, guess on decode
  1861. group = (key >> 16) & 0xff
  1862. group_name = index_s(group, self.cfg_by_key_group)
  1863. if "Unk" == group_name:
  1864. group_name = str(group)
  1865. name = "CFG-%s-%u" % (group_name, key & 0xff)
  1866. size = (key >> 28) & 0x07
  1867. item = (name, key, self.cfg_by_key_kmap[size], 1, "Unk", "Unknown")
  1868. return item
  1869. def cfg_by_name(self, name):
  1870. """Find a config item by name"""
  1871. for item in self.cfgs:
  1872. if item[0] == name:
  1873. return item
  1874. return None
  1875. id_map = {
  1876. 0: {"name": "GPS",
  1877. "sig": {0: "L1C/A", 3: "L2 CL", 4: "L2 CM"}},
  1878. 1: {"name": "SBAS",
  1879. "sig": {0: "L1C/A", 3: "L2 CL", 4: "L2 CM"}},
  1880. 2: {"name": "Galileo",
  1881. "sig": {0: "E1C", 1: "E1 B", 5: "E5 bl", 6: "E5 bQ"}},
  1882. 3: {"name": "BeiDou",
  1883. "sig": {0: "B1I D1", 1: "B1I D2", 2: "B2I D1", 3: "B2I D2"}},
  1884. 4: {"name": "IMES",
  1885. "sig": {0: "L1C/A", 3: "L2 CL", 4: "L2 CM"}},
  1886. 5: {"name": "QZSS",
  1887. "sig": {0: "L1C/A", 4: "L2 CM", 5: "L2 CL"}},
  1888. 6: {"name": "GLONASS",
  1889. "sig": {0: "L1 OF", 2: "L2 OF"}},
  1890. }
  1891. def gnss_s(self, gnssId, svId, sigId):
  1892. """Verbose decode of gnssId, svId and sigId"""
  1893. s = ''
  1894. if gnssId in self.id_map:
  1895. if "name" not in self.id_map[gnssId]:
  1896. s = "%d:%d:%d" % (gnssId, svId, sigId)
  1897. elif sigId not in self.id_map[gnssId]["sig"]:
  1898. s = ("%s:%d:%d" %
  1899. (self.id_map[gnssId]["name"], svId, sigId))
  1900. else:
  1901. s = ("%s:%d:%s" %
  1902. (self.id_map[gnssId]["name"], svId,
  1903. self.id_map[gnssId]["sig"][sigId]))
  1904. else:
  1905. s = "%d:%d:%d" % (gnssId, svId, sigId)
  1906. return s
  1907. def ack_ack(self, buf):
  1908. """UBX-ACK-ACK decode"""
  1909. # NOTE: Not all messages to u-blox GPS are ACKed...
  1910. u = struct.unpack_from('<BB', buf, 0)
  1911. return ' ACK to %s' % self.class_id_s(u[0], u[1])
  1912. def ack_nak(self, buf):
  1913. """UBX-ACK-NAK decode"""
  1914. # NOTE: Not all messages to u-blox GPS are ACKed...
  1915. u = struct.unpack_from('<BB', buf, 0)
  1916. return ' NAK to %s' % self.class_id_s(u[0], u[1])
  1917. # UBX-ACK-
  1918. ack_ids = {0: {'str': 'NAK', 'dec': ack_nak, 'minlen': 2,
  1919. 'name': 'UBX-ACK-NAK'},
  1920. 1: {'str': 'ACK', 'dec': ack_ack, 'minlen': 2,
  1921. 'name': 'UBX-ACK-ACK'}}
  1922. # UBX-AID-
  1923. def aid_alm(self, buf):
  1924. """UBX-AID-ALM decode, GPS Aiding Almanac Data"""
  1925. m_len = len(buf)
  1926. if 1 == m_len:
  1927. return " Poll request svid %u" % buf[0]
  1928. if 8 > m_len:
  1929. return " Bad Length %s" % m_len
  1930. u = struct.unpack_from('<LL', buf, 0)
  1931. s = ' svid %u week %u ' % u
  1932. if 0 != u[1] and 8 < m_len <= 40:
  1933. u = struct.unpack_from('<LLLLLLLL', buf, 8)
  1934. s += ('\n dwrd %08x %08x %08x %08x'
  1935. '\n %08x %08x %08x %08x' % u)
  1936. return s
  1937. def aid_alp(self, buf):
  1938. """UBX-AID-ALP decode, AlmanacPlus"""
  1939. # u-blox 6, protVer 6 to 7
  1940. m_len = len(buf)
  1941. if 1 == m_len(buf):
  1942. # different meaning for in and out
  1943. u = struct.unpack_from('<B', buf, 0)
  1944. return ' dummy/ack %u' % u
  1945. if 24 == m_len(buf):
  1946. # different meaning for in and out
  1947. u = struct.unpack_from('LLlHHLBBH', buf, 0)
  1948. return (' predTow %u predDur %u age %d predWno %u almWno %u\n'
  1949. ' res1 %u svs %u res23 %u %u' % u)
  1950. # else
  1951. s = ' alpData len %u' % u
  1952. # FIXME: partial decode
  1953. return s
  1954. def aid_alpsrv(self, buf):
  1955. """UBX-AID-ALPSRV decode, AlmanacPlus"""
  1956. # u-blox 6, protVer 6 to 7
  1957. u = struct.unpack_from('<BBHHH', buf, 0)
  1958. s = ' idSize %u type %u ofx %u size %u fileId %u' % u
  1959. # FIXME: partial decode
  1960. return s
  1961. def aid_aop(self, buf):
  1962. """UBX-AID-AOP decode, AssistNow Autonomous data"""
  1963. m_len = len(buf)
  1964. if 1 == m_len:
  1965. return " Poll request svid %u" % buf[0]
  1966. # length 2 is undocumented...
  1967. if 2 > m_len:
  1968. return " Bad Length %s" % m_len
  1969. u = struct.unpack_from('<BB', buf, 0)
  1970. s = ' gnssid %u svid %u' % u
  1971. # FIXME: dump the rest...
  1972. return s
  1973. def aid_data(self, buf):
  1974. """UBX-AID-DATA decode, Poll all GPS Initial Aiding Data"""
  1975. # u-blox 6
  1976. # If this poll is received, the messages AID-INI, AID-HUI,
  1977. # AID-EPH and AID-ALM are sent.
  1978. return " Poll all GPS Initial Aiding Data"
  1979. def aid_eph(self, buf):
  1980. """UBX-AID-EPH decode, GPS Aiding Ephemeris Data"""
  1981. m_len = len(buf)
  1982. if 1 == m_len:
  1983. return " Poll request svid %u" % buf[0]
  1984. if 8 > m_len:
  1985. return " Bad Length %s" % m_len
  1986. u = struct.unpack_from('<LL', buf, 0)
  1987. s = ' svid %u how x%x ' % u
  1988. if 0 != u[1] and 8 < m_len <= 104:
  1989. u = struct.unpack_from('<LLLLLLLLLLLLLLLLLLLLLLLL', buf, 8)
  1990. s += ('\n sf1d %08x %08x %08x %08x'
  1991. '\n %08x %08x %08x %08x'
  1992. '\n sf2d %08x %08x %08x %08x'
  1993. '\n %08x %08x %08x %08x'
  1994. '\n sf3d %08x %08x %08x %08x'
  1995. '\n %08x %08x %08x %08x' % u)
  1996. return s
  1997. def aid_hui(self, buf):
  1998. """UBX-AID-HUI decode, GPS Heatlh, UTC, Ionosphere"""
  1999. u = struct.unpack_from('<LddlhhhhhhffffffffL', buf, 0)
  2000. s = (' health x%x utcA0 %e utcA1 %e utcTOW %d'
  2001. '\n utcWNT %d utcLS %d utcWNF %d utcDN %d utcLSF %d utcSpare %d'
  2002. '\n klobA0 %e klobA1 %e klobA2 %e'
  2003. '\n klobA3 %e klobB0 %e klobB1 %e'
  2004. '\n klobB2 %e klobB3 %e flags x%x' % u)
  2005. return s
  2006. def aid_ini(self, buf):
  2007. """UBX-AID-INI decode, Aiding position, time, frequency, clock drift"""
  2008. u = struct.unpack_from('<lllLHHLlLLlLL', buf, 0)
  2009. s = (' ecefXOrLat %d ecefYOrLon %d ecefZOrAlt %d posAcc %u'
  2010. '\n tmCfg x%x wnoOrDate %u towOrTime %u towNs %d'
  2011. '\n tAccMs %u tAccNs %u clkDOrFreq %d clkDAccOrFreqAcc %u'
  2012. '\n flags x%x' % u)
  2013. return s
  2014. def aid_req(self, buf):
  2015. """UBX-AID-REQ decode, Sends a poll for all GPS Aiding Data"""
  2016. return " poll (AID-DATA) for all GPS Aiding Data"
  2017. # All UBX-AID messages are deprecated; use UBX-MGA messages instead
  2018. aid_ids = {
  2019. # u-blox 6
  2020. 0x00: {'str': 'REQ', 'dec': aid_req, 'minlen': 0,
  2021. 'name': 'UBX-AID-REQ'},
  2022. 0x01: {'str': 'INI', 'dec': aid_ini, 'minlen': 48,
  2023. 'name': 'UBX-AID-INI'},
  2024. 0x02: {'str': 'HUI', 'dec': aid_hui, 'minlen': 72,
  2025. 'name': 'UBX-AID-HUI'},
  2026. # u-blox 6
  2027. 0x10: {'str': 'DATA', 'dec': aid_data, 'minlen': 0,
  2028. 'name': 'UBX-AID-DATA'},
  2029. 0x30: {'str': 'ALM', 'dec': aid_alm, 'minlen': 1,
  2030. 'name': 'UBX-AID-ALM'},
  2031. 0x31: {'str': 'EPH', 'dec': aid_eph, 'minlen': 1,
  2032. 'name': 'UBX-AID-EPH'},
  2033. # u-blox 6
  2034. 0x32: {'str': 'ALPSRV', 'dec': aid_alpsrv, 'minlen': 8,
  2035. 'name': 'UBX-AID-ALPSRV'},
  2036. 0x33: {'str': 'AOP', 'dec': aid_aop, 'minlen': 1,
  2037. 'name': 'UBX-AID-AOP'},
  2038. 0x50: {'str': 'ALP', 'dec': aid_alp, 'minlen': 1,
  2039. 'name': 'UBX-AID-ALP'},
  2040. }
  2041. cfg_ant_pins = {
  2042. 1: 'svcs',
  2043. 2: 'scd',
  2044. 4: 'ocd',
  2045. 8: 'pdwnOnSCD',
  2046. 0x10: 'recovery',
  2047. }
  2048. def cfg_ant(self, buf):
  2049. """UBX-CFG-ANT decode"""
  2050. u = struct.unpack_from('<HH', buf, 0)
  2051. s = ' flags x%x pins x%x ' % u
  2052. s += ('pinSwitch %u pinSCD %u pinOCD %u reconfig %u' %
  2053. (u[1] & 0x1f, (u[1] >> 5) & 0x1f, (u[1] >> 10) & 0x1f,
  2054. u[1] >> 15))
  2055. if gps.VERB_DECODE <= self.verbosity:
  2056. s += ('\n flags (%s)' % flag_s(u[0], self.cfg_ant_pins))
  2057. return s
  2058. cfg_batch_flags = {
  2059. 1: 'enable',
  2060. 4: 'extraPvt',
  2061. 8: 'extraOdo',
  2062. 0x20: 'pioEnable',
  2063. 0x40: 'pioActiveLow',
  2064. }
  2065. def cfg_batch(self, buf):
  2066. """UBX-CFG-BATCH decode"""
  2067. u = struct.unpack_from('<BBHHBB', buf, 0)
  2068. s = (" version %u flags x%x bufsize %u notifThrs %u\n"
  2069. " pioId %u reserved1 %u" % u)
  2070. if gps.VERB_DECODE <= self.verbosity:
  2071. s += ('\n flags (%s)' % flag_s(u[1], self.cfg_batch_flags))
  2072. return s
  2073. cfg_cfg_mask = {
  2074. 0x1: 'ioPort',
  2075. 0x2: 'msgConf',
  2076. 0x4: 'infMsg',
  2077. 0x8: 'navConf',
  2078. 0x10: 'rxmConf',
  2079. 0x100: 'senConf', # not on M8030, sfdrConf in u-blox 5
  2080. 0x200: 'rinvConf',
  2081. 0x400: 'antConf',
  2082. 0x800: 'logConf', # not in u-blox 5
  2083. 0x1000: 'ftsConf', # protVer 16+
  2084. }
  2085. cfg_cfg_dev = {
  2086. 0x1: 'devBBR',
  2087. 0x2: 'devFlash',
  2088. 0x4: 'devEEPROM',
  2089. 0x10: 'devSpiFlash',
  2090. }
  2091. def cfg_cfg(self, buf):
  2092. """UBX-CFG-CFG decode"""
  2093. m_len = len(buf)
  2094. if 12 == m_len:
  2095. u = struct.unpack_from('<LLL', buf, 0)
  2096. else:
  2097. u = struct.unpack_from('<LLLB', buf, 0)
  2098. s = (' clearMask: %#x (%s)\n' %
  2099. (u[0], flag_s(u[0], self.cfg_cfg_mask)))
  2100. s += (' saveMask: %#x (%s)\n' %
  2101. (u[1], flag_s(u[1], self.cfg_cfg_mask)))
  2102. s += (' loadMask: %#x (%s)\n' %
  2103. (u[2], flag_s(u[2], self.cfg_cfg_mask)))
  2104. if 13 <= m_len:
  2105. s += (' deviceMask: %#x (%s)\n' %
  2106. (u[3], flag_s(u[3], self.cfg_cfg_dev)))
  2107. return s
  2108. def cfg_dat(self, buf):
  2109. """UBX-CFG-DAT decode, Standard Datum configuration"""
  2110. # u-blox 5 to 9, protVer 4.00 to 29
  2111. m_len = len(buf)
  2112. if 2 == m_len:
  2113. # standard datum
  2114. u = struct.unpack_from('<H', buf, 0)
  2115. s = " datumNum %u" % u
  2116. elif 44 > m_len:
  2117. s = " Bad Length %d" % m_len
  2118. elif 44 == m_len:
  2119. # set user defined datum
  2120. u = struct.unpack_from('<ddfffffff', buf, 0)
  2121. s = (" majA %.1f flat %.1f dX %.1f dY %.1f dZ %.1f\n"
  2122. " rotX %.1f rotY %.1f rotZ %.1f scale %.1f" % u)
  2123. elif 52 > m_len:
  2124. s = " Bad Length %d" % m_len
  2125. elif 52 <= m_len:
  2126. # get user defined datum
  2127. u = struct.unpack_from('<HBBBBBBddfffffff', buf, 0)
  2128. s = (" datumNum %u datumNam %u %u %u %u %u %u\n"
  2129. " majA %.1f flat %.1f dX %.1f dY %.1f dZ %.1f\n"
  2130. " rotX %.1f rotY %.1f rotZ %.1f scale %.1f" % u)
  2131. if gps.VERB_DECODE <= self.verbosity:
  2132. s += ('\n datumName (%s)' %
  2133. gps.polystr(buf[2:8]).rstrip('\0'))
  2134. else:
  2135. s = "I'm confused..."
  2136. return s
  2137. cfg_dgnss_mode = {
  2138. 2: "RTK Float",
  2139. 3: "RTK Fixed",
  2140. }
  2141. def cfg_dgnss(self, buf):
  2142. """UBX-CFG-DGNSS decode, DGNSS configuration"""
  2143. u = struct.unpack_from('<BBBB', buf, 0)
  2144. s = (" dgnssMode %u (%s) reserved1 %u %u %u" % u
  2145. (u[0], index_s(u[0], self.cfg_dgnss_mode), u[1], u[2], u[3]))
  2146. return s
  2147. def cfg_dosc(self, buf):
  2148. """UBX-CFG-DOSC decode, Disciplined oscillator configuration"""
  2149. u = struct.unpack_from('<BBBB', buf, 0)
  2150. s = " version %u numOsc %u reserved1 %u" % u
  2151. # FIXME, partial decode
  2152. return s
  2153. def cfg_dynseed(self, buf):
  2154. """UBX-CFG-DYNSEED decode,
  2155. Programming the dynamic seed for host interface signature"""
  2156. # u-blox 8 only, protVer 18 to 23
  2157. u = struct.unpack_from('<BBHLL', buf, 0)
  2158. s = " version %u reserved1 %u %u seedHi %u seedLo %u" % u
  2159. return s
  2160. def cfg_esrc(self, buf):
  2161. """UBX-CFG-ESRC decode, External synchronization source
  2162. configuration"""
  2163. u = struct.unpack_from('<BBBB', buf, 0)
  2164. s = " version %u numSources %u reserved1 %u" % u
  2165. # FIXME, partial decode
  2166. return s
  2167. def cfg_fixseed(self, buf):
  2168. """UBX-CFG-FIXSEED decode,
  2169. Programming the fixed seed for host interface signature"""
  2170. # u-blox 8 only, protVer 18 to 23
  2171. u = struct.unpack_from('<BBHLL', buf, 0)
  2172. s = " version %u length %u reserved1 %u seedHi %u seedLo %u" % u
  2173. # FIXME, partial decode
  2174. return s
  2175. cfg_fxn_flags = {
  2176. 2: "sleep Float",
  2177. 8: "absAlign",
  2178. 0x10: "onOff",
  2179. }
  2180. def cfg_fxn(self, buf):
  2181. """UBX-CFG-FXN decode, FXN FixNOW configuration"""
  2182. # Antaris 4, u-blox 5, protVer 6.00 to 6.02
  2183. u = struct.unpack_from('<LLLLLLLLL', buf, 0)
  2184. s = (" flags x%x tReacq %u tAcq %u tReacqOff %u\n"
  2185. " tAcqOff %u tOn %u tOff %u res %u baseTow %u\n" % u)
  2186. if gps.VERB_DECODE <= self.verbosity:
  2187. s += ("\n flags (%s)" %
  2188. (flag_s(u[0], self.cfg_fxn_flags)))
  2189. return s
  2190. def cfg_geofence(self, buf):
  2191. """UBX-CFG-GEOFENCE decode, Geofencing configuration"""
  2192. u = struct.unpack_from('<BBBBBBBB', buf, 0)
  2193. s = (" version %u numFences %u confLvl %u reserved1 %u\n"
  2194. " pioEnabled %u pinPolarity %u pin %u reserved2 %u" % u)
  2195. for i in range(0, u[1]):
  2196. u = struct.unpack_from('<llL', buf, 8 + (i * 12))
  2197. s = "\n lat %d lon %d radius %d" % u
  2198. return s
  2199. # signals defined in protver 27+
  2200. # signals used in protver 15+
  2201. # top byte used, but not defined
  2202. cfg_gnss_sig = {
  2203. 0: {0x010000: "L1C/A", # GPS
  2204. 0x100000: "L2C"},
  2205. 1: {0x010000: "L1C/A"}, # SBAS
  2206. 2: {0x010000: "E1", # Galileo
  2207. 0x200000: "E5b"},
  2208. 3: {0x010000: "B1I", # BeiDou
  2209. 0x100000: "B2I"},
  2210. 4: {0x010000: "L1"}, # IMES
  2211. 5: {0x010000: "L1C/A", # QZSS
  2212. 0x040000: "L1S",
  2213. 0x100000: "L2C"},
  2214. 6: {0x010000: "L1", # GLONASS
  2215. 0x100000: "L2"},
  2216. }
  2217. def cfg_gnss(self, buf):
  2218. """UBX-CFG-GNSS decode, GNSS system configuration"""
  2219. u = struct.unpack_from('<BBBB', buf, 0)
  2220. s = " msgVer %u numTrkChHw %u numTrkChUse %u numConfigBlocks %u" % u
  2221. for i in range(0, u[3]):
  2222. u = struct.unpack_from('<BBBBL', buf, 4 + (i * 8))
  2223. sat = u[0]
  2224. s += ("\n gnssId %u TrkCh %2u maxTrCh %2u reserved %u "
  2225. "Flags x%08x\n" % u)
  2226. if 7 > sat:
  2227. s += (" %s %s " %
  2228. (index_s(sat, self.gnss_id),
  2229. flag_s(u[4], self.cfg_gnss_sig[sat])))
  2230. else:
  2231. s += "Unk "
  2232. if u[4] & 0x01:
  2233. s += 'enabled'
  2234. return s
  2235. def cfg_hnr(self, buf):
  2236. """UBX-CFG-HNR decode, High Navigation Rate Settings"""
  2237. u = struct.unpack_from('<BBBb', buf, 0)
  2238. s = " highNavRate %u reserved %u %u %u" % u
  2239. return s
  2240. cfg_inf_protid = {
  2241. 0: "UBX",
  2242. 1: "NMEA",
  2243. # labels of following values based on u-blox document
  2244. # no. GPS.G3-X-03002-D (Antaris protocol specification)
  2245. 2: "RTCM", # cannot be used to output INF messages
  2246. 3: "RAW", # used by u-center
  2247. 12: "User 0", # used by u-center
  2248. 13: "User 1", # used by u-center
  2249. 14: "User 2", # used by u-center
  2250. 15: "User 3", # used by u-center
  2251. }
  2252. def cfg_inf(self, buf):
  2253. """UBX-CFG-INF decode, Poll configuration for one protocol"""
  2254. m_len = len(buf)
  2255. if 1 == m_len:
  2256. return (" Poll request: %s" %
  2257. index_s(buf[0], self.cfg_inf_protid))
  2258. if 8 > m_len:
  2259. return " Bad Length %d" % m_len
  2260. # very old u-blox have 8 octets, e.g. Antaris 4 w/ protVer 11
  2261. u = struct.unpack_from('<BBBBBBBB', buf, 0)
  2262. s = (" protocolId %u reserved1 %u %u %u\n"
  2263. " infMsgMask %u %u %u %u" % u)
  2264. # newer u-blox have 10 octets, e.g. u-blox 6 w/ protVer 13
  2265. if 9 < m_len:
  2266. u = struct.unpack_from('<BB', buf[8:], 0)
  2267. s += (" %u %u" % u)
  2268. if gps.VERB_DECODE <= self.verbosity:
  2269. s += ('\n protocolId (%s)' %
  2270. index_s(buf[0], self.cfg_inf_protid))
  2271. return s
  2272. cfg_itfm_config = {
  2273. 0x80000000: "enable",
  2274. }
  2275. cfg_itfm_config2 = {
  2276. 0x4000: "enable2",
  2277. }
  2278. cfg_itfm_ant = {
  2279. 1: "passive",
  2280. 2: "active",
  2281. }
  2282. def cfg_itfm(self, buf):
  2283. """UBX-CFG-ITFM decode, Jamming/Interference Monitor configuration"""
  2284. u = struct.unpack_from('<LL', buf, 0)
  2285. s = " config x%x config2 x%x" % u
  2286. if gps.VERB_DECODE <= self.verbosity:
  2287. s += ("\n config (%s) bbThreshold %u cwThreshold %u "
  2288. "algorithmBits x%x"
  2289. "\n config2 (%s) generalBits x%x antSetting (%s)" %
  2290. (flag_s(buf[0], self.cfg_itfm_config),
  2291. u[0] & 0x0f, (u[0] >> 4) & 0x1f, (u[0] >> 9) & 0x1fffff,
  2292. flag_s(buf[1], self.cfg_itfm_config2),
  2293. u[1] & 0x0fff,
  2294. index_s((u[1] >> 12) & 3, self.cfg_itfm_config2)))
  2295. return s
  2296. cfg_logfilter_flags = {
  2297. 1: "recordEnabled",
  2298. 2: "psmOncePerWakupEnabled",
  2299. 4: "applyAllFilterSettings",
  2300. }
  2301. def cfg_logfilter(self, buf):
  2302. """UBX-CFG-LOGFILTER decode, Data Logger Configuration"""
  2303. # u-blox 7+, protVer 14+
  2304. u = struct.unpack_from('<BBHHHL', buf, 0)
  2305. s = (" version %u flags x%x minInterval %u timeThreshold %u\n"
  2306. " speedThreshold %u positionThreshold %u" % u)
  2307. if gps.VERB_DECODE <= self.verbosity:
  2308. s += ("\n flags (%s)" %
  2309. (flag_s(buf[1], self.cfg_logfilter_flags)))
  2310. return s
  2311. utc_std = {
  2312. 0: "Default",
  2313. 1: "CRL",
  2314. 2: "NIST",
  2315. 3: "USNO",
  2316. 4: "BIPM",
  2317. 5: "tbd",
  2318. 6: "SU",
  2319. 7: "NTSC",
  2320. }
  2321. cfg_nav5_dyn = {
  2322. 0: "Portable",
  2323. 2: "Stationary",
  2324. 3: "Pedestrian",
  2325. 4: "Automotive",
  2326. 5: "Sea",
  2327. 6: "Airborne with <1g Acceleration",
  2328. 7: "Airborne with <2g Acceleration",
  2329. 8: "Airborne with <4g Acceleration",
  2330. }
  2331. cfg_nav5_fix = {
  2332. 1: "2D only",
  2333. 2: "3D only",
  2334. 3: "Auto 2D/3D",
  2335. }
  2336. cfg_nav5_mask = {
  2337. 1: "dyn",
  2338. 2: "minEl",
  2339. 4: "posFixMode",
  2340. 8: "drLim",
  2341. 0x10: "posMask",
  2342. 0x20: "timeMask",
  2343. 0x40: "staticHoldMask",
  2344. 0x80: "dgpsMask",
  2345. 0x100: "cnoThreshold",
  2346. 0x400: "utc",
  2347. }
  2348. def cfg_nav5(self, buf):
  2349. """UBX-CFG-NAV5 nav Engine Settings"""
  2350. u = struct.unpack_from('<HBBlLbBHHHHbbbbHHbBL', buf, 0)
  2351. s = (' mask %#x dynModel %u fixmode %d fixedAlt %d FixedAltVar %u\n'
  2352. ' minElev %d drLimit %u pDop %u tDop %u pAcc %u tAcc %u\n'
  2353. ' staticHoldThresh %u dgpsTimeOut %u cnoThreshNumSVs %u\n'
  2354. ' cnoThresh %u res %u staticHoldMaxDist %u utcStandard %u\n'
  2355. ' reserved x%x %x' % u)
  2356. if gps.VERB_DECODE <= self.verbosity:
  2357. s += ("\n dynModel (%s) fixMode (%s) utcStandard (%s)"
  2358. "\n mask (%s)" %
  2359. (index_s(u[1], self.cfg_nav5_dyn),
  2360. index_s(u[2], self.cfg_nav5_fix),
  2361. index_s(u[17] >> 4, self.utc_std),
  2362. flag_s(u[0] >> 4, self.cfg_nav5_mask)))
  2363. return s
  2364. cfg_navx5_mask1 = {
  2365. 4: "minMax",
  2366. 8: "minCno",
  2367. 0x40: "initial3dfix",
  2368. 0x200: "wknRoll",
  2369. 0x400: "ackAid",
  2370. 0x2000: "ppp",
  2371. 0x4000: "aop",
  2372. }
  2373. cfg_navx5_mask2 = {
  2374. 0x40: "adr",
  2375. 0x80: "sigAttenComp",
  2376. }
  2377. cfg_navx5_aop = {
  2378. 1: "useAOP",
  2379. }
  2380. def cfg_navx5(self, buf):
  2381. """UBX-CFG-NAVX5 decode, Navigation Engine Expert Settings"""
  2382. # deprecated protver 23+
  2383. # length == 20 case seems broken?
  2384. m_len = len(buf)
  2385. u = struct.unpack_from('<HHLHBBBBBHBH', buf, 0)
  2386. s = (" version %u mask1 x%x mask2 x%x reserved1 %u minSVs %u "
  2387. "maxSVs %u minCNO %u\n"
  2388. " reserved2 %u iniFix3D %u reserved3 %u ackAiding %u "
  2389. "wknRollover %u" % u)
  2390. # length == 40 in protver 27
  2391. if 40 <= m_len:
  2392. u1 = struct.unpack_from('<BBHHBBHHLHBB', buf, 20)
  2393. s += ("\n sigAttenCompMode %u reserved456 %u %u %u usePPP %u "
  2394. "aopCfg %u reserved7 %u"
  2395. "\n aopOrbMaxErr %u reserved89 %u %u %u useAdr %u" % u1)
  2396. if gps.VERB_DECODE <= self.verbosity:
  2397. s += ("\n mask1 (%s)"
  2398. "\n mask2 (%s) aopCfg (%s)" %
  2399. (flag_s(u[1], self.cfg_navx5_mask1),
  2400. flag_s(u[2], self.cfg_navx5_mask2),
  2401. flag_s(u1[5], self.cfg_navx5_aop)))
  2402. return s
  2403. def cfg_msg(self, buf):
  2404. """UBX-CFG-MSG decode"""
  2405. m_len = len(buf)
  2406. if 2 == m_len:
  2407. u = struct.unpack_from('<BB', buf, 0)
  2408. return ' Rate request %s' % self.class_id_s(u[0], u[1])
  2409. if 3 == m_len:
  2410. u = struct.unpack_from('<BBB', buf, 0)
  2411. return (' Rate set %s Rate %d' %
  2412. (self.class_id_s(u[0], u[1]), u[2]))
  2413. if 8 != m_len:
  2414. return " Bad Length %s" % m_len
  2415. u = struct.unpack_from('<BBBBBBBB', buf, 0)
  2416. s = (' %s Rates %u %u %u %u %u %u' %
  2417. (self.class_id_s(u[0], u[1]), u[2], u[3], u[4], u[5], u[6], u[7]))
  2418. return s
  2419. cfg_nmea_filter = {
  2420. 1: "posFilt",
  2421. 2: "mskPosFilt",
  2422. 4: "timeFilt",
  2423. 8: "dateFilt",
  2424. 0x10: "gpsOnlyFilter",
  2425. 0x20: "trackFilt",
  2426. }
  2427. cfg_nmea_ver = {
  2428. 0x21: "2.1",
  2429. 0x23: "2.3",
  2430. 0x40: "4.0",
  2431. 0x41: "4.10",
  2432. 0x4b: "4.11",
  2433. }
  2434. cfg_nmea_flags = {
  2435. 1: "compat",
  2436. 2: "consider",
  2437. 4: "limit82",
  2438. 8: "highPrec",
  2439. }
  2440. cfg_nmea_svn = {
  2441. 0: "Strict",
  2442. 1: "Extended",
  2443. }
  2444. cfg_nmea_mtid = {
  2445. 0: "Default",
  2446. 1: "GP",
  2447. 2: "GL",
  2448. 3: "GN",
  2449. 4: "GA",
  2450. 5: "GB",
  2451. 6: "GQ",
  2452. }
  2453. cfg_nmea_gtid = {
  2454. 0: "GNSS Specific",
  2455. 1: "Main",
  2456. }
  2457. cfg_nmea_gnssfilt = {
  2458. 1: "gps",
  2459. 2: "sbas",
  2460. 4: "galileo",
  2461. 0x10: "qzss",
  2462. 0x20: "glonass",
  2463. 0x40: "beidou",
  2464. }
  2465. def cfg_nmea(self, buf):
  2466. """UBX-CFG-NMEA decode, NMEA protocol configuration"""
  2467. # old u-blox have 4 octets, e.g. u-blox 6 w/ protVer < 14
  2468. # less old u-blox have 12 octets, e.g. u-blox 7 w/ protVer == 14
  2469. # more recent u-blox have 20 octets, e.g. u-blox 8 w/ protVer > 14
  2470. # deprecated in most recent u-blox, e.g. u-blox 9 w/ protVer > 23.01
  2471. u = struct.unpack_from('<BBBB', buf, 0)
  2472. s = (" filter x%x nmeaVersion x%x numSv %u flags x%x " % u)
  2473. if 11 < len(buf):
  2474. u1 = struct.unpack_from('<LBBBB', buf[4:], 0)
  2475. s += ("gnssToFilter x%x\n svNumbering %u"
  2476. " mainTalkerId %u gsvTalkerId %u version %u" % u1)
  2477. u += u1
  2478. if 19 < len(buf):
  2479. u2 = struct.unpack_from('<BBBBBBBB', buf[12:], 0)
  2480. s += ("\n bdsTalkerId %u %u reserved1 %u %u %u %u %u %u" % u2)
  2481. u += u2
  2482. if gps.VERB_DECODE <= self.verbosity:
  2483. s += ("\n filter (%s) NMEA Version (%s) numSV (%s) flags (%s)" %
  2484. (flag_s(u[0], self.cfg_nmea_filter),
  2485. index_s(u[1], self.cfg_nmea_ver),
  2486. u[2] if 0 != u[2] else "Unlimited",
  2487. flag_s(u[3], self.cfg_nmea_flags)))
  2488. if 11 < len(buf):
  2489. s += ("\n gnssToFilter (%s) svNumbering (%s)"
  2490. "mainTalkerId (%s)"
  2491. "\n gsvTalkerId (%s)" %
  2492. (flag_s(u[4], self.cfg_nmea_gnssfilt),
  2493. index_s(u[5], self.cfg_nmea_svn),
  2494. index_s(u[6], self.cfg_nmea_mtid),
  2495. index_s(u[7], self.cfg_nmea_gtid)))
  2496. return s
  2497. cfg_nvs_mask = {
  2498. 0x20000: 'alm',
  2499. 0x20000000: 'aop',
  2500. }
  2501. def cfg_nvs(self, buf):
  2502. """UBX-CFG-NVS decode, Clear,
  2503. Save and Load non-volatile storage data"""
  2504. # u-blox 6, protVer 7.03
  2505. u = struct.unpack_from('<LLLB', buf, 0)
  2506. s = (' clearMask: %#x (%s)\n' %
  2507. (u[0], flag_s(u[0], self.cfg_nvs_mask)))
  2508. s += (' saveMask: %#x (%s)\n' %
  2509. (u[1], flag_s(u[1], self.cfg_nvs_mask)))
  2510. s += (' loadMask: %#x (%s)\n' %
  2511. (u[2], flag_s(u[2], self.cfg_nvs_mask)))
  2512. s += (' deviceMask: %#x (%s)\n' %
  2513. (u[3], flag_s(u[3], self.cfg_cfg_dev)))
  2514. return s
  2515. cfg_odo_flags = {
  2516. 1: "useODO",
  2517. 2: "useCOG",
  2518. 4: "useLPVel",
  2519. 8: "useLPCog",
  2520. }
  2521. cfg_odo_profile = {
  2522. 0: "Running",
  2523. 1: "Cycling",
  2524. 2: "Swimming",
  2525. 3: "Car",
  2526. 4: "Custom",
  2527. }
  2528. def cfg_odo(self, buf):
  2529. """UBX-CFG-ODO decode, Odometer, Low-speed COG Engine Settings"""
  2530. u = struct.unpack_from('<BBBBBBBBBBBBBBBBBBBB', buf, 0)
  2531. s = (" version %u reserved1 %u %u %u flags x%x odoCfg x%x\n"
  2532. " reserved2 %u %u %u %u %u %u\n"
  2533. " cagMaxSpeed %u cogMaxPosAcc %u reserved3 %u %u\n"
  2534. " velLpGain %u cogLpGain %u reserved4 %u %u" % u)
  2535. if gps.VERB_DECODE <= self.verbosity:
  2536. s += ("\n flags (%s) odoCfg (%s)" %
  2537. (flag_s(u[4], self.cfg_odo_flags),
  2538. index_s(u[5], self.cfg_odo_profile)))
  2539. return s
  2540. cfg_pm_flags = {
  2541. 0x20: "extintWake",
  2542. 0x40: "extintBackup",
  2543. 0x80: "extintInactive",
  2544. 0x400: "waitTimeFix",
  2545. 0x800: "updateRTC",
  2546. 0x1000: "updateEPH",
  2547. 0x10000: "doNotEnterOff",
  2548. }
  2549. cfg_pm_limitPeakCurr = {
  2550. 0: "disabled",
  2551. 1: "enabled",
  2552. 2: "reserved",
  2553. 3: "reserved3",
  2554. }
  2555. def cfg_pm(self, buf):
  2556. """UBX-CFG-PM decode, Poswer Management Configuration"""
  2557. # u-blox 5, protVer 6.00 to 6.02
  2558. u = struct.unpack_from('<BBBBLLLLHH', buf, 0)
  2559. s = (" version %u res1 %u res2 %u res3 %u flags x%x updatePeriod %u\n"
  2560. " searchPeriod %u gridOffset %u onTime %u minAcqTime %u\n" % u)
  2561. if gps.VERB_DECODE <= self.verbosity:
  2562. s += ('\n flags (%s) extintSel (EXTINT%u) '
  2563. 'limitPeakCurr (%s)' %
  2564. (flag_s(u[4], self.cfg_pm_flags),
  2565. (u[4] >> 4) & 1,
  2566. index_s((u[4] >> 8) & 3, self.cfg_pm_limitPeakCurr)))
  2567. return s
  2568. cfg_pm2_mode = {
  2569. 0: "ON/OFF operation (PSMOO)",
  2570. 1: "Cyclic tracking operation (PSMCT)",
  2571. 2: "reserved",
  2572. 3: "reserves3",
  2573. }
  2574. cfg_pm2_optTarget = {
  2575. 0: "performance",
  2576. 1: "power save",
  2577. }
  2578. def cfg_pm2(self, buf):
  2579. """UBX-CFG-PM2 decode, Extended Power Mode Configuration"""
  2580. # three versions, two lengths
  2581. # "version" 1 is 44 bytes
  2582. # "version" 2 is 48 bytes,protver <= 22
  2583. # "version" 2 is 48 bytes,protver >= 23
  2584. m_len = len(buf)
  2585. # 48 bytes protver 18+
  2586. u = struct.unpack_from('<BBBBLLLLHHLLLLL', buf, 0)
  2587. s = (" version %u reserved1 %u maxStartupStateDur %u reserved2 %u\n"
  2588. " flags x%x updatePeriod %u searchPeriod %u\n"
  2589. " gridOffset %u ontime %u minAcqTime %u\n"
  2590. " reserved3 %u %u %u %u %u" % u)
  2591. if 48 <= m_len:
  2592. u1 = struct.unpack_from('<L', buf, 44)
  2593. s += "\n extintInactivityMs %u" % u1
  2594. if gps.VERB_DECODE <= self.verbosity:
  2595. s += ('\n flags (%s) extintSel (EXTINT%u)'
  2596. '\n limitPeakCurr (%s)'
  2597. '\n optTarget (%s) mode (%s)' %
  2598. (flag_s(u[4], self.cfg_pm_flags),
  2599. (u[4] >> 4) & 1,
  2600. index_s((u[4] >> 8) & 3, self.cfg_pm_limitPeakCurr),
  2601. index_s((u[4] >> 1) & 3, self.cfg_pm2_optTarget,
  2602. nf="reserved"),
  2603. index_s((u[4] >> 17) & 3, self.cfg_pm2_mode)))
  2604. return s
  2605. cfg_pms_values = {0: "Full power",
  2606. 1: "Balanced",
  2607. 2: "Interval",
  2608. 3: "Aggressive with 1Hz",
  2609. 4: "Aggressive with 2Hz",
  2610. 5: "Aggressive with 4Hz",
  2611. 0xff: "Invalid"
  2612. }
  2613. def cfg_pms(self, buf):
  2614. """UBX-CFG-PMS decode, Power Mode Setup"""
  2615. u = struct.unpack_from('<BBHHBB', buf, 0)
  2616. s = (' version %u powerSetupValue %u'
  2617. ' period %u onTime %#x reserved1 %u %u' % u)
  2618. if gps.VERB_DECODE <= self.verbosity:
  2619. s += ('\n powerSetupValue (%s)' %
  2620. index_s(u[1], self.cfg_pms_values))
  2621. return s
  2622. cfg_prt_flags = {
  2623. 0x2: 'extendedTxTimeout',
  2624. }
  2625. cfg_prt_proto = {
  2626. 0x1: 'UBX',
  2627. 0x2: 'NMEA',
  2628. 0x4: 'RTCM2', # not in u-blox 5
  2629. 0x20: 'RTCM3', # protVer 20+
  2630. }
  2631. def cfg_prt(self, buf):
  2632. """UBX-CFG-PRT decode, Port Configuration """
  2633. m_len = len(buf)
  2634. portid = buf[0]
  2635. idstr = '%u (%s)' % (portid, self.port_ids.get(portid, '?'))
  2636. if 1 == m_len:
  2637. return " Poll request PortID %s" % idstr
  2638. # Note that this message can contain multiple 20-byte submessages, but
  2639. # only in the send direction, which we don't currently do.
  2640. if 20 > m_len:
  2641. return " Bad Length %s" % m_len
  2642. u = struct.unpack_from('<BBHLLHHHH', buf, 0)
  2643. s = [' PortID %s reserved1 %u txReady %#x' % (idstr, u[1], u[2])]
  2644. s.append({1: ' mode %#x baudRate %u',
  2645. 2: ' mode %#x baudRate %u',
  2646. 3: ' reserved2 [%u %u]',
  2647. 4: ' mode %#x reserved2 %u',
  2648. 0: ' mode %#x reserved2 %u',
  2649. }.get(portid, ' ???: %u,%u') % tuple(u[3:5]))
  2650. s.append(' inProtoMask %#x outProtoMask %#x' % tuple(u[5:7]))
  2651. s.append({1: ' flags %#x reserved2 %u',
  2652. 2: ' flags %#x reserved2 %u',
  2653. 3: ' reserved3 %u reserved4 %u',
  2654. 4: ' flags %#x reserved3 %u',
  2655. 0: ' flags %#x reserved3 %u',
  2656. }.get(portid, ' ??? %u,%u') % tuple(u[7:]))
  2657. if portid == 0:
  2658. s.append(' slaveAddr %#x' % (u[3] >> 1 & 0x7F))
  2659. s.append(' inProtoMask (%s)\n'
  2660. ' outProtoMask (%s)' %
  2661. (flag_s(u[5], self.cfg_prt_proto),
  2662. flag_s(u[6], self.cfg_prt_proto)))
  2663. if portid in set([1, 2, 4, 0]):
  2664. s.append(' flags (%s)' % flag_s(u[7], self.cfg_prt_flags))
  2665. return '\n'.join(s)
  2666. cfg_pwr_state = {
  2667. 0x52554E20: "GNSS running",
  2668. 0x53544F50: "GNSS stopped",
  2669. 0x42434B50: "Software Backup",
  2670. }
  2671. def cfg_pwr(self, buf):
  2672. """UBX-CFG-PWR decode, Put receiver in a defined power state"""
  2673. u = struct.unpack_from('<BBBBL', buf, 0)
  2674. s = (" version %u reserved %u %u %u state %u" %
  2675. (u + (index_s(u[0], self.cfg_pwr_state),)))
  2676. return s
  2677. cfg_rate_system = {
  2678. 0: "UTC",
  2679. 1: "GPS",
  2680. 2: "GLONASS",
  2681. 3: "BeiDou",
  2682. 4: "Galileo",
  2683. }
  2684. def cfg_rate(self, buf):
  2685. """UBX-CFG-RATE decode, Navigation/Measurement Rate Settings"""
  2686. u = struct.unpack_from('<HHH', buf, 0)
  2687. s = (" measRate %u navRate %u timeRef %u (%s)" %
  2688. (u + (index_s(u[2], self.cfg_rate_system),)))
  2689. return s
  2690. cfg_rinv_flags = {
  2691. 1: "dump",
  2692. 2: "binary",
  2693. }
  2694. def cfg_rinv(self, buf):
  2695. """UBX-CFG-RINV decode, Contents of Remote Inventory"""
  2696. # u-blox 5, protVer 6.00 to 6.02
  2697. m_len = len(buf)
  2698. u = struct.unpack_from('<B', buf, 0)
  2699. s = (" flags x%x (%s) data:" %
  2700. (u + (flag_s(u[0], self.cfg_rinv_flags),)))
  2701. for i in range(0, m_len - 1):
  2702. if 0 == (i % 8):
  2703. s += "\n "
  2704. u = struct.unpack_from('<B', buf, i + 1)
  2705. s += " %3u" % u
  2706. return s
  2707. cfg_rst_navBbr = {
  2708. 0: "Hot Start",
  2709. 1: "Warm Start",
  2710. 0xffff: "Cold Start",
  2711. }
  2712. cfg_rst_navBbr1 = {
  2713. 1: "eph",
  2714. 2: "alm",
  2715. 4: "health",
  2716. 8: "klob",
  2717. 0x10: "pos",
  2718. 0x20: "clkd",
  2719. 0x40: "osc",
  2720. 0x80: "utc",
  2721. 0x100: "rtc",
  2722. 0x8000: "aop",
  2723. }
  2724. cfg_rst_resetMode = {
  2725. 0: "Hardware reset",
  2726. 1: "Software reset",
  2727. 2: "Software reset (GNSS only)",
  2728. 4: "Hardware reset, after shutdown",
  2729. 8: "Controlled GNSS stop",
  2730. 9: "Controlled GNSS start",
  2731. }
  2732. def cfg_rst(self, buf):
  2733. """"UBX-CFG-RST decode, Reset Receiver/Clear Backup Data Structures"""
  2734. u = struct.unpack_from('<HBB', buf, 0)
  2735. s = ' navBbrmask x%x resetMode %u reserved %u' % u
  2736. if gps.VERB_DECODE <= self.verbosity:
  2737. # fun, two different ways to decode...
  2738. s1 = index_s(u[0], self.cfg_rst_navBbr, nf="")
  2739. if not s1:
  2740. s1 = flag_s(u[0], self.cfg_rst_navBbr1)
  2741. s += ("\n resetMode (%s)"
  2742. "\n navBbrMask (%s)" %
  2743. (index_s(u[1], self.cfg_rst_resetMode),
  2744. s1))
  2745. return s
  2746. cfg_rxm_lpMode = {
  2747. 0: "Continuous Mode",
  2748. 1: "Power Save Mode",
  2749. 4: "Continuous Mode",
  2750. }
  2751. def cfg_rxm(self, buf):
  2752. """UBX-CFG-RXM decode, Navigation/Measurement"""
  2753. u = struct.unpack_from('<BB', buf, 0)
  2754. s = (" reserved1 %u lpMode %u (%s)" %
  2755. (u + (index_s(u[1], self.cfg_rxm_lpMode),)))
  2756. return s
  2757. cfg_sbas_mode = {
  2758. 1: "enabled",
  2759. 2: "test",
  2760. }
  2761. cfg_sbas_usage = {
  2762. 1: "range",
  2763. 2: "diffCorr",
  2764. 3: "integrity",
  2765. }
  2766. cfg_sbas_scanmode1 = {
  2767. 1: "PRN120",
  2768. 2: "PRN121",
  2769. 4: "PRN122",
  2770. 8: "PRN123",
  2771. 0x10: "PRN124",
  2772. 0x20: "PRN125",
  2773. 0x40: "PRN126",
  2774. 0x80: "PRN127",
  2775. 0x100: "PRN128",
  2776. 0x200: "PRN129",
  2777. 0x400: "PRN130",
  2778. 0x800: "PRN131",
  2779. 0x1000: "PRN132",
  2780. 0x2000: "PRN133",
  2781. 0x4000: "PRN134",
  2782. 0x8000: "PRN135",
  2783. 0x10000: "PRN136",
  2784. 0x20000: "PRN137",
  2785. 0x40000: "PRN138",
  2786. 0x80000: "PRN139",
  2787. 0x100000: "PRN140",
  2788. 0x200000: "PRN141",
  2789. 0x400000: "PRN142",
  2790. 0x800000: "PRN143",
  2791. 0x1000000: "PRN144",
  2792. 0x2000000: "PRN145",
  2793. 0x4000000: "PRN146",
  2794. 0x8000000: "PRN147",
  2795. 0x10000000: "PRN148",
  2796. 0x20000000: "PRN149",
  2797. 0x40000000: "PRN150",
  2798. 0x80000000: "PRN151",
  2799. }
  2800. cfg_sbas_scanmode2 = {
  2801. 1: "PRN152",
  2802. 2: "PRN153",
  2803. 4: "PRN154",
  2804. 8: "PRN155",
  2805. 0x10: "PRN156",
  2806. 0x20: "PRN157",
  2807. 0x40: "PRN158",
  2808. }
  2809. def cfg_sbas(self, buf):
  2810. """UBX-CFG-SBAS decode, SBAS Configuration"""
  2811. u = struct.unpack_from('<BBBBL', buf, 0)
  2812. s = (" mode x%x usage x%x maxSBAS %u scanMode2 x%x"
  2813. " scanMode1: x%x" % u)
  2814. if gps.VERB_DECODE <= self.verbosity:
  2815. s += ("\n mode (%s) usage (%s) scanmode2 (%s)"
  2816. "\n scanmode1 (%s)" %
  2817. (flag_s(u[0], self.cfg_sbas_mode),
  2818. flag_s(u[1], self.cfg_sbas_usage),
  2819. flag_s(u[3], self.cfg_sbas_scanmode2),
  2820. flag_s(u[4], self.cfg_sbas_scanmode1)))
  2821. return s
  2822. cfg_slas_mode = {
  2823. 1: "enabled",
  2824. 2: "test",
  2825. 4: "raim",
  2826. }
  2827. def cfg_slas(self, buf):
  2828. """UBX-CFG-SLAS decode, SLAS configuration"""
  2829. # protVer 19.2 (ADR, UDR only)
  2830. u = struct.unpack_from('<BBH', buf, 0)
  2831. s = " mode %u reserved1 %u %u" % u
  2832. if gps.VERB_DECODE <= self.verbosity:
  2833. s += "\n mode (%s)" % (flag_s(u[0], self.cfg_slas_mode))
  2834. return s
  2835. cfg_smgr_messageCfg = {
  2836. 1: "measInternal",
  2837. 2: "measGNSS",
  2838. 4: "measEXTINT0",
  2839. 8: "measEXTINT1",
  2840. }
  2841. def cfg_smgr(self, buf):
  2842. """UBX-CFG-SMGR decode, Synchronization manager configuration"""
  2843. u = struct.unpack_from('<BBHHBBHHHHL', buf, 0)
  2844. s = (" version %u minGNSSFix %u maxFreqChangeRate %u "
  2845. "maxPhaseCorrR %u\n"
  2846. " reserved1 %u %u freqTolerance %u timeTolerance %u "
  2847. "messageCfg x%x\n"
  2848. " maxSlewRate %u flags x%x" % u)
  2849. if gps.VERB_DECODE <= self.verbosity:
  2850. s += ("\n messageCfg (%s)" %
  2851. (flag_s(u[7], self.cfg_smgr_messageCfg)))
  2852. return s
  2853. cfg_tmode_timeMode = {
  2854. 0: "Disabled",
  2855. 1: "Survey In",
  2856. 2: "Fixed Mode",
  2857. }
  2858. def cfg_tmode(self, buf):
  2859. """UBX-CFG-TMODE decode, Time Mode Settings"""
  2860. # u-blox 5, protVer 5.00 to 6.02 (timing feature only)
  2861. u = struct.unpack_from('<BBHlllLLL', buf, 0)
  2862. s = (' timeMode %u fixedPosX %d fixedPosY %d fixedPosZ %d\n'
  2863. ' fixedPosVar %u svinMinDur %u svinAccLimit %u' % u)
  2864. if gps.VERB_DECODE <= self.verbosity:
  2865. s += ("\n timeMode (%s)" %
  2866. (index_s(u[0], self.cfg_tmode_timeMode)))
  2867. return s
  2868. cfg_tmode2_flags = {
  2869. 1: "lla",
  2870. 2: "altInv",
  2871. }
  2872. def cfg_tmode2(self, buf):
  2873. """UBX-CFG-TMODE2 decode, Time Mode Settings 2"""
  2874. # u-blox 6, 7 and 8 (timing only)
  2875. # not in u-blox 9
  2876. # protver 13+
  2877. u = struct.unpack_from('<BBHlllLLL', buf, 0)
  2878. s = (' timeMode %u reserved1 %u usage %#x\n'
  2879. ' ecefXOrLat %d ecefYOrLon %d ecefZOrAlt %d\n'
  2880. ' fixedPosAcc %u svinMinDur %u svinAccLimit %u' % u)
  2881. if gps.VERB_DECODE <= self.verbosity:
  2882. s += ("\n timeMode (%s) flags (%s)" %
  2883. (index_s(u[0], self.cfg_tmode_timeMode),
  2884. flag_s(u[2], self.cfg_tmode2_flags)))
  2885. return s
  2886. cfg_tmode3_flags = {
  2887. 0x100: "lla",
  2888. }
  2889. def cfg_tmode3(self, buf):
  2890. """UBX-CFG-TMODE3 decode, Time Mode Settings 3"""
  2891. # in M8 HP only, protver 20 to 23
  2892. # Not in u-blox 7-, HP only
  2893. # undocumented, but present in ZED-F9T
  2894. # documented in ZED-F9P, protver 27
  2895. # deprecated in 23.01
  2896. u = struct.unpack_from('<BBHlllbbbBLLLLL', buf, 0)
  2897. s = (' version %u reserved1 %u flags x%x\n'
  2898. ' ecefXOrLat %d ecefYOrLon %d ecefZOrAlt %d\n'
  2899. ' ecefXOrLatHP %d ecefYOrLonHP %d ecefZOrAltHP %d\n'
  2900. ' reserved2 %u fixedPosAcc %u svinMinDur %u svinAccLimit %u\n'
  2901. ' reserved3 %u %u' % u)
  2902. if gps.VERB_DECODE <= self.verbosity:
  2903. s += ("\n flags (%s %s)" %
  2904. (index_s(u[2], self.cfg_tmode_timeMode),
  2905. flag_s(u[2] & 0x100, self.cfg_tmode3_flags)))
  2906. return s
  2907. cfg_tp_status = {
  2908. -1: "negative",
  2909. 0: "off",
  2910. 1: "positive",
  2911. }
  2912. cfg_tp_timeRef = {
  2913. 0: "UTC",
  2914. 1: "GPS",
  2915. 2: "Local",
  2916. }
  2917. cfg_tp_flags = {
  2918. 1: "syncMode",
  2919. }
  2920. def cfg_tp(self, buf):
  2921. """UBX-CFG-TP decode, Time Pulse Settings"""
  2922. # protVer 4.00 to 6.02
  2923. u = struct.unpack_from('<HHbBBBhhl', buf, 0)
  2924. s = (' interval %u length %u status %d timeRef %u flags x%x res x%x\n'
  2925. ' antennaCableDelay %u rfGroupDelay %d userDelay %d' % u)
  2926. if gps.VERB_DECODE <= self.verbosity:
  2927. s += ("\n flags (%s, %s, %s)" %
  2928. (index_s(u[2], self.cfg_tp_status),
  2929. index_s(u[3], self.cfg_tp_timeRef),
  2930. flag_s(u[4], self.cfg_tp_flags)))
  2931. return s
  2932. cfg_tp5_flags = {
  2933. 1: "Active",
  2934. 2: "lockGnssFreq",
  2935. 4: "lockedOtherSet",
  2936. 8: "isFreq",
  2937. 0x10: "isLength",
  2938. 0x20: "alignToTow",
  2939. 0x40: "RisingEdge",
  2940. }
  2941. cfg_tp5_grid = {
  2942. 0: 'UTC',
  2943. 1: 'GPS',
  2944. 2: 'Glonass',
  2945. 3: 'BeiDou',
  2946. 4: 'Galileo',
  2947. }
  2948. def cfg_tp5(self, buf):
  2949. """UBX-CFG-TP5 decode, Time Pulse Parameters"""
  2950. m_len = len(buf)
  2951. if 1 == m_len:
  2952. return " Poll request tpIdx %d" % buf[0]
  2953. if 32 > m_len:
  2954. return " Bad Length %s" % m_len
  2955. u = struct.unpack_from('<BBHhhLLLLlL', buf, 0)
  2956. s = (" tpIdx %u version %u reserved1 %u\n"
  2957. " antCableDelay %d rfGroupDelay %d freqPeriod %u "
  2958. "freqPeriodLock %u\n"
  2959. " pulseLenRatio %u pulseLenRatioLock %u userConfigDelay %d\n"
  2960. " flags x%x" % u)
  2961. if gps.VERB_DECODE <= self.verbosity:
  2962. s += ("\n flags (%s)"
  2963. "\n gridToGps (%s) syncMode %d" %
  2964. (flag_s(u[10] & 0x7f, self.cfg_tp5_flags),
  2965. index_s((u[10] >> 7) & 0x0f, self.cfg_tp5_grid),
  2966. (u[10] >> 11) & 0x03))
  2967. return s
  2968. cfg_usb_flags = {1: "reEnum "}
  2969. cfg_usb_powerMode = {0: "self-powered",
  2970. 2: "bus-powered",
  2971. }
  2972. def cfg_usb(self, buf):
  2973. """UBX-CFG-USB decode, USB Configuration"""
  2974. u = struct.unpack_from('<HHHHHH', buf, 0)
  2975. s = (' vendorID %#x productID %#x reserved1 %u reserved2 %u\n'
  2976. ' powerConsumption %u mA flags %#x' % u)
  2977. if gps.VERB_DECODE <= self.verbosity:
  2978. s += ("\n flags (%s%s)" %
  2979. (flag_s(u[5] & 1, self.cfg_usb_flags),
  2980. index_s(u[5] & 2, self.cfg_usb_powerMode)))
  2981. s += ('\n vendorString %s\n'
  2982. ' productString %s\n'
  2983. ' serialNumber %s' %
  2984. (gps.polystr(buf[12:43]).rstrip('\0'),
  2985. gps.polystr(buf[44:75]).rstrip('\0'),
  2986. gps.polystr(buf[76:107]).rstrip('\0')))
  2987. return s
  2988. cfg_valdel_layers = {
  2989. 1: 'ram',
  2990. 2: 'bbr',
  2991. 4: 'flash',
  2992. }
  2993. cfg_valget_layers = {
  2994. 0: 'ram',
  2995. 1: 'bbr',
  2996. 2: 'flash',
  2997. 7: 'default',
  2998. }
  2999. cfg_valxxx_trans = {
  3000. 0: "Transactionless",
  3001. 1: "(Re)start Transaction",
  3002. 2: "Continue Transaction",
  3003. 3: "Apply and end Transaction",
  3004. }
  3005. def cfg_valdel(self, buf):
  3006. """"UBX-CFG-VALDEL decode, Delete configuration items"""
  3007. m_len = len(buf)
  3008. # this is a poll options, so does not set min protver
  3009. u = struct.unpack_from('<BBBB', buf, 0)
  3010. s = ' version %u layer %#x transaction %#x reserved %u\n' % u
  3011. s += (' layers (%s) transaction (%s)' %
  3012. (flag_s(u[1], self.cfg_valdel_layers),
  3013. index_s(u[2], self.cfg_valxxx_trans)))
  3014. m_len -= 4
  3015. i = 0
  3016. while 0 < m_len:
  3017. u = struct.unpack_from('<L', buf, 4 + i * 4)
  3018. item = self.cfg_by_key(u[0])
  3019. s += ('\n item: %s/%#x' % (item[0], u[0]))
  3020. m_len -= 4
  3021. i += 1
  3022. return s
  3023. def cfg_valget(self, buf):
  3024. """"UBX-CFG-VALGET decode, Get configuration items"""
  3025. m_len = len(buf)
  3026. # version zero is a poll
  3027. # version one is the response
  3028. u = struct.unpack_from('<BBH', buf, 0)
  3029. s = ' version %u layer %u position %u\n' % u
  3030. s += ' layers (%s)' % index_s(u[1], self.cfg_valget_layers)
  3031. m_len -= 4
  3032. i = 0
  3033. if 0 == u[0]:
  3034. # this is a poll option, so does not set min protver
  3035. while 0 < m_len:
  3036. u = struct.unpack_from('<L', buf, 4 + i * 4)
  3037. item = self.cfg_by_key(u[0])
  3038. s += ('\n item %s/%#x' % (item[0], u[0]))
  3039. m_len -= 4
  3040. i += 1
  3041. else:
  3042. # answer to poll
  3043. # we are at least protver 27
  3044. if 27 > self.protver:
  3045. self.protver = 27
  3046. # sort of duplicated in cfg_valset()
  3047. i += 4
  3048. while 4 < m_len:
  3049. u = struct.unpack_from('<L', buf, i)
  3050. m_len -= 4
  3051. i += 4
  3052. item = self.cfg_by_key(u[0])
  3053. cfg_type = self.item_to_type(item)
  3054. size = cfg_type[0]
  3055. if size > m_len:
  3056. s += "\nWARNING: not enough bytes!"
  3057. break
  3058. frmat = cfg_type[1]
  3059. # flavor = cfg_type[2] UNUSED
  3060. v = struct.unpack_from(frmat, buf, i)
  3061. s += ('\n item %s/%#x val %s' % (item[0], u[0], v[0]))
  3062. m_len -= size
  3063. i += size
  3064. if 0 < m_len:
  3065. s += "\nWARNING: %d extra bytes!" % m_len
  3066. return s
  3067. def cfg_valset(self, buf):
  3068. """"UBX-CFG-VALSET decode, Set configuration items"""
  3069. m_len = len(buf)
  3070. # this is a poll option, so does not set min protver
  3071. u = struct.unpack_from('<BBBB', buf, 0)
  3072. s = ' version %u layer %#x transaction %#x reserved %u\n' % u
  3073. s += (' layers (%s) transaction (%s)' %
  3074. (flag_s(u[1], self.cfg_valdel_layers),
  3075. index_s(u[2], self.cfg_valxxx_trans)))
  3076. # sort of duplicated in cfg_valget()
  3077. m_len -= 4
  3078. i = 4
  3079. while 4 < m_len:
  3080. u = struct.unpack_from('<L', buf, i)
  3081. m_len -= 4
  3082. i += 4
  3083. item = self.cfg_by_key(u[0])
  3084. cfg_type = self.item_to_type(item)
  3085. size = cfg_type[0]
  3086. # FIXME! should check for enough bytes to unpack from
  3087. frmat = cfg_type[1]
  3088. # flavor = cfg_type[2] UNUSED
  3089. v = struct.unpack_from(frmat, buf, i)
  3090. s += ('\n item %s/%#x val %s' % (item[0], u[0], v[0]))
  3091. m_len -= size
  3092. i += size
  3093. if 0 < m_len:
  3094. s += "\nWARNING: %d extra bytes!" % m_len
  3095. return s
  3096. cfg_ids = {
  3097. # in u-blox 5+
  3098. 0x00: {'str': 'PRT', 'dec': cfg_prt, 'minlen': 1,
  3099. 'name': 'UBX-CFG-PRT'},
  3100. # in u-blox 5+
  3101. 0x01: {'str': 'MSG', 'dec': cfg_msg, 'minlen': 2,
  3102. 'name': 'UBX-CFG-MSG'},
  3103. # in u-blox 5+
  3104. 0x02: {'str': 'INF', 'dec': cfg_inf, 'minlen': 1,
  3105. 'name': 'UBX-CFG-INF'},
  3106. # in u-blox 5+
  3107. 0x04: {'str': 'RST', 'dec': cfg_rst, 'minlen': 4,
  3108. 'name': 'UBX-CFG-RST'},
  3109. # in u-blox 5 to 9
  3110. 0x06: {'str': 'DAT', 'dec': cfg_dat, 'minlen': 2,
  3111. 'name': 'UBX-CFG-DAT'},
  3112. # u-blox 5, 6. Not in u-blox 7+
  3113. 0x07: {'str': 'TP', 'dec': cfg_tp, 'minlen': 28,
  3114. 'name': 'UBX-CFG-TP'},
  3115. # in u-blox 5+
  3116. 0x08: {'str': 'RATE', 'dec': cfg_rate, 'minlen': 6,
  3117. 'name': 'UBX-CFG-RATE'},
  3118. # in u-blox 5+
  3119. 0x09: {'str': 'CFG', 'dec': cfg_cfg, 'minlen': 12,
  3120. 'name': 'UBX-CFG-CFG'},
  3121. # Antaris 4, deprecated in u-blox 5/6, gone in 7
  3122. 0x0e: {'str': 'FXM', 'dec': cfg_fxn, 'minlen': 36,
  3123. 'name': 'UBX-CFG-FXM'},
  3124. # u-blox 5, 6, 7, 8
  3125. 0x11: {'str': 'RXM', 'dec': cfg_rxm, 'minlen': 2,
  3126. 'name': 'UBX-CFG-RXM'},
  3127. # in u-blox 6, SFDR only. Not in 5- or 7+
  3128. 0x12: {'str': 'EKF', 'minlen': 16, 'name': 'UBX-CFG-EKF'},
  3129. # in u-blox 5+
  3130. 0x13: {'str': 'ANT', 'dec': cfg_ant, 'minlen': 4,
  3131. 'name': 'UBX-CFG-ANT'},
  3132. # in u-blox 5+
  3133. 0x16: {'str': 'SBAS', 'dec': cfg_sbas, 'minlen': 8,
  3134. 'name': 'UBX-CFG-SBAS'},
  3135. # in u-blox 5+
  3136. 0x17: {'str': 'NMEA', 'dec': cfg_nmea, 'minlen': 4,
  3137. 'name': 'UBX-CFG-NMEA'},
  3138. # in u-blox 6+, Not in u-blox 5-
  3139. 0x1b: {'str': 'USB', 'dec': cfg_usb, 'minlen': 108,
  3140. 'name': 'UBX-CFG-USB'},
  3141. # u-blox 5 and 6. Not in u-blox 7+
  3142. 0x1d: {'str': 'TMODE', 'dec': cfg_tmode, 'minlen': 28,
  3143. 'name': 'UBX-CFG-TMODE'},
  3144. # in u-blox 8+. Not in u-blox 7-
  3145. 0x1e: {'str': 'ODO', 'dec': cfg_odo, 'minlen': 20,
  3146. 'name': 'UBX-CFG-ODO'},
  3147. # in u-blox 6, not in u-blox 7+
  3148. 0x22: {'str': 'NVS', 'dec': cfg_nvs, 'minlen': 13,
  3149. 'name': 'UBX-CFG-NVS'},
  3150. # in u-blox 5+
  3151. 0x23: {'str': 'NAVX5', 'dec': cfg_navx5, 'minlen': 20,
  3152. 'name': 'UBX-CFG-NAVX5'},
  3153. # in u-blox 6+. Not in 5-
  3154. 0x24: {'str': 'NAV5', 'dec': cfg_nav5, 'minlen': 36,
  3155. 'name': 'UBX-CFG-NAV5'},
  3156. # in u-blox 6. SFDR only. Not in u-blox 5- or 7+
  3157. 0x29: {'str': 'ESFGWT', 'minlen': 44, 'name': 'UBX-CFG-ESFGWT'},
  3158. # in u-blox 6+, Not u-blox 5-
  3159. 0x31: {'str': 'TP5', 'dec': cfg_tp5, 'minlen': 1,
  3160. 'name': 'UBX-CFG-TP5'},
  3161. # In u-blox 5, 6. Not in u-blox 7+
  3162. 0x32: {'str': 'PM', 'dec': cfg_pm, 'minlen': 24,
  3163. 'name': 'UBX-CFG-PM'},
  3164. # in u-blox 5+
  3165. 0x34: {'str': 'RINV', 'dec': cfg_rinv, 'minlen': 1,
  3166. 'name': 'UBX-CFG-RINV'},
  3167. # in u-blox 6+. Not in u-blox 5-
  3168. 0x39: {'str': 'ITFM', 'dec': cfg_itfm, 'minlen': 8,
  3169. 'name': 'UBX-CFG-ITFM'},
  3170. # in u-blox 6+. Not in u-blox 5-
  3171. 0x3b: {'str': 'PM2', 'dec': cfg_pm2, 'minlen': 44,
  3172. 'name': 'UBX-CFG-PM2'},
  3173. # in u-blox 6 and 7. Not in u-blox 5- or 8+
  3174. 0x3d: {'str': 'TMODE2', 'dec': cfg_tmode2, 'minlen': 28,
  3175. 'name': 'UBX-CFG-TMODE2'},
  3176. # in u-blox 7+ Not in u-blox 6-
  3177. 0x3e: {'str': 'GNSS', 'dec': cfg_gnss, 'minlen': 4,
  3178. 'name': 'UBX-CFG-GNSS'},
  3179. # in u-blox 7+ Not in u-blox 6-
  3180. 0x47: {'str': 'LOGFILTER', 'dec': cfg_logfilter, 'minlen': 12,
  3181. 'name': 'UBX-CFG-LOGFILTER'},
  3182. # Not in u-blox 7-, FTS only
  3183. 0x53: {'str': 'TXSLOT', 'minlen': 2, 'name': 'UBX-CFG-TXSLOT'},
  3184. # Not in u-blox 7-
  3185. 0x57: {'str': 'PWR', 'dec': cfg_pwr, 'minlen': 8,
  3186. 'name': 'UBX-CFG-PWR'},
  3187. # Not in u-blox 8-
  3188. 0x5c: {'str': 'HNR', 'dec': cfg_hnr, 'minlen': 4,
  3189. 'name': 'UBX-CFG-HNR'},
  3190. # Not in u-blox 7-
  3191. 0x60: {'str': 'ESRC', 'dec': cfg_esrc, 'minlen': 4,
  3192. 'name': 'UBX-CFG-ESRC'},
  3193. # Not in u-blox 8-
  3194. 0x61: {'str': 'DOSC', 'dec': cfg_dosc, 'minlen': 4,
  3195. 'name': 'UBX-CFG-DOSC'},
  3196. # Not in u-blox 8-
  3197. 0x62: {'str': 'SMGR', 'dec': cfg_smgr, 'minlen': 20,
  3198. 'name': 'UBX-CFG-SMGR'},
  3199. # Not in u-blox 8-
  3200. 0x69: {'str': 'GEOFENCE', 'dec': cfg_geofence, 'minlen': 8,
  3201. 'name': 'UBX-CFG-GEOFENCE'},
  3202. # Not in u-blox 8-
  3203. 0x70: {'str': 'DGNSS', 'dec': cfg_dgnss, 'minlen': 4,
  3204. 'name': 'UBX-CFG-DGNSS'},
  3205. # Not in u-blox 7-, HP only
  3206. # undocumented, but present in ZED-F9T
  3207. 0x71: {'str': 'TMODE3', 'dec': cfg_tmode3, 'minlen': 40,
  3208. 'name': 'UBX-CFG-TMODE3'},
  3209. # Not in u-blox 7-
  3210. 0x84: {'str': 'FIXSEED', 'dec': cfg_fixseed, 'minlen': 12,
  3211. 'name': 'UBX-CFG-FIXSEED'},
  3212. # Not in u-blox 7-
  3213. 0x85: {'str': 'DYNSEED', 'dec': cfg_dynseed, 'minlen': 12,
  3214. 'name': 'UBX-CFG-DYNSEED'},
  3215. # Not in u-blox 8-
  3216. 0x86: {'str': 'PMS', 'dec': cfg_pms, 'minlen': 8,
  3217. 'name': 'UBX-CFG-PMS'},
  3218. # in u-blox 9
  3219. 0x8a: {'str': 'VALSET', 'dec': cfg_valset, 'minlen': 4,
  3220. 'name': 'UBX-CFG-VALSET'},
  3221. # in u-blox 9
  3222. 0x8b: {'str': 'VALGET', 'dec': cfg_valget, 'minlen': 4,
  3223. 'name': 'UBX-CFG-VALGET'},
  3224. # in u-blox 9
  3225. 0x8c: {'str': 'VALDEL', 'dec': cfg_valdel, 'minlen': 4,
  3226. 'name': 'UBX-CFG-VALDEL'},
  3227. # u-blox 8
  3228. 0x8d: {'str': 'SLAS', 'dec': cfg_slas, 'minlen': 4,
  3229. 'name': 'UBX-CFG-SLAS'},
  3230. # only in u-blox 8
  3231. 0x93: {'str': 'BATCH', 'dec': cfg_batch, 'minlen': 8,
  3232. 'name': 'UBX-CFG-BATCH'},
  3233. }
  3234. # UBX-ESF-
  3235. # only with ADR or UDR products
  3236. esf_ids = {0x02: {'str': 'MEAS', 'minlen': 8, 'name': "UBX-ESF-MEAS"},
  3237. 0x03: {'str': 'RAW', 'minlen': 4, 'name': "UBX-ESF-RAW"},
  3238. 0x10: {'str': 'STATUS', 'minlen': 16, 'name': "UBX-ESF-STATUS"},
  3239. 0x15: {'str': 'INS', 'minlen': 16, 'name': "UBX-ESF-INS"},
  3240. }
  3241. # UBX-HNR-
  3242. # only with ADR or UDR products
  3243. hnr_ids = {0x00: {'str': 'PVT', 'minlen': 72, 'name': "UBX-HNR-PVT"},
  3244. 0x02: {'str': 'INS', 'minlen': 36, 'name': "UBX-HNR-INS"},
  3245. }
  3246. def inf_debug(self, buf):
  3247. """UBX-INF-DEBUG decode"""
  3248. return ' Debug: ' + gps.polystr(buf)
  3249. def inf_error(self, buf):
  3250. """UBX-INF-ERROR decode"""
  3251. return ' Error: ' + gps.polystr(buf)
  3252. def inf_notice(self, buf):
  3253. """UBX-INF-NOTICE decode"""
  3254. return ' Notice: ' + gps.polystr(buf)
  3255. def inf_test(self, buf):
  3256. """UBX-INF-TET decode"""
  3257. return ' Test: ' + gps.polystr(buf)
  3258. def inf_warning(self, buf):
  3259. """UBX-INF-WARNING decode"""
  3260. return ' Warning: ' + gps.polystr(buf)
  3261. inf_ids = {0x0: {'str': 'ERROR', 'dec': inf_error, 'minlen': 0,
  3262. 'name': 'UBX-INF-ERROR'},
  3263. 0x1: {'str': 'WARNING', 'dec': inf_warning, 'minlen': 0,
  3264. 'name': 'UBX-INF-WARNING'},
  3265. 0x2: {'str': 'NOTICE', 'dec': inf_notice, 'minlen': 0,
  3266. 'name': 'UBX-INF-NOTICE'},
  3267. 0x3: {'str': 'TEST', 'dec': inf_test, 'minlen': 0,
  3268. 'name': 'UBX-INF-TEST'},
  3269. 0x4: {'str': 'DEBUG', 'dec': inf_debug, 'minlen': 0,
  3270. 'name': 'UBX-INF-DEBUG'},
  3271. }
  3272. log_batch_contentValid = {
  3273. 1: 'extraPvt',
  3274. 2: 'extraOdo',
  3275. }
  3276. log_batch_valid = {
  3277. 1: 'validDate',
  3278. 2: 'validTime',
  3279. }
  3280. log_batch_fixType = {
  3281. 0: 'No Fix',
  3282. 2: '2D Fix',
  3283. 3: '3D Fix',
  3284. 4: 'GNSS + DR', # only UBX-LOG-RETRIEVEPOS
  3285. }
  3286. log_batch_flags = {
  3287. 1: 'gnssFixOK',
  3288. 2: 'diffSoln',
  3289. }
  3290. log_batch_psmState = {
  3291. 0: 'Not Active',
  3292. 4: 'Enabled',
  3293. 8: 'Acquisition',
  3294. 9: 'Tracking',
  3295. 0x10: 'Power Optimized Tracking',
  3296. 0x11: 'Inactive',
  3297. }
  3298. def log_batch(self, buf):
  3299. """UBX-LOG-BATCH decode
  3300. Oddly this is polled with UBX-LOG-RETRIEVEBATCH
  3301. """
  3302. # u-blox 8, protVer 23+
  3303. # in NEO-M9N, protVer 32.00
  3304. u = struct.unpack_from('<BBHLHBBBBBBLlBBBBllllLLlllllLLHHLLLL', buf, 0)
  3305. s = (" version %u contentValid x%x msgCnt %u iTow %u\n"
  3306. " year %u month %u day %u hour %u min %u sec %u valid x%x\n"
  3307. " tAcc %u fracSec %d fixType %u flags x%x flags2 x%x numSV %u\n"
  3308. " lon %d lat %d height %d hMSL %d\n"
  3309. " hAcc %u vAcc %u\n"
  3310. " vel N %u E %u D %u gSpeed %d headMot %d sAcc %u headAcc %u\n"
  3311. " pdep %u reserved1 x%x distance %u totalDistance %u\n"
  3312. " distanceStd %u reserved2 x%x" % u)
  3313. if gps.VERB_DECODE <= self.verbosity:
  3314. # flags2 undocumented
  3315. s += ("\n contentValid (%s) valid (%s)"
  3316. "\n fixType (%s)"
  3317. "\n flags (%s) psmState (%s)" %
  3318. (flag_s(u[1], self.log_batch_contentValid),
  3319. flag_s(u[10], self.log_batch_valid),
  3320. index_s(u[13], self.log_batch_fixType),
  3321. flag_s(u[14] & 3, self.log_batch_flags),
  3322. index_s(u[14] & 0x1c, self.log_batch_psmState)))
  3323. return s
  3324. log_create_logCfg = {
  3325. 1: 'circular',
  3326. }
  3327. log_create_logSize = {
  3328. 0: 'Maximum safe',
  3329. 1: 'Minimum safe',
  3330. 2: 'user defined',
  3331. }
  3332. def log_create(self, buf):
  3333. """UBX-LOG-CREATE decode"""
  3334. # u-blox 7+, protVer 14+
  3335. u = struct.unpack_from('<BBBBL', buf, 0)
  3336. s = (" version %u logCfg x%x reserved1 x%x logSize %u\n"
  3337. " userDefinedSize %u" % u)
  3338. if gps.VERB_DECODE <= self.verbosity:
  3339. s += ("\n logCfg (%s) logSize (%s)" %
  3340. (flag_s(u[1], self.log_create_logCfg),
  3341. index_s(u[3], self.log_create_logSize)))
  3342. return s
  3343. def log_erase(self, buf):
  3344. """UBX-LOG-ERASE decode"""
  3345. # u-blox 7+, protVer 14+
  3346. return " Erase Logged Data"
  3347. log_findtime_type = {
  3348. 0: 'request',
  3349. 1: 'response',
  3350. }
  3351. def log_findtime(self, buf):
  3352. """UBX-LOG-FINDTIME decode"""
  3353. # u-blox 7+, protVer 14+
  3354. m_len = len(buf)
  3355. # length 8 (version 1, type 1) is response.
  3356. # WTF; length 10 (version 0, type 0) is request
  3357. # length 12 (version 0, type 0) is request
  3358. if 8 == m_len:
  3359. # response
  3360. u = struct.unpack_from('<BBHL', buf, 0)
  3361. s = " version %u type %u reserved1 x%x entryNumber %u" % u
  3362. if 1 != u[0] or 1 != u[1]:
  3363. s += "\nWARNING: Unknown version, type (%u, %u)" % (u[0], u[1])
  3364. elif 10 == m_len:
  3365. # request
  3366. u = struct.unpack_from('<BBHBBBBBB', buf, 0)
  3367. s = (" version %u type %u\n"
  3368. " year %u month %u day %u hour %u min %u sec %u "
  3369. "reserved2 x%x" % u)
  3370. if 0 != u[0] or 0 != u[1]:
  3371. s += "\nWARNING: Unknown version, type (%u, %u)" % (u[0], u[1])
  3372. elif 12 == m_len:
  3373. # request
  3374. u = struct.unpack_from('<BBHHBBBBBB', buf, 0)
  3375. s = (" version %u type %u reserved1 x%x\n"
  3376. " year %u month %u day %u hour %u min %u sec %u "
  3377. "reserved2 x%x" % u)
  3378. if 0 != u[0] or 0 != u[1]:
  3379. s += "\nWARNING: Unknown version, type (%u, %u)" % (u[0], u[1])
  3380. else:
  3381. return " Bad Length %s" % m_len
  3382. if gps.VERB_DECODE <= self.verbosity:
  3383. s += ("\n type (%s)" %
  3384. (index_s(u[1], self.log_findtime_type)))
  3385. return s
  3386. log_info_status = {
  3387. 8: 'recording',
  3388. 0x10: 'inactive',
  3389. 0x20: 'circular',
  3390. }
  3391. def log_info(self, buf):
  3392. """UBX-LOG-INFO decode"""
  3393. # u-blox 7+, protVer 14+
  3394. u = struct.unpack_from('<BBHLLLLLLHBBBBBBHBBBBBBBBH', buf, 0)
  3395. s = (" version %u reserved1 x%x x%x filestoreCapacity %u "
  3396. "reserved2 x%x x%x\n"
  3397. " currentMaxLogSize %u currentLogSize %u entryCount %u\n"
  3398. " oldestYear %u oldestMonth %u oldestDay %u \n"
  3399. " oldestHour %u oldestMin %u oldestSec %u reserved3 x%x\n"
  3400. " newestYear %u newestMonth %u newestDay %u \n"
  3401. " newestHour %u newestMin %u newestSec %u reserved4 x%x\n"
  3402. " status x%x reserved5 x%x x%x" % u)
  3403. if gps.VERB_DECODE <= self.verbosity:
  3404. s += ("\n status (%s)" %
  3405. (flag_s(u[23], self.log_info_status)))
  3406. return s
  3407. log_retrievebatch_flags = {
  3408. 1: 'sendMonFirst',
  3409. }
  3410. def log_retrieve(self, buf):
  3411. """UBX-LOG-RETRIEVE decode"""
  3412. # u-blox 7+, protVer 14+
  3413. u = struct.unpack_from('<LLBBH', buf, 0)
  3414. s = " startNumber %u entryCount %u version %u reserved1 x%x %x" % u
  3415. return s
  3416. def log_retrievebatch(self, buf):
  3417. """UBX-LOG-RETRIEVEBATCH decode
  3418. Oddly this is the poll for UBX-LOG-BATCH
  3419. """
  3420. # u-blox 8, protVer 23.01 to 23.99
  3421. # not in u-blox 7 or 9
  3422. u = struct.unpack_from('<BBH', buf, 0)
  3423. s = (" version %u flags x%x reserved1 x%x" % u)
  3424. if gps.VERB_DECODE <= self.verbosity:
  3425. # flags2 undocumented
  3426. s += ("\n flags (%s)" %
  3427. flag_s(u[1], self.log_retrievebatch_flags))
  3428. return s
  3429. def log_retrievepos(self, buf):
  3430. """UBX-LOG-RETRIEVEPOS decode"""
  3431. # u-blox 7+, protVer 14+
  3432. u = struct.unpack_from('<LlllLLLBBHBBBBBBBB', buf, 0)
  3433. s = (" entryIndex %u lon %d lat %d hMSL %d hAcc %u\n"
  3434. " gSpeed %u heading %u version %u fixType %u\n"
  3435. " year %u month %u day %u hour %u min %u sec %u\n"
  3436. " reserved1 x%x numSV %u reserved2 x%x" % u)
  3437. if gps.VERB_DECODE <= self.verbosity:
  3438. s += ("\n fixType (%s)" %
  3439. (index_s(u[8], self.log_batch_fixType)))
  3440. return s
  3441. def log_retrieveposextra(self, buf):
  3442. """UBX-LOG-RETRIEVEPOSEXTRA decode"""
  3443. # u-blox 8+, protVer 15+
  3444. u = struct.unpack_from('<LBBHBBBBBBHLLLL', buf, 0)
  3445. s = (" entryIndex %u version %u reserved1 x%x\n"
  3446. " year %u month %u day %u hour %u minute %u seconds %u\n"
  3447. " reserved2 x%x %x distance %u reserved3 x%x %x %x" % u)
  3448. return s
  3449. def log_retrievestring(self, buf):
  3450. """UBX-LOG-RETRIEVESTRING decode"""
  3451. # u-blox 7+, protVer 14+
  3452. u = struct.unpack_from('<LBBHBBBBBBH', buf, 0)
  3453. s = (" entryIndex %u version %u reserved2 x%x\n"
  3454. " year %u month %u day %u hour %u min %u sec %u\n"
  3455. " reserved2 x%x byteCount %u\n"
  3456. " bytes \"" % u)
  3457. if 0 < u[10]:
  3458. for c in buf[16:16 + u[10]]:
  3459. if c < 127 and chr(c) in string.printable:
  3460. s += chr(c)
  3461. else:
  3462. s += "\\x%02x" % c
  3463. s += '"'
  3464. return s
  3465. def log_string(self, buf):
  3466. """UBX-LOG-STRING decode"""
  3467. # u-blox 7+, protVer 14+
  3468. m_len = len(buf)
  3469. if 256 < m_len:
  3470. return " Bad Length %s" % m_len
  3471. s = " bytes "
  3472. if 0 < m_len:
  3473. s += gps.polystr(binascii.hexlify(buf))
  3474. return s
  3475. # UBX-LOG-
  3476. log_ids = {
  3477. 0x03: {'str': 'ERASE', 'dec': log_erase, 'minlen': 0,
  3478. 'name': "UBX-LOG-ERASE"},
  3479. 0x04: {'str': 'STRING', 'dec': log_string, 'minlen': 0,
  3480. 'name': "UBX-LOG-STRING"},
  3481. 0x07: {'str': 'CREATE', 'dec': log_create, 'minlen': 8,
  3482. 'name': "UBX-LOG-CREATE"},
  3483. 0x08: {'str': 'INFO', 'dec': log_info, 'minlen': 48,
  3484. 'name': "UBX-LOG-INFO"},
  3485. 0x09: {'str': 'RETRIEVE', 'dec': log_retrieve, 'minlen': 12,
  3486. 'name': "UBX-LOG-RETRIEVE"},
  3487. 0x0b: {'str': 'RETRIEVEPOS', 'dec': log_retrievepos,
  3488. 'minlen': 40,
  3489. 'name': "UBX-LOG-RETRIEVEPOS"},
  3490. 0x0d: {'str': 'RETRIEVESTRING', 'dec': log_retrievestring,
  3491. 'minlen': 16,
  3492. 'name': "UBX-LOG-RETRIEVESTRING"},
  3493. 0x0e: {'str': 'FINDTIME', 'dec': log_findtime, 'minlen': 8,
  3494. 'name': "UBX-LOG-FINDTIME"},
  3495. 0x0f: {'str': 'RETRIEVEPOSEXTRA', 'dec': log_retrieveposextra,
  3496. 'minlen': 32,
  3497. 'name': "UBX-LOG-RETRIEVEPOSEXTRA"},
  3498. 0x10: {'str': 'RETRIEVEBATCH', 'dec': log_retrievebatch,
  3499. 'minlen': 2,
  3500. 'name': "UBX-LOG-RETRIEVEBATCH"},
  3501. 0x11: {'str': 'BATCH', 'dec': log_batch, 'minlen': 100,
  3502. 'name': "UBX-LOG-BATCH"},
  3503. }
  3504. # UBX-MGA-
  3505. def mga_dbd(self, buf):
  3506. """UBX-MGA-DBD- decode, Navigation Database Dump Entry"""
  3507. # max 172
  3508. u = struct.unpack_from('<LLL', buf, 0)
  3509. s = ' reserved1 %u %u %u' % u
  3510. # plus some anonymous data...
  3511. return s
  3512. mga_ids = {0x00: {'str': 'GPS', 'minlen': 16, 'name': "UBX-MGA-GPS"},
  3513. 0x02: {'str': 'GAL', 'minlen': 12, 'name': "UBX-MGA-GAL"},
  3514. 0x03: {'str': 'BDS', 'minlen': 16, 'name': "UBX-MGA-BDS"},
  3515. 0x05: {'str': 'QZSS', 'minlen': 12, 'name': "UBX-MGA-QZSS"},
  3516. 0x06: {'str': 'GLO', 'minlen': 20, 'name': "UBX-MGA-GLO"},
  3517. 0x20: {'str': 'ANO', 'minlen': 76, 'name': "UBX-MGA-ANO"},
  3518. 0x21: {'str': 'FLASH', 'minlen': 2, 'name': "UBX-MGA-FLASH"},
  3519. 0x40: {'str': 'INI', 'minlen': 12, 'name': "UBX-MGA-INI"},
  3520. 0x60: {'str': 'ACK', 'minlen': 8, 'name': "UBX-MGA-ACK"},
  3521. 0x80: {'str': 'DBD', 'dec': mga_dbd, 'minlen': 12,
  3522. 'name': "UBX-MGA-DBD"},
  3523. }
  3524. def mon_batch(self, buf):
  3525. """UBX-MON-BATCH decode, Data batching buffer status"""
  3526. # in u-blox 8 only, not in 7 or 9.
  3527. # protVer 23.01, gone in 24
  3528. u = struct.unpack_from('<BBBBHHHH', buf, 0)
  3529. s = (" version %u reserved1 %u %u %u fillLevel %u\n"
  3530. " dropsAll %u dropsSinceMon %u nextMsgCnt %u" % u)
  3531. return s
  3532. mon_comms_prot = {
  3533. 0: "UBX",
  3534. 1: "NMEA",
  3535. 2: "RTCM2",
  3536. 5: "RTCM3",
  3537. 255: "None",
  3538. }
  3539. def mon_comms(self, buf):
  3540. """UBX-MON-COMMS decode, Comm port information"""
  3541. # at least protver 27
  3542. if 27 > self.protver:
  3543. self.protver = 27
  3544. u = struct.unpack_from('<BBBBBBBB', buf, 0)
  3545. s = ('version %u nPorts %u txErrors x%x reserved1 %u\n'
  3546. 'protIds %#x/%x/%x/%x' % u)
  3547. s += (' (%s/%s/%s/%s)\n' %
  3548. (index_s(u[4], self.mon_comms_prot),
  3549. index_s(u[5], self.mon_comms_prot),
  3550. index_s(u[6], self.mon_comms_prot),
  3551. index_s(u[7], self.mon_comms_prot)))
  3552. if gps.VERB_DECODE <= self.verbosity:
  3553. errors = {
  3554. 0x40: "mem",
  3555. 0x80: "alloc",
  3556. }
  3557. s += " txErrors (%s)\n" % (flag_s(u[2], errors))
  3558. for i in range(0, u[1]):
  3559. u = struct.unpack_from('<HHLBBHLBBHHHHHLLL', buf, (8 + (i * 40)))
  3560. name = "%#x (%s)" % (u[0], index_s(u[0], self.port_ids1))
  3561. if 0 < i:
  3562. s += "\n"
  3563. s += ' Port: %s\n' % name
  3564. s += (' txPending %u txBytes %u txUsage %u txPeakUsage %u\n'
  3565. ' rxPending %u rxBytes %u rxUsage %u rxPeakUsage %u\n'
  3566. ' overrunErrs %u msgs %u/%u/%u/%u reserved %x %x '
  3567. 'skipped %u'
  3568. % u[1:])
  3569. return s
  3570. mon_gnss_supported_bits = {
  3571. 1: "GPS",
  3572. 2: "Glonass",
  3573. 4: "Beidou",
  3574. 8: "Galileo",
  3575. }
  3576. def mon_gnss(self, buf):
  3577. """UBX-MON-GNSS decode, Information message major GNSS selection"""
  3578. m_len = len(buf)
  3579. if 8 > m_len:
  3580. return " Bad Length %s" % m_len
  3581. u = struct.unpack_from('<BBBBBBBB', buf, 0)
  3582. s = (' version %u supported %#x defaultGnss %#x enabled %#x\n'
  3583. ' simultaneous %u reserved1 %u %u %u' % u)
  3584. if gps.VERB_DECODE <= self.verbosity:
  3585. s += ('\n supported (%s)'
  3586. '\n defaultGnss (%s)'
  3587. '\n enabled (%s)' %
  3588. (flag_s(u[1], self.mon_gnss_supported_bits),
  3589. flag_s(u[2], self.mon_gnss_supported_bits),
  3590. flag_s(u[3], self.mon_gnss_supported_bits)))
  3591. return s
  3592. mon_hw_flags = {
  3593. 1: "rtcCalib",
  3594. 2: "safeBoot",
  3595. }
  3596. mon_hw_aPower = {
  3597. 0: "Off",
  3598. 1: "On",
  3599. }
  3600. jammingState = {
  3601. 0: "Unk",
  3602. 1: "OK",
  3603. 2: "Warning",
  3604. 3: "Critical",
  3605. }
  3606. def mon_hw(self, buf):
  3607. """UBX-MON-HW decode, Hardware Status"""
  3608. u = struct.unpack_from('<LLLLHHBBBBLBBBBBBBBBBBBBBBBBBBBLLL', buf, 0)
  3609. s = (' pinSel %#x pinBank %#x pinDir %#x pinVal %#x noisePerMS %u\n'
  3610. ' agcCnt %u aStatus %u aPower %u flags %#x reserved1 %u\n'
  3611. ' usedMask %#x\n'
  3612. ' VP %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u\n'
  3613. ' jamInd %u reserved2 %u %u pinIrq %#x pullH %#x pullL %#x' % u)
  3614. if gps.VERB_DECODE <= self.verbosity:
  3615. s += ("\n aStatus (%s) aPower (%s) flags (%s) "
  3616. "jammingState (%s)" %
  3617. (index_s(u[6], self.mon_rf_antstat),
  3618. index_s(u[7], self.mon_hw_aPower),
  3619. index_s(u[8], self.mon_hw_flags),
  3620. index_s((u[6] >> 2) & 0x03, self.jammingState)))
  3621. return s
  3622. mon_hw2_cfgSource = {
  3623. 102: "flash image",
  3624. 111: "OTP",
  3625. 112: "config pins",
  3626. 114: "ROM",
  3627. }
  3628. def mon_hw2(self, buf):
  3629. """UBX-MON-HW2 decode, Extended Hardware Status"""
  3630. u = struct.unpack_from('<bBbBBBBBLLLLL', buf, 0)
  3631. s = (' ofsI %d magI %u ofsQ %d magQ %u cfgSource %u\n'
  3632. ' reserved0 %u %u %u lowLevCfg %d reserved1 %u %u\n'
  3633. ' postStatus %u reserved2 %u' % u)
  3634. if gps.VERB_DECODE <= self.verbosity:
  3635. s += ('\n cfgSource (%s)' %
  3636. (index_s(u[4], self.mon_hw2_cfgSource)))
  3637. return s
  3638. mon_hw3_flags = {
  3639. 1: "rtcCalib",
  3640. 2: "safeBoot",
  3641. 4: "xtgalAbsent",
  3642. }
  3643. mon_hw3_pio = {
  3644. 0: "peripheral",
  3645. 1: "PIO",
  3646. }
  3647. mon_hw3_bank = {
  3648. 0: "A",
  3649. 1: "B",
  3650. 2: "C",
  3651. 3: "D",
  3652. 4: "E",
  3653. 5: "F",
  3654. 6: "G",
  3655. 7: "H",
  3656. }
  3657. mon_hw3_dir = {
  3658. 0: "In",
  3659. 1: "Out",
  3660. }
  3661. mon_hw3_value = {
  3662. 0: "Lo",
  3663. 1: "Hi",
  3664. }
  3665. mon_hw3_mask = {
  3666. 0x20: "VPM",
  3667. 0x40: "IRQ",
  3668. 0x100: "PUp",
  3669. 0x200: "PDn",
  3670. }
  3671. def mon_hw3(self, buf):
  3672. """UBX-MON-HW3 decode, HW I/O pin information"""
  3673. # at least protver 27
  3674. if 27 > self.protver:
  3675. self.protver = 27
  3676. u = struct.unpack_from('<BBB', buf, 0)
  3677. s = ' version %u nPins %u flags x%x' % u
  3678. nPins = u[1]
  3679. substr = buf[3:12]
  3680. substr = substr.split(gps.polybytes('\0'))[0]
  3681. s += ' hwVersion %s\n' % gps.polystr(substr)
  3682. u1 = struct.unpack_from('<BBBBBBBBB', buf, 13)
  3683. s += ' reserved1 %02x %02x %02x %02x %02x %02x %02x %02x %02x' % u1
  3684. if gps.VERB_DECODE <= self.verbosity:
  3685. s += ('\n flags (%s)' %
  3686. (index_s(u[2], self.mon_hw3_flags)))
  3687. for i in range(22, 22 + (nPins * 6), 6):
  3688. u = struct.unpack_from('<HHBB', buf, i)
  3689. s += ('\n pinId %4u pinMask %#5x VP %3u reserved2 %u' % u)
  3690. if gps.VERB_DECODE <= self.verbosity:
  3691. s += ('\n pinMask (%s %s %s %s %s)' %
  3692. (index_s(u[1] & 1, self.mon_hw3_pio),
  3693. index_s((u[1] >> 1) & 7, self.mon_hw3_bank),
  3694. index_s((u[1] >> 4) & 1, self.mon_hw3_dir),
  3695. index_s((u[1] >> 5) & 1, self.mon_hw3_value),
  3696. flag_s(u[1] & 0xffc0, self.mon_hw3_mask)))
  3697. return s
  3698. def mon_io(self, buf):
  3699. """UBX-MON-IO decode, I/O Subsystem Status"""
  3700. m_len = len(buf)
  3701. s = ''
  3702. for i in range(0, int(m_len / 20)):
  3703. if 0 < i:
  3704. s += "\n"
  3705. u = struct.unpack_from('<LLHHHHL', buf, i * 20)
  3706. s += (' Port: %u (%s)\n' % (i, index_s(i, self.port_ids)))
  3707. s += (' rxBytes %u txBytes %u parityErrs %u framingErrs %u\n'
  3708. ' overrunErrs %u breakCond %u reserved %u' % u)
  3709. return s
  3710. def mon_msgpp(self, buf):
  3711. """UBX-MON-MSGPP decode, Message Parse and Process Status"""
  3712. s = ''
  3713. for i in range(1, 7):
  3714. u = struct.unpack_from('<HHHHHHHH', buf, 0)
  3715. s += " msg%u %u %u %u %u %u %u %u %u\n" % ((i,) + u)
  3716. u = struct.unpack_from('<LLLLLL', buf, 0)
  3717. s += " skipped %u %u %u %u %u %u" % u
  3718. return s
  3719. mon_patch_act = {
  3720. 1: "Active"
  3721. }
  3722. mon_patch_loc = {
  3723. 0: "eFuse",
  3724. 2: "ROM",
  3725. 4: "BBR",
  3726. 6: "File System",
  3727. }
  3728. def mon_patch(self, buf):
  3729. """UBX-MON-PATCH decode, Output information about installed patches."""
  3730. # first seen in protver 15
  3731. # len 0 == Poll requestm handled earlier
  3732. u = struct.unpack_from('<HH', buf, 0)
  3733. s = " version %u nEntries %u" % u
  3734. for i in range(0, u[1]):
  3735. u = struct.unpack_from('<LLLL', buf, 4 + (i * 16))
  3736. s += ("\n patchInfo x%x comparatorNumber %u patchAddress %u "
  3737. "patchData %u" % u)
  3738. if gps.VERB_DECODE <= self.verbosity:
  3739. s += ('\n patchInfo (%s, %s)' %
  3740. (flag_s(u[0] & 0x01, self.mon_patch_act),
  3741. index_s(u[0] & 0x06, self.mon_patch_loc)))
  3742. return s
  3743. mon_rf_antstat = {
  3744. 0: "Init",
  3745. 1: "Unk",
  3746. 2: "OK",
  3747. 3: "Short",
  3748. 4: "Open",
  3749. }
  3750. mon_rf_antpwr = {
  3751. 0: "Off",
  3752. 1: "On",
  3753. 2: "Unk",
  3754. }
  3755. def mon_rf(self, buf):
  3756. """UBX-MON-RF decode, RF Information"""
  3757. # first seen in protver 27
  3758. # at least protver 27
  3759. if 27 > self.protver:
  3760. self.protver = 27
  3761. u = struct.unpack_from('<BBBB', buf, 0)
  3762. s = ' version %u nBlocks %u reserved1 %u %u' % u
  3763. for i in range(0, u[1]):
  3764. u = struct.unpack_from('<BBBBLBBBBHHBbBbBBBB', buf, 4 + (24 * i))
  3765. s += ("\n blockId %u flags x%x antStatus %u antPower %u "
  3766. "postStatus %u reserved2 %u %u %u %u"
  3767. "\n noisePerMS %u agcCnt %u jamInd %u ofsI %d magI %u "
  3768. "ofsQ %d magQ %u"
  3769. "\n reserved3 %u %u %u" % u)
  3770. if gps.VERB_DECODE <= self.verbosity:
  3771. s += ('\n jammingState (%s) antStatus (%s) antPower (%s)' %
  3772. (index_s(u[1] & 0x03, self.jammingState),
  3773. index_s(u[2], self.mon_rf_antstat),
  3774. index_s(u[3], self.mon_rf_antpwr)))
  3775. return s
  3776. def mon_rxbuf(self, buf):
  3777. """UBX-MON-RXBUF decode, Receiver Buffer Status"""
  3778. rxbuf_name = {
  3779. 1: " pending ",
  3780. 2: " usage ",
  3781. 3: " peakUsage ",
  3782. }
  3783. s = ''
  3784. u = struct.unpack_from('<HHHHHH', buf, 0)
  3785. s += rxbuf_name[1] + "%u %u %u %u %u %u\n" % u
  3786. for i in range(2, 4):
  3787. u = struct.unpack_from('<BBBBBB', buf, 6 * i)
  3788. s += rxbuf_name[i] + "%u %u %u %u %u %u\n" % u
  3789. return s
  3790. mon_rxr_flags = {
  3791. 1: "Awake",
  3792. }
  3793. def mon_rxr(self, buf):
  3794. """UBX-MON-RXBUF decode, Receiver Status Information"""
  3795. # No way to poll
  3796. u = struct.unpack_from('<B', buf, 0)
  3797. s = " flags: x%x" % u
  3798. if gps.VERB_DECODE <= self.verbosity:
  3799. s += ("\n flags (%s)" %
  3800. index_s(u[0], self.mon_rxr_flags))
  3801. return s
  3802. mon_smgr_OscState = {
  3803. 0: "autonomous operation",
  3804. 1: "calibration ongoing",
  3805. 2: "oscillator steered by host",
  3806. 3: "idle state",
  3807. }
  3808. mon_smgr_Osc = {
  3809. 0x10: "OscCalib",
  3810. 0x20: "OscDisc",
  3811. }
  3812. mon_smgr_discSrc = {
  3813. 0: "internal oscillator",
  3814. 1: "GNSS",
  3815. 2: "EXTINT0",
  3816. 3: "EXTINT1",
  3817. 4: "internal oscillator measured by host",
  3818. 5: "external oscillator measured by host",
  3819. }
  3820. def mon_smgr(self, buf):
  3821. """UBX-MON-SMGR decode, Synchronization manager status"""
  3822. u = struct.unpack_from('<BBBBLHHBBBB', buf, 0)
  3823. s = (" version %u reserved1 %u %u %u iTOW %u intOsc x%x extOsc x%x\n"
  3824. " discOsc %u gnss x%x extInt0 x%x extInt1 x%x" % u)
  3825. if gps.VERB_DECODE <= self.verbosity:
  3826. s += ("\n intOsc (%s) intOscState (%s)"
  3827. "\n extOsc(%s) extoscState (%s)"
  3828. "\n flags (%s)" %
  3829. (flag_s(u[3], self.mon_smgr_Osc),
  3830. index_s(u[3] & 0x0f, self.mon_smgr_OscState),
  3831. flag_s(u[4], self.mon_smgr_Osc),
  3832. index_s(u[4] & 0x0f, self.mon_smgr_OscState),
  3833. index_s(u[5], self.mon_smgr_discSrc)))
  3834. return s
  3835. def mon_txbuf(self, buf):
  3836. """UBX-MON-TXBUF decode, Transmitter Buffer Status"""
  3837. txbuf_name = {
  3838. 1: " pending ",
  3839. 2: " usage ",
  3840. 3: " peakUsage ",
  3841. }
  3842. errors = {
  3843. 0x40: "mem",
  3844. 0x80: "alloc",
  3845. }
  3846. s = ''
  3847. u = struct.unpack_from('<HHHHHH', buf, 0)
  3848. s += txbuf_name[1] + "%u %u %u %u %u %u\n" % u
  3849. for i in range(2, 4):
  3850. u = struct.unpack_from('<BBBBBB', buf, 6 * i)
  3851. s += txbuf_name[i] + "%u %u %u %u %u %u\n" % u
  3852. u = struct.unpack_from('<BBBB', buf, 24)
  3853. s += " tUsage %u tPeakUsage %u errors x%x reserved1 %u" % u
  3854. if gps.VERB_DECODE <= self.verbosity:
  3855. s += ("\n errors (%s) limit (%u)" %
  3856. (flag_s(u[2], errors), u[2] & 0x3f))
  3857. return s
  3858. def mon_ver(self, buf):
  3859. """UBX-MON-VER decode, Poll Receiver/Software Version"""
  3860. # min len = 40 in u-blox 5/6
  3861. # min len = 70 in u-blox 9
  3862. m_len = len(buf)
  3863. substr = buf.split(gps.polybytes('\0'))[0]
  3864. substr1 = buf[30:39]
  3865. substr1 = substr1.split(gps.polybytes('\0'))[0]
  3866. s = (" swVersion %s\n"
  3867. " hwVersion %s" %
  3868. (gps.polystr(substr), gps.polystr(substr1)))
  3869. # extensions??
  3870. protver = None
  3871. num_ext = int((m_len - 40) / 30)
  3872. for i in range(0, num_ext):
  3873. loc = 40 + (i * 30)
  3874. substr = buf[loc:]
  3875. substr = substr.split(gps.polybytes('\0'))[0]
  3876. polystr = gps.polystr(substr)
  3877. s += '\n extension %s' % polystr
  3878. # is protver? delimiter may be space or equal
  3879. if "PROTVER" == polystr[:7]:
  3880. protver = "%.2f" % float(polystr[8:])
  3881. opts_protver = "%.2f" % self.protver
  3882. if protver and protver != opts_protver:
  3883. s += ('\nWARNING: protVer is %s, should be %s.'
  3884. ' Hint: use option "-P %s"' %
  3885. (opts_protver, protver, protver))
  3886. # prolly too late to fix, try anyway.
  3887. self.protver = float(protver)
  3888. return s
  3889. mon_ids = {0x02: {'str': 'IO', 'dec': mon_io, 'minlen': 20,
  3890. 'name': 'UBX-MON-IO'},
  3891. 0x04: {'str': 'VER', 'dec': mon_ver, 'minlen': 40,
  3892. 'name': 'UBX-MON-VER'},
  3893. 0x06: {'str': 'MSGPP', 'dec': mon_msgpp, 'minlen': 120,
  3894. 'name': 'UBX-MON-MSGPP'},
  3895. 0x07: {'str': 'RXBUF', 'dec': mon_rxbuf, 'minlen': 24,
  3896. 'name': 'UBX-MON-RXBUF'},
  3897. 0x08: {'str': 'TXBUF', 'dec': mon_txbuf, 'minlen': 28,
  3898. 'name': 'UBX-MON-TXBUF'},
  3899. 0x09: {'str': 'HW', 'dec': mon_hw, 'minlen': 60,
  3900. 'name': 'UBX-MON-HW'},
  3901. 0x0b: {'str': 'HW2', 'dec': mon_hw2, 'minlen': 28,
  3902. 'name': 'UBX-MON-HW2'},
  3903. 0x21: {'str': 'RXR', 'dec': mon_rxr, 'minlen': 1,
  3904. 'name': 'UBX-MON-RXR'},
  3905. 0x27: {'str': 'PATCH', 'dec': mon_patch, 'minlen': 4,
  3906. 'name': 'UBX-MON-PATCH'},
  3907. 0x28: {'str': 'GNSS', 'dec': mon_gnss, 'minlen': 8,
  3908. 'name': 'UBX-MON-GNSS'},
  3909. 0x2e: {'str': 'SMGR', 'dec': mon_smgr, 'minlen': 16,
  3910. 'name': 'UBX-MON-SMGR'},
  3911. 0x32: {'str': 'BATCH', 'dec': mon_batch, 'minlen': 12,
  3912. 'name': 'UBX-MON-BATCH'},
  3913. 0x36: {'str': 'COMMS', 'dec': mon_comms, 'minlen': 8,
  3914. 'name': 'UBX-MON-COMMS'},
  3915. 0x37: {'str': 'HW3', 'dec': mon_hw3, 'minlen': 22,
  3916. 'name': 'UBX-MON-HW3'},
  3917. 0x38: {'str': 'RF', 'dec': mon_rf, 'minlen': 4,
  3918. 'name': 'UBX-MON-RF'},
  3919. }
  3920. def nav_aopstatus(self, buf):
  3921. """UBX-NAV-AOPSTATUS decode, AssistNow Autonomous Status"""
  3922. u = struct.unpack_from('<LBBLLH', buf, 0)
  3923. s = ' iTOW %u aopCfg %u status %u reserved1 %u %u %u' % u
  3924. if gps.VERB_DECODE <= self.verbosity:
  3925. aopCfg = {1: "useAOP"}
  3926. s += "\n aopCfg (%s)" % flag_s(u[1], aopCfg)
  3927. return s
  3928. def nav_att(self, buf):
  3929. """UBX-NAV-ATT decode, Attitude Solution"""
  3930. u = struct.unpack_from('<LBHBlllLLL', buf, 0)
  3931. s = (" iTOW %u version %u reserved1 %u %u\n"
  3932. " roll %d pitch %d heading %d\n"
  3933. " accRoll %d accPitch %d accHeading %d" % u)
  3934. return s
  3935. def nav_clock(self, buf):
  3936. """UBX-NAV-CLOCK decode, Clock Solution"""
  3937. u = struct.unpack_from('<LllLL', buf, 0)
  3938. return ' iTOW %u clkB %d clkD %d tAcc %u fAcc %u' % u
  3939. nav_dgps_status = {
  3940. 0: "None",
  3941. 1: "PR+PRR correction",
  3942. }
  3943. def nav_dgps(self, buf):
  3944. """UBX-NAV-DGPS decode, DGPS Data used for NAV"""
  3945. # not present in protver 27+
  3946. u = struct.unpack_from('<LlhhBBH', buf, 0)
  3947. s = (' iTOW %u age %d baseID %d basehealth %d numCh %u\n'
  3948. ' status x%x reserved1 %u' % u)
  3949. if gps.VERB_DECODE <= self.verbosity:
  3950. s += ("\n status (%s)" %
  3951. index_s(u[5], self.nav_dgps_status))
  3952. for i in range(0, u[4]):
  3953. u = struct.unpack_from('<BbHff', buf, 16 + i * 12)
  3954. s += ('\n svid %3u flags x%2x ageC %u prc %f prcc %f' % u)
  3955. if gps.VERB_DECODE <= self.verbosity:
  3956. s += ("\n channel %u dgps %u" %
  3957. (u[1] & 0x0f, (u[1] >> 4) & 1))
  3958. return s
  3959. def nav_dop(self, buf):
  3960. """UBX-NAV-DOP decode, Dilution of Precision"""
  3961. u = struct.unpack_from('<Lhhhhhhh', buf, 0)
  3962. s = (' iTOW %u gDOP %u pDOP %u tDOP %u vDOP %u\n'
  3963. ' hDOP %u nDOP %u eDOP %u' % u)
  3964. return s
  3965. def nav_eoe(self, buf):
  3966. """UBX-NAV-EOE decode, End Of Epoch"""
  3967. u = struct.unpack_from('<L', buf, 0)
  3968. return ' iTOW %u' % u
  3969. nav_geofence_state = {
  3970. 1: "Inside",
  3971. 2: "Outside",
  3972. }
  3973. nav_geofence_status = {
  3974. 0: "n/a",
  3975. 1: "Active",
  3976. }
  3977. def nav_geofence(self, buf):
  3978. """UBX-NAV-GEOFENCE decode, Geofencing status"""
  3979. u = struct.unpack_from('<LBBBB', buf, 0)
  3980. s = ' iTOW:%u version %u status %u numFences %u combState %u' % u
  3981. if gps.VERB_DECODE <= self.verbosity:
  3982. s += ("\n status (%s) combState (%s)" %
  3983. (index_s(u[2], self.nav_geofence_status),
  3984. index_s(u[4], self.nav_geofence_state)))
  3985. for i in range(0, u[3]):
  3986. u = struct.unpack_from('<BB', buf, 8 + (i * 2))
  3987. s += '\n state %u reserved1 %u' % u
  3988. if gps.VERB_DECODE <= self.verbosity:
  3989. s += ("\n state (%s)" %
  3990. (index_s(u[0], self.nav_geofence_state)))
  3991. return s
  3992. def nav_hpposecef(self, buf):
  3993. """UBX-NAV-POSECEF decode, High Precision Position Solution in ECEF"""
  3994. u = struct.unpack_from('<BBBBLlllbbbbL', buf, 0)
  3995. return (' version %u reserved1 %u %u %u iTOW %u\n'
  3996. ' ecef: X %d Y %d Z %d\n'
  3997. ' ecefHP: X %d Y %d Z %d\n'
  3998. ' reserved2 %u pAcc %u' % u)
  3999. def nav_hpposllh(self, buf):
  4000. """UBX-NAV-HPPOSLLH decode, HP Geodetic Position Solution"""
  4001. u = struct.unpack_from('<BBBBLllllbbbbLL', buf, 0)
  4002. return (' version %u reserved1 %u %u %u iTOW %u\n'
  4003. ' lon %d lat %d height %d hMSL %d\n'
  4004. ' lonHp %d latHp %d heightHp %d hMSLHp %d\n'
  4005. ' hAcc %u vAcc %u' % u)
  4006. def nav_odo(self, buf):
  4007. """UBX-NAV-ODO decode, Odometer Solution"""
  4008. u = struct.unpack_from('<BBBBLLLL', buf, 0)
  4009. return (" version %u reserved1 %u %u %u iTOW %u\n"
  4010. " distance %u totalDistance %u distanceStd %u" % u)
  4011. nav_orb_almUsability = {
  4012. 0: "Unusable",
  4013. 30: "> 30 days",
  4014. 31: "Unknown",
  4015. }
  4016. nav_orb_ephUsability = {
  4017. 0: "Unusable",
  4018. 30: "> 450 mins",
  4019. 31: "Unknown",
  4020. }
  4021. nav_orb_ephSource = {
  4022. 0: "not available",
  4023. 1: "GNSS transmission",
  4024. 2: "external aiding",
  4025. }
  4026. nav_orb_type = {
  4027. 0: "not available",
  4028. 1: "Assist now offline data",
  4029. 2: "Assist now autonomous data",
  4030. }
  4031. def nav_orb(self, buf):
  4032. """UBX-NAV-ORB decode, GNSS Orbit Database Info"""
  4033. u = struct.unpack_from('<LBBH', buf, 0)
  4034. s = " iTOW %u version %u numSv %u reserved1 %u" % u
  4035. for i in range(0, u[2]):
  4036. u = struct.unpack_from('<BBBBBB', buf, 8 + (i * 6))
  4037. s += ("\n gnssId %u svId %3u svFlag x%02x eph x%02x alm x%02x "
  4038. "otherOrb x%x" % u)
  4039. if gps.VERB_DECODE <= self.verbosity:
  4040. eph = int(u[3] & 0x1f)
  4041. s1 = index_s(eph, self.nav_orb_ephUsability, nf="")
  4042. if not s1:
  4043. s1 = "%d to %d mins" % ((eph - 1) * 15, eph * 15)
  4044. alm = int(u[4] & 0x1f)
  4045. s2 = index_s(alm, self.nav_orb_almUsability, nf="")
  4046. if not s2:
  4047. s2 = "%d to %d days" % (alm - 1, alm)
  4048. other = int(u[5] & 0x1f)
  4049. s3 = index_s(other, self.nav_orb_almUsability, nf="")
  4050. if not s3:
  4051. s3 = "%d to %d days" % (other - 1, other)
  4052. s += ("\n (%s:%u) health (%s) visibility (%s)"
  4053. "\n ephUsability (%s) ephSource (%s)"
  4054. "\n almUsability (%s) almSource (%s)"
  4055. "\n anoAopUsability (%s) type (%s)" %
  4056. (index_s(u[0], self.gnss_id), u[1],
  4057. index_s(u[2] & 3, self.health),
  4058. index_s((u[2] >> 2) & 3, self.visibility),
  4059. s1,
  4060. index_s(u[3] >> 5, self.nav_orb_ephSource, nf="other"),
  4061. s2,
  4062. index_s(u[4] >> 5, self.nav_orb_ephSource, nf="other"),
  4063. s3,
  4064. index_s(u[5] >> 5, self.nav_orb_type, nf="other")))
  4065. return s
  4066. def nav_posecef(self, buf):
  4067. """UBX-NAV-POSECEF decode, Position Solution in ECEF"""
  4068. # protVer 4+
  4069. u = struct.unpack_from('<LlllL', buf, 0)
  4070. return ' iTOW %u ecefX %d Y %d Z %d pAcc %u' % u
  4071. def nav_posllh(self, buf):
  4072. """UBX-NAV-POSLLH decode, Geodetic Position Solution"""
  4073. u = struct.unpack_from('<LllllLL', buf, 0)
  4074. return (' iTOW %u lon %d lat %d height %d\n'
  4075. ' hMSL %d hAcc %u vAcc %u' % u)
  4076. nav_pvt_valid = {
  4077. 1: "validDate",
  4078. 2: "ValidTime",
  4079. 4: "fullyResolved",
  4080. 8: "validMag", # protver 27
  4081. }
  4082. # u-blox TIME ONLY is same as Surveyed
  4083. nav_pvt_fixType = {
  4084. 0: 'None',
  4085. 1: 'Dead Reckoning',
  4086. 2: '2D',
  4087. 3: '3D',
  4088. 4: 'GPS+DR',
  4089. 5: 'Surveyed',
  4090. }
  4091. nav_pvt_flags = {
  4092. 1: "gnssFixOK",
  4093. 2: "diffSoln",
  4094. 0x20: "headVehValid",
  4095. }
  4096. nav_pvt_flags2 = {
  4097. 0x20: "confirmedAvai",
  4098. 0x40: "confirmedDate",
  4099. 0x80: "confirmedTime",
  4100. }
  4101. nav_pvt_psm = {
  4102. 0: "Not Active",
  4103. 1: "Enabled",
  4104. 2: "Acquisition",
  4105. 3: "Tracking",
  4106. 4: "Power Optimized Tracking",
  4107. 5: "Inactive",
  4108. }
  4109. # protver 27+
  4110. carrSoln = {
  4111. 0: "None",
  4112. 1: "Floating",
  4113. 2: "Fixed",
  4114. }
  4115. def nav_pvt(self, buf):
  4116. """UBX-NAV-PVT decode, Navigation Position Velocity Time Solution"""
  4117. m_len = len(buf)
  4118. # 84 bytes long in protver 14.
  4119. # 92 bytes long in protver 15.
  4120. # flags2 is protver 27
  4121. u = struct.unpack_from('<LHBBBBBBLlBBBBllllLLlllllLLHHHH', buf, 0)
  4122. s = (' iTOW %u time %u/%u/%u %02u:%02u:%02u valid x%x\n'
  4123. ' tAcc %u nano %d fixType %u flags x%x flags2 x%x\n'
  4124. ' numSV %u lon %d lat %d height %d\n'
  4125. ' hMSL %d hAcc %u vAcc %u\n'
  4126. ' velN %d velE %d velD %d gSpeed %d headMot %d\n'
  4127. ' sAcc %u headAcc %u pDOP %u reserved1 %u %u %u' % u)
  4128. if 92 <= m_len:
  4129. # version 15
  4130. u1 = struct.unpack_from('<lhH', buf, 81)
  4131. s += ('\n headVeh %d magDec %d magAcc %u' % u1)
  4132. if gps.VERB_DECODE <= self.verbosity:
  4133. s += ("\n valid (%s)"
  4134. "\n fixType (%s)"
  4135. "\n flags (%s)"
  4136. "\n flags2 (%s)"
  4137. "\n psmState (%s)"
  4138. "\n carrSoln (%s)" %
  4139. (flag_s(u[7], self.nav_pvt_valid),
  4140. index_s(u[10], self.nav_pvt_fixType),
  4141. flag_s(u[11], self.nav_pvt_flags),
  4142. flag_s(u[12], self.nav_pvt_flags2),
  4143. index_s((u[11] >> 2) & 0x0f, self.nav_pvt_psm),
  4144. index_s((u[11] >> 6) & 0x03, self.carrSoln)))
  4145. return s
  4146. nav_relposned_flags = {
  4147. 1: "gnssFixOK",
  4148. 2: "diffSoln",
  4149. 4: "relPosValid",
  4150. 0x20: "isMoving", # protVer 20.3+
  4151. 0x40: "refPosMiss", # protVer 20.3+
  4152. 0x80: "refObsMiss", # protVer 20.3+
  4153. 0x100: "relPosHeadingValid", # protVer 27.11+
  4154. 0x200: "relPosNormalized", # protVer 27.11+
  4155. }
  4156. def nav_relposned(self, buf):
  4157. """UBX-NAV-RELPOSNED decode
  4158. Relative Positioning Information in NED frame.
  4159. protVer 20+ is 40 bytes
  4160. protVer 27.11+ is 64 bytes, and things reordered, so not upward compatible
  4161. High Precision GNSS products only."""
  4162. m_len = len(buf)
  4163. # common part
  4164. u = struct.unpack_from('<BBHLlll', buf, 0)
  4165. s = (' version %u reserved1 %u refStationId %u iTOW %u\n'
  4166. ' relPosN %d relPosE %d relPosD %d\n' % u)
  4167. if (1 == u[0] and 64 <= m_len):
  4168. # valid version 1 packet, newer u-blox 9
  4169. u1 = struct.unpack_from('<llLbbbbLLLLLLL', buf, 20)
  4170. s += (' relLength %d relHeading %d reserved2 %u\n'
  4171. ' relPosHPN %d relPosHPE %d relPosHPD %d '
  4172. 'relPosHPLength %d\n'
  4173. ' accN %u accE %u accD %u accLength %u accHeading %u\n'
  4174. ' reserved3 %u flags x%x' % u1)
  4175. flags = u1[13]
  4176. elif (0 == u[0] and 40 <= m_len):
  4177. # valid version 0 packet, u-blox 8, and some u-blox 9
  4178. u1 = struct.unpack_from('<bbbbLLLLLLL', buf, 20)
  4179. s += (' relPosHPN %d relPosHPE %d relPosHPD %d reserved2 %u\n'
  4180. ' accN %u accE %u accD %u flags x%x' % u1)
  4181. flags = u1[7]
  4182. else:
  4183. # WTF?
  4184. return " Bad Length %d version %u combination" % (m_len, u[0])
  4185. if gps.VERB_DECODE <= self.verbosity:
  4186. s += ("\n flags (%s)\n"
  4187. " carrSoln (%s)" %
  4188. (flag_s(flags, self.nav_relposned_flags),
  4189. index_s((flags >> 3) & 0x03, self.carrSoln)))
  4190. return s
  4191. def nav_resetodo(self, buf):
  4192. """UBX-NAV-RESETODO decode, reset odometer"""
  4193. m_len = len(buf)
  4194. if 0 == m_len:
  4195. s = " reset request"
  4196. else:
  4197. s = " unexpected data"
  4198. return s
  4199. qualityInd = {
  4200. 0: "None",
  4201. 1: "Searching",
  4202. 2: "Acquired",
  4203. 3: "Detected",
  4204. 4: "Code and time locked",
  4205. 5: "Code, carrier and time locked",
  4206. 6: "Code, carrier and time locked",
  4207. 7: "Code, carrier and time locked",
  4208. }
  4209. health = {
  4210. 0: "Unknown",
  4211. 1: "Healthy",
  4212. 2: "Unhealthy",
  4213. }
  4214. visibility = {
  4215. 1: "below horizon",
  4216. 2: "above horizon",
  4217. 3: "above elevation mask",
  4218. }
  4219. nav_sat_orbit = {
  4220. 0: "None",
  4221. 1: "Ephemeris",
  4222. 2: "Almanac",
  4223. 3: "AssistNow Offline",
  4224. 4: "AssistNow Autonomous",
  4225. 5: "Other",
  4226. 6: "Other",
  4227. 7: "Other",
  4228. }
  4229. nav_sat_flags = {
  4230. 8: "svUsed",
  4231. 0x40: "diffCorr",
  4232. 0x80: "smoothed",
  4233. 0x800: "ephAvail",
  4234. 0x1000: "almAvail",
  4235. 0x2000: "anoAvail",
  4236. 0x4000: "aopAvail",
  4237. 0x10000: "sbasCorrUsed",
  4238. 0x20000: "rtcmCorrUsed",
  4239. 0x40000: "slasCorrUsed",
  4240. 0x100000: "prCorrUsed",
  4241. 0x200000: "crCorrUsed",
  4242. 0x400000: "doCorrUsed",
  4243. }
  4244. def nav_sat(self, buf):
  4245. """UBX-NAV-SAT decode"""
  4246. u = struct.unpack_from('<LBBBB', buf, 0)
  4247. s = ' iTOW %u version %u numSvs %u reserved1 %u %u' % u
  4248. for i in range(0, u[2]):
  4249. u = struct.unpack_from('<BBBbhhL', buf, 8 + (i * 12))
  4250. s += ('\n gnssId %u svid %3u cno %2u elev %3d azim %3d prRes %6d'
  4251. ' flags x%x' % u)
  4252. if gps.VERB_DECODE <= self.verbosity:
  4253. s += ("\n flags (%s)"
  4254. "\n qualityInd x%x (%s) health (%s)"
  4255. "\n orbitSource (%s)" %
  4256. (flag_s(u[6], self.nav_sat_flags),
  4257. u[6] & 7, index_s(u[6] & 7, self.qualityInd),
  4258. index_s((u[6] >> 4) & 3, self.health),
  4259. index_s((u[6] >> 8) & 7, self.nav_sat_orbit)))
  4260. return s
  4261. nav_sbas_mode = {
  4262. 0: "Disabled",
  4263. 1: "Enabled Integrity",
  4264. 2: "Enabled Testmode",
  4265. }
  4266. # sometimes U1 or I1, 255 or -1 == Unknown
  4267. nav_sbas_sys = {
  4268. 0: "WAAS",
  4269. 1: "EGNOS",
  4270. 2: "MSAS",
  4271. 3: "GAGAN",
  4272. 4: "SDCM", # per ICAO Annex 10, v1, Table B-27
  4273. 16: "GPS",
  4274. }
  4275. nav_sbas_service = {
  4276. 1: "Ranging",
  4277. 2: "Corrections",
  4278. 4: "Integrity",
  4279. 8: "Testmode",
  4280. }
  4281. def nav_sbas(self, buf):
  4282. """UBX-NAV-SBAS decode, SBAS Status Data"""
  4283. # present in protver 10+ (Antaris4 to ZOE-M8B
  4284. # undocumented, but present in protver 27+
  4285. # undocumented, but present in protver 32, NEO-M9N
  4286. u = struct.unpack_from('<LBBbBBBBB', buf, 0)
  4287. s = (" iTOW %d geo %u mode x%x sys %d service x%x cnt %u "
  4288. "reserved0 %u %u %u" % u)
  4289. if gps.VERB_DECODE <= self.verbosity:
  4290. s += ("\n mode (%s) sys (%s)"
  4291. "\n service (%s)" %
  4292. (index_s(u[2], self.nav_sbas_mode),
  4293. index_s(u[3], self.nav_sbas_sys),
  4294. flag_s(u[4], self.nav_sbas_service)))
  4295. for i in range(0, u[5]):
  4296. u = struct.unpack_from('<BBBBBBhHh', buf, 12 + (i * 12))
  4297. s += ("\n svid %3d flags x%04x udre x%02x svSys %3d svService %2d"
  4298. " reserved2 %u"
  4299. "\n prc %3d reserved3 %u ic %3d" % u)
  4300. if gps.VERB_DECODE <= self.verbosity:
  4301. # where are flags and udre defined??
  4302. s += ("\n svSys (%s) svService (%s)" %
  4303. (index_s(u[3], self.nav_sbas_sys),
  4304. flag_s(u[4], self.nav_sbas_service)))
  4305. return s
  4306. nav_sig_corrSource = {
  4307. 0: "None",
  4308. 1: "SBAS",
  4309. 2: "BeiDou",
  4310. 3: "RTCM2",
  4311. 4: "RTCM3 OSR",
  4312. 5: "RTCM3 SSR",
  4313. 6: "QZSS SLAS",
  4314. }
  4315. nav_sig_ionoModel = {
  4316. 0: "None",
  4317. 1: "Klobuchar over GPS",
  4318. 2: "SBAS",
  4319. 3: "Klobuchar over BeiDou",
  4320. 8: "Dual Frequency obs",
  4321. }
  4322. nav_sig_sigFlags = {
  4323. 4: "prSmoothed",
  4324. 8: "prUsed",
  4325. 0x10: "crUsed",
  4326. 0x20: "doUsed",
  4327. 0x40: "prCorrUsed",
  4328. 0x80: "crCorrUsed",
  4329. 0x100: "doCorrUsed",
  4330. }
  4331. def nav_sig(self, buf):
  4332. """UBX-NAV-SIG decode, Signal Information"""
  4333. u = struct.unpack_from('<LBBH', buf, 0)
  4334. s = ' iTOW %u version %u numSigs %u reserved1 %u' % u
  4335. for i in range(0, u[2]):
  4336. u = struct.unpack_from('<BBBBhBBBBHL', buf, 8 + (i * 16))
  4337. s += ('\n gnssId %u svId %u sigId %u freqId %u prRes %d cno %u '
  4338. 'qualityInd %u\n'
  4339. ' corrSource %u ionoModel %u sigFlags %#x reserved2 %u' %
  4340. u)
  4341. if gps.VERB_DECODE <= self.verbosity:
  4342. s += ("\n (%s) corrSource (%s)"
  4343. "\n qualityInd (%s)"
  4344. "\n ionoModel (%s) health (%s)"
  4345. "\n sigFlags (%s)" %
  4346. (self.gnss_s(u[0], u[1], u[2]),
  4347. index_s(u[7], self.nav_sig_corrSource),
  4348. index_s(u[6], self.qualityInd),
  4349. index_s(u[8], self.nav_sig_ionoModel),
  4350. index_s(u[9] & 3, self.health),
  4351. flag_s(u[9], self.nav_sig_sigFlags)))
  4352. return s
  4353. nav_slas_flags = {
  4354. 1: "gmsAvailable",
  4355. 2: "qzssSvAvailable",
  4356. 4: "testMode",
  4357. }
  4358. def nav_slas(self, buf):
  4359. """UBX-NAV-SLAS decode, QZSS L1S SLAS Status Data"""
  4360. u = struct.unpack_from('<LBBBBllBBBB', buf, 0)
  4361. s = (' iTOW %u version %u reserved1 %u %u %u'
  4362. ' gmsLon %d gmsLon %d gmsCode %u qzssSvId %u'
  4363. ' serviceFlags x%x cnt %d' % u)
  4364. for i in range(0, u[8]):
  4365. u = struct.unpack_from('<BBLh', buf, 20 + (i * 8))
  4366. s += '\n gnssId %u svId %u reserved23 %u prc %d ' % u
  4367. if gps.VERB_DECODE <= self.verbosity:
  4368. s += ("\n flags (%s)" %
  4369. (flag_s(u[3], self.nav_slas_flags)))
  4370. return s
  4371. nav_sol_flags = {
  4372. 1: "GPSfixOK",
  4373. 2: "DiffSoln",
  4374. 4: "WKNSET",
  4375. 8: "TOWSET",
  4376. }
  4377. def nav_sol(self, buf):
  4378. """UBX-NAV-SOL decode, Navigation Solution Information"""
  4379. # deprecated by u-blox
  4380. u = struct.unpack_from('<LlhBBlllLlllLHBBL', buf, 0)
  4381. s = (' iTOW %u fTOW %d week %d gpsFix %u flags x%x\n'
  4382. ' ECEF X %d Y %d Z %d pAcc %u\n'
  4383. ' VECEF X %d Y %d Z %d sAcc %u\n'
  4384. ' pDOP %u reserved1 %u numSV %u reserved2 %u' % u)
  4385. if gps.VERB_DECODE <= self.verbosity:
  4386. s += ("\n gpsfix (%s)"
  4387. "\n flags (%s)" %
  4388. (index_s(u[3], self.nav_pvt_fixType),
  4389. flag_s(u[4], self.nav_sol_flags)))
  4390. return s
  4391. def nav_status(self, buf):
  4392. """UBX-NAV-STATUS decode"""
  4393. u = struct.unpack_from('<LBBBBLL', buf, 0)
  4394. return (' iTOW:%d ms, fix:%d flags:%#x fixstat:%#x flags2:%#x\n'
  4395. ' ttff:%d, msss:%d' % u)
  4396. def nav_svin(self, buf):
  4397. """UBX-NAV-SVIN decode, Survey-in data"""
  4398. # in M8 HPG only
  4399. u = struct.unpack_from('<BBBBLLlllbbbBLLBB', buf, 0)
  4400. return (' version %u reserved1[%u %u %u] iTOW %u dur %u\n'
  4401. ' meanX %d meanY %d meanZ %d\n'
  4402. ' meanXHP %d meanYHP %d meanZHP %d reserved2 %u meanAcc %u\n'
  4403. ' obs %u valid %u active %u' % u)
  4404. nav_svinfo_gflags = {
  4405. 0: 'Antaris, Antaris 4',
  4406. 1: 'u-blox 5',
  4407. 2: 'u-blox 6',
  4408. 3: 'u-blox 7',
  4409. 4: 'u-blox 8/M8',
  4410. }
  4411. nav_svinfo_flags = {
  4412. 1: 'svUsed',
  4413. 2: 'diffCorr',
  4414. 4: 'orbitAvail',
  4415. 8: 'orbitEph',
  4416. 0x10: 'unhealthy',
  4417. 0x20: 'orbitAlm',
  4418. 0x40: 'orbitAop',
  4419. 0x80: 'smoothed',
  4420. }
  4421. nav_svinfo_quality = {
  4422. 0: 'no signal',
  4423. 1: 'searching signal',
  4424. 2: 'signal acquired',
  4425. 3: 'signal detected but unusable',
  4426. 4: 'code locked, time synced',
  4427. 5: 'code and carrier locked, time synced',
  4428. 6: 'code and carrier locked, time synced',
  4429. 7: 'code and carrier locked, time synced',
  4430. }
  4431. def nav_svinfo(self, buf):
  4432. """UBX-NAV-SVINFO decode"""
  4433. # in M8 Timing and FTS only
  4434. m_len = len(buf)
  4435. u = struct.unpack_from('<LbbH', buf, 0)
  4436. s = ' iTOW:%d numCh %d globalFlags %d reserved1 x%x' % u
  4437. if gps.VERB_DECODE <= self.verbosity:
  4438. s += '\n globalFlags (%s)' % index_s(u[2], self.nav_svinfo_gflags)
  4439. m_len -= 8
  4440. i = 0
  4441. while 0 < m_len:
  4442. u = struct.unpack_from('<BBBBBbhl', buf, 8 + i * 12)
  4443. s += ('\n chn %3d svid %3d flags %#0.2x quality %u cno %2d'
  4444. ' elev %3d azim %3d prRes %6d' % u)
  4445. if gps.VERB_DECODE <= self.verbosity:
  4446. s += ('\n flags (%s)'
  4447. '\n quality (%s)' %
  4448. (flag_s(u[2], self.nav_svinfo_flags),
  4449. index_s(u[3], self.nav_svinfo_quality)))
  4450. m_len -= 12
  4451. i += 1
  4452. return s
  4453. nav_time_valid = {
  4454. 1: "towValid",
  4455. 2: "weekValid",
  4456. 4: "leapValid",
  4457. }
  4458. def nav_timebds(self, buf):
  4459. """UBX-NAV-TIMEBDS decode"""
  4460. u = struct.unpack_from('<LLlhbBL', buf, 0)
  4461. s = (" iTOW %d SOW %d fSOW %d week %d leapS %d\n"
  4462. " Valid %#x tAcc %d" % u)
  4463. if gps.VERB_DECODE <= self.verbosity:
  4464. s += ("\n valid (%s)" %
  4465. (flag_s(u[5], self.nav_time_valid)))
  4466. return s
  4467. def nav_timegal(self, buf):
  4468. """UBX-NAV-TIMEGAL decode"""
  4469. u = struct.unpack_from('<LLlhbBL', buf, 0)
  4470. s = (" iTOW %d galTOW %d fGalTow %d galWno %d leapS %d\n"
  4471. " Valid x%x, tAcc %d" % u)
  4472. if gps.VERB_DECODE <= self.verbosity:
  4473. s += ("\n valid (%s)" %
  4474. (flag_s(u[5], self.nav_time_valid)))
  4475. return s
  4476. def nav_timeglo(self, buf):
  4477. """UBX-NAV-TIMEGLO decode"""
  4478. u = struct.unpack_from('<LLlhbBL', buf, 0)
  4479. s = (" iTOW %d TOD %d fTOD %d Nt %d N4 %d\n"
  4480. " Valid x%x tAcc %d" % u)
  4481. if gps.VERB_DECODE <= self.verbosity:
  4482. s += ("\n valid (%s)" %
  4483. (flag_s(u[5], self.nav_time_valid)))
  4484. return s
  4485. def nav_timegps(self, buf):
  4486. """UBX-NAV-TIMEGPS decode"""
  4487. u = struct.unpack_from('<LlhbBL', buf, 0)
  4488. s = " iTOW %u fTOW %u week %d leapS %d valid x%x tAcc %d" % u
  4489. if gps.VERB_DECODE <= self.verbosity:
  4490. s += ("\n valid (%s)" %
  4491. (flag_s(u[4], self.nav_time_valid)))
  4492. return s
  4493. nav_timels_src = {
  4494. 0: "Default",
  4495. 1: "GPS/GLONASS derived",
  4496. 2: "GPS",
  4497. 3: "SBAS",
  4498. 4: "BeiDou",
  4499. 5: "Galileo",
  4500. 6: "Aided data",
  4501. 7: "Configured",
  4502. }
  4503. nav_timels_src1 = {
  4504. 0: "None",
  4505. 2: "GPS",
  4506. 3: "SBAS",
  4507. 4: "BeiDou",
  4508. 5: "Galileo",
  4509. 6: "GLONASS",
  4510. }
  4511. nav_timels_valid = {
  4512. 1: "validCurrLs",
  4513. 2: "validTimeToLsEvent",
  4514. }
  4515. def nav_timels(self, buf):
  4516. """UBX-NAV-TIMELS decode, Leap second event information"""
  4517. u = struct.unpack_from('<LBBBBBbBblHHBBBB', buf, 0)
  4518. s = (' iTOW %u version %u reserved2 %u %u %u srcOfCurrLs %u\n'
  4519. ' currLs %d srcOfLsChange %u lsChange %d timeToLsEvent %d\n'
  4520. ' dateOfLsGpsWn %u dateOfLsGpsDn %u reserved2 %u %u %u\n'
  4521. ' valid x%x' % u)
  4522. if gps.VERB_DECODE <= self.verbosity:
  4523. s += ("\n srcOfCurrLs (%s) srcOfLsChange (%s)"
  4524. "\n valid (%s)" %
  4525. (index_s(u[5], self.nav_timels_src),
  4526. index_s(u[7], self.nav_timels_src1),
  4527. flag_s(u[15], self.nav_timels_valid)))
  4528. return s
  4529. nav_timeutc_valid = {
  4530. 1: "validTOW",
  4531. 2: "validWKN",
  4532. 4: "validUTC",
  4533. }
  4534. def nav_timeutc(self, buf):
  4535. """UBX-NAV-TIMEUTC decode"""
  4536. u = struct.unpack_from('<LLlHbbbbbB', buf, 0)
  4537. s = (" iTOW %d tAcc %d nano %d Time %d/%d/%d %d:%d:%d\n"
  4538. " valid x%x" % u)
  4539. if gps.VERB_DECODE <= self.verbosity:
  4540. s += ("\n valid (%s) utcStandard (%s)" %
  4541. (flag_s(u[9], self.nav_timeutc_valid),
  4542. index_s(u[9] >> 4, self.utc_std)))
  4543. return s
  4544. def nav_velecef(self, buf):
  4545. """UBX-NAV-VELECEF decode"""
  4546. # protVer 4+
  4547. u = struct.unpack_from('<LlllL', buf, 0)
  4548. return ' iTOW %d ecef: VX %d VY %d VZ %d vAcc:%u' % u
  4549. def nav_velned(self, buf):
  4550. """UBX-NAV-VELNED decode."""
  4551. # protVer 15+
  4552. u = struct.unpack_from('<LlllLLlLL', buf, 0)
  4553. return (' iTOW %u vel: N %d E %d D %d speed %u\n'
  4554. ' gspeed %u heading %d sAcc %u cAcc %u' % u)
  4555. nav_ids = {0x01: {'str': 'POSECEF', 'dec': nav_posecef, 'minlen': 20,
  4556. 'name': 'UBX-NAV-POSECEF'},
  4557. 0x02: {'str': 'POSLLH', 'dec': nav_posllh, 'minlen': 20,
  4558. 'name': 'UBX-NAV-POSLLH'},
  4559. 0x03: {'str': 'STATUS', 'dec': nav_status, 'minlen': 16,
  4560. 'name': 'UBX-NAV-STATUS'},
  4561. 0x04: {'str': 'DOP', 'dec': nav_dop, 'minlen': 18,
  4562. 'name': 'UBX-NAV-DOP'},
  4563. 0x05: {'str': 'ATT', 'dec': nav_att, 'minlen': 32,
  4564. 'name': 'UBX-NAV-ATT'},
  4565. 0x06: {'str': 'SOL', 'dec': nav_sol, 'minlen': 52,
  4566. 'name': 'UBX-NAV-SOL'},
  4567. 0x07: {'str': 'PVT', 'dec': nav_pvt, 'minlen': 84,
  4568. 'name': 'UBX-NAV-PVT'},
  4569. 0x09: {'str': 'ODO', 'dec': nav_odo, 'minlen': 20,
  4570. 'name': 'UBX-NAV-ODO'},
  4571. 0x10: {'str': 'RESETODO', 'dec': nav_resetodo, 'minlen': 0,
  4572. 'name': 'UBX-NAV-RESETODO'},
  4573. 0x11: {'str': 'VELECEF', 'dec': nav_velecef, 'minlen': 20,
  4574. 'name': 'UBX-NAV-VELECEF'},
  4575. 0x12: {'str': 'VELNED', 'dec': nav_velned, 'minlen': 36,
  4576. 'name': 'UBX-NAV-VELNED'},
  4577. 0x13: {'str': 'HPPOSECEF', 'dec': nav_hpposecef, 'minlen': 28,
  4578. 'name': 'UBX-NAV-HPPOSECEF'},
  4579. 0x14: {'str': 'HPPOSLLH', 'dec': nav_hpposllh, 'minlen': 36,
  4580. 'name': 'UBX-NAV-HPPOSLLH'},
  4581. 0x20: {'str': 'TIMEGPS', 'dec': nav_timegps, 'minlen': 16,
  4582. 'name': 'UBX-NAV-TIMEGPS'},
  4583. 0x21: {'str': 'TIMEUTC', 'dec': nav_timeutc, 'minlen': 20,
  4584. 'name': 'UBX-NAV-TIMEUTC'},
  4585. 0x22: {'str': 'CLOCK', 'dec': nav_clock, 'minlen': 20,
  4586. 'name': 'UBX-NAV-CLOCK'},
  4587. 0x23: {'str': 'TIMEGLO', 'dec': nav_timeglo, 'minlen': 20,
  4588. 'name': 'UBX-NAV-TIMEGLO'},
  4589. 0x24: {'str': 'TIMEBDS', 'dec': nav_timebds, 'minlen': 20,
  4590. 'name': 'UBX-NAV-TIMEBDS'},
  4591. 0x25: {'str': 'TIMEGAL', 'dec': nav_timegal, 'minlen': 20,
  4592. 'name': 'UBX-NAV-TIMEGAL'},
  4593. 0x26: {'str': 'TIMELS', 'dec': nav_timels, 'minlen': 24,
  4594. 'name': 'UBX-NAV-TIMELS'},
  4595. 0x30: {'str': 'SVINFO', 'dec': nav_svinfo, 'minlen': 8,
  4596. 'name': 'UBX-NAV-SVINFO'},
  4597. 0x31: {'str': 'DGPS', 'dec': nav_dgps, 'minlen': 16,
  4598. 'name': 'UBX-NAV-DGPS'},
  4599. 0x32: {'str': 'SBAS', 'dec': nav_sbas, 'minlen': 12,
  4600. 'name': 'UBX-NAV-SBAS'},
  4601. 0x34: {'str': 'ORB', 'dec': nav_orb, 'minlen': 8,
  4602. 'name': 'UBX-NAV-ORB'},
  4603. 0x35: {'str': 'SAT', 'dec': nav_sat, 'minlen': 8,
  4604. 'name': 'UBX-NAV-SAT'},
  4605. 0x39: {'str': 'GEOFENCE', 'dec': nav_geofence, 'minlen': 8,
  4606. 'name': 'UBX-NAV-GEOFENCE'},
  4607. 0x3B: {'str': 'SVIN', 'dec': nav_svin, 'minlen': 40,
  4608. 'name': 'UBX-NAV-SVIN'},
  4609. # M8P length = 40, M9P length = 64
  4610. 0x3C: {'str': 'RELPOSNED', 'dec': nav_relposned, 'minlen': 40,
  4611. 'name': 'UBX-NAV-RELPOSNED'},
  4612. # deprecated in u-blox 6, SFDR only
  4613. 0x40: {'str': 'EKFSTATUS', 'minlen': 36,
  4614. 'name': 'UBX-NAV-EKFSTATUS'},
  4615. 0x42: {'str': 'SLAS', 'dec': nav_slas, 'minlen': 20,
  4616. 'name': 'UBX-NAV-SLAS'},
  4617. 0x43: {'str': 'SIG', 'dec': nav_sig, 'minlen': 8,
  4618. 'name': 'UBX-NAV-SIG'},
  4619. 0x60: {'str': 'AOPSTATUS', 'dec': nav_aopstatus, 'minlen': 16,
  4620. 'name': 'UBX-NAV-AOPSTATUS'},
  4621. 0x61: {'str': 'EOE', 'dec': nav_eoe, 'minlen': 4,
  4622. 'name': 'UBX-NAV-EOE'},
  4623. }
  4624. # used for RTCM3 rate config
  4625. rtcm_ids = {5: {'str': '1005'},
  4626. 0x4a: {'str': '1074'},
  4627. 0x4d: {'str': '1077'},
  4628. 0x54: {'str': '1084'},
  4629. 0x57: {'str': '1087'},
  4630. 0x61: {'str': '1097'},
  4631. 0x7c: {'str': '1124'},
  4632. 0x7f: {'str': '1127'},
  4633. 0xe6: {'str': '1230'},
  4634. 0xfd: {'str': '4072-1'},
  4635. 0xfe: {'str': '4072-0'},
  4636. }
  4637. # used for NMEA rate config
  4638. nmea_ids = {0: {'str': 'GGA'},
  4639. 1: {'str': 'GLL'},
  4640. 2: {'str': 'GSA'},
  4641. 3: {'str': 'GSV'},
  4642. 4: {'str': 'RMC'},
  4643. 5: {'str': 'VTG'},
  4644. 6: {'str': 'GRS'},
  4645. 7: {'str': 'GST'},
  4646. 8: {'str': 'ZDA'},
  4647. 9: {'str': 'GBS'},
  4648. 0x0a: {'str': 'DTM'},
  4649. 0x0d: {'str': 'GNS'},
  4650. 0x0f: {'str': 'VLW'},
  4651. 0x40: {'str': 'GPQ'},
  4652. 0x41: {'str': 'TXT'},
  4653. 0x42: {'str': 'GNQ'},
  4654. 0x43: {'str': 'GLQ'},
  4655. 0x44: {'str': 'GBQ'},
  4656. 0x45: {'str': 'GAQ'},
  4657. }
  4658. def rxm_imes(self, buf):
  4659. """UBX-RXM-IMES decode, Indoor Messaging System Information"""
  4660. u = struct.unpack_from('<BBH', buf, 0)
  4661. s = ' numTx %u version %u reserved1 %u' % u
  4662. for i in range(0, u[0]):
  4663. u = struct.unpack_from('<BBHBBHlLLLllLLL', buf, 4 + (i * 44))
  4664. s += ('\n reserved %u txId %u reserved3 %u %u cno %u reserved4 %u'
  4665. '\n doppler %d position1_1 x%x position1_2 x%x'
  4666. '\n position2_1 x%x lat %d lon %d shortIdFrame x%x'
  4667. '\n mediumIdLSB %u mediumId_2 x%x' % u)
  4668. return s
  4669. def rxm_measx(self, buf):
  4670. """UBX-RXM-RAW decode"""
  4671. m_len = len(buf)
  4672. u = struct.unpack_from('<BBBBLLLLLHHHHHBBLL', buf, 0)
  4673. s = (' version %u reserved1 %u %u %u gpsTOW %u gloTOW %u\n'
  4674. ' bdsTOW %u reserved2 %u qzssTOW %u gpsTOWacc %u\n'
  4675. ' gloTOWacc %u bdsTOWacc %u reserved3 %u qzssTOWacc %u\n'
  4676. ' numSV %u flags %#x reserved4 %u %u' % u)
  4677. m_len -= 44
  4678. i = 0
  4679. while 0 < m_len:
  4680. u = struct.unpack_from('<BBBBllHHLBBH', buf, 44 + i * 24)
  4681. s += ('\n gnssId %u svId %u cNo %u mpathIndic %u DopplerMS %d\n'
  4682. ' dopplerHz %d wholeChips %u fracChips %u codephase %u\n'
  4683. ' intCodePhase %u pseudoRangeRMSErr %u reserved5 %u' % u)
  4684. m_len -= 24
  4685. i += 1
  4686. return s
  4687. def rxm_raw(self, buf):
  4688. """UBX-RXM-RAW decode"""
  4689. m_len = len(buf)
  4690. u = struct.unpack_from('<lhBB', buf, 0)
  4691. s = ' iTOW %d weeks %d numSV %u res1 %u' % u
  4692. m_len -= 8
  4693. i = 0
  4694. while 0 < m_len:
  4695. u = struct.unpack_from('<ddfBbbB', buf, 8 + i * 24)
  4696. s += ('\n cpMes %f prMes %f doMes %f sv %d mesQI %d\n'
  4697. ' eno %d lli %d' % u)
  4698. m_len -= 24
  4699. i += 1
  4700. return s
  4701. rxm_rawx_recs = {
  4702. 1: "leapSec",
  4703. 2: "clkReset",
  4704. }
  4705. def rxm_rawx(self, buf):
  4706. """UBX-RXM-RAWX decode"""
  4707. m_len = len(buf)
  4708. # version not here before protver 18, I hope it is zero.
  4709. u = struct.unpack_from('<dHbBBBBB', buf, 0)
  4710. s = (' rcvTow %.3f week %u leapS %d numMeas %u recStat %#x'
  4711. ' version %u\n'
  4712. ' reserved1[2] %#x %#x\n recStat (' % u)
  4713. s += flag_s(u[4], self.rxm_rawx_recs) + ')'
  4714. m_len -= 16
  4715. i = 0
  4716. while 0 < m_len:
  4717. u = struct.unpack_from('<ddfBBBBHBBBBB', buf, 16 + i * 32)
  4718. s += ('\n prmes %.3f cpMes %.3f doMes %f\n'
  4719. ' gnssId %u svId %u sigId %u freqId %u locktime %u '
  4720. 'cno %u\n'
  4721. ' prStdev %u cpStdev %u doStdev %u trkStat %u' % u)
  4722. if gps.VERB_DECODE < self.verbosity:
  4723. s += '\n (%s)' % self.gnss_s(u[3], u[4], u[5])
  4724. m_len -= 32
  4725. i += 1
  4726. return s
  4727. def rxm_rlm(self, buf):
  4728. """UBX-RXM-RLM decode, Galileo SAR RLM report"""
  4729. m_len = len(buf)
  4730. # common to Short-RLM and Long-RLM report
  4731. u = struct.unpack_from('<BBBBLLB', buf, 0)
  4732. s = (" version %u type %u svId %u reserved1 %u beacon x%x %x "
  4733. " message %u" % u)
  4734. if 16 == m_len:
  4735. # Short-RLM report
  4736. u = struct.unpack_from('<BBB', buf, 13)
  4737. s += "\n params %u %u reserved2 %u" % u
  4738. elif 28 == m_len:
  4739. # Long-RLM report
  4740. u = struct.unpack_from('<BBBBBBBBBBBBBBB', buf, 13)
  4741. s += ("\n params %u %u %u %u %u %u %u %u %u %u %u %u"
  4742. "\n reserved2 %u %u %u" % u)
  4743. return s
  4744. rxm_rtcm_flags = {
  4745. 1: "crcFailed",
  4746. }
  4747. def rxm_rtcm(self, buf):
  4748. """UBX-RXM-RTCM decode, RTCM Input Status"""
  4749. # present in some u-blox 8 and 9, protVer 20+
  4750. # undocumented, but in NEO-M9N, protVer 32
  4751. u = struct.unpack_from('<BBHHH', buf, 0)
  4752. s = " version %u flags x%x subtype %u refstation %u msgtype %u" % u
  4753. if gps.VERB_DECODE <= self.verbosity:
  4754. s += ('\n flags (%s)' % flag_s(u[1], self.rxm_rtcm_flags))
  4755. return s
  4756. def rxm_sfrb(self, buf):
  4757. """UBX-RXM-SFRB decode, Subframe Buffer"""
  4758. u = struct.unpack_from('<BBLLLLLLLLLL', buf, 0)
  4759. s = (' chn %d s svid %3d\n'
  4760. ' dwrd %08x %08x %08x %08x %08x\n'
  4761. ' %08x %08x %08x %08x %08x' % u)
  4762. return s
  4763. # decode GPS subframe 5, pages 1 to 24,
  4764. # and subframe 4, pages 2 to 5, and 7 to 10
  4765. def almanac(self, words):
  4766. """Decode GPS Almanac"""
  4767. # [1] Section 20.3.3.5, Figure 20-1 Sheet 4, and Table 20-VI.
  4768. # Current almanac: https://www.navcen.uscg.gov/?pageName=gpsAlmanacs
  4769. # e = Eccentricity
  4770. # toa = Almanac reference time
  4771. # deltai =
  4772. # Omegadot = Rate of Right Ascension
  4773. # SVH = SV Health
  4774. # sqrtA = Square Root of the Semi-Major Axis
  4775. # Omega0 = Longitude of Ascending Node of Orbit Plane at Weekly Epoch
  4776. # omega = Argument of Perigee
  4777. # M0 = Mean Anomaly at Reference Time
  4778. # af0 = SV Clock Bias Correction Coefficient
  4779. # af1 = SV Clock Drift Correction Coefficient
  4780. s = " Almanac"
  4781. s += ("\n e %e toa %u deltai %e Omegadot %e"
  4782. "\n SVH x%x sqrtA %.6f Omega0 %e omega %e"
  4783. "\n M0 %e af0 %e af1 %e" %
  4784. (unpack_u16(words[2], 6) * (2 ** -21),
  4785. unpack_u8(words[3], 22) * (2 ** 12),
  4786. unpack_s16(words[3], 6) * (2 ** -19),
  4787. unpack_s16(words[4], 14) * (2 ** -38),
  4788. unpack_u8(words[4], 6),
  4789. unpack_u24(words[5], 6) * (2 ** -11), # sqrtA
  4790. unpack_s24(words[6], 6) * (2 ** -23),
  4791. unpack_s24(words[7], 6) * (2 ** -23),
  4792. unpack_s24(words[8], 6) * (2 ** -23), # M0
  4793. unpack_s11s(words[9]) * (2 ** -20),
  4794. unpack_s11(words[9], 11) * (2 ** -38)))
  4795. return s
  4796. cnav_msgids = {
  4797. 10: "Ephemeris 1",
  4798. 11: "Ephemeris 2",
  4799. 12: "Reduced Almanac",
  4800. 13: "Clock Differential Correction",
  4801. 14: "Ephemeris Differential Correction",
  4802. 15: "Text",
  4803. 30: "Clock, IONO & Group Delay",
  4804. 31: "Clock & Reduced Almanac",
  4805. 32: "Clock & EOP",
  4806. 33: "Clock & UTC",
  4807. 34: "Clock & Differential Correction",
  4808. 35: "Clock & GGTO",
  4809. 36: "Clock & Text",
  4810. 37: "Clock & Midi Almanac",
  4811. }
  4812. # map subframe 4 SV ID to Page number
  4813. # IS-GPS-200K Table 20-V
  4814. sbfr4_svid_page = {
  4815. 0: 0, # dummy/self
  4816. 57: 1, # Reserved (Dupe, also 6, 11, 16 21)
  4817. 25: 2,
  4818. 26: 3,
  4819. 27: 4,
  4820. 28: 5,
  4821. # 57: 6, # Reserved (Dupe)
  4822. 29: 7,
  4823. 30: 8,
  4824. 31: 9,
  4825. 32: 10,
  4826. # 57: 11, # Reserved (Dupe)
  4827. 62: 12, # reserved (Dupe 12 and 24)
  4828. 52: 13, # navigation message correction table (NMCT)
  4829. 53: 14, # reserved
  4830. 54: 15, # reserved
  4831. # 57: 16, # Reserved (Dupe)
  4832. 55: 17, # Special messages
  4833. 56: 18, # Ionospheric and UTC data
  4834. 58: 19, # reserved
  4835. 59: 20, # reserved
  4836. # 57: 21, # Reserved (Dupe)
  4837. 60: 22, # reserved
  4838. 61: 23, # reserved
  4839. # 62: 24, # reserved (Dupe 12 and 24)
  4840. 63: 25, # A-S Flags/ SV health
  4841. }
  4842. # map subframe 5 SV ID to Page number
  4843. # IS-GPS-200K Table 20-V
  4844. sbfr5_svid_page = {
  4845. 0: 0, # dummy/self
  4846. 1: 1,
  4847. 2: 2,
  4848. 3: 3,
  4849. 4: 4,
  4850. 5: 5,
  4851. 6: 6,
  4852. 7: 7,
  4853. 8: 8,
  4854. 9: 9,
  4855. 10: 10,
  4856. 11: 11,
  4857. 12: 12,
  4858. 13: 13,
  4859. 14: 14,
  4860. 15: 15,
  4861. 16: 16,
  4862. 17: 17,
  4863. 18: 18,
  4864. 19: 19,
  4865. 20: 20,
  4866. 21: 21,
  4867. 22: 22,
  4868. 23: 23,
  4869. 24: 24,
  4870. 51: 25, # SV Health, SC 1 to 24
  4871. }
  4872. # URA Index to URA meters
  4873. ura_meters = {
  4874. 0: "2.40 m",
  4875. 1: "3.40 m",
  4876. 2: "4.85 m",
  4877. 3: "6.85 m",
  4878. 4: "9.65 m",
  4879. 5: "13.65 m",
  4880. 6: "24.00 m",
  4881. 7: "48.00 m",
  4882. 8: "96.00 m",
  4883. 9: "192.00 m",
  4884. 10: "384.00 m",
  4885. 11: "768.00 m",
  4886. 12: "1536.00 m",
  4887. 13: "3072.00 m",
  4888. 14: "6144.00 m",
  4889. 15: "Unk",
  4890. }
  4891. codes_on_l2 = {
  4892. 0: "Invalid",
  4893. 1: "P-code ON",
  4894. 2: "C/A-code ON",
  4895. 3: "Invalid",
  4896. }
  4897. nmct_ai = {
  4898. 0: "OK",
  4899. 1: "Encrypted",
  4900. 2: "Unavailable",
  4901. 3: "Reserved",
  4902. }
  4903. sv_conf = {
  4904. 0: "Reserved",
  4905. 1: "Block II/Block IIA/IIR SV",
  4906. 2: "M-code, L2C, Block IIR-M SV",
  4907. 3: "M-code, L2C, L5, Block IIF SV",
  4908. 4: "M-code, L2C, L5, No SA, Block III SV",
  4909. 5: "Reserved",
  4910. 6: "Reserved",
  4911. 7: "Reserved",
  4912. }
  4913. def rxm_sfrbx(self, buf):
  4914. """UBX-RXM-SFRBX decode, Broadcast Navigation Data Subframe"""
  4915. # The way u-blox packs the subfram data is perverse, and
  4916. # undocuemnted. Even more perverse than native subframes.
  4917. u = struct.unpack_from('<BBBBBBBB', buf, 0)
  4918. svId = u[1]
  4919. s = (' gnssId %u svId %3u reserved1 %u freqId %u numWords %u\n'
  4920. ' chn %u version %u reserved2 %u\n' % u)
  4921. s += ' dwrd'
  4922. words = ()
  4923. for i in range(0, u[4]):
  4924. u1 = struct.unpack_from('<L', buf, 8 + (i * 4))
  4925. if 6 == (i % 7):
  4926. s += "\n "
  4927. s += " %08x" % u1
  4928. words += (u1[0],)
  4929. if 0 == u[0]:
  4930. # GPS
  4931. preamble = words[0] >> 24
  4932. if 0x8b == preamble:
  4933. # CNAV
  4934. msgid = (words[0] >> 12) & 0x3f
  4935. s += ("\n CNAV: preamble %#x PRN %u msgid %d (%s)\n" %
  4936. (preamble, (words[0] >> 18) & 0x3f,
  4937. msgid, index_s(msgid, self.cnav_msgids)))
  4938. else:
  4939. # IS-GPS-200, Figure 20-2
  4940. # LNAV-L, from sat is 10 words of 30 bits
  4941. # from u-blox each of 10 words right aligned into 32 bits
  4942. # plus something in top 2 bits?
  4943. preamble = words[0] >> 22
  4944. subframe = (words[1] >> 8) & 0x07
  4945. s += ("\n LNAV-L: preamble %#x TLM %#x ISF %u" %
  4946. (preamble, (words[0] >> 8) & 0xffff,
  4947. 1 if (words[0] & 0x40) else 0))
  4948. s += ("\n TOW17 %u Alert %u A-S %u Subframe %u" %
  4949. (unpack_u17(words[1], 13) * 6,
  4950. 1 if (words[0] & 0x1000) else 0,
  4951. 1 if (words[0] & 0x800) else 0,
  4952. subframe))
  4953. if 1 == subframe:
  4954. # not well validated decode, possibly wrong...
  4955. # [1] Figure 20-1 Sheet 1, Table 20-I
  4956. # WN = GPS week number
  4957. # TGD = Group Delay Differential
  4958. # tOC = Time of Clock
  4959. # af0 = SV Clock Bias Correction Coefficient
  4960. # af1 = SV Clock Drift Correction Coefficient
  4961. # af2 = Drift Rate Correction Coefficient
  4962. ura = (words[2] >> 14) & 0x0f
  4963. c_on_l2 = (words[2] >> 18) & 0x03
  4964. iodc = ((((words[2] >> 6) & 0x03) << 8) |
  4965. (words[7] >> 24) & 0xff)
  4966. s += ("\n WN %u Codes on L2 %u (%s) URA %u (%s) "
  4967. "SVH %#04x IODC %u" %
  4968. (words[2] >> 20,
  4969. c_on_l2, index_s(c_on_l2, self.codes_on_l2),
  4970. ura, index_s(ura, self.ura_meters),
  4971. (words[2] >> 8) & 0x3f, iodc))
  4972. # tOC = Clock Data Reference Time of Week
  4973. s += ("\n L2 P DF %u TGD %e tOC %u\n"
  4974. " af2 %e af1 %e af0 %e" %
  4975. ((words[2] >> 29) & 0x03,
  4976. unpack_s8(words[6], 6) * (2 ** -31),
  4977. unpack_u16(words[7], 6) * 16,
  4978. unpack_s8(words[8], 22) * (2 ** -55),
  4979. unpack_s16(words[8], 6) * (2 ** -43),
  4980. unpack_s22(words[9], 8) * (2 ** -31)))
  4981. elif 2 == subframe:
  4982. # not well validated decode, possibly wrong...
  4983. # [1] Figure 20-1 Sheet 1, Tables 20-II and 20-III
  4984. # IODE = Issue of Data (Ephemeris)
  4985. # Crs = Amplitude of the Sine Harmonic Correction
  4986. # Term to the Orbit Radius
  4987. # Deltan = Mean Motion Difference From Computed Value
  4988. # M0 = Mean Anomaly at Reference Time
  4989. # Cuc = Amplitude of the Cosine Harmonic Correction
  4990. # Term to the Argument of Latitude
  4991. # e = Eccentricity
  4992. # Cus = Amplitude of the Sine Harmonic Correction Term
  4993. # to the Argument of Latitude
  4994. # sqrtA = Square Root of the Semi-Major Axis
  4995. # tOE = Reference Time Ephemeris
  4996. s += ("\n IODE %u Crs %e Deltan %e M0 %e"
  4997. "\n Cuc %e e %e Cus %e sqrtA %f"
  4998. "\n tOE %u" %
  4999. (unpack_u8(words[2], 22),
  5000. unpack_s16(words[2], 6) * (2 ** -5),
  5001. unpack_s16(words[3], 14) * (2 ** -43),
  5002. # M0
  5003. unpack_s32s(words[4], words[3]) * (2 ** -31),
  5004. unpack_s16(words[5], 14) * (2 ** -29),
  5005. unpack_u32s(words[6], words[5]) * (2 ** -33),
  5006. unpack_s16(words[7], 14) * (2 ** -29),
  5007. unpack_u32s(words[8], words[7]) * (2 ** -19),
  5008. unpack_u16(words[9], 14) * 16))
  5009. elif 3 == subframe:
  5010. # not well validated decode, possibly wrong...
  5011. # [1] Figure 20-1 Sheet 3, Table 20-II, Table 20-III
  5012. # Cic = Amplitude of the Cosine Harmonic Correction
  5013. # Term to the Angle of Inclination
  5014. # Omega0 = Longitude of Ascending Node of Orbit
  5015. # Plane at Weekly Epoch
  5016. # Cis = Amplitude of the Sine Harmonic Correction
  5017. # Term to the Orbit Radius
  5018. # i0 = Inclination Angle at Reference Time
  5019. # Crc = Amplitude of the Cosine Harmonic Correction
  5020. # Term to the Orbit Radius
  5021. # omega = Argument of Perigee
  5022. # Omegadot = Rate of Right Ascension
  5023. # IODE = Issue of Data (Ephemeris)
  5024. # IODT = Rate of Inclination Angle
  5025. s += ("\n Cic %e Omega0 %e Cis %e i0 %e"
  5026. "\n Crc %e omega %e Omegadot %e"
  5027. "\n IDOE %u IDOT %e" %
  5028. (unpack_s16(words[2], 14) * (2 ** -29),
  5029. unpack_s32s(words[3], words[2]) * (2 ** -31),
  5030. unpack_s16(words[4], 14) * (2 ** -29),
  5031. unpack_s32s(words[5], words[4]) * (2 ** -31),
  5032. # Crc
  5033. unpack_s16(words[6], 14) * (2 ** -5),
  5034. unpack_s32s(words[7], words[6]) * (2 ** -31),
  5035. # Omegadot
  5036. unpack_s24(words[8], 6) * (2 ** -43),
  5037. unpack_u8(words[9], 22),
  5038. unpack_s14(words[9], 8) * (2 ** -43)))
  5039. elif 4 == subframe:
  5040. # pages:
  5041. # 2 to 5, 7 to 10 almanac data for SV 25 through 32
  5042. # 13 navigation message correction table (NMCT_
  5043. # 17 Special Messages
  5044. # 18 Ionospheric and UTC data
  5045. # 25 A-S flags/ SV health
  5046. # 1, 6, 11, 16 and 21 reserved
  5047. # 12, 19, 20, 22, 23 and 24 reserved
  5048. # 14 and 15 reserved
  5049. # as of 2018, data ID is always 1.
  5050. svid = (words[2] >> 22) & 0x3f
  5051. # 0 === svid is dummy SV
  5052. # almanac for dummy sat 0, same as transmitting sat
  5053. # Sec 3.2.1: "Users shall only use non-dummy satellites"
  5054. page = index_s(svid, self.sbfr4_svid_page)
  5055. s += ("\n dataid %u svid %u (page %s)\n" %
  5056. (words[2] >> 28, svid, page))
  5057. if 6 == page:
  5058. s += " reserved"
  5059. elif 2 <= page <= 10:
  5060. s += self.almanac(words)
  5061. elif 13 == page:
  5062. # 20.3.3.5.1.9 NMCT.
  5063. # 30 ERDs, but more sats. A sat skips own ERD.
  5064. # no ERD for sat 32
  5065. # erds are signed! 0x20 == NA
  5066. s += (" NMCT AI %u(%s)"
  5067. "\n ERD1: %s %s %s %s %s %s %s %s"
  5068. "\n ERD9: %s %s %s %s %s %s %s %s"
  5069. "\n ERD17: %s %s %s %s %s %s %s %s"
  5070. "\n ERD25: %s %s %s %s %s %s" %
  5071. ((words[2] >> 22) & 0x3, # AI
  5072. index_s((words[2] >> 22) & 0x3, self.nmct_ai),
  5073. erd_s((words[2] >> 16) & 0x3f), # erd1
  5074. erd_s((words[2] >> 8) & 0x3f),
  5075. erd_s((((words[2] >> 2) & 0x30) |
  5076. (words[3] >> 26) & 0x0f)),
  5077. erd_s((words[3] >> 20) & 0x3f),
  5078. erd_s((words[3] >> 14) & 0x3f), # erd5
  5079. erd_s((words[3] >> 8) & 0x3f),
  5080. erd_s((((words[3] >> 2) & 0x30) |
  5081. (words[4] >> 26) & 0x0f)),
  5082. erd_s((words[4] >> 20) & 0x3f),
  5083. erd_s((words[4] >> 14) & 0x3f), # erd9
  5084. erd_s((words[4] >> 8) & 0x3f),
  5085. erd_s((((words[4] >> 2) & 0x30) |
  5086. (words[5] >> 26) & 0x0f)),
  5087. erd_s((words[5] >> 20) & 0x3f),
  5088. erd_s((words[5] >> 14) & 0x3f), # erd 13
  5089. erd_s((words[5] >> 8) & 0x3f),
  5090. erd_s((((words[5] >> 2) & 0x30) |
  5091. (words[6] >> 26) & 0x0f)),
  5092. erd_s((words[6] >> 20) & 0x3f),
  5093. erd_s((words[6] >> 14) & 0x3f), # erd17
  5094. erd_s((words[6] >> 8) & 0x3f),
  5095. erd_s((((words[6] >> 2) & 0x30) |
  5096. (words[7] >> 26) & 0x0f)),
  5097. erd_s((words[7] >> 20) & 0x3f),
  5098. erd_s((words[7] >> 14) & 0x3f), # erd21
  5099. erd_s((words[7] >> 8) & 0x3f),
  5100. erd_s((((words[7] >> 2) & 0x30) |
  5101. (words[8] >> 26) & 0x0f)),
  5102. erd_s((words[8] >> 20) & 0x3f),
  5103. erd_s((words[8] >> 14) & 0x3f), # erd25
  5104. erd_s((words[8] >> 8) & 0x3f),
  5105. erd_s((((words[8] >> 2) & 0x30) |
  5106. (words[9] >> 26) & 0x0f)),
  5107. erd_s((words[9] >> 20) & 0x3f),
  5108. erd_s((words[9] >> 14) & 0x3f), # erd29
  5109. erd_s((words[9] >> 8) & 0x3f), # erd30
  5110. ))
  5111. elif 17 == page:
  5112. s += (" Special messages: " +
  5113. chr((words[2] >> 14) & 0xff) +
  5114. chr((words[2] >> 6) & 0xff) +
  5115. chr((words[3] >> 22) & 0xff) +
  5116. chr((words[3] >> 14) & 0xff) +
  5117. chr((words[3] >> 6) & 0xff) +
  5118. chr((words[4] >> 22) & 0xff) +
  5119. chr((words[4] >> 14) & 0xff) +
  5120. chr((words[4] >> 6) & 0xff) +
  5121. chr((words[5] >> 22) & 0xff) +
  5122. chr((words[5] >> 14) & 0xff) +
  5123. chr((words[5] >> 6) & 0xff) +
  5124. chr((words[6] >> 22) & 0xff) +
  5125. chr((words[6] >> 14) & 0xff) +
  5126. chr((words[6] >> 6) & 0xff) +
  5127. chr((words[7] >> 22) & 0xff) +
  5128. chr((words[7] >> 14) & 0xff) +
  5129. chr((words[7] >> 6) & 0xff) +
  5130. chr((words[8] >> 22) & 0xff) +
  5131. chr((words[8] >> 14) & 0xff) +
  5132. chr((words[8] >> 6) & 0xff) +
  5133. chr((words[9] >> 22) & 0xff) +
  5134. chr((words[9] >> 14) & 0xff))
  5135. elif 18 == page:
  5136. alpha1 = (words[2] >> 14) & 0xff
  5137. alpha0 = (words[2] >> 6) & 0xff
  5138. alpha2 = (words[3] >> 22) & 0xff
  5139. alpha3 = (words[3] >> 14) & 0xff
  5140. beta0 = (words[3] >> 6) & 0xff
  5141. beta1 = (words[4] >> 6) & 0xff
  5142. beta2 = (words[4] >> 22) & 0xff
  5143. beta3 = (words[4] >> 14) & 0xff
  5144. A1 = (words[5] >> 6) & 0xffffff
  5145. A0 = (((words[6] << 2) & 0xffffff00) |
  5146. ((words[7] >> 22) & 0xff))
  5147. tot = (words[7] >> 14) & 0xff
  5148. WNt = (words[7] >> 6) & 0xff
  5149. deltatls = (words[8] >> 22) & 0xff
  5150. WNlsf = (words[8] >> 14) & 0xff
  5151. DN = (words[8] >> 6) & 0xff
  5152. deltatlsf = (words[9] >> 22) & 0xff
  5153. s += (" Ionospheric and UTC data\n"
  5154. " alpah0 x%02x alpah1 x%02x "
  5155. "alpah2 x%02x alpah3 x%02x\n"
  5156. " beta0 x%02x beta1 x%02x "
  5157. "beta2 x%02x beta3 x%02x\n"
  5158. " A0 x%08x A1 x%06x tot x%02x WNt x%02x\n"
  5159. " deltatls x%02x WNlsf x%02x DN x%02x "
  5160. "deltatlsf x%02x" %
  5161. (alpha0, alpha1, alpha2, alpha3,
  5162. beta0, beta1, beta2, beta3,
  5163. A0, A1, tot, WNt,
  5164. deltatls, WNlsf, DN, deltatlsf))
  5165. elif 25 == page:
  5166. aspoof = []
  5167. aspoof.append((words[2] >> 18) & 0x0f)
  5168. aspoof.append((words[2] >> 14) & 0x0f)
  5169. aspoof.append((words[2] >> 10) & 0x0f)
  5170. aspoof.append((words[2] >> 6) & 0x0f)
  5171. for i in range(3, 7):
  5172. aspoof.append((words[i] >> 26) & 0x0f)
  5173. aspoof.append((words[i] >> 22) & 0x0f)
  5174. aspoof.append((words[i] >> 18) & 0x0f)
  5175. aspoof.append((words[i] >> 14) & 0x0f)
  5176. aspoof.append((words[i] >> 10) & 0x0f)
  5177. aspoof.append((words[i] >> 6) & 0x0f)
  5178. aspoof.append((words[7] >> 26) & 0x0f)
  5179. aspoof.append((words[7] >> 22) & 0x0f)
  5180. aspoof.append((words[7] >> 18) & 0x0f)
  5181. aspoof.append((words[7] >> 14) & 0x0f)
  5182. sv = []
  5183. sv.append((words[7] >> 6) & 0x3f)
  5184. sv.append((words[8] >> 24) & 0x3f)
  5185. sv.append((words[8] >> 18) & 0x3f)
  5186. sv.append((words[8] >> 12) & 0x3f)
  5187. sv.append((words[8] >> 6) & 0x3f)
  5188. sv.append((words[9] >> 24) & 0x3f)
  5189. sv.append((words[9] >> 18) & 0x3f)
  5190. sv.append((words[9] >> 12) & 0x3f)
  5191. s += (" A/S flags:\n"
  5192. " as01 x%x as02 x%x as03 x%x as04 x%x "
  5193. "as05 x%x as06 x%x as07 x%x as08 x%x\n"
  5194. " as09 x%x as10 x%x as11 x%x as12 x%x "
  5195. "as13 x%x as14 x%x as15 x%x as16 x%x\n"
  5196. " as17 x%x as18 x%x as19 x%x as20 x%x "
  5197. "as21 x%x as22 x%x as23 x%x as24 x%x\n"
  5198. " as25 x%x as26 x%x as27 x%x as28 x%x "
  5199. "as29 x%x as30 x%x as31 x%x as32 x%x\n" %
  5200. tuple(aspoof))
  5201. if gps.VERB_DECODE <= self.verbosity:
  5202. for i in range(1, 33):
  5203. f = aspoof[i - 1]
  5204. s += (" as%02d x%x (A-S %s, Conf %s)\n" %
  5205. (i, f,
  5206. 'On' if (f & 8) else 'Off',
  5207. index_s(f & 7, self.sv_conf)))
  5208. s += (" SV HEALTH:\n"
  5209. " sv25 x%2x sv26 x%2x sv27 x%2x sv28 x%2x "
  5210. "sv29 x%2x sv30 x%2x sv31 x%2x sv32 x%2x" %
  5211. tuple(sv))
  5212. else:
  5213. s += " Reserved"
  5214. elif 5 == subframe:
  5215. svid = (words[2] >> 22) & 0x3f
  5216. # 0 === svid is dummy SV
  5217. # almanac for dummy sat 0, same as transmitting sat
  5218. # Sec 3.2.1: "Users shall only use non-dummy satellites"
  5219. page = index_s(svid, self.sbfr5_svid_page)
  5220. s += ("\n dataid %u svid %u (page %s)\n" %
  5221. (words[2] >> 28, svid, page))
  5222. if 1 <= page <= 24:
  5223. s += self.almanac(words)
  5224. elif 25 == page:
  5225. toa = (words[2] >> 14) & 0xff
  5226. WNa = (words[2] >> 6) & 0xff
  5227. sv = []
  5228. for i in range(3, 9):
  5229. sv.append((words[i] >> 24) & 0x3f)
  5230. sv.append((words[i] >> 18) & 0x3f)
  5231. sv.append((words[i] >> 12) & 0x3f)
  5232. sv.append((words[i] >> 6) & 0x3f)
  5233. s += " SV HEALTH toa %u WNa %u\n" % (toa, WNa)
  5234. s += (" sv01 x%2x sv02 x%2x sv03 x%2x sv04 x%2x "
  5235. "sv05 x%2x sv06 x%2x sv07 x%2x sv08 x%2x\n"
  5236. " sv09 x%2x sv10 x%2x sv11 x%2x sv12 x%2x "
  5237. "sv13 x%2x sv14 x%2x sv15 x%2x sv16 x%2x\n"
  5238. " sv17 x%2x sv18 x%2x sv19 x%2x sv20 x%2x "
  5239. "sv21 x%2x sv22 x%2x sv23 x%2x sv24 x%2x" %
  5240. tuple(sv))
  5241. else:
  5242. s += " Reserved"
  5243. return s
  5244. def rxm_svsi(self, buf):
  5245. """UBX-RXM-SVSI decode, SV Status Info"""
  5246. m_len = len(buf)
  5247. u = struct.unpack_from('<LhBB', buf, 0)
  5248. s = ' iTOW %d week %d numVis %d numSV %d' % u
  5249. m_len -= 8
  5250. i = 0
  5251. while 0 < m_len:
  5252. u = struct.unpack_from('<BBhbB', buf, 8 + i * 6)
  5253. s += '\n svid %3d svFlag %#x azim %3d elev % 3d age %3d' % u
  5254. m_len -= 6
  5255. i += 1
  5256. return s
  5257. rxm_ids = {0x10: {'str': 'RAW', 'dec': rxm_raw, 'minlen': 8,
  5258. 'name': 'UBX-RXM-RAW'}, # obsolete
  5259. 0x11: {'str': 'SFRB', 'dec': rxm_sfrb, 'minlen': 42,
  5260. 'name': 'UBX-RXM-SFRB'},
  5261. 0x13: {'str': 'SFRBX', 'dec': rxm_sfrbx, 'minlen': 8,
  5262. 'name': 'UBX-RXM-SFRBX'},
  5263. 0x14: {'str': 'MEASX', 'dec': rxm_measx, 'minlen': 44,
  5264. 'name': 'UBX-RXM-MEASX'},
  5265. 0x15: {'str': 'RAWX', 'dec': rxm_rawx, 'minlen': 16,
  5266. 'name': 'UBX-RXM-RAWX'},
  5267. 0x20: {'str': 'SVSI', 'dec': rxm_svsi, 'minlen': 8,
  5268. 'name': 'UBX-RXM-SVSI'},
  5269. # deprecated in u-blox 6, 7, raw option only
  5270. 0x30: {'str': 'ALM', 'minlen': 1, 'name': 'UBX-RXM-ALM'},
  5271. # deprecated in u-blox 6, 7, raw option only
  5272. 0x31: {'str': 'EPH', 'minlen': 1, 'name': 'UBX-RXM-EPH'},
  5273. 0x32: {'str': 'RTCM', 'dec': rxm_rtcm, 'minlen': 8,
  5274. 'name': 'UBX-RXM-RTCM'},
  5275. 0x41: {'str': 'PMREQ', 'minlen': 8, 'name': 'UBX-RXM-PMREQ'},
  5276. 0x59: {'str': 'RLM', 'dec': rxm_rlm, 'minlen': 16,
  5277. 'name': 'UBX-RXM-RLM'},
  5278. 0x61: {'str': 'IMES', 'dec': rxm_imes, 'minlen': 4,
  5279. 'name': 'UBX-RXM-IMES'},
  5280. # NEO-D9S, 24 to 528 bytes
  5281. 0x72: {'str': 'PMP', 'minlen': 24, 'name': 'UBX-RXM-PMP'},
  5282. }
  5283. # UBX-SEC-
  5284. def sec_uniqid(self, buf):
  5285. """UBX-SEC_UNIQID decode Unique chip ID"""
  5286. # protVer 18 to 23
  5287. u = struct.unpack_from('<BBHBBBBB', buf, 0)
  5288. s = (" version %u reserved %u %u uniqueId %#02x%02x%02x%02x%02x"
  5289. % u)
  5290. return s
  5291. def sec_sign(self, buf):
  5292. """UBX-SEC_SIGN decode, Signature of a previous message"""
  5293. # protVer 18 to 23
  5294. u = struct.unpack_from('<BBHBBH', buf, 0)
  5295. s = (" version %u reserved %u %u classId x%x messageID x%x "
  5296. " checksum %u\n hash " % u)
  5297. s += gps.polystr(binascii.hexlify(buf[8:39]))
  5298. return s
  5299. sec_ids = {0x01: {'str': 'SIGN', 'minlen': 40, 'dec': sec_sign,
  5300. 'name': 'UBX-SEC-SIGN'},
  5301. 0x03: {'str': 'UNIQID', 'minlen': 9, 'dec': sec_uniqid,
  5302. 'name': 'UBX-SEC-UNIQID'},
  5303. }
  5304. # UBX-TIM-
  5305. def tim_svin(self, buf):
  5306. """UBX-TIM-SVIN decode, Survey-in data"""
  5307. u = struct.unpack_from('<LlllLLBB', buf, 0)
  5308. s = (' dur %u meanX %d meanY %d meanZ %d meanV %u\n'
  5309. ' obs %u valid %u active %u' % u)
  5310. return s
  5311. def tim_tm2(self, buf):
  5312. """UBX-TIM-TM2 decode, Time mark data"""
  5313. u = struct.unpack_from('<BBHHHLLLLL', buf, 0)
  5314. s = (' ch %u flags %#x count %u wnR %u wnF %u\n'
  5315. ' towMsR %u towSubMsR %u towMsF %u towSubMsF %u accEst %u\n' % u)
  5316. return s
  5317. def tim_tp(self, buf):
  5318. """UBX-TIM-TP decode, Time Pulse Timedata"""
  5319. u = struct.unpack_from('<LLlHbb', buf, 0)
  5320. s = (' towMS %u towSubMS %u qErr %d week %d\n'
  5321. ' flags %#x refInfo %#x\n flags ' % u)
  5322. if 0x01 & u[4]:
  5323. s += "timeBase is UTC, "
  5324. else:
  5325. s += "timeBase is GNSS, "
  5326. if 0x02 & u[4]:
  5327. s += "UTC available, "
  5328. else:
  5329. s += "UTC not available, "
  5330. raim = (u[4] >> 2) & 0x03
  5331. if 0 == raim:
  5332. s += "RAIM not available"
  5333. elif 1 == raim:
  5334. s += "RAIM not active"
  5335. elif 2 == raim:
  5336. s += "RAIM active"
  5337. else:
  5338. s += "RAIM ??"
  5339. return s
  5340. tim_vrfy_flags = {
  5341. 0: "no time aiding done",
  5342. 2: "source was RTC",
  5343. 3: "source was AID-IN",
  5344. }
  5345. def tim_vrfy(self, buf):
  5346. """UBX-TIM-VRFY decode, Sourced Time Verification"""
  5347. u = struct.unpack_from('<llllHBB', buf, 0)
  5348. s = (' itow %d frac %d deltaMs %d deltaMs %d\n'
  5349. ' wno %u flags x%x reserved1 %u' % u)
  5350. if gps.VERB_DECODE <= self.verbosity:
  5351. s += ('\n flags (%s)' %
  5352. index_s(u[5] & 3, self.tim_vrfy_flags))
  5353. return s
  5354. tim_ids = {0x01: {'str': 'TP', 'dec': tim_tp, 'minlen': 16,
  5355. 'name': 'UBX-TIM-TP'},
  5356. 0x03: {'str': 'TM2', 'dec': tim_tm2, 'minlen': 28,
  5357. 'name': 'UBX-TIM-TM2'},
  5358. 0x04: {'str': 'SVIN', 'dec': tim_svin, 'minlen': 28,
  5359. 'name': 'UBX-TIM-SVIN'},
  5360. 0x06: {'str': 'VRFY', 'dec': tim_vrfy, 'minlen': 20,
  5361. 'name': 'UBX-TIM-VRFY'},
  5362. # u-blox 8, FTS only
  5363. 0x11: {'str': 'DOSC', 'minlen': 8, 'name': 'UBX-TIM-DOSC'},
  5364. # u-blox 8, FTS only
  5365. 0x12: {'str': 'TOS', 'minlen': 56, 'name': 'UBX-TIM-TOS'},
  5366. # u-blox 8, FTS only
  5367. 0x13: {'str': 'SMEAS', 'minlen': 12, 'name': 'UBX-TIM-SMEAS'},
  5368. # u-blox 8, FTS only
  5369. 0x15: {'str': 'VCOCAL', 'minlen': 1, 'name': 'UBX-TIM-VCOCAL'},
  5370. # u-blox 8, FTS only
  5371. 0x16: {'str': 'FCHG', 'minlen': 32, 'name': 'UBX-TIM-FCHG'},
  5372. # u-blox 8, FTS only
  5373. 0x17: {'str': 'HOC', 'minlen': 8, 'name': 'UBX-TIM-HOC'},
  5374. }
  5375. # UBX-UPD-
  5376. upd_sos_cmd = {
  5377. 0: "Create Backup File in Flash",
  5378. 1: "Clear Backup in Flash",
  5379. 2: "Backup File Creation Acknowledge",
  5380. 3: "System Restored from Backup",
  5381. }
  5382. upd_sos_response2 = {
  5383. 0: "Not Acknowledged",
  5384. 1: "Acknowledged",
  5385. }
  5386. upd_sos_response3 = {
  5387. 0: "Unknown",
  5388. 1: "Failed restoring from backup file",
  5389. 2: "Restored from backup file",
  5390. 3: "Not restored (no backup)",
  5391. }
  5392. def upd_sos(self, buf):
  5393. """UBX-UPD-SOS decode, Backup File stuff"""
  5394. m_len = len(buf)
  5395. if 0 == m_len:
  5396. return " Poll Backup File Restore Status"
  5397. if 4 > m_len:
  5398. return " Bad Length %s" % m_len
  5399. u = struct.unpack_from('<BBH', buf, 0)
  5400. s = ' command %u reserved1 x%x %x' % u
  5401. s1 = ""
  5402. if 0 == u[0]:
  5403. # Create Backup in Flash
  5404. pass
  5405. elif 1 == u[0]:
  5406. # Clear Backup in Flash
  5407. pass
  5408. elif 8 > m_len:
  5409. s += " Bad Length %s" % m_len
  5410. elif 2 == u[0]:
  5411. # Backup File Creation Acknowledge
  5412. u1 = struct.unpack_from('<BBH', buf, 4)
  5413. s += '\n response %u reserved2 x%x %x' % u1
  5414. s1 = ' response (%s)' % index_s(u1[0], self.upd_sos_response2)
  5415. elif 3 == u[0]:
  5416. # System Restored from Backup
  5417. u1 = struct.unpack_from('<BBH', buf, 4)
  5418. s += '\n response %u reserved2 x%x %x' % u1
  5419. s1 = ' response (%s)' % index_s(u1[0], self.upd_sos_response3)
  5420. if gps.VERB_DECODE <= self.verbosity:
  5421. s += '\n cmd (%s)%s' % (index_s(u[0], self.upd_sos_cmd), s1)
  5422. return s
  5423. upd_ids = {
  5424. # undocumented firmware update message
  5425. 0x0c: {'str': 'undoc1', 'minlen': 13, 'name': "UBX-UPD-undoc1"},
  5426. 0x14: {'str': 'SOS', 'dec': upd_sos, 'name': "UBX-UPD-SOS"},
  5427. # undocumented firmware update message
  5428. 0x25: {'str': 'undoc2', 'minlen': 20, 'name': "UBX-UPD-undoc2"},
  5429. }
  5430. classes = {
  5431. 0x01: {'str': 'NAV', 'ids': nav_ids},
  5432. 0x02: {'str': 'RXM', 'ids': rxm_ids},
  5433. 0x04: {'str': 'INF', 'ids': inf_ids},
  5434. 0x05: {'str': 'ACK', 'ids': ack_ids},
  5435. 0x06: {'str': 'CFG', 'ids': cfg_ids},
  5436. 0x09: {'str': 'UPD', 'ids': upd_ids},
  5437. 0x0A: {'str': 'MON', 'ids': mon_ids},
  5438. 0x0B: {'str': 'AID', 'ids': aid_ids},
  5439. 0x0D: {'str': 'TIM', 'ids': tim_ids},
  5440. 0x10: {'str': 'ESF', 'ids': esf_ids},
  5441. 0x13: {'str': 'MGA', 'ids': mga_ids},
  5442. 0x21: {'str': 'LOG', 'ids': log_ids},
  5443. 0x27: {'str': 'SEC', 'ids': sec_ids},
  5444. 0x28: {'str': 'HNR', 'ids': hnr_ids},
  5445. # Antaris 4
  5446. # 0x4x USR, SCK Customer Messages
  5447. 0xf0: {'str': 'NMEA', 'ids': nmea_ids},
  5448. 0xf5: {'str': 'RTCM', 'ids': rtcm_ids},
  5449. }
  5450. def class_id_s(self, m_class, m_id):
  5451. """Return class and ID numbers as a string."""
  5452. s = 'Class x%02x' % (m_class)
  5453. if (((m_class in self.classes and
  5454. 'str' in self.classes[m_class]))):
  5455. s += ' (%s)' % (self.classes[m_class]['str'])
  5456. s += ' ID x%02x' % (m_id)
  5457. if (((m_class in self.classes and
  5458. 'ids' in self.classes[m_class] and
  5459. m_id in self.classes[m_class]['ids'] and
  5460. 'str' in self.classes[m_class]['ids'][m_id]))):
  5461. s += ' (%s)' % (self.classes[m_class]['ids'][m_id]['str'])
  5462. return s
  5463. def decode_msg(self, out):
  5464. """Decode one message and then return number of chars consumed"""
  5465. state = 'BASE'
  5466. consumed = 0
  5467. # decode state machine
  5468. for this_byte in out:
  5469. consumed += 1
  5470. if isinstance(this_byte, str):
  5471. # a character, probably read from a file
  5472. c = ord(this_byte)
  5473. else:
  5474. # a byte, probably read from a serial port
  5475. c = int(this_byte)
  5476. if gps.VERB_RAW <= self.verbosity:
  5477. if ord(' ') <= c <= ord('~'):
  5478. # c is printable
  5479. print("state: %s char %c (%#x)" % (state, chr(c), c))
  5480. else:
  5481. # c is not printable
  5482. print("state: %s char %#x" % (state, c))
  5483. if 'BASE' == state:
  5484. # start fresh
  5485. # place to store 'comments'
  5486. comment = ''
  5487. m_class = 0
  5488. m_id = 0
  5489. m_len = 0
  5490. m_raw = bytearray(0) # class, id, len, payload
  5491. m_payload = bytearray(0) # just the payload
  5492. m_ck_a = 0
  5493. m_ck_b = 0
  5494. if 0xb5 == c:
  5495. # got header 1, mu
  5496. state = 'HEADER1'
  5497. if ord('$') == c:
  5498. # got $, so NMEA?
  5499. state = 'NMEA'
  5500. comment = '$'
  5501. if ord("{") == c:
  5502. # JSON, treat as comment line
  5503. state = 'JSON'
  5504. # start fresh
  5505. comment = "{"
  5506. continue
  5507. if ord("#") == c:
  5508. # comment line
  5509. state = 'COMMENT'
  5510. # start fresh
  5511. comment = "#"
  5512. continue
  5513. if 0xd3 == c:
  5514. # RTCM3 Leader 1
  5515. state = 'RTCM3_1'
  5516. # start fresh
  5517. comment = "#"
  5518. continue
  5519. if (ord('\n') == c) or (ord('\r') == c):
  5520. # CR or LF, leftovers
  5521. return 1
  5522. continue
  5523. if state in ('COMMENT', 'JSON'):
  5524. # inside comment
  5525. if ord('\n') == c or ord('\r') == c:
  5526. # Got newline or linefeed
  5527. # terminate messages on <CR> or <LF>
  5528. # Done, got a full message
  5529. if gps.polystr('{"class":"ERROR"') in comment:
  5530. # always print gpsd errors
  5531. if 0 < self.timestamp:
  5532. timestamp(self.timestamp)
  5533. print(comment)
  5534. elif gps.VERB_DECODE <= self.verbosity:
  5535. if 0 < self.timestamp:
  5536. timestamp(self.timestamp)
  5537. print(comment)
  5538. return consumed
  5539. # else:
  5540. comment += chr(c)
  5541. continue
  5542. if 'NMEA' == state:
  5543. # getting NMEA payload
  5544. if (ord('\n') == c) or (ord('\r') == c):
  5545. # CR or LF, done, got a full message
  5546. # terminates messages on <CR> or <LF>
  5547. if gps.VERB_DECODE <= self.verbosity:
  5548. if 0 < self.timestamp:
  5549. timestamp(self.timestamp)
  5550. print(comment)
  5551. return consumed
  5552. # else:
  5553. comment += chr(c)
  5554. continue
  5555. if 'RTCM3_1' == state:
  5556. # high 6 bits must be zero,
  5557. if 0 != (c & 0xfc):
  5558. state = 'BASE'
  5559. else:
  5560. # low 2 bits are MSB of a 10-bit length
  5561. m_len = c << 8
  5562. state = 'RTCM3_2'
  5563. m_raw.extend([c])
  5564. continue
  5565. if 'RTCM3_2' == state:
  5566. # 8 bits are LSB of a 10-bit length
  5567. m_len |= 0xff & c
  5568. # add 3 for checksum
  5569. m_len += 3
  5570. state = 'RTCM3_PAYLOAD'
  5571. m_raw.extend([c])
  5572. continue
  5573. if 'RTCM3_PAYLOAD' == state:
  5574. m_len -= 1
  5575. m_raw.extend([c])
  5576. m_payload.extend([c])
  5577. if 0 == m_len:
  5578. state = 'BASE'
  5579. ptype = m_payload[0] << 4
  5580. ptype |= 0x0f & (m_payload[1] >> 4)
  5581. if gps.VERB_DECODE <= self.verbosity:
  5582. print("RTCM3 packet: type %d\n" % ptype)
  5583. continue
  5584. if ord('b') == c and 'HEADER1' == state:
  5585. # got header 2
  5586. state = 'HEADER2'
  5587. continue
  5588. if 'HEADER2' == state:
  5589. # got class
  5590. state = 'CLASS'
  5591. m_class = c
  5592. m_raw.extend([c])
  5593. continue
  5594. if 'CLASS' == state:
  5595. # got ID
  5596. state = 'ID'
  5597. m_id = c
  5598. m_raw.extend([c])
  5599. continue
  5600. if 'ID' == state:
  5601. # got first length
  5602. state = 'LEN1'
  5603. m_len = c
  5604. m_raw.extend([c])
  5605. continue
  5606. if 'LEN1' == state:
  5607. # got second length
  5608. m_raw.extend([c])
  5609. m_len += 256 * c
  5610. if 0 == m_len:
  5611. # no payload
  5612. state = 'CSUM1'
  5613. else:
  5614. state = 'PAYLOAD'
  5615. continue
  5616. if 'PAYLOAD' == state:
  5617. # getting payload
  5618. m_raw.extend([c])
  5619. m_payload.extend([c])
  5620. if len(m_payload) == m_len:
  5621. state = 'CSUM1'
  5622. continue
  5623. if 'CSUM1' == state:
  5624. # got ck_a
  5625. state = 'CSUM2'
  5626. m_ck_a = c
  5627. continue
  5628. if 'CSUM2' == state:
  5629. # got a complete, maybe valid, message
  5630. if 0 < self.timestamp:
  5631. timestamp(self.timestamp)
  5632. # ck_b
  5633. state = 'BASE'
  5634. m_ck_b = c
  5635. # check checksum
  5636. chk = self.checksum(m_raw, len(m_raw))
  5637. if (chk[0] != m_ck_a) or (chk[1] != m_ck_b):
  5638. print("%s: ERROR checksum failed,"
  5639. "was (%d,%d) s/b (%d, %d)\n" %
  5640. (PROG_NAME, m_ck_a, m_ck_b, chk[0], chk[1]))
  5641. s_payload = ''.join('{:02x} '.format(x) for x in m_payload)
  5642. x_payload = ','.join(['%02x' % x for x in m_payload])
  5643. if m_class in self.classes:
  5644. this_class = self.classes[m_class]
  5645. if 'ids' in this_class:
  5646. if m_id in this_class['ids']:
  5647. # got an entry for this message
  5648. # name is mandatory
  5649. s_payload = this_class['ids'][m_id]['name']
  5650. s_payload += ':\n'
  5651. if ((('minlen' in this_class['ids'][m_id]) and
  5652. (0 == m_len) and
  5653. (0 != this_class['ids'][m_id]['minlen']))):
  5654. s_payload += " Poll request"
  5655. elif (('minlen' in this_class['ids'][m_id]) and
  5656. (this_class['ids'][m_id]['minlen'] >
  5657. m_len)):
  5658. # failed minimum length for this message
  5659. s_payload += " Bad Length %s" % m_len
  5660. elif 'dec' in this_class['ids'][m_id]:
  5661. # got a decoder for this message
  5662. dec = this_class['ids'][m_id]['dec']
  5663. s_payload += dec(self, m_payload)
  5664. else:
  5665. s_payload += (" len %#x, raw %s" %
  5666. (m_len, x_payload))
  5667. if not s_payload:
  5668. # huh?
  5669. s_payload = ("%s, len %#x, raw %s" %
  5670. (self.class_id_s(m_class, m_id),
  5671. m_len, x_payload))
  5672. if gps.VERB_INFO <= self.verbosity:
  5673. print("%s, len: %#x" %
  5674. (self.class_id_s(m_class, m_id), m_len))
  5675. x_raw = ','.join(['%02x' % x for x in m_raw[0:4]])
  5676. print("header: b5,62,%s" % x_raw)
  5677. print("payload: %s" % x_payload)
  5678. print("chksum: %02x,%02x" % (m_ck_a, m_ck_b))
  5679. print("%s\n" % s_payload)
  5680. return consumed
  5681. # give up
  5682. state = 'BASE'
  5683. # fell out of loop, no more chars to look at
  5684. return 0
  5685. def checksum(self, msg, m_len):
  5686. """Calculate u-blox message checksum"""
  5687. # the checksum is calculated over the Message, starting and including
  5688. # the CLASS field, up until, but excluding, the Checksum Field:
  5689. ck_a = 0
  5690. ck_b = 0
  5691. for c in msg[0:m_len]:
  5692. ck_a += c
  5693. ck_b += ck_a
  5694. return [ck_a & 0xff, ck_b & 0xff]
  5695. def make_pkt(self, m_class, m_id, m_data):
  5696. """Make a message packet"""
  5697. # always little endian, leader, class, id, length
  5698. m_len = len(m_data)
  5699. # build core message
  5700. msg = bytearray(m_len + 6)
  5701. struct.pack_into('<BBH', msg, 0, m_class, m_id, m_len)
  5702. # copy payload into message buffer
  5703. i = 0
  5704. while i < m_len:
  5705. msg[i + 4] = m_data[i]
  5706. i += 1
  5707. # add checksum
  5708. chk = self.checksum(msg, m_len + 4)
  5709. m_chk = bytearray(2)
  5710. struct.pack_into('<BB', m_chk, 0, chk[0], chk[1])
  5711. header = b"\xb5\x62"
  5712. return header + msg[:m_len + 4] + m_chk
  5713. def gps_send(self, m_class, m_id, m_data):
  5714. """Build, and send, a message to GPS"""
  5715. m_all = self.make_pkt(m_class, m_id, m_data)
  5716. self.gps_send_raw(m_all)
  5717. def gps_send_raw(self, m_all):
  5718. """Send a raw message to GPS"""
  5719. if not self.read_only:
  5720. self.io_handle.ser.write(m_all)
  5721. if gps.VERB_QUIET < self.verbosity:
  5722. sys.stdout.write("sent:\n")
  5723. if gps.VERB_INFO < self.verbosity:
  5724. sys.stdout.write(gps.polystr(binascii.hexlify(m_all)))
  5725. sys.stdout.write("\n")
  5726. self.decode_msg(m_all)
  5727. sys.stdout.flush()
  5728. def send_able_cfg_batch(self, able, args):
  5729. """dis/enable batching, UBX-CFG-BATCH"""
  5730. flags = 0x0d if able else 0x0c
  5731. m_data = []
  5732. struct.pack_into('<BBHHBB', m_data, 0, 0, flags, 128, 0, 0, 0)
  5733. self.gps_send(6, 0x93, m_data)
  5734. def send_able_beidou(self, able, args):
  5735. """dis/enable BeiDou"""
  5736. # Two frequency GNSS receivers use BeiDou or GLONASS
  5737. # disable, then enable
  5738. self.send_cfg_gnss1(3, able, args)
  5739. def send_able_binary(self, able, args):
  5740. """dis/enable basic binary messages. -e/-d BINARY"""
  5741. # FIXME: does not change UBX-CFG-PRT outProtoMask for current port.
  5742. # FIXME: in u-blox 9, use VAL-SET to ensure NMEA mask on.
  5743. # Workarouund: gpsctl -b
  5744. # try to keep in sync with driver_ubx.c, ubx_cfg_prt()
  5745. # UBX-NAV we always toggle
  5746. # we assume no oddball UBX to toggle
  5747. ubx_nav_toggle = (
  5748. 0x04, # msg id = UBX-NAV-DOP
  5749. # UBX-NAV-TIMEGPS
  5750. # Note: UTC may, or may not be UBX-NAV-TIMEGPS.
  5751. # depending on UBX-CFG-NAV5 utcStandard
  5752. # Note: We use TIMEGPS to get the leapS
  5753. # UBX-NAV-TIMEGPS is a great cycle ender, NAV-EOE better
  5754. 0x20, # msg id = UBX-NAV-TIMEGPS
  5755. )
  5756. # UBX for protver < 15
  5757. ubx_14_nav_on = (
  5758. # UBX-NAV-SOL is ECEF. deprecated in protver 14, gone in protver 27
  5759. 0x06, # msg id = NAV-SOL
  5760. 0x30, # msg id = NAV-SVINFO
  5761. )
  5762. # UBX for protver >= 15
  5763. ubx_15_nav_on = (
  5764. # Need NAV-POSECEF, NAV-VELECEF and NAV-PVT to replace NAV-SOL
  5765. 0x01, # msg id = NAV-POSECEF
  5766. 0x07, # msg id = NAV-PVT
  5767. 0x11, # msg id = NAV-VELECEF
  5768. 0x35, # msg id = NAV-SAT
  5769. 0x61, # msg id = NAV-EOE, first in protver 18
  5770. )
  5771. # some we always turn off, user can enable later
  5772. ubx_nav_off = (
  5773. 0x12, # msg id = NAV-VELNED
  5774. # turn off NAV-SBAS as the gpsd decode does not go to JSON,
  5775. # so the data is wasted. */
  5776. 0x32, # msg id = NAV-SBAS, in u-blox 4 to 8, not 9
  5777. )
  5778. rate = 1 if able else 0
  5779. # msgClass (UBX-NAV), msgID, rate
  5780. m_data = bytearray([0x01, 0x09, rate])
  5781. for id in ubx_nav_toggle:
  5782. m_data[1] = id
  5783. # UBX-CFG-MSG
  5784. self.gps_send(6, 1, m_data)
  5785. if 15 > self.protver:
  5786. for id in ubx_14_nav_on:
  5787. m_data[1] = id
  5788. # UBX-CFG-MSG
  5789. self.gps_send(6, 1, m_data)
  5790. # turn off >= 15 messages. Yes this makes NAKs.
  5791. m_data[2] = 0 # rate off
  5792. for id in ubx_15_nav_on:
  5793. m_data[1] = id
  5794. # UBX-CFG-MSG
  5795. self.gps_send(6, 1, m_data)
  5796. else:
  5797. for id in ubx_15_nav_on:
  5798. m_data[1] = id
  5799. # UBX-CFG-MSG
  5800. self.gps_send(6, 1, m_data)
  5801. # turn off < 15 messages. Yes this may make NAKs.
  5802. m_data[2] = 0 # rate off
  5803. for id in ubx_14_nav_on:
  5804. m_data[1] = id
  5805. # UBX-CFG-MSG
  5806. self.gps_send(6, 1, m_data)
  5807. # msgClass (UBX-NAV), msgID (TIMELS), rate (0xff)
  5808. # 0xff is about every 4 minutes if nav rate is 1Hz
  5809. m_data = bytearray([0x01, 0x26, 0xff])
  5810. # UBX-CFG-MSG
  5811. self.gps_send(6, 1, m_data)
  5812. # always off NAV messages
  5813. m_data[2] = 0 # rate off
  5814. for id in ubx_nav_off:
  5815. m_data[1] = id
  5816. # UBX-CFG-MSG
  5817. self.gps_send(6, 1, m_data)
  5818. def send_able_ecef(self, able, args):
  5819. """Enable ECEF messages"""
  5820. # set NAV-POSECEF rate
  5821. self.send_cfg_msg(1, 1, able)
  5822. # set NAV-VELECEF rate
  5823. self.send_cfg_msg(1, 0x11, able)
  5824. def send_able_gps(self, able, args):
  5825. """dis/enable GPS/QZSS"""
  5826. # GPS and QZSS both on, or both off, together
  5827. # GPS
  5828. self.send_cfg_gnss1(0, able, args)
  5829. # QZSS
  5830. self.send_cfg_gnss1(5, able, args)
  5831. def send_able_galileo(self, able, args):
  5832. """dis/enable GALILEO"""
  5833. self.send_cfg_gnss1(2, able, args)
  5834. def send_able_glonass(self, able, args):
  5835. """dis/enable GLONASS"""
  5836. # Two frequency GPS use BeiDou or GLONASS
  5837. # disable, then enable
  5838. self.send_cfg_gnss1(6, able, args)
  5839. def send_able_logfilter(self, able, args):
  5840. """Enable logging"""
  5841. if able:
  5842. m_data = bytearray([1, # version
  5843. 5, # flags
  5844. # All zeros below == log all
  5845. 0, 0, # minInterval
  5846. 0, 0, # timeThreshold
  5847. 0, 0, # speedThreshold
  5848. 0, 0, 0, 0 # positionThreshold
  5849. ])
  5850. else:
  5851. m_data = bytearray([1, # version
  5852. 0, # flags
  5853. 0, 0, # minInterval
  5854. 0, 0, # timeThreshold
  5855. 0, 0, # speedThreshold
  5856. 0, 0, 0, 0 # positionThreshold
  5857. ])
  5858. # set UBX-CFG-LOGFILTER
  5859. self.gps_send(6, 0x47, m_data)
  5860. def send_able_ned(self, able, args):
  5861. """Enable NAV-RELPOSNED and VELNED messages.
  5862. protver 15+ required for VELNED
  5863. protver 20+, and HP GNSS, required for RELPOSNED"""
  5864. if 15 > self.protver:
  5865. sys.stderr.write('%s: WARNING: protver %d too low for NED\n' %
  5866. (PROG_NAME, self.protver))
  5867. return
  5868. # set NAV-VELNED rate
  5869. self.send_cfg_msg(1, 0x12, able)
  5870. if 20 > self.protver:
  5871. sys.stderr.write('%s: WARNING: protver %d too low for '
  5872. 'RELPOSNED\n' %
  5873. (PROG_NAME, self.protver))
  5874. return
  5875. # set NAV-RELPOSNED rate
  5876. self.send_cfg_msg(1, 0x3C, able)
  5877. def send_able_nmea(self, able, args):
  5878. """dis/enable basic NMEA messages"""
  5879. # try to keep in sync with driver_ubx.c, ubx_cfg_prt()
  5880. # FIXME: does not change UBX-CFG-PRT outProtoMask for current port.
  5881. # FIXME: in u-blox 9, use VAL-SET to ensure NMEA mask on.
  5882. # Workarouund: gpsctl -n
  5883. # we assume no oddball NMEA to toggle
  5884. nmea_toggle = (
  5885. 0x00, # msg id = GGA
  5886. # 0x01, # msg id = GLL, only need RMC */
  5887. 0x02, # msg id = GSA
  5888. 0x03, # msg id = GSV
  5889. 0x04, # msg id = RMC
  5890. 0x05, # msg id = VTG
  5891. 0x07, # msg id = GST, GNSS pseudorange error statistics
  5892. 0x08, # msg id = ZDA, for UTC year
  5893. 0x09, # msg id = GBS, for RAIM errors
  5894. )
  5895. rate = 1 if able else 0
  5896. # msgClass (UBX-NMEA), msgID, rate
  5897. m_data = bytearray([0xf0, 0x09, rate])
  5898. for id in nmea_toggle:
  5899. m_data[1] = id
  5900. # UBX-CFG-MSG
  5901. self.gps_send(6, 1, m_data)
  5902. # xxGLL, never need it
  5903. m_data = bytearray([0xf0, 0x01, 0])
  5904. self.gps_send(6, 1, m_data)
  5905. def send_able_rtcm3(self, able, args):
  5906. """dis/enable RTCM3 1005, 1077, 1087, 1230 messages"""
  5907. # protVer 20+, High Precision only
  5908. # No u-blox outputs RTCM2
  5909. # USB ONLY!
  5910. if able:
  5911. rate = 1
  5912. # UBX-CFG-PRT, USB
  5913. # can't really do other portIDs as the messages are different
  5914. # and need data we do not have.
  5915. # does not seem to hurt to enable all in and out, even unsupported
  5916. m_data = bytearray(20)
  5917. m_data[0] = 0x03 # default to USB port
  5918. m_data[12] = 0x27 # in: RTCM3, RTCM2, NMEA and UBX
  5919. # Ensures RTCM3 output (all) are set (outProtoMask)
  5920. # no u-blox has RTCM2 out
  5921. m_data[14] = 0x23 # out: RTCM3, NMEA and UBX
  5922. self.gps_send(0x06, 0x00, m_data)
  5923. else:
  5924. # leave UBX-CFG-PRT alone
  5925. rate = 0
  5926. # 1005, Stationary RTK reference station ARP
  5927. m_data = bytearray([0xf5, 0x05, rate])
  5928. self.gps_send(6, 1, m_data)
  5929. # 1077, GPS MSM7
  5930. m_data = bytearray([0xf5, 0x4d, rate])
  5931. self.gps_send(6, 1, m_data)
  5932. # 1087, GLONASS MSM7
  5933. m_data = bytearray([0xf5, 0x57, rate])
  5934. self.gps_send(6, 1, m_data)
  5935. # 1230, GLONASS code-phase biases
  5936. m_data = bytearray([0xf5, 0xe6, rate])
  5937. self.gps_send(6, 1, m_data)
  5938. # we skip Galileo or BeiDou for now, unsupported by u-blox rover
  5939. # ZED-F9P rover requires MSM7 and 4072,0 or 4072,1
  5940. # 4072,0
  5941. m_data = bytearray([0xf5, 0xfe, rate])
  5942. # 4072,1
  5943. m_data = bytearray([0xf5, 0xfd, rate])
  5944. self.gps_send(6, 1, m_data)
  5945. def send_able_rawx(self, able, args):
  5946. """dis/enable UBX-RXM-RAW/RAWXX"""
  5947. rate = 1 if able else 0
  5948. if 15 > self.protver:
  5949. # u-blox 7 or earlier, use RAW
  5950. sid = 0x10
  5951. else:
  5952. # u-blox 8 or later, use RAWX
  5953. sid = 0x15
  5954. m_data = bytearray([0x2, sid, rate])
  5955. self.gps_send(6, 1, m_data)
  5956. def send_able_pps(self, able, args):
  5957. """dis/enable PPS, using UBX-CFG-TP5"""
  5958. m_data = bytearray(32)
  5959. m_data[0] = 0 # tpIdx
  5960. m_data[1] = 1 # version
  5961. m_data[2] = 0 # reserved
  5962. m_data[3] = 0 # reserved
  5963. m_data[4] = 2 # antCableDelay
  5964. m_data[5] = 0 # antCableDelay
  5965. m_data[6] = 0 # rfGroupDelay
  5966. m_data[7] = 0 # rfGroupDelay
  5967. m_data[8] = 0x40 # freqPeriod
  5968. m_data[9] = 0x42 # freqPeriod
  5969. m_data[10] = 0x0f # freqPeriod
  5970. m_data[11] = 0 # freqPeriod
  5971. m_data[12] = 0x40 # freqPeriodLock
  5972. m_data[13] = 0x42 # freqPeriodLock
  5973. m_data[14] = 0x0f # freqPeriodLock
  5974. m_data[15] = 0 # freqPeriodLock
  5975. m_data[16] = 0 # pulseLenRatio
  5976. m_data[17] = 0 # pulseLenRatio
  5977. m_data[18] = 0 # pulseLenRatio
  5978. m_data[19] = 0 # pulseLenRatio
  5979. m_data[20] = 0xa0 # pulseLenRatioLock
  5980. m_data[21] = 0x86 # pulseLenRatioLock
  5981. m_data[22] = 0x1 # pulseLenRatioLock
  5982. m_data[23] = 0 # pulseLenRatioLock
  5983. m_data[24] = 0 # userConfigDelay
  5984. m_data[25] = 0 # userConfigDelay
  5985. m_data[26] = 0 # userConfigDelay
  5986. m_data[27] = 0 # userConfigDelay
  5987. m_data[28] = 0x77 # flags
  5988. m_data[29] = 0 # flags
  5989. m_data[30] = 0 # flags
  5990. m_data[31] = 0 # flags
  5991. if not able:
  5992. m_data[28] &= ~1 # bit 0 is active
  5993. self.gps_send(6, 0x31, m_data)
  5994. def send_able_sbas(self, able, args):
  5995. """dis/enable SBAS"""
  5996. self.send_cfg_gnss1(1, able, args)
  5997. def send_able_sfrbx(self, able, args):
  5998. """dis/enable UBX-RXM-SFRB/SFRBX"""
  5999. rate = 1 if able else 0
  6000. if 15 > self.protver:
  6001. # u-blox 7 or earlier, use SFRB
  6002. sid = 0x11
  6003. else:
  6004. # u-blox 8 or later, use SFRBX
  6005. sid = 0x13
  6006. m_data = bytearray([0x2, sid, rate])
  6007. self.gps_send(6, 1, m_data)
  6008. def send_able_tmode2(self, able, args):
  6009. """SURVEYIN, UBX-CFG-TMODE2, set time mode 2 config"""
  6010. m_data = bytearray(28)
  6011. # on a NEO-M8T, with good antenna
  6012. # five minutes, gets about 1 m
  6013. # ten minutes, gets about 0.9 m
  6014. # twenty minutes, gets about 0.7 m
  6015. # one hour, gets about 0.5 m
  6016. # twelve hours, gets about 0.14 m
  6017. # Survey-in minimum duration seconds
  6018. seconds = 300
  6019. # Survey-in position accuracy limit in mm
  6020. # make it big, so the duration decides when to end survey
  6021. mmeters = 50000 # default 50 meters
  6022. if able:
  6023. # enable survey-in
  6024. m_data[0] = 1
  6025. if args and len(args[0]):
  6026. seconds = int(args[0])
  6027. if 1 < len(args) and len(args[1]):
  6028. mmeters = int(args[1])
  6029. struct.pack_into('<LL', m_data, 20, seconds, mmeters)
  6030. self.gps_send(6, 0x3d, m_data)
  6031. def send_able_tmode3(self, able, args):
  6032. """SURVEYIN3, UBX-CFG-TMODE3, set time mode 3 config"""
  6033. m_data = bytearray(40)
  6034. # Survey-in minimum duration seconds
  6035. seconds = 300
  6036. # Survey-in position accuracy limit in 0.1mm
  6037. # make it big, so the duration decides when to end survey
  6038. # mmeters is 5m!
  6039. mmeters = 500000 # default 50 meters
  6040. if able:
  6041. # enable survey-in
  6042. m_data[2] = 1
  6043. if args and len(args[0]):
  6044. seconds = int(args[0])
  6045. if 1 < len(args) and len(args[1]):
  6046. mmeters = int(args[1])
  6047. struct.pack_into('<LL', m_data, 24, seconds, mmeters)
  6048. self.gps_send(6, 0x71, m_data)
  6049. def send_able_tp(self, able, args):
  6050. """dis/enable UBX-TIM-TP Time Pulse"""
  6051. rate = 1 if able else 0
  6052. m_data = bytearray([0xd, 0x1, rate])
  6053. self.gps_send(6, 1, m_data)
  6054. def send_cfg_cfg(self, save_clear, args=[]):
  6055. """UBX-CFG-CFG, save config"""
  6056. # Save: save_clear = 0
  6057. # Clear: save_clear = 1
  6058. # basic configs always available to change:
  6059. # ioPort = 1, msgConf = 2, infMsg = 4, navConf = 8, rxmConf =0x10
  6060. cfg1 = 0x1f
  6061. # senConf = 1, rinvConf = 2, antConf = 4, logConf = 8, ftsConf = 0x10
  6062. cfg2 = 0x0f
  6063. m_data = bytearray(13)
  6064. # clear mask
  6065. # as of protver 27, any bit in clearMask clears all
  6066. if 0 == save_clear:
  6067. # saving, so do not clear
  6068. m_data[0] = 0
  6069. m_data[1] = 0
  6070. else:
  6071. # clearing
  6072. m_data[0] = cfg1
  6073. m_data[1] = cfg2
  6074. m_data[2] = 0 #
  6075. m_data[3] = 0 #
  6076. # save mask
  6077. # as of protver 27, any bit in saveMask saves all
  6078. if 0 == save_clear:
  6079. # saving
  6080. m_data[4] = cfg1
  6081. m_data[5] = cfg2
  6082. else:
  6083. # clearing, so do not save
  6084. m_data[4] = 0
  6085. m_data[5] = 0
  6086. m_data[6] = 0 #
  6087. m_data[7] = 0 #
  6088. # load mask
  6089. # as of protver 27, any bit in loadMask loads all
  6090. if False and 0 == save_clear:
  6091. # saving
  6092. m_data[8] = 0
  6093. m_data[9] = 0
  6094. else:
  6095. # clearing, load it to save a reboot
  6096. m_data[8] = cfg1
  6097. m_data[9] = cfg2
  6098. m_data[10] = 0 #
  6099. m_data[11] = 0 #
  6100. # deviceMask, where to save it, try all options
  6101. # devBBR = 1, devFLASH = 2, devEEPROM = 4, devSpiFlash = 0x10
  6102. m_data[12] = 0x17
  6103. self.gps_send(6, 0x9, m_data)
  6104. def send_cfg_gnss1(self, gnssId, enable, args):
  6105. """UBX-CFG-GNSS, set GNSS config
  6106. WARNING: the receiver will ACK, then ignore, many seemingly valid settings.
  6107. Always double check with "-p CFG-GNSS".
  6108. """
  6109. # FIXME! Add warning if ,2 is requested on single frequency devices
  6110. # Only u-blox 9 supports L2, except for M9N does not.
  6111. m_data = bytearray(12)
  6112. m_data[0] = 0 # version 0, msgVer
  6113. m_data[1] = 0 # read only protVer 23+, numTrkChHw
  6114. m_data[2] = 0xFF # read only protVer 23+, numTrkChUse
  6115. m_data[3] = 1 # 1 block follows
  6116. # block 1
  6117. m_data[4] = gnssId # gnssId
  6118. # m_data[5], resTrkCh, read only protVer 23+
  6119. # m_data[6], maxTrkCh, read only protVer 23+
  6120. m_data[7] = 0 # reserved1
  6121. m_data[8] = enable # flags
  6122. m_data[9] = 0 # flags, unused
  6123. # m_data[10], sigCfgMask, enable all signals
  6124. if args:
  6125. parm1 = args[0]
  6126. else:
  6127. parm1 = ''
  6128. if 0 == gnssId:
  6129. # GPS. disable does not seem to work on NEO-M9N?
  6130. m_data[5] = 8 # resTrkCh
  6131. m_data[6] = 16 # maxTrkCh
  6132. if '2' == parm1 and enable:
  6133. # The NEO-M9N ACKS, then ignores if 0x11 is sent
  6134. m_data[10] = 0x11 # flags L1C/A, L2C
  6135. else:
  6136. m_data[10] = 0x01 # flags L1C/A
  6137. elif 1 == gnssId:
  6138. # SBAS
  6139. m_data[5] = 1 # resTrkCh
  6140. m_data[6] = 3 # maxTrkCh
  6141. m_data[10] = 1 # flags L1C/A
  6142. elif 2 == gnssId:
  6143. # Galileo
  6144. m_data[5] = 4 # resTrkCh
  6145. m_data[6] = 8 # maxTrkCh
  6146. if '2' == parm1 and enable:
  6147. # The NEO-M9N ACKS, then ignores if 0x11 is sent
  6148. m_data[10] = 0x21 # flags E1, E5b
  6149. else:
  6150. m_data[10] = 0x01 # flags E1
  6151. elif 3 == gnssId:
  6152. # BeiDou
  6153. m_data[5] = 2 # resTrkCh
  6154. m_data[6] = 16 # maxTrkCh
  6155. if '2' == parm1 and enable:
  6156. # The NEO-M9N ACKS, then ignores if 0x11 is sent
  6157. m_data[10] = 0x11 # flags B1I, B2I
  6158. else:
  6159. m_data[10] = 0x01 # flags B1I
  6160. elif 4 == gnssId:
  6161. # IMES
  6162. m_data[5] = 0 # resTrkCh
  6163. m_data[6] = 8 # maxTrkCh
  6164. m_data[10] = 1 # flags L1
  6165. elif 5 == gnssId:
  6166. # QZSS
  6167. m_data[5] = 0 # resTrkCh
  6168. m_data[6] = 3 # maxTrkCh
  6169. if '2' == parm1 and enable:
  6170. # The NEO-M9N ACKS, then ignores if 0x11 is sent
  6171. m_data[10] = 0x15 # flags L1C/A, L1S, L2C
  6172. else:
  6173. m_data[10] = 0x05 # flags L1C/A, L1S
  6174. elif 6 == gnssId:
  6175. # GLONASS
  6176. m_data[5] = 8 # resTrkCh
  6177. m_data[6] = 14 # maxTrkCh
  6178. if '2' == parm1 and enable:
  6179. # The NEO-M9N ACKS, then ignores if 0x11 is sent
  6180. m_data[10] = 0x11 # flags L1, L2
  6181. else:
  6182. m_data[10] = 0x01 # flags L1
  6183. else:
  6184. # what else?
  6185. m_data[10] = 1 # flags L1
  6186. m_data[11] = 0 # flags, bits 24:31, unused
  6187. self.gps_send(6, 0x3e, m_data)
  6188. def poll_cfg_inf(self):
  6189. """UBX-CFG-INF, poll"""
  6190. m_data = bytearray(1)
  6191. m_data[0] = 0 # UBX
  6192. self.gps_send(6, 0x02, m_data)
  6193. m_data[0] = 1 # NMEA
  6194. self.gps_send(6, 0x02, m_data)
  6195. def send_poll_cfg_msg(self, args):
  6196. """UBX-CFG-MSG, mandatory args: class, ID, optional rate"""
  6197. if 0 == len(args):
  6198. sys.stderr.write('%s: ERROR: CFG-MSG missing class\n' %
  6199. (PROG_NAME))
  6200. sys.exit(1)
  6201. if 1 == len(args):
  6202. sys.stderr.write('%s: ERROR: CFG-MSG,x%x missing ID\n' %
  6203. (PROG_NAME, args[0]))
  6204. sys.exit(1)
  6205. if 2 < len(args):
  6206. # optional set rate
  6207. m_data = bytearray(3)
  6208. m_data[2] = int(args[2])
  6209. else:
  6210. m_data = bytearray(2)
  6211. m_data[0] = int(args[0])
  6212. m_data[1] = int(args[1])
  6213. self.gps_send(6, 1, m_data)
  6214. def send_cfg_nav5_model(self, args):
  6215. """MODEL, UBX-CFG-NAV5, set dynamic platform model"""
  6216. m_data = bytearray(36)
  6217. if 0 < len(args):
  6218. m_data[0] = 1 # just setting dynamic model
  6219. m_data[1] = 0 # just setting dynamic model
  6220. m_data[2] = int(args[0])
  6221. # else:
  6222. # Just polling deprecated
  6223. self.gps_send(6, 0x24, m_data)
  6224. def send_cfg_msg(self, m_class, m_id, rate=None):
  6225. """UBX-CFG-MSG, poll, or set, message rates decode"""
  6226. m_data = bytearray(2)
  6227. m_data[0] = m_class
  6228. m_data[1] = m_id
  6229. if rate is not None:
  6230. m_data.extend([rate])
  6231. self.gps_send(6, 1, m_data)
  6232. def send_cfg_pms(self, args):
  6233. """UBX-CFG-PMS, poll/set Power Management Settings"""
  6234. if 0 < len(args):
  6235. m_data = bytearray(8)
  6236. # set powerSetupValue to mode
  6237. m_data[1] = int(args[0])
  6238. # leave period and onTime zero, which breaks powerSetupValue = 3
  6239. else:
  6240. # just poll, DEPRECATED
  6241. m_data = []
  6242. self.gps_send(6, 0x86, m_data)
  6243. def send_cfg_prt(self, args=None):
  6244. """UBX-CFG-PRT, get I/O Port settings"""
  6245. if 0 == len(args):
  6246. # get current port
  6247. m_data = []
  6248. else:
  6249. # get specified port
  6250. # seems broken on ZED-F9P
  6251. m_data = bytearray([int(args[0])])
  6252. self.gps_send(6, 0x0, m_data)
  6253. def send_cfg_rate(self, args):
  6254. """UBX-CFG-RATE, poll/set rate settings"""
  6255. if 0 == len(args):
  6256. # poll
  6257. self.gps_send(6, 0x08, [])
  6258. return
  6259. m_data = bytearray(6)
  6260. measRate = int(args[0])
  6261. navRate = 1
  6262. timeRef = 1
  6263. if 1 < len(args):
  6264. navRate = int(args[1])
  6265. if 2 < len(args):
  6266. timeRef = int(args[2])
  6267. struct.pack_into('<HHH', m_data, 0, measRate, navRate, timeRef)
  6268. self.gps_send(6, 0x08, m_data)
  6269. def send_cfg_rst(self, reset_type):
  6270. """UBX-CFG-RST, reset"""
  6271. # Always do a hardware reset
  6272. # If on native USB: both Hardware reset (0) and Software reset (1)
  6273. # will disconnect and reconnect, giving you a new /dev/tty.
  6274. m_data = bytearray(4)
  6275. m_data[0] = reset_type & 0xff
  6276. m_data[1] = (reset_type >> 8) & 0xff
  6277. self.gps_send(6, 0x4, m_data)
  6278. def send_cfg_rxm(self, args):
  6279. """UBX-CFG-RXM, poll/set low power mode"""
  6280. if 0 == len(args):
  6281. # poll
  6282. m_data = []
  6283. else:
  6284. # lpMode
  6285. m_data = bytearray([0, int(args[0])])
  6286. self.gps_send(6, 0x11, m_data)
  6287. def send_cfg_slas(self, args):
  6288. """UBX-CFG-SLAS, poll/set SLAS mode"""
  6289. if 0 == len(args):
  6290. # poll
  6291. m_data = []
  6292. else:
  6293. # mode
  6294. m_data = bytearray(4)
  6295. m_data[0] = int(args[0])
  6296. self.gps_send(6, 0x8d, m_data)
  6297. def send_cfg_tp5(self, args):
  6298. """UBX-CFG-TP5, get time0 decodes"""
  6299. if 0 == len(args):
  6300. # poll default tpIdx 0
  6301. m_data = []
  6302. else:
  6303. # tpIdx
  6304. m_data = bytearray([int(args[0])])
  6305. self.gps_send(6, 0x31, m_data)
  6306. def send_set_speed(self, speed):
  6307. """"UBX-CFG-PRT, set port"""
  6308. port = self.port
  6309. # FIXME! Determine and use current port as default
  6310. if port is None:
  6311. port = 1 # Default to port 1 (UART/UART_1)
  6312. if port not in set([1, 2]):
  6313. sys.stderr.write('%s: Invalid UART port - %d\n' %
  6314. (PROG_NAME, port))
  6315. sys.exit(2)
  6316. # FIXME! Poll current masks, then adjust speed
  6317. m_data = bytearray(20)
  6318. m_data[0] = port
  6319. m_data[4] = 0xc0 # 8N1
  6320. m_data[5] = 0x8 # 8N1
  6321. m_data[8] = speed & 0xff
  6322. m_data[9] = (speed >> 8) & 0xff
  6323. m_data[10] = (speed >> 16) & 0xff
  6324. m_data[11] = (speed >> 24) & 0xff
  6325. m_data[12] = 3 # in, ubx and nmea
  6326. m_data[14] = 3 # out, ubx and nmea
  6327. self.gps_send(6, 0, m_data)
  6328. def send_cfg_valdel(self, keys):
  6329. """UBX-CFG-VALDEL, delete config items by key"""
  6330. # present in u-blox NEO-D9S+, protver 24
  6331. # present in 9-series and higher
  6332. m_data = bytearray(4)
  6333. m_data[0] = 0 # version, 0 = transactionless, 1 = transaction
  6334. m_data[1] = 6 # 2 = BBR, 4 = flash
  6335. # can not delete RAM layer!
  6336. # so options stay set until reset!
  6337. for key in keys:
  6338. k_data = bytearray(4)
  6339. k_data[0] = (key) & 0xff
  6340. k_data[1] = (key >> 8) & 0xff
  6341. k_data[2] = (key >> 16) & 0xff
  6342. k_data[3] = (key >> 24) & 0xff
  6343. m_data.extend(k_data)
  6344. self.gps_send(0x06, 0x8c, m_data)
  6345. def send_cfg_valget(self, keys, layer, position):
  6346. """UBX-CFG-VALGET, get config items by key"""
  6347. # present in u-blox NEO-D9S+, protver 24
  6348. # present in 9-series and higher
  6349. m_data = bytearray(4)
  6350. # version, 0 = request, 1 = answer
  6351. # RAM layer
  6352. # position
  6353. struct.pack_into('<BBH', m_data, 0, 0, 0, position)
  6354. k_data = bytearray(4)
  6355. for key in keys:
  6356. struct.pack_into('<L', k_data, 0, key)
  6357. m_data.extend(k_data)
  6358. if layer is None:
  6359. # blast them for now, should do one at a time...
  6360. layers = set([0, 1, 2, 7])
  6361. for layer in layers:
  6362. m_data[1] = layer
  6363. self.gps_send(0x06, 0x8b, m_data)
  6364. else:
  6365. m_data[1] = layer
  6366. self.gps_send(0x06, 0x8b, m_data)
  6367. def send_cfg_valset(self, nvs):
  6368. """UBX-CFG-VALSET, set config items by key/val pairs"""
  6369. # present in u-blox NEO-D9S+, protver 24
  6370. # present in 9-series and higher
  6371. m_data = bytearray(4)
  6372. m_data[0] = 0 # version, 0 = request, 1 = transaction
  6373. m_data[1] = 0x7 # RAM layer, 1=RAM, 2=BBR, 4=Flash
  6374. for nv in nvs:
  6375. size = 4
  6376. nv_split = nv.split(',')
  6377. name = nv_split[0]
  6378. val = nv_split[1]
  6379. if 3 <= len(nv_split):
  6380. m_data[1] = int(nv_split[2])
  6381. item = self.cfg_by_name(name)
  6382. key = item[1]
  6383. val_type = item[2]
  6384. cfg_type = self.item_to_type(item)
  6385. size = 4 + cfg_type[0]
  6386. frmat = cfg_type[1]
  6387. flavor = cfg_type[2]
  6388. if 'u' == flavor:
  6389. val1 = int(val)
  6390. elif 'i' == flavor:
  6391. val1 = int(val)
  6392. elif 'f' == flavor:
  6393. val1 = float(val)
  6394. kv_data = bytearray(size)
  6395. kv_data[0] = (key) & 0xff
  6396. kv_data[1] = (key >> 8) & 0xff
  6397. kv_data[2] = (key >> 16) & 0xff
  6398. kv_data[3] = (key >> 24) & 0xff
  6399. struct.pack_into(frmat, kv_data, 4, val1)
  6400. m_data.extend(kv_data)
  6401. self.gps_send(0x06, 0x8a, m_data)
  6402. def send_log_findtime(self, args):
  6403. """UBX-LOG-FINDTIME, search log for y,m,d,h,m,s"""
  6404. m_data = bytearray(10)
  6405. m_data[0] = 0 # version, 0 = request
  6406. m_data[1] = 0 # type, 0 = request
  6407. # the doc says two reserved bytes here, the doc is wrong
  6408. # searches for before 1 Jan 2004 always fail
  6409. year = 2004
  6410. month = 1
  6411. day = 1
  6412. hour = 0
  6413. minute = 0
  6414. second = 0
  6415. if 0 < len(args):
  6416. year = int(args[0])
  6417. if 1 < len(args):
  6418. month = int(args[1])
  6419. if 2 < len(args):
  6420. day = int(args[2])
  6421. if 3 < len(args):
  6422. hour = int(args[3])
  6423. if 4 < len(args):
  6424. minute = int(args[4])
  6425. if 5 < len(args):
  6426. second = int(args[5])
  6427. m_data[2] = year % 256 # year 1-65635
  6428. m_data[3] = int(year / 256) & 0xff # year
  6429. m_data[4] = month # month 1-12
  6430. m_data[5] = day # day 1-31
  6431. m_data[6] = hour # hour 0-23
  6432. m_data[7] = minute # minute 0-59
  6433. m_data[8] = second # second 0-60
  6434. m_data[9] = 0 # reserved
  6435. self.gps_send(0x21, 0x0e, m_data)
  6436. def send_log_retrieve(self, args):
  6437. """UBX-LOG-RETRIEVE, gets logs from start,count"""
  6438. m_data = bytearray(12)
  6439. # defaults
  6440. startNumber = 0
  6441. entryCount = 256 # max 256
  6442. if 0 < len(args):
  6443. startNumber = int(args[0])
  6444. if 1 < len(args):
  6445. entryCount = int(args[1])
  6446. struct.pack_into('<LLB', m_data, 0, startNumber, entryCount, 0)
  6447. self.gps_send(0x21, 0x09, m_data)
  6448. def send_log_string(self, args):
  6449. """UBX-LOG-STRING, send string to log"""
  6450. if 0 < len(args):
  6451. string = args[0:256]
  6452. else:
  6453. string = "Hi"
  6454. m_data = gps.polybytes(string)
  6455. self.gps_send(0x21, 0x04, m_data)
  6456. def send_poll(self, m_data):
  6457. """generic send poll request"""
  6458. self.gps_send(m_data[0], m_data[1], m_data[2:])
  6459. CFG_ANT = [0x06, 0x13]
  6460. CFG_BATCH = [0x06, 0x93]
  6461. CFG_DAT = [0x06, 0x06]
  6462. CFG_GNSS = [0x06, 0x3e]
  6463. CFG_GEOFENCE = [0x06, 0x69]
  6464. CFG_INF_0 = [0x06, 0x02, 0]
  6465. CFG_INF_1 = [0x06, 0x02, 1]
  6466. CFG_LOGFILTER = [0x06, 0x47]
  6467. CFG_ODO = [0x06, 0x1e]
  6468. CFG_PRT = [0x06, 0x00] # current port only
  6469. CFG_NAV5 = [0x06, 0x24]
  6470. CFG_NAVX5 = [0x06, 0x23]
  6471. CFG_NMEA = [0x06, 0x17]
  6472. CFG_PM2 = [0x06, 0x3b]
  6473. CFG_PMS = [0x06, 0x86]
  6474. CFG_RATE = [0x06, 0x08]
  6475. CFG_RXM = [0x06, 0x11]
  6476. CFG_TMODE3 = [0x06, 0x71]
  6477. CFG_TP5 = [0x06, 0x31]
  6478. CFG_USB = [0x06, 0x1b]
  6479. LOG_INFO = [0x21, 0x08]
  6480. MON_COMMS = [0x0a, 0x36]
  6481. MON_GNSS = [0x0a, 0x28]
  6482. MON_HW = [0x0a, 0x09]
  6483. MON_HW2 = [0x0a, 0x0b]
  6484. MON_HW3 = [0x0a, 0x37]
  6485. MON_IO = [0x0a, 0x02]
  6486. MON_MSGPP = [0x0a, 0x06]
  6487. MON_RF = [0x0a, 0x38]
  6488. MON_RXBUF = [0x0a, 0x0a]
  6489. MON_TXBUF = [0x0a, 0x08]
  6490. MON_VER = [0x0a, 0x04]
  6491. NAV_SVIN = [0x01, 0x3b]
  6492. TIM_SVIN = [0x0d, 0x04]
  6493. def get_config(self):
  6494. """CONFIG. Get a bunch of config messages"""
  6495. cmds = [ubx.MON_VER, # UBX-MON-VER
  6496. ubx.CFG_ANT, # UBX-CFG-ANT
  6497. ubx.CFG_DAT, # UBX-CFG-DAT
  6498. # skip UBX-CFG-DGNSS, HP only
  6499. # skip UBX-CFG-DOSC, FTS only
  6500. # skip UBX-CFG-ESRC, FTS only
  6501. ubx.CFG_GEOFENCE, # UBX-CFG-GEOFENCE
  6502. ubx.CFG_GNSS, # UBX-CFG-GNSS
  6503. # skip UBX-CFG-HNR, ADR, UDR, only
  6504. ubx.CFG_INF_0, # UBX-CFG-INF
  6505. ubx.CFG_INF_1,
  6506. # skip UBX-CFG-ITFM
  6507. ubx.CFG_LOGFILTER, # UBX-CFG-LOGFILTER
  6508. ubx.CFG_NAV5, # UBX-CFG-NAV5
  6509. ubx.CFG_NAVX5, # UBX-CFG-NAVX5
  6510. ubx.CFG_NMEA, # UBX-CFG-NMEA
  6511. ubx.CFG_ODO, # UBX-CFG-ODO
  6512. ubx.CFG_PRT, # UBX-CFG-PRT
  6513. ubx.CFG_PM2, # UBX-CFG-PM2
  6514. ubx.CFG_PMS, # UBX-CFG-PMS
  6515. ubx.CFG_RATE, # UBX-CFG-RATE
  6516. ubx.CFG_RXM, # UBX-CFG-RXM
  6517. ubx.CFG_TP5, # UBX-CFG-TP5
  6518. ubx.CFG_USB, # UBX-CFG-USB
  6519. ]
  6520. if 20 < self.protver:
  6521. cmds.append(ubx.CFG_TMODE3) # UBX-CFG-TMODE3, protVer 20+
  6522. if 22 < self.protver:
  6523. cmds.append(ubx.CFG_BATCH) # UBX-CFG-BATCH, protVer 23.01+
  6524. # blast them for now, should do one at a time...
  6525. for cmd in cmds:
  6526. self.send_poll(cmd)
  6527. def get_status(self):
  6528. """STATUS. Get a bunch of status messages"""
  6529. cmds = [ubx.MON_VER, # UBX-MON-VER
  6530. ubx.LOG_INFO, # UBX-LOG-INFO
  6531. ubx.MON_GNSS, # UBX-MON-GNSS
  6532. # UBX-MON-PATH, skipping
  6533. ]
  6534. if 27 <= self.protver:
  6535. cmds.extend([ubx.MON_COMMS, # UBX-MON-COMMS
  6536. ubx.MON_HW3, # UBX-MON-HW3
  6537. ])
  6538. else:
  6539. # deprecated in 27+
  6540. cmds.extend([ubx.MON_HW, # UBX-MON-HW
  6541. ubx.MON_HW2, # UBX-MON-HW2
  6542. ubx.MON_IO, # UBX-MON-IO
  6543. ubx.MON_MSGPP, # UBX-MON-MSGPP
  6544. ubx.MON_RF, # UBX-MON-RF
  6545. ubx.MON_RXBUF, # UBX-MON-RXBUF
  6546. ubx.MON_TXBUF, # UBX-MON-TXBUF
  6547. ])
  6548. # should only send these for Time or HP products
  6549. cmds.extend([ubx.NAV_SVIN, # UBX-NAV-SVIN
  6550. ubx.TIM_SVIN, # UBX-TIM-SVIN
  6551. ])
  6552. # blast them for now, should do one at a time...
  6553. for cmd in cmds:
  6554. self.send_poll(cmd)
  6555. able_commands = {
  6556. # en/dis able BATCH
  6557. "BATCH": {"command": send_able_cfg_batch,
  6558. "help": "batching, using CFG-BATCH"},
  6559. # en/dis able BeiDou
  6560. "BEIDOU": {"command": send_able_beidou,
  6561. "help": "BeiDou B1. BEIDOU,5 for B1 and B2"},
  6562. # en/dis able basic binary messages
  6563. "BINARY": {"command": send_able_binary,
  6564. "help": "basic binary messages"},
  6565. # en/dis able ECEF
  6566. "ECEF": {"command": send_able_ecef,
  6567. "help": "ECEF"},
  6568. # en/dis able GPS
  6569. "GPS": {"command": send_able_gps,
  6570. "help": "GPS and QZSS L1C/A. GPS,2 for L1C/A and L2C"},
  6571. # en/dis able GALILEO
  6572. "GALILEO": {"command": send_able_galileo,
  6573. "help": "GALILEO E1. GALILEO,2 for E1 and E5b"},
  6574. # en/dis able GLONASS
  6575. "GLONASS": {"command": send_able_glonass,
  6576. "help": "GLONASS L1. GLONASS,2 for L1 and L2"},
  6577. # en/dis able LOG
  6578. "LOG": {"command": send_able_logfilter,
  6579. "help": "Data Logger"},
  6580. # en/dis able NED
  6581. "NED": {"command": send_able_ned,
  6582. "help": "NAV-VELNED and NAV-RELPOSNED"},
  6583. # en/dis able basic NMEA messages
  6584. "NMEA": {"command": send_able_nmea,
  6585. "help": "basic NMEA messages"},
  6586. # en/dis able RAW/RAWX
  6587. "RAWX": {"command": send_able_rawx,
  6588. "help": "RAW/RAWX measurements"},
  6589. # en/dis able PPS
  6590. "PPS": {"command": send_able_pps,
  6591. "help": "PPS on TIMPULSE"},
  6592. # en/dis able SBAS
  6593. "SBAS": {"command": send_able_sbas,
  6594. "help": "SBAS L1C"},
  6595. # en/dis able SFRB/SFRBX
  6596. "SFRBX": {"command": send_able_sfrbx,
  6597. "help": "SFRB/SFRBX subframes"},
  6598. # en/dis able TP time pulse message (deprecated)
  6599. "TIM-TP": {"command": send_able_tp,
  6600. "help": "TIM-TP Time Pulse message"},
  6601. # en/dis able TP time pulse message (deprecated)
  6602. "TP": {"command": send_able_tp,
  6603. "help": "TP Time Pulse message (Deprecated, use TIM-TP)"},
  6604. # en/dis able TMODE2 Survey-in
  6605. "SURVEYIN": {"command": send_able_tmode2,
  6606. "help": "Survey-in mode with TMODE2.\n"
  6607. " "
  6608. " SURVEYIN2[,svinMinDur[,svinAccLimit]]\n"
  6609. " "
  6610. "Default svinMinDur 300 seconds\n"
  6611. " "
  6612. "Default svinAccLimit 50000",
  6613. "args": 1},
  6614. # en/dis able TMODE3 Survey-in
  6615. "SURVEYIN3": {"command": send_able_tmode3,
  6616. "help": "Survey-in mode with TMODE3.\n"
  6617. " "
  6618. " SURVEYIN3[,svinMinDur[,svinAccLimit]]\n"
  6619. " "
  6620. "Default svinMinDur 300 seconds\n"
  6621. " "
  6622. "Default svinAccLimit 500000",
  6623. "args": 1},
  6624. # en/dis able RTCM3 messages 1005, 1077, 1087, 1230
  6625. "RTCM3": {"command": send_able_rtcm3,
  6626. "help": "required RTCM3 messages. USB port only"},
  6627. }
  6628. commands = {
  6629. # UBX-CFG-RST
  6630. "COLDBOOT": {"command": send_cfg_rst,
  6631. "help": "UBS-CFG-RST coldboot the GPS",
  6632. "opt": 0xffff},
  6633. # CONFIG
  6634. "CONFIG": {"command": get_config,
  6635. "help": "Get a lot of receiver config"},
  6636. # UBX-CFG-RST
  6637. "HOTBOOT": {"command": send_cfg_rst,
  6638. "help": "UBX-CFG-RST hotboot the GPS",
  6639. "opt": 0},
  6640. # UBX-CFG-NAV5
  6641. "MODEL": {"command": send_cfg_nav5_model,
  6642. "help": "set UBX-CFG-NAV5 Dynamic Platform Model. "
  6643. "MODEL,model",
  6644. "args": 1},
  6645. # UBX-CFG-CFG
  6646. "RESET": {"command": send_cfg_cfg,
  6647. "help": "UBX-CFG-CFG reset config to defaults",
  6648. "opt": 1},
  6649. # UBX-CFG-CFG
  6650. "SAVE": {"command": send_cfg_cfg,
  6651. "help": "UBX-CFG-CFG save current config",
  6652. "opt": 0},
  6653. # STATUS
  6654. "STATUS": {"command": get_status,
  6655. "help": "Get a lot of receiver status"},
  6656. # UBX-CFG-RST
  6657. "WARMBOOT": {"command": send_cfg_rst,
  6658. "help": "UBX-CFG-RST warmboot the GPS",
  6659. "opt": 1},
  6660. # UBX-AID-ALM
  6661. "AID-ALM": {"command": send_poll, "opt": [0x0b, 0x30],
  6662. "help": "poll UBX-AID-ALM Poll GPS Aiding Almanac Data"},
  6663. # UBX-AID-AOP
  6664. "AID-AOP": {"command": send_poll, "opt": [0x0b, 0x33],
  6665. "help": "poll UBX-AID-AOP Poll Poll AssistNow "
  6666. "Autonomous data"},
  6667. # UBX-AID-DATA
  6668. "AID-DATA": {"command": send_poll, "opt": [0x0b, 0x10],
  6669. "help": "Poll all GPS Initial Aiding Data"},
  6670. # UBX-AID-EPH
  6671. "AID-EPH": {"command": send_poll, "opt": [0x0b, 0x31],
  6672. "help": "poll UBX-AID-EPH Poll GPS Aiding Ephemeris Data"},
  6673. # UBX-AID-HUI
  6674. "AID-HUI": {"command": send_poll, "opt": [0x0b, 0x02],
  6675. "help": "poll UBX-AID-HUI Poll GPS Health, UTC, Iono"},
  6676. # UBX-AID-INI
  6677. "AID-INI": {"command": send_poll, "opt": [0x0b, 0x01],
  6678. "help": "poll UBX-AID-INI Poll Aiding position, time,\n"
  6679. " "
  6680. "frequency, clock drift"},
  6681. # UBX-CFG-ANT
  6682. "CFG-ANT": {"command": send_poll, "opt": [0x06, 0x13],
  6683. "help": "poll UBX-CFG-ANT antenna config"},
  6684. # UBX-CFG-BATCH
  6685. # Assume 23 is close enough to the proper 23.01
  6686. "CFG-BATCH": {"command": send_poll, "opt": [0x06, 0x93],
  6687. "help": "poll UBX-CFG-BATCH data batching config",
  6688. "minVer": 23},
  6689. # UBX-CFG-DAT
  6690. "CFG-DAT": {"command": send_poll, "opt": [0x06, 0x06],
  6691. "help": "poll UBX-CFG-DAT Datum Setting"},
  6692. # UBX-CFG-DGNSS
  6693. "CFG-DGNSS": {"command": send_poll, "opt": [0x06, 0x70],
  6694. "help": "poll UBX-CFG-DGNSS DGNSS configuration"},
  6695. # UBX-CFG-DOSC
  6696. "CFG-DOSC": {"command": send_poll, "opt": [0x06, 0x61],
  6697. "help": "poll UBX-CFG-DOSC Disciplined oscillator "
  6698. "configuration"},
  6699. # UBX-CFG-ESRC
  6700. "CFG-ESRC": {"command": send_poll, "opt": [0x06, 0x60],
  6701. "help": "poll UBX-CFG-ESRC External synchronization "
  6702. "source config"},
  6703. # UBX-CFG-FXN
  6704. "CFG-FXN": {"command": send_poll, "opt": [0x06, 0x0e],
  6705. "help": "poll UBX-CFG-FXN FXN Configuration"},
  6706. # UBX-CFG-GEOFENCE
  6707. "CFG-GEOFENCE": {"command": send_poll, "opt": [0x06, 0x69],
  6708. "help": "poll UBX-CFG-GEOFENCE Geofencing "
  6709. "configuration"},
  6710. # UBX-CFG-GNSS
  6711. "CFG-GNSS": {"command": send_poll, "opt": [0x06, 0x3e],
  6712. "help": "poll UBX-CFG-GNSS GNSS config"},
  6713. # UBX-CFG-HNR
  6714. "CFG-HNR": {"command": send_poll, "opt": [0x06, 0x5c],
  6715. "help": "poll UBX-CFG-HNR High Navigation Rate Settings"},
  6716. # UBX-CFG-INF
  6717. "CFG-INF": {"command": poll_cfg_inf,
  6718. "help": "poll UBX-CFG-INF Information Message "
  6719. "Configuration"},
  6720. # UBX-CFG-ITFM
  6721. "CFG-ITFM": {"command": send_poll, "opt": [0x06, 0x39],
  6722. "help": "poll UBX-CFG-ITFM Jamming/Interference "
  6723. "Monitor configuration"},
  6724. # UBX-CFG-LOGFILTER
  6725. "CFG-LOGFILTER": {"command": send_poll, "opt": [0x06, 0x47],
  6726. "help": "poll UBX-CFG-LOGFILTER "
  6727. " Data Logger Configuration",
  6728. "minVer": 14},
  6729. # UBX-CFG-MSG
  6730. "CFG-MSG": {"command": send_poll_cfg_msg,
  6731. "help": "poll/set UBX-CFG-MSG,class,ID[,rate]\n"
  6732. " "
  6733. "rate is optional and sets rate.",
  6734. "args": 2},
  6735. # UBX-CFG-NAV5
  6736. "CFG-NAV5": {"command": send_poll, "opt": [0x06, 0x24],
  6737. "help": "poll UBX-CFG-NAV5 Nav Engines settings"},
  6738. # UBX-CFG-NAVX5
  6739. "CFG-NAVX5": {"command": send_poll, "opt": [0x06, 0x23],
  6740. "help": "poll UBX-CFG-NAVX5 Nav Expert Settings"},
  6741. # UBX-CFG-NMEA
  6742. "CFG-NMEA": {"command": send_poll, "opt": [0x06, 0x17],
  6743. "help": "poll UBX-CFG-NMEA Extended NMEA protocol "
  6744. "configuration V1"},
  6745. # UBX-CFG-ODO
  6746. "CFG-ODO": {"command": send_poll, "opt": [0x06, 0x1e],
  6747. "help": "poll UBX-CFG-ODO Odometer, Low-speed COG "
  6748. "Engine Settings"},
  6749. # UBX-CFG-PM
  6750. "CFG-PM": {"command": send_poll, "opt": [0x06, 0x32],
  6751. "help": "poll UBX-CFG-PM Power management settings"},
  6752. # UBX-CFG-PM2
  6753. "CFG-PM2": {"command": send_poll, "opt": [0x06, 0x3b],
  6754. "help": "poll UBX-CFG-PM2 Extended power management "
  6755. "settings"},
  6756. # UBX-CFG-PMS
  6757. "CFG-PMS": {"command": send_cfg_pms,
  6758. "help": "poll/set UBX-CFG-PMS power management settings\n"
  6759. " "
  6760. "CFG-PMS[,powerSetupValue]",
  6761. "args": 1},
  6762. # UBX-CFG-PRT
  6763. "CFG-PRT": {"command": send_cfg_prt,
  6764. "help": "poll UBX-CFG-PRT I/O port settings.\n"
  6765. " "
  6766. "CFG-PRT[,portID] defaults to current port",
  6767. "args": 1},
  6768. # TODO: UBX-CFG-PWR
  6769. # UBX-CFG-RATE
  6770. "CFG-RATE": {"command": send_cfg_rate,
  6771. "help": "poll/set UBX-CFG-RATE measure/nav settings.\n"
  6772. " "
  6773. "CFG-RATE[,measRate,[navRate]]",
  6774. "args": 2},
  6775. # UBX-CFG-RINV
  6776. "CFG-RINV": {"command": send_poll, "opt": [0x06, 0x34],
  6777. "help": "poll UBX-CFG-RINV Contents of Remote Inventory"},
  6778. # UBX-CFG-RST, see COLDBOOT, WARMBOOT, HOTBOOT
  6779. # UBX-CFG-RXM
  6780. "CFG-RXM": {"command": send_cfg_rxm,
  6781. "help": "poll/set UBX-CFG-RXM RXM configuration.\n"
  6782. " "
  6783. "CFG-RXM[,lpMode]",
  6784. "args": 1},
  6785. # UBX-CFG-SBAS
  6786. "CFG-SBAS": {"command": send_poll, "opt": [0x06, 0x16],
  6787. "help": "poll UBX-CFG-SBAS SBAS settings"},
  6788. # UBX-CFG-SLAS
  6789. "CFG-SLAS": {"command": send_cfg_slas,
  6790. "help": "poll/set UBX-CFG-SLAS SLAS configuration.\n"
  6791. " "
  6792. "CFG-SLAS[,mode]",
  6793. "args": 1},
  6794. # UBX-CFG-SMGR
  6795. "CFG-SMGR": {"command": send_poll, "opt": [0x06, 0x62],
  6796. "help": "poll UBX-CFG-SMGR Synchronization manager "
  6797. "configuration"},
  6798. # UBX-CFG-TMODE
  6799. "CFG-TMODE": {"command": send_poll, "opt": [0x06, 0x1d],
  6800. "help": "poll UBX-CFG-TMODE time mode settings",
  6801. "maxVer": 6},
  6802. # UBX-CFG-TMODE2
  6803. "CFG-TMODE2": {"command": send_poll, "opt": [0x06, 0x3d],
  6804. "help": "poll UBX-CFG-TMODE2 time mode 2 config",
  6805. "minVer": 14},
  6806. # UBX-CFG-TMODE3
  6807. "CFG-TMODE3": {"command": send_poll, "opt": [0x06, 0x71],
  6808. "help": "poll UBX-CFG-TMODE3 time mode 3 config",
  6809. "minVer": 20},
  6810. # UBX-CFG-TP
  6811. "CFG-TP": {"command": send_poll, "opt": [0x06, 0x07],
  6812. "help": "poll UBX-CFG-TP TimePulse Parameters."},
  6813. # UBX-CFG-TP5
  6814. "CFG-TP5": {"command": send_cfg_tp5,
  6815. "help": "poll UBX-TIM-TP5 time pulse decodes.\n"
  6816. " "
  6817. "CFG-TP5[,tpIdx] Default tpIdx is 0",
  6818. "args": 1},
  6819. # UBX-CFG-USB
  6820. "CFG-USB": {"command": send_poll, "opt": [0x06, 0x1b],
  6821. "help": "poll UBX-CFG-USB USB config"},
  6822. # UBX-ESF-INS
  6823. "ESF-INS": {"command": send_poll, "opt": [0x10, 0x15],
  6824. "help": "poll UBX-ESF-INS Vehicle dynamics info"},
  6825. # UBX-ESF-MEAS
  6826. "ESF-MEAS": {"command": send_poll, "opt": [0x10, 0x02],
  6827. "help": "poll UBX-ESF-MEAS External sensor fusion "
  6828. "measurements"},
  6829. # UBX-ESF-STATUS
  6830. "ESF-STATUS": {"command": send_poll, "opt": [0x10, 0x10],
  6831. "help": "poll UBX-ESF-STATUS External sensor fusion "
  6832. "status"},
  6833. # UBX-LOG-CREATE
  6834. "LOG-CREATE": {"command": send_poll,
  6835. "opt": [0x21, 0x07, 0, 1, 0, 0, 0, 0, 0, 0],
  6836. "help": "send UBX-LOG-CREATE",
  6837. "minVer": 14},
  6838. # UBX-LOG-ERASE
  6839. "LOG-ERASE": {"command": send_poll, "opt": [0x21, 0x03],
  6840. "help": "send UBX-LOG-ERASE",
  6841. "minVer": 14},
  6842. # UBX-LOG-FINDTIME
  6843. "LOG-FINDTIME": {"command": send_log_findtime,
  6844. "help": "search logs by time. "
  6845. "LOG-FINDTIME,y,m,d,h,m,s\n"
  6846. " "
  6847. "all parameters optional",
  6848. "args": 6},
  6849. # UBX-LOG-INFO
  6850. "LOG-INFO": {"command": send_poll, "opt": [0x21, 0x08],
  6851. "help": "poll UBX-LOG-INFO",
  6852. "minVer": 14},
  6853. # UBX-LOG-RETRIEVE
  6854. "LOG-RETRIEVE": {"command": send_log_retrieve,
  6855. "help": "send UBX-LOG-RETRIEVE. "
  6856. "LOG-RETRIEVE[,start,[count]]",
  6857. "minVer": 14,
  6858. "args": 2},
  6859. # UBX-LOG-RETRIEVEBATCH
  6860. # Assume 23 is close enough to the proper 23.01
  6861. "LOG-RETRIEVEBATCH": {"command": send_poll,
  6862. "opt": [0x21, 0x10, 0, 1, 0, 0],
  6863. "help": "send UBX-LOG-RETRIEVEBATCH",
  6864. "minVer": 23},
  6865. # UBX-LOG-STRING
  6866. "LOG-STRING": {"command": send_log_string,
  6867. "help": "send UBX-LOG-STRING. LOG-STRING[,string]",
  6868. "minVer": 14,
  6869. "args": 1},
  6870. # UBX-MGA-DBD
  6871. "MGA-DBD": {"command": send_poll, "opt": [0x13, 0x80],
  6872. "help": "poll UBX-MGA-DBD Poll the Navigation Database"},
  6873. # UBX-MON-BATCH
  6874. # Assume 23 is close enough to the proper 23.01
  6875. "MON-BATCH": {"command": send_poll, "opt": [0x0a, 0x32],
  6876. "help": "poll UBX-MON-BATCH Data batching "
  6877. "buffer status",
  6878. "maxVer": 23.99,
  6879. "minVer": 23},
  6880. # UBX-MON-COMMS
  6881. "MON-COMMS": {"command": send_poll, "opt": [0x0a, 0x36],
  6882. "help": "poll UBX-MON-COMMS Comm port information"},
  6883. # UBX-MON-GNSS
  6884. "MON-GNSS": {"command": send_poll, "opt": [0x0a, 0x28],
  6885. "help": "poll UBX-MON-GNSS major GNSS selection"},
  6886. # UBX-MON-HW
  6887. "MON-HW": {"command": send_poll, "opt": [0x0a, 0x09],
  6888. "help": "poll UBX-MON-HW Hardware Status"},
  6889. # UBX-MON-HW2
  6890. "MON-HW2": {"command": send_poll, "opt": [0x0a, 0x0b],
  6891. "help": "poll UBX-MON-HW2 Extended Hardware Status"},
  6892. # UBX-MON-HW3
  6893. "MON-HW3": {"command": send_poll, "opt": [0x0a, 0x37],
  6894. "help": "poll UBX-MON-HW3 HW I/O pin information"},
  6895. # UBX-MON-IO
  6896. "MON-IO": {"command": send_poll, "opt": [0x0a, 0x02],
  6897. "help": "poll UBX-MON-IO I/O Subsystem Status"},
  6898. # UBX-MON-MSGPP
  6899. "MON-MSGPP": {"command": send_poll, "opt": [0x0a, 0x06],
  6900. "help": "poll UBX-MON-MSGPP Message Parese and "
  6901. "Process Status"},
  6902. # UBX-MON-PATCH
  6903. "MON-PATCH": {"command": send_poll, "opt": [0x0a, 0x27],
  6904. "help": "poll UBX-MON-PATCH Info on Installed Patches"},
  6905. # UBX-MON-RF
  6906. "MON-RF": {"command": send_poll, "opt": [0x0a, 0x38],
  6907. "help": "poll UBX-MON-RF RF Information"},
  6908. # UBX-MON-RXBUF
  6909. "MON-RXBUF": {"command": send_poll, "opt": [0x0a, 0x07],
  6910. "help": "poll UBX-MON-RXBUF Receiver Buffer Status"},
  6911. # UBX-MON-SMGR
  6912. "MON-SMGR": {"command": send_poll, "opt": [0x0a, 0x2e],
  6913. "help": "poll UBX-MON-SMGR Synchronization manager "
  6914. "configuration"},
  6915. # UBX-MON-TXBUF
  6916. "MON-TXBUF": {"command": send_poll, "opt": [0x0a, 0x08],
  6917. "help": "poll UBX-MON-TXBUF Transmitter Buffer Status"},
  6918. # UBX-MON-VER
  6919. "MON-VER": {"command": send_poll, "opt": [0x0a, 0x04],
  6920. "help": "poll UBX-MON-VER GPS version"},
  6921. # UBX-NAV-AOPSTATUS
  6922. "NAV-AOPSTATUS": {"command": send_poll, "opt": [0x01, 0x60],
  6923. "help": "poll UBX-NAV-AOPSTATUS AssistNow "
  6924. "Autonomous Status"},
  6925. # UBX-NAV-ATT
  6926. "NAV-ATT": {"command": send_poll, "opt": [0x1, 0x5],
  6927. "help": "poll UBX-NAV-ATT Attitude Solution"},
  6928. # UBX-NAV-CLOCK
  6929. "NAV-CLOCK": {"command": send_poll, "opt": [0x01, 0x22],
  6930. "help": "poll UBX-NAV-CLOCK Clock Solution"},
  6931. # UBX-NAV-DGPS
  6932. "NAV-DGPS": {"command": send_poll, "opt": [0x01, 0x31],
  6933. "help": "poll UBX-NAV-DGPS DGPS Data Used for NAV"},
  6934. # UBX-NAV-DOP
  6935. "NAV-DOP": {"command": send_poll, "opt": [0x01, 0x04],
  6936. "help": "poll UBX-NAV-DOP Dilution of Precision"},
  6937. # UBX-NAV-GEOFENCE
  6938. "NAV-GEOFENCE": {"command": send_poll, "opt": [0x01, 0x39],
  6939. "help": "poll UBX-NAV-GEOFENCE Geofence status"},
  6940. # UBX-NAV-HPPOSECEF
  6941. "NAV-HPPOSECEF": {"command": send_poll, "opt": [0x01, 0x13],
  6942. "help": "poll UBX-NAV-HPPOSECEF ECEF position"},
  6943. # UBX-NAV-HPPOSLLH
  6944. "NAV-HPPOSLLH": {"command": send_poll, "opt": [0x01, 0x14],
  6945. "help": "poll UBX-NAV-HPPOSECEF LLH position"},
  6946. # UBX-NAV-ODO
  6947. "NAV-ODO": {"command": send_poll, "opt": [0x01, 0x09],
  6948. "help": "poll UBX-NAV-ODO Odometer Solution"},
  6949. # UBX-NAV-ORB
  6950. "NAV-ORB": {"command": send_poll, "opt": [0x01, 0x34],
  6951. "help": "poll UBX-NAV-ORB GNSS Orbit Database Info"},
  6952. # UBX-NAV-POSECEF
  6953. "NAV-POSECEF": {"command": send_poll, "opt": [0x01, 0x01],
  6954. "help": "poll UBX-NAV-POSECEF ECEF position"},
  6955. # UBX-NAV-POSLLH
  6956. "NAV-POSLLH": {"command": send_poll, "opt": [0x01, 0x02],
  6957. "help": "poll UBX-NAV-POSLLH LLH position"},
  6958. # UBX-NAV-PVT
  6959. "NAV-PVT": {"command": send_poll, "opt": [0x01, 0x07],
  6960. "help": "poll UBX-NAV-PVT Navigation Position Velocity "
  6961. "Time Solution"},
  6962. # UBX-NAV-RELPOSNED
  6963. # HP only, 20+, otherwise not ACKed or NACKed
  6964. "NAV-RELPOSNED": {"command": send_poll, "opt": [0x01, 0x3c],
  6965. "help": "poll UBX-NAV-RELPOSNED Relative "
  6966. "Positioning Info in NED frame"},
  6967. # UBX-NAV-RESETODO
  6968. "NAV-RESETODO": {"command": send_poll, "opt": [0x01, 0x10],
  6969. "help": "UBX-NAV-RESETODO Reset odometer"},
  6970. # UBX-NAV-SAT
  6971. "NAV-SAT": {"command": send_poll, "opt": [0x01, 0x35],
  6972. "help": "poll UBX-NAV-SAT Satellite Information"},
  6973. # UBX-NAV-SBAS
  6974. "NAV-SBAS": {"command": send_poll, "opt": [0x01, 0x32],
  6975. "help": "poll UBX-NAV-SBAS SBAS Status Data"},
  6976. # UBX-NAV-SIG
  6977. "NAV-SIG": {"command": send_poll, "opt": [0x01, 0x43],
  6978. "help": "poll UBX-NAV-SIG Signal Information"},
  6979. # UBX-NAV-SLAS
  6980. "NAV-SLAS": {"command": send_poll, "opt": [0x01, 0x42],
  6981. "help": "poll UBX-NAV-SLAS QZSS L1S SLAS Status Data"},
  6982. # UBX-NAV-SOL
  6983. "NAV-SOL": {"command": send_poll, "opt": [0x01, 0x06],
  6984. "help": "poll UBX-NAV-SOL Navigation Solution "
  6985. "Information"},
  6986. # UBX-NAV-STATUS
  6987. "NAV-STATUS": {"command": send_poll, "opt": [0x01, 0x03],
  6988. "help": "poll UBX-NAV-STATUS Receiver Nav Status"},
  6989. # UBX-NAV-SVIN
  6990. "NAV-SVIN": {"command": send_poll, "opt": [0x01, 0x3b],
  6991. "help": "poll UBX-NAV-SVIN Survey-in data",
  6992. "minver": 20},
  6993. # UBX-NAV-SVINFO
  6994. "NAV-SVINFO": {"command": send_poll, "opt": [0x01, 0x30],
  6995. "help": "poll UBX-NAV-SVINFO Satellite Information"},
  6996. # UBX-NAV-TIMEBDS
  6997. "NAV-TIMEBDS": {"command": send_poll, "opt": [0x01, 0x24],
  6998. "help": "poll UBX-NAV-TIMEBDS BDS Time Solution"},
  6999. # UBX-NAV-TIMEGAL
  7000. "NAV-TIMEGAL": {"command": send_poll, "opt": [0x01, 0x25],
  7001. "help": "poll UBX-NAV-TIMEGAL Galileo Time Solution"},
  7002. # UBX-NAV-TIMEGLO
  7003. "NAV-TIMEGLO": {"command": send_poll, "opt": [0x01, 0x23],
  7004. "help": "poll UBX-NAV-TIMEGLO GLO Time Solution"},
  7005. # UBX-NAV-TIMEGPS
  7006. "NAV-TIMEGPS": {"command": send_poll, "opt": [0x01, 0x20],
  7007. "help": "poll UBX-NAV-TIMEGPS GPS Time Solution"},
  7008. # UBX-NAV-TIMELS
  7009. "NAV-TIMELS": {"command": send_poll, "opt": [0x01, 0x26],
  7010. "help": "poll UBX-NAV-TIMELS Leap Second Info"},
  7011. # UBX-NAV-TIMEUTC
  7012. "NAV-TIMEUTC": {"command": send_poll, "opt": [0x01, 0x21],
  7013. "help": "poll UBX-NAV-TIMEUTC UTC Time Solution"},
  7014. # UBX-NAV-VELECEF
  7015. "NAV-VELECEF": {"command": send_poll, "opt": [0x01, 0x11],
  7016. "help": "poll UBX-NAV-VELECEF ECEF velocity"},
  7017. # UBX-NAV-VELNED
  7018. "NAV-VELNED": {"command": send_poll, "opt": [0x01, 0x12],
  7019. "help": "poll UBX-NAV-VELNED NED velocity"},
  7020. # UBX-RXM-IMES
  7021. "RXM-IMES": {"command": send_poll, "opt": [0x02, 0x61],
  7022. "help": "poll UBX-RXM-IMES Indoor Messaging System "
  7023. "Information"},
  7024. # UBX-RXM-MEASX
  7025. "RXM-MEASX": {"command": send_poll, "opt": [0x02, 0x14],
  7026. "help": "poll UBX-RXM-MEASX Satellite Measurements "
  7027. " for RRLP"},
  7028. # UBX-RXM-RAWX
  7029. "RXM-RAWX": {"command": send_poll, "opt": [0x02, 0x15],
  7030. "help": "poll UBX-RXM-RAWX raw measurement data"},
  7031. # UBX-CFG-SBAS
  7032. "SEC-UNIQID": {"command": send_poll, "opt": [0x27, 0x03],
  7033. "help": "poll UBX-SEC-UNIQID Unique chip ID"},
  7034. # UBX-TIM-SVIN
  7035. "TIM-SVIN": {"command": send_poll, "opt": [0x0d, 0x04],
  7036. "help": "poll UBX-TIM-SVIN survey in data"},
  7037. # UBX-TIM-TM2
  7038. "TIM-TM2": {"command": send_poll, "opt": [0x0d, 0x03],
  7039. "help": "poll UBX-TIM-TM2 time mark data"},
  7040. # UBX-TIM-TP
  7041. "TIM-TP": {"command": send_poll, "opt": [0x0d, 0x01],
  7042. "help": "poll UBX-TIM-TP time pulse timedata"},
  7043. # UBX-TIM-VRFY
  7044. "TIM-VRFY": {"command": send_poll, "opt": [0x0d, 0x06],
  7045. "help": "poll UBX-TIM-VRFY Sourced Time Verification"},
  7046. # UBX-UPD-SOS
  7047. "UPD-SOS": {"command": send_poll, "opt": [0x09, 0x14],
  7048. "help": "poll UBX-UPD-SOS Backup File restore Status"},
  7049. # UBX-UPD-SOS
  7050. "UPD-SOS0": {"command": send_poll, "opt": [0x09, 0x14, 0, 0, 0, 0],
  7051. "help": "UBX-UPD-SOS Create Backup File in Flash"},
  7052. # UBX-UPD-SOS
  7053. "UPD-SOS1": {"command": send_poll, "opt": [0x09, 0x14, 1, 0, 0, 0],
  7054. "help": "UBX-UPD-SOS Create Clear File in Flash"},
  7055. }
  7056. # end class ubx