ubxtool 291 KB

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