123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482 |
- /* Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of The Linux Foundation, nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
- #define LOG_NDEBUG 0
- #define LOG_TAG "LocSvc_GnssAdapter"
- #include <inttypes.h>
- #include <sys/stat.h>
- #include <errno.h>
- #include <ctype.h>
- #include <cutils/properties.h>
- #include <math.h>
- #include <arpa/inet.h>
- #include <netinet/in.h>
- #include <netdb.h>
- #include <GnssAdapter.h>
- #include <string>
- #include <sstream>
- #include <loc_log.h>
- #include <loc_nmea.h>
- #include <Agps.h>
- #include <SystemStatus.h>
- #include <vector>
- #include <loc_misc_utils.h>
- #include <gps_extended_c.h>
- #include <sys/stat.h>
- #define RAD2DEG (180.0 / M_PI)
- #define DEG2RAD (M_PI / 180.0)
- #define PROCESS_NAME_ENGINE_SERVICE "engine-service"
- #ifdef FEATURE_AUTOMOTIVE
- #define MIN_TRACKING_INTERVAL (100) // 100 msec
- #else
- #define MIN_TRACKING_INTERVAL (1000) // 1 sec
- #endif //FEATURE_AUTOMOTIVE
- #define BILLION_NSEC (1000000000ULL)
- #define NMEA_MIN_THRESHOLD_MSEC (99)
- #define NMEA_MAX_THRESHOLD_MSEC (975)
- #define DGNSS_RANGE_UPDATE_TIME_10MIN_IN_MILLI 600000
- using namespace loc_core;
- static int loadEngHubForExternalEngine = 0;
- static loc_param_s_type izatConfParamTable[] = {
- {"LOAD_ENGHUB_FOR_EXTERNAL_ENGINE", &loadEngHubForExternalEngine, nullptr,'n'}
- };
- /* Method to fetch status cb from loc_net_iface library */
- typedef AgpsCbInfo& (*LocAgpsGetAgpsCbInfo)(LocAgpsOpenResultCb openResultCb,
- LocAgpsCloseResultCb closeResultCb, void* userDataPtr);
- static void agpsOpenResultCb (bool isSuccess, AGpsExtType agpsType, const char* apn,
- AGpsBearerType bearerType, void* userDataPtr);
- static void agpsCloseResultCb (bool isSuccess, AGpsExtType agpsType, void* userDataPtr);
- typedef const CdfwInterface* (*getCdfwInterface)();
- typedef void getPdnTypeFromWds(const std::string& apnName, std::function<void(int)> pdnCb);
- GnssReportLoggerUtil::GnssReportLoggerUtil() : mLogLatency(nullptr) {
- int loadDiagIfaceLib = 1;
- const loc_param_s_type gps_conf_params[] = {
- {"LOC_DIAGIFACE_ENABLED", &loadDiagIfaceLib, nullptr, 'n'}
- };
- UTIL_READ_CONF(LOC_PATH_GPS_CONF, gps_conf_params);
- LOC_LOGi("Loc_DiagIface_enabled: %d", loadDiagIfaceLib);
- if (0 != loadDiagIfaceLib) {
- const char* libname = "liblocdiagiface.so";
- void* libHandle = nullptr;
- mLogLatency = (LogGnssLatency)dlGetSymFromLib(libHandle, libname, "LogGnssLatency");
- if (nullptr == mLogLatency) {
- LOC_LOGw("DiagIface mLogLatency is null");
- }
- }
- }
- inline bool GnssReportLoggerUtil::isLogEnabled() {
- return (mLogLatency != nullptr);
- }
- inline void GnssReportLoggerUtil::log(const GnssLatencyInfo& gnssLatencyMeasInfo) {
- if (mLogLatency != nullptr) {
- mLogLatency(gnssLatencyMeasInfo);
- }
- }
- GnssAdapter::GnssAdapter() :
- LocAdapterBase(0,
- LocContext::getLocContext(LocContext::mLocationHalName),
- true, nullptr, true),
- mEngHubProxy(new EngineHubProxyBase()),
- mNHzNeeded(false),
- mSPEAlreadyRunningAtHighestInterval(false),
- mLocPositionMode(),
- mGnssSvIdUsedInPosition(),
- mGnssSvIdUsedInPosAvail(false),
- mGnssMbSvIdUsedInPosition{},
- mGnssMbSvIdUsedInPosAvail(false),
- mControlCallbacks(),
- mAfwControlId(0),
- mNmeaMask(0),
- mGnssSvIdConfig(),
- mGnssSeconaryBandConfig(),
- mGnssSvTypeConfig(),
- mGnssSvTypeConfigCb(nullptr),
- mSupportNfwControl(true),
- mLocConfigInfo{},
- mNiData(),
- mAgpsManager(),
- mNfwCb(NULL),
- mIsE911Session(NULL),
- mIsMeasCorrInterfaceOpen(false),
- mIsAntennaInfoInterfaceOpened(false),
- mQDgnssListenerHDL(nullptr),
- mCdfwInterface(nullptr),
- mDGnssNeedReport(false),
- mDGnssDataUsage(false),
- mOdcpiRequestCb(nullptr),
- mOdcpiStateMask(0),
- mCallbackPriority(OdcpiPrioritytype::ODCPI_HANDLER_PRIORITY_LOW),
- mOdcpiTimer(this),
- mOdcpiRequest(),
- mLastDeleteAidingDataTime(0),
- mSystemStatus(SystemStatus::getInstance(mMsgTask)),
- mServerUrl(":"),
- mXtraObserver(mSystemStatus->getOsObserver(), mMsgTask),
- mLocSystemInfo{},
- mSystemPowerState(POWER_STATE_UNKNOWN),
- mBlockCPIInfo{},
- mPowerOn(false),
- mDreIntEnabled(false),
- mNativeAgpsHandler(mSystemStatus->getOsObserver(), *this),
- mGnssEnergyConsumedCb(nullptr),
- mPowerStateCb(nullptr),
- mSendNmeaConsent(false),
- mDgnssState(0),
- mDgnssLastNmeaBootTimeMilli(0),
- mPowerIndicationCb(nullptr),
- mGnssPowerStatisticsInit(false),
- mBootReferenceEnergy(0),
- mPowerElapsedRealTimeCal(30000000),
- mAddressRequestCb(nullptr),
- mPositionElapsedRealTimeCal(30000000)
- {
- LOC_LOGD("%s]: Constructor %p", __func__, this);
- mLocPositionMode.mode = LOC_POSITION_MODE_INVALID;
- pthread_condattr_t condAttr;
- pthread_condattr_init(&condAttr);
- pthread_condattr_setclock(&condAttr, CLOCK_REALTIME);
- pthread_cond_init(&mNiData.session.tCond, &condAttr);
- pthread_cond_init(&mNiData.sessionEs.tCond, &condAttr);
- pthread_condattr_destroy(&condAttr);
- /* Set ATL open/close callbacks */
- AgpsAtlOpenStatusCb atlOpenStatusCb =
- [this](int handle, int isSuccess, char* apn, uint32_t apnLen,
- AGpsBearerType bearerType, AGpsExtType agpsType,
- LocApnTypeMask mask) {
- mLocApi->atlOpenStatus(
- handle, isSuccess, apn, apnLen, bearerType, agpsType, mask);
- };
- AgpsAtlCloseStatusCb atlCloseStatusCb =
- [this](int handle, int isSuccess) {
- mLocApi->atlCloseStatus(handle, isSuccess);
- };
- mAgpsManager.registerATLCallbacks(atlOpenStatusCb, atlCloseStatusCb);
- readConfigCommand();
- initDefaultAgpsCommand();
- initCDFWServiceCommand();
- initEngHubProxyCommand();
- // at last step, let us inform adapater base that we are done
- // with initialization, e.g.: ready to process handleEngineUpEvent
- doneInit();
- }
- void
- GnssAdapter::setControlCallbacksCommand(LocationControlCallbacks& controlCallbacks)
- {
- struct MsgSetControlCallbacks : public LocMsg {
- GnssAdapter& mAdapter;
- const LocationControlCallbacks mControlCallbacks;
- inline MsgSetControlCallbacks(GnssAdapter& adapter,
- LocationControlCallbacks& controlCallbacks) :
- LocMsg(),
- mAdapter(adapter),
- mControlCallbacks(controlCallbacks) {}
- inline virtual void proc() const {
- mAdapter.setControlCallbacks(mControlCallbacks);
- }
- };
- sendMsg(new MsgSetControlCallbacks(*this, controlCallbacks));
- }
- void
- GnssAdapter::convertOptions(LocPosMode& out, const TrackingOptions& trackingOptions)
- {
- switch (trackingOptions.mode) {
- case GNSS_SUPL_MODE_MSB:
- out.mode = LOC_POSITION_MODE_MS_BASED;
- break;
- case GNSS_SUPL_MODE_MSA:
- out.mode = LOC_POSITION_MODE_MS_ASSISTED;
- break;
- default:
- out.mode = LOC_POSITION_MODE_STANDALONE;
- break;
- }
- out.share_position = true;
- out.min_interval = trackingOptions.minInterval;
- out.powerMode = trackingOptions.powerMode;
- out.timeBetweenMeasurements = trackingOptions.tbm;
- }
- bool
- GnssAdapter::checkAndSetSPEToRunforNHz(TrackingOptions & out) {
- // first check if NHz meas is needed at all, if not, just return false
- // if a NHz capable engine is subscribed for NHz measurement or NHz positions,
- // always run the SPE only session at 100ms TBF.
- // If SPE session is already set to highest interval, no need to start it again.
- bool isSPERunningAtHighestInterval = false;
- if (!mNHzNeeded) {
- LOC_LOGd("No nHz session needed.");
- } else if (mSPEAlreadyRunningAtHighestInterval) {
- LOC_LOGd("SPE is already running at highest interval.");
- isSPERunningAtHighestInterval = true;
- } else if (out.minInterval > MIN_TRACKING_INTERVAL) {
- out.minInterval = MIN_TRACKING_INTERVAL;
- LOC_LOGd("nHz session is needed, starting SPE only session at 100ms TBF.");
- mSPEAlreadyRunningAtHighestInterval = true;
- }
- return isSPERunningAtHighestInterval;
- }
- void
- GnssAdapter::convertLocation(Location& out, const UlpLocation& ulpLocation,
- const GpsLocationExtended& locationExtended)
- {
- memset(&out, 0, sizeof(Location));
- out.size = sizeof(Location);
- if (LOC_GPS_LOCATION_HAS_LAT_LONG & ulpLocation.gpsLocation.flags) {
- out.flags |= LOCATION_HAS_LAT_LONG_BIT;
- out.latitude = ulpLocation.gpsLocation.latitude;
- out.longitude = ulpLocation.gpsLocation.longitude;
- }
- if (LOC_GPS_LOCATION_HAS_ALTITUDE & ulpLocation.gpsLocation.flags) {
- out.flags |= LOCATION_HAS_ALTITUDE_BIT;
- out.altitude = ulpLocation.gpsLocation.altitude;
- }
- if (LOC_GPS_LOCATION_HAS_SPEED & ulpLocation.gpsLocation.flags) {
- out.flags |= LOCATION_HAS_SPEED_BIT;
- out.speed = ulpLocation.gpsLocation.speed;
- }
- if (LOC_GPS_LOCATION_HAS_BEARING & ulpLocation.gpsLocation.flags) {
- out.flags |= LOCATION_HAS_BEARING_BIT;
- out.bearing = ulpLocation.gpsLocation.bearing;
- }
- if (LOC_GPS_LOCATION_HAS_ACCURACY & ulpLocation.gpsLocation.flags) {
- out.flags |= LOCATION_HAS_ACCURACY_BIT;
- out.accuracy = ulpLocation.gpsLocation.accuracy;
- }
- if (GPS_LOCATION_EXTENDED_HAS_VERT_UNC & locationExtended.flags) {
- out.flags |= LOCATION_HAS_VERTICAL_ACCURACY_BIT;
- out.verticalAccuracy = locationExtended.vert_unc;
- }
- if (GPS_LOCATION_EXTENDED_HAS_SPEED_UNC & locationExtended.flags) {
- out.flags |= LOCATION_HAS_SPEED_ACCURACY_BIT;
- out.speedAccuracy = locationExtended.speed_unc;
- }
- if (GPS_LOCATION_EXTENDED_HAS_BEARING_UNC & locationExtended.flags) {
- out.flags |= LOCATION_HAS_BEARING_ACCURACY_BIT;
- out.bearingAccuracy = locationExtended.bearing_unc;
- }
- if (GPS_LOCATION_EXTENDED_HAS_CONFORMITY_INDEX & locationExtended.flags) {
- out.flags |= LOCATION_HAS_CONFORMITY_INDEX_BIT;
- out.conformityIndex = locationExtended.conformityIndex;
- }
- out.timestamp = ulpLocation.gpsLocation.timestamp;
- if (GPS_LOCATION_EXTENDED_HAS_POS_TECH_MASK & locationExtended.flags) {
- out.flags |= LOCATION_HAS_TECH_MASK_BIT;
- }
- if (LOC_POS_TECH_MASK_SATELLITE & locationExtended.tech_mask) {
- out.techMask |= LOCATION_TECHNOLOGY_GNSS_BIT;
- }
- if (LOC_POS_TECH_MASK_CELLID & locationExtended.tech_mask) {
- out.techMask |= LOCATION_TECHNOLOGY_CELL_BIT;
- }
- if (LOC_POS_TECH_MASK_WIFI & locationExtended.tech_mask) {
- out.techMask |= LOCATION_TECHNOLOGY_WIFI_BIT;
- }
- if (LOC_POS_TECH_MASK_SENSORS & locationExtended.tech_mask) {
- out.techMask |= LOCATION_TECHNOLOGY_SENSORS_BIT;
- }
- if (LOC_POS_TECH_MASK_REFERENCE_LOCATION & locationExtended.tech_mask) {
- out.techMask |= LOCATION_TECHNOLOGY_REFERENCE_LOCATION_BIT;
- }
- if (LOC_POS_TECH_MASK_INJECTED_COARSE_POSITION & locationExtended.tech_mask) {
- out.techMask |= LOCATION_TECHNOLOGY_INJECTED_COARSE_POSITION_BIT;
- }
- if (LOC_POS_TECH_MASK_AFLT & locationExtended.tech_mask) {
- out.techMask |= LOCATION_TECHNOLOGY_AFLT_BIT;
- }
- if (LOC_POS_TECH_MASK_HYBRID & locationExtended.tech_mask) {
- out.techMask |= LOCATION_TECHNOLOGY_HYBRID_BIT;
- }
- if (LOC_POS_TECH_MASK_PPE & locationExtended.tech_mask) {
- out.techMask |= LOCATION_TECHNOLOGY_PPE_BIT;
- }
- if (LOC_POS_TECH_MASK_VEH & locationExtended.tech_mask) {
- out.techMask |= LOCATION_TECHNOLOGY_VEH_BIT;
- }
- if (LOC_POS_TECH_MASK_VIS & locationExtended.tech_mask) {
- out.techMask |= LOCATION_TECHNOLOGY_VIS_BIT;
- }
- if (LOC_NAV_MASK_DGNSS_CORRECTION & locationExtended.navSolutionMask) {
- out.techMask |= LOCATION_TECHNOLOGY_DGNSS_BIT;
- }
- if (LOC_GPS_LOCATION_HAS_SPOOF_MASK & ulpLocation.gpsLocation.flags) {
- out.flags |= LOCATION_HAS_SPOOF_MASK_BIT;
- out.spoofMask = ulpLocation.gpsLocation.spoof_mask;
- }
- out.qualityType = LOCATION_STANDALONE_QUALITY_TYPE;
- if (GPS_LOCATION_EXTENDED_HAS_NAV_SOLUTION_MASK & locationExtended.flags) {
- out.flags |= LOCATION_HAS_QUALITY_TYPE_BIT;
- if ((LOC_NAV_MASK_RTK_FIXED_CORRECTION & locationExtended.navSolutionMask) &&
- (LOC_NAV_MASK_RTK_CORRECTION & locationExtended.navSolutionMask)) {
- out.qualityType = LOCATION_FIXED_QUALITY_TYPE;
- } else if (LOC_NAV_MASK_RTK_CORRECTION & locationExtended.navSolutionMask) {
- out.qualityType = LOCATION_FLOAT_QUALITY_TYPE;
- } else if (LOC_NAV_MASK_PPP_CORRECTION & locationExtended.navSolutionMask) {
- //If HEPE<5cm, we shall claim 'FIXED'; otherwise, 'FLOAT'
- out.qualityType = LOCATION_FLOAT_QUALITY_TYPE;
- if ((LOC_GPS_LOCATION_HAS_ACCURACY & ulpLocation.gpsLocation.flags) &&
- (ulpLocation.gpsLocation.accuracy < 0.05)) {
- out.qualityType = LOCATION_FIXED_QUALITY_TYPE;
- }
- } else if (LOC_NAV_MASK_DGNSS_CORRECTION & locationExtended.navSolutionMask) {
- out.qualityType = LOCATION_DGNSS_QUALITY_TYPE;
- }
- }
- }
- void GnssAdapter::fillElapsedRealTime(const GpsLocationExtended& locationExtended,
- Location& out) {
- if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_GPS_TIME) {
- int64_t elapsedTimeNs = 0;
- float elapsedTimeUncMsec = 0.0;
- if (mPositionElapsedRealTimeCal.getElapsedRealtimeForGpsTime(
- locationExtended.gpsTime, elapsedTimeNs, elapsedTimeUncMsec)) {
- out.flags |= LOCATION_HAS_ELAPSED_REAL_TIME_BIT;
- out.elapsedRealTime = elapsedTimeNs;
- out.elapsedRealTimeUnc = (int64_t) (elapsedTimeUncMsec * 1000000);
- }
- #ifndef FEATURE_AUTOMOTIVE
- else if (out.timestamp > 0) {
- int64_t locationTimeNanos = (int64_t)out.timestamp * 1000000;
- bool isCurDataTimeTrustable = (out.timestamp % mLocPositionMode.min_interval == 0);
- out.flags |= LOCATION_HAS_ELAPSED_REAL_TIME_BIT;
- out.elapsedRealTime = mPositionElapsedRealTimeCal.getElapsedRealtimeEstimateNanos(
- locationTimeNanos, isCurDataTimeTrustable,
- (int64_t)mLocPositionMode.min_interval * 1000000);
- out.elapsedRealTimeUnc = mPositionElapsedRealTimeCal.getElapsedRealtimeUncNanos();
- }
- #endif //FEATURE_AUTOMOTIVE
- }
- }
- /* This is utility routine that computes number of SV used
- in the fix from the svUsedIdsMask.
- */
- #define MAX_SV_CNT_SUPPORTED_IN_ONE_CONSTELLATION 64
- uint16_t GnssAdapter::getNumSvUsed(uint64_t svUsedIdsMask,
- int totalSvCntInThisConstellation)
- {
- if (totalSvCntInThisConstellation > MAX_SV_CNT_SUPPORTED_IN_ONE_CONSTELLATION) {
- LOC_LOGe ("error: total SV count in this constellation %d exceeded limit of %d",
- totalSvCntInThisConstellation, MAX_SV_CNT_SUPPORTED_IN_ONE_CONSTELLATION);
- return 0;
- }
- uint16_t numSvUsed = 0;
- uint64_t mask = 0x1;
- for (int i = 0; i < totalSvCntInThisConstellation; i++) {
- if (svUsedIdsMask & mask) {
- numSvUsed++;
- }
- mask <<= 1;
- }
- return numSvUsed;
- }
- void
- GnssAdapter::convertLocationInfo(GnssLocationInfoNotification& out,
- const GpsLocationExtended& locationExtended,
- enum loc_sess_status status)
- {
- out.size = sizeof(GnssLocationInfoNotification);
- if (GPS_LOCATION_EXTENDED_HAS_ALTITUDE_MEAN_SEA_LEVEL & locationExtended.flags) {
- out.flags |= GNSS_LOCATION_INFO_ALTITUDE_MEAN_SEA_LEVEL_BIT;
- out.altitudeMeanSeaLevel = locationExtended.altitudeMeanSeaLevel;
- }
- if (GPS_LOCATION_EXTENDED_HAS_EXT_DOP & locationExtended.flags) {
- out.flags |= (GNSS_LOCATION_INFO_DOP_BIT|GNSS_LOCATION_INFO_EXT_DOP_BIT);
- out.pdop = locationExtended.extDOP.PDOP;
- out.hdop = locationExtended.extDOP.HDOP;
- out.vdop = locationExtended.extDOP.VDOP;
- out.gdop = locationExtended.extDOP.GDOP;
- out.tdop = locationExtended.extDOP.TDOP;
- } else if (GPS_LOCATION_EXTENDED_HAS_DOP & locationExtended.flags) {
- out.flags |= GNSS_LOCATION_INFO_DOP_BIT;
- out.pdop = locationExtended.pdop;
- out.hdop = locationExtended.hdop;
- out.vdop = locationExtended.vdop;
- }
- if (GPS_LOCATION_EXTENDED_HAS_MAG_DEV & locationExtended.flags) {
- out.flags |= GNSS_LOCATION_INFO_MAGNETIC_DEVIATION_BIT;
- out.magneticDeviation = locationExtended.magneticDeviation;
- }
- if (GPS_LOCATION_EXTENDED_HAS_HOR_RELIABILITY & locationExtended.flags) {
- out.flags |= GNSS_LOCATION_INFO_HOR_RELIABILITY_BIT;
- switch (locationExtended.horizontal_reliability) {
- case LOC_RELIABILITY_VERY_LOW:
- out.horReliability = LOCATION_RELIABILITY_VERY_LOW;
- break;
- case LOC_RELIABILITY_LOW:
- out.horReliability = LOCATION_RELIABILITY_LOW;
- break;
- case LOC_RELIABILITY_MEDIUM:
- out.horReliability = LOCATION_RELIABILITY_MEDIUM;
- break;
- case LOC_RELIABILITY_HIGH:
- out.horReliability = LOCATION_RELIABILITY_HIGH;
- break;
- default:
- out.horReliability = LOCATION_RELIABILITY_NOT_SET;
- break;
- }
- }
- if (GPS_LOCATION_EXTENDED_HAS_VERT_RELIABILITY & locationExtended.flags) {
- out.flags |= GNSS_LOCATION_INFO_VER_RELIABILITY_BIT;
- switch (locationExtended.vertical_reliability) {
- case LOC_RELIABILITY_VERY_LOW:
- out.verReliability = LOCATION_RELIABILITY_VERY_LOW;
- break;
- case LOC_RELIABILITY_LOW:
- out.verReliability = LOCATION_RELIABILITY_LOW;
- break;
- case LOC_RELIABILITY_MEDIUM:
- out.verReliability = LOCATION_RELIABILITY_MEDIUM;
- break;
- case LOC_RELIABILITY_HIGH:
- out.verReliability = LOCATION_RELIABILITY_HIGH;
- break;
- default:
- out.verReliability = LOCATION_RELIABILITY_NOT_SET;
- break;
- }
- }
- if (GPS_LOCATION_EXTENDED_HAS_HOR_ELIP_UNC_MAJOR & locationExtended.flags) {
- out.flags |= GNSS_LOCATION_INFO_HOR_ACCURACY_ELIP_SEMI_MAJOR_BIT;
- out.horUncEllipseSemiMajor = locationExtended.horUncEllipseSemiMajor;
- }
- if (GPS_LOCATION_EXTENDED_HAS_HOR_ELIP_UNC_MINOR & locationExtended.flags) {
- out.flags |= GNSS_LOCATION_INFO_HOR_ACCURACY_ELIP_SEMI_MINOR_BIT;
- out.horUncEllipseSemiMinor = locationExtended.horUncEllipseSemiMinor;
- }
- if (GPS_LOCATION_EXTENDED_HAS_HOR_ELIP_UNC_AZIMUTH & locationExtended.flags) {
- out.flags |= GNSS_LOCATION_INFO_HOR_ACCURACY_ELIP_AZIMUTH_BIT;
- out.horUncEllipseOrientAzimuth = locationExtended.horUncEllipseOrientAzimuth;
- }
- if (GPS_LOCATION_EXTENDED_HAS_NORTH_STD_DEV & locationExtended.flags) {
- out.flags |= GNSS_LOCATION_INFO_NORTH_STD_DEV_BIT;
- out.northStdDeviation = locationExtended.northStdDeviation;
- }
- if (GPS_LOCATION_EXTENDED_HAS_EAST_STD_DEV & locationExtended.flags) {
- out.flags |= GNSS_LOCATION_INFO_EAST_STD_DEV_BIT;
- out.eastStdDeviation = locationExtended.eastStdDeviation;
- }
- if (GPS_LOCATION_EXTENDED_HAS_NORTH_VEL & locationExtended.flags) {
- out.flags |= GNSS_LOCATION_INFO_NORTH_VEL_BIT;
- out.northVelocity = locationExtended.northVelocity;
- }
- if (GPS_LOCATION_EXTENDED_HAS_NORTH_VEL_UNC & locationExtended.flags) {
- out.flags |= GNSS_LOCATION_INFO_NORTH_VEL_UNC_BIT;
- out.northVelocityStdDeviation = locationExtended.northVelocityStdDeviation;
- }
- if (GPS_LOCATION_EXTENDED_HAS_EAST_VEL & locationExtended.flags) {
- out.flags |= GNSS_LOCATION_INFO_EAST_VEL_BIT;
- out.eastVelocity = locationExtended.eastVelocity;
- }
- if (GPS_LOCATION_EXTENDED_HAS_EAST_VEL_UNC & locationExtended.flags) {
- out.flags |= GNSS_LOCATION_INFO_EAST_VEL_UNC_BIT;
- out.eastVelocityStdDeviation = locationExtended.eastVelocityStdDeviation;
- }
- if (GPS_LOCATION_EXTENDED_HAS_UP_VEL & locationExtended.flags) {
- out.flags |= GNSS_LOCATION_INFO_UP_VEL_BIT;
- out.upVelocity = locationExtended.upVelocity;
- }
- if (GPS_LOCATION_EXTENDED_HAS_UP_VEL_UNC & locationExtended.flags) {
- out.flags |= GNSS_LOCATION_INFO_UP_VEL_UNC_BIT;
- out.upVelocityStdDeviation = locationExtended.upVelocityStdDeviation;
- }
- if (GPS_LOCATION_EXTENDED_HAS_GNSS_SV_USED_DATA & locationExtended.flags) {
- out.flags |= GNSS_LOCATION_INFO_GNSS_SV_USED_DATA_BIT;
- out.svUsedInPosition.gpsSvUsedIdsMask =
- locationExtended.gnss_sv_used_ids.gps_sv_used_ids_mask;
- out.svUsedInPosition.gloSvUsedIdsMask =
- locationExtended.gnss_sv_used_ids.glo_sv_used_ids_mask;
- out.svUsedInPosition.galSvUsedIdsMask =
- locationExtended.gnss_sv_used_ids.gal_sv_used_ids_mask;
- out.svUsedInPosition.bdsSvUsedIdsMask =
- locationExtended.gnss_sv_used_ids.bds_sv_used_ids_mask;
- out.svUsedInPosition.qzssSvUsedIdsMask =
- locationExtended.gnss_sv_used_ids.qzss_sv_used_ids_mask;
- out.svUsedInPosition.navicSvUsedIdsMask =
- locationExtended.gnss_sv_used_ids.navic_sv_used_ids_mask;
- out.flags |= GNSS_LOCATION_INFO_NUM_SV_USED_IN_POSITION_BIT;
- out.numSvUsedInPosition = getNumSvUsed(out.svUsedInPosition.gpsSvUsedIdsMask,
- GPS_SV_PRN_MAX - GPS_SV_PRN_MIN + 1);
- out.numSvUsedInPosition += getNumSvUsed(out.svUsedInPosition.gloSvUsedIdsMask,
- GLO_SV_PRN_MAX - GLO_SV_PRN_MIN + 1);
- out.numSvUsedInPosition += getNumSvUsed(out.svUsedInPosition.qzssSvUsedIdsMask,
- QZSS_SV_PRN_MAX - QZSS_SV_PRN_MIN + 1);
- out.numSvUsedInPosition += getNumSvUsed(out.svUsedInPosition.bdsSvUsedIdsMask,
- BDS_SV_PRN_MAX - BDS_SV_PRN_MIN + 1);
- out.numSvUsedInPosition += getNumSvUsed(out.svUsedInPosition.galSvUsedIdsMask,
- GAL_SV_PRN_MAX - GAL_SV_PRN_MIN + 1);
- out.numSvUsedInPosition += getNumSvUsed(out.svUsedInPosition.navicSvUsedIdsMask,
- NAVIC_SV_PRN_MAX - NAVIC_SV_PRN_MIN + 1);
- out.numOfMeasReceived = locationExtended.numOfMeasReceived;
- for (int idx =0; idx < locationExtended.numOfMeasReceived; idx++) {
- out.measUsageInfo[idx].gnssSignalType =
- locationExtended.measUsageInfo[idx].gnssSignalType;
- out.measUsageInfo[idx].gnssSvId =
- locationExtended.measUsageInfo[idx].gnssSvId;
- out.measUsageInfo[idx].gnssConstellation =
- locationExtended.measUsageInfo[idx].gnssConstellation;
- }
- }
- if (GPS_LOCATION_EXTENDED_HAS_NAV_SOLUTION_MASK & locationExtended.flags) {
- out.flags |= GNSS_LOCATION_INFO_NAV_SOLUTION_MASK_BIT;
- out.navSolutionMask = locationExtended.navSolutionMask;
- }
- if (GPS_LOCATION_EXTENDED_HAS_POS_DYNAMICS_DATA & locationExtended.flags) {
- out.flags |= GPS_LOCATION_EXTENDED_HAS_POS_DYNAMICS_DATA;
- if (locationExtended.bodyFrameData.bodyFrameDataMask &
- LOCATION_NAV_DATA_HAS_LONG_ACCEL_BIT) {
- out.bodyFrameData.bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_LONG_ACCEL_BIT;
- }
- if (locationExtended.bodyFrameData.bodyFrameDataMask &
- LOCATION_NAV_DATA_HAS_LAT_ACCEL_BIT) {
- out.bodyFrameData.bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_LAT_ACCEL_BIT;
- }
- if (locationExtended.bodyFrameData.bodyFrameDataMask &
- LOCATION_NAV_DATA_HAS_VERT_ACCEL_BIT) {
- out.bodyFrameData.bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_VERT_ACCEL_BIT;
- }
- if (locationExtended.bodyFrameData.bodyFrameDataMask &
- LOCATION_NAV_DATA_HAS_YAW_RATE_BIT) {
- out.bodyFrameData.bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_YAW_RATE_BIT;
- }
- if (locationExtended.bodyFrameData.bodyFrameDataMask &
- LOCATION_NAV_DATA_HAS_PITCH_BIT) {
- out.bodyFrameData.bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_PITCH_BIT;
- }
- if (locationExtended.bodyFrameData.bodyFrameDataMask &
- LOCATION_NAV_DATA_HAS_LONG_ACCEL_UNC_BIT) {
- out.bodyFrameData.bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_LONG_ACCEL_UNC_BIT;
- }
- if (locationExtended.bodyFrameData.bodyFrameDataMask &
- LOCATION_NAV_DATA_HAS_LAT_ACCEL_UNC_BIT) {
- out.bodyFrameData.bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_LAT_ACCEL_UNC_BIT;
- }
- if (locationExtended.bodyFrameData.bodyFrameDataMask &
- LOCATION_NAV_DATA_HAS_VERT_ACCEL_UNC_BIT) {
- out.bodyFrameData.bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_VERT_ACCEL_UNC_BIT;
- }
- if (locationExtended.bodyFrameData.bodyFrameDataMask &
- LOCATION_NAV_DATA_HAS_YAW_RATE_UNC_BIT) {
- out.bodyFrameData.bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_YAW_RATE_UNC_BIT;
- }
- if (locationExtended.bodyFrameData.bodyFrameDataMask &
- LOCATION_NAV_DATA_HAS_PITCH_UNC_BIT) {
- out.bodyFrameData.bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_PITCH_UNC_BIT;
- }
- if (locationExtended.bodyFrameDataExt.bodyFrameDataMask &
- LOCATION_NAV_DATA_HAS_PITCH_RATE_BIT) {
- out.bodyFrameDataExt.bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_PITCH_RATE_BIT;
- }
- if (locationExtended.bodyFrameDataExt.bodyFrameDataMask &
- LOCATION_NAV_DATA_HAS_PITCH_RATE_UNC_BIT) {
- out.bodyFrameDataExt.bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_PITCH_RATE_UNC_BIT;
- }
- if (locationExtended.bodyFrameDataExt.bodyFrameDataMask &
- LOCATION_NAV_DATA_HAS_ROLL_BIT) {
- out.bodyFrameDataExt.bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_ROLL_BIT;
- }
- if (locationExtended.bodyFrameDataExt.bodyFrameDataMask &
- LOCATION_NAV_DATA_HAS_ROLL_UNC_BIT) {
- out.bodyFrameDataExt.bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_ROLL_UNC_BIT;
- }
- if (locationExtended.bodyFrameDataExt.bodyFrameDataMask &
- LOCATION_NAV_DATA_HAS_ROLL_RATE_BIT) {
- out.bodyFrameDataExt.bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_ROLL_RATE_BIT;
- }
- if (locationExtended.bodyFrameDataExt.bodyFrameDataMask &
- LOCATION_NAV_DATA_HAS_ROLL_RATE_UNC_BIT) {
- out.bodyFrameDataExt.bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_ROLL_RATE_UNC_BIT;
- }
- if (locationExtended.bodyFrameDataExt.bodyFrameDataMask &
- LOCATION_NAV_DATA_HAS_YAW_BIT) {
- out.bodyFrameDataExt.bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_YAW_BIT;
- }
- if (locationExtended.bodyFrameDataExt.bodyFrameDataMask &
- LOCATION_NAV_DATA_HAS_YAW_UNC_BIT) {
- out.bodyFrameDataExt.bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_YAW_UNC_BIT;
- }
- out.bodyFrameData.longAccel = locationExtended.bodyFrameData.longAccel;
- out.bodyFrameData.latAccel = locationExtended.bodyFrameData.latAccel;
- out.bodyFrameData.vertAccel = locationExtended.bodyFrameData.vertAccel;
- out.bodyFrameData.yawRate = locationExtended.bodyFrameData.yawRate;
- out.bodyFrameData.pitch = locationExtended.bodyFrameData.pitch;
- out.bodyFrameData.longAccelUnc = locationExtended.bodyFrameData.longAccelUnc;
- out.bodyFrameData.latAccelUnc = locationExtended.bodyFrameData.latAccelUnc;
- out.bodyFrameData.vertAccelUnc = locationExtended.bodyFrameData.vertAccelUnc;
- out.bodyFrameData.yawRateUnc = locationExtended.bodyFrameData.yawRateUnc;
- out.bodyFrameData.pitchUnc = locationExtended.bodyFrameData.pitchUnc;
- out.bodyFrameDataExt.pitchRate = locationExtended.bodyFrameDataExt.pitchRate;
- out.bodyFrameDataExt.pitchRateUnc = locationExtended.bodyFrameDataExt.pitchRateUnc;
- out.bodyFrameDataExt.roll = locationExtended.bodyFrameDataExt.roll;
- out.bodyFrameDataExt.rollUnc = locationExtended.bodyFrameDataExt.rollUnc;
- out.bodyFrameDataExt.rollRate = locationExtended.bodyFrameDataExt.rollRate;
- out.bodyFrameDataExt.rollRateUnc = locationExtended.bodyFrameDataExt.rollRateUnc;
- out.bodyFrameDataExt.yaw = locationExtended.bodyFrameDataExt.yaw;
- out.bodyFrameDataExt.yawUnc = locationExtended.bodyFrameDataExt.yawUnc;
- }
- // Validity of this structure is established from the timeSrc of the GnssSystemTime structure.
- out.gnssSystemTime = locationExtended.gnssSystemTime;
- if (GPS_LOCATION_EXTENDED_HAS_LEAP_SECONDS & locationExtended.flags) {
- out.flags |= GNSS_LOCATION_INFO_LEAP_SECONDS_BIT;
- out.leapSeconds = locationExtended.leapSeconds;
- }
- if (GPS_LOCATION_EXTENDED_HAS_TIME_UNC & locationExtended.flags) {
- out.flags |= GNSS_LOCATION_INFO_TIME_UNC_BIT;
- out.timeUncMs = locationExtended.timeUncMs;
- }
- if (GPS_LOCATION_EXTENDED_HAS_CALIBRATION_CONFIDENCE & locationExtended.flags) {
- out.flags |= GNSS_LOCATION_INFO_CALIBRATION_CONFIDENCE_BIT;
- out.calibrationConfidence = locationExtended.calibrationConfidence;
- }
- if (GPS_LOCATION_EXTENDED_HAS_CALIBRATION_STATUS & locationExtended.flags) {
- out.flags |= GNSS_LOCATION_INFO_CALIBRATION_STATUS_BIT;
- out.calibrationStatus = locationExtended.calibrationStatus;
- }
- if (GPS_LOCATION_EXTENDED_HAS_OUTPUT_ENG_TYPE & locationExtended.flags) {
- out.flags |= GNSS_LOCATION_INFO_OUTPUT_ENG_TYPE_BIT;
- out.locOutputEngType = locationExtended.locOutputEngType;
- }
- if (GPS_LOCATION_EXTENDED_HAS_OUTPUT_ENG_MASK & locationExtended.flags) {
- out.flags |= GNSS_LOCATION_INFO_OUTPUT_ENG_MASK_BIT;
- out.locOutputEngMask = locationExtended.locOutputEngMask;
- }
- if (GPS_LOCATION_EXTENDED_HAS_CONFORMITY_INDEX & locationExtended.flags) {
- out.flags |= GNSS_LOCATION_INFO_CONFORMITY_INDEX_BIT;
- out.conformityIndex = locationExtended.conformityIndex;
- }
- if (GPS_LOCATION_EXTENDED_HAS_LLA_VRP_BASED & locationExtended.flags) {
- out.flags |= GNSS_LOCATION_INFO_LLA_VRP_BASED_BIT;
- out.llaVRPBased = locationExtended.llaVRPBased;
- }
- if (GPS_LOCATION_EXTENDED_HAS_ENU_VELOCITY_LLA_VRP_BASED & locationExtended.flags) {
- out.flags |= GNSS_LOCATION_INFO_ENU_VELOCITY_VRP_BASED_BIT;
- // copy over east, north and up vrp based velocity
- out.enuVelocityVRPBased[0] = locationExtended.enuVelocityVRPBased[0];
- out.enuVelocityVRPBased[1] = locationExtended.enuVelocityVRPBased[1];
- out.enuVelocityVRPBased[2] = locationExtended.enuVelocityVRPBased[2];
- }
- if (GPS_LOCATION_EXTENDED_HAS_DR_SOLUTION_STATUS_MASK & locationExtended.flags) {
- out.flags |= GNSS_LOCATION_INFO_DR_SOLUTION_STATUS_MASK_BIT;
- out.drSolutionStatusMask = locationExtended.drSolutionStatusMask;
- }
- if (GPS_LOCATION_EXTENDED_HAS_ALTITUDE_ASSUMED & locationExtended.flags) {
- out.flags |= GNSS_LOCATION_INFO_ALTITUDE_ASSUMED_BIT;
- out.altitudeAssumed = locationExtended.altitudeAssumed;
- }
- out.flags |= GNSS_LOCATION_INFO_SESSION_STATUS_BIT;
- out.sessionStatus = status;
- }
- inline uint32_t
- GnssAdapter::convertSuplVersion(const GnssConfigSuplVersion suplVersion)
- {
- switch (suplVersion) {
- case GNSS_CONFIG_SUPL_VERSION_2_0_4:
- return 0x00020004;
- case GNSS_CONFIG_SUPL_VERSION_2_0_0:
- return 0x00020000;
- case GNSS_CONFIG_SUPL_VERSION_2_0_2:
- return 0x00020002;
- case GNSS_CONFIG_SUPL_VERSION_1_0_0:
- default:
- return 0x00010000;
- }
- }
- uint32_t
- GnssAdapter::convertLppeCp(const GnssConfigLppeControlPlaneMask lppeControlPlaneMask)
- {
- uint32_t mask = 0;
- if (GNSS_CONFIG_LPPE_CONTROL_PLANE_DBH_BIT & lppeControlPlaneMask) {
- mask |= (1<<0);
- }
- if (GNSS_CONFIG_LPPE_CONTROL_PLANE_WLAN_AP_MEASUREMENTS_BIT & lppeControlPlaneMask) {
- mask |= (1<<1);
- }
- if (GNSS_CONFIG_LPPE_CONTROL_PLANE_SRN_AP_MEASUREMENTS_BIT & lppeControlPlaneMask) {
- mask |= (1<<2);
- }
- if (GNSS_CONFIG_LPPE_CONTROL_PLANE_SENSOR_BARO_MEASUREMENTS_BIT & lppeControlPlaneMask) {
- mask |= (1<<3);
- }
- if (GNSS_CONFIG_LPPE_CONTROL_PLANE_NON_E911_BIT & lppeControlPlaneMask) {
- mask |= (1<<4);
- }
- if (GNSS_CONFIG_LPPE_CONTROL_PLANE_CIV_ADDRESS_BIT & lppeControlPlaneMask) {
- mask |= (1<<5);
- }
- return mask;
- }
- uint32_t
- GnssAdapter::convertLppeUp(const GnssConfigLppeUserPlaneMask lppeUserPlaneMask)
- {
- uint32_t mask = 0;
- if (GNSS_CONFIG_LPPE_USER_PLANE_DBH_BIT & lppeUserPlaneMask) {
- mask |= (1<<0);
- }
- if (GNSS_CONFIG_LPPE_USER_PLANE_WLAN_AP_MEASUREMENTS_BIT & lppeUserPlaneMask) {
- mask |= (1<<1);
- }
- if (GNSS_CONFIG_LPPE_USER_PLANE_SRN_AP_MEASUREMENTS_BIT & lppeUserPlaneMask) {
- mask |= (1<<2);
- }
- if (GNSS_CONFIG_LPPE_USER_PLANE_SENSOR_BARO_MEASUREMENTS_BIT & lppeUserPlaneMask) {
- mask |= (1<<3);
- }
- if (GNSS_CONFIG_LPPE_USER_PLANE_NON_E911_BIT & lppeUserPlaneMask) {
- mask |= (1<<4);
- }
- if (GNSS_CONFIG_LPPE_USER_PLANE_CIV_ADDRESS_BIT & lppeUserPlaneMask) {
- mask |= (1<<5);
- }
- return mask;
- }
- uint32_t
- GnssAdapter::convertAGloProt(const GnssConfigAGlonassPositionProtocolMask aGloPositionProtocolMask)
- {
- uint32_t mask = 0;
- if (GNSS_CONFIG_RRC_CONTROL_PLANE_BIT & aGloPositionProtocolMask) {
- mask |= (1<<0);
- }
- if (GNSS_CONFIG_RRLP_USER_PLANE_BIT & aGloPositionProtocolMask) {
- mask |= (1<<1);
- }
- if (GNSS_CONFIG_LLP_USER_PLANE_BIT & aGloPositionProtocolMask) {
- mask |= (1<<2);
- }
- if (GNSS_CONFIG_LLP_CONTROL_PLANE_BIT & aGloPositionProtocolMask) {
- mask |= (1<<3);
- }
- return mask;
- }
- uint32_t
- GnssAdapter::convertEP4ES(const GnssConfigEmergencyPdnForEmergencySupl emergencyPdnForEmergencySupl)
- {
- switch (emergencyPdnForEmergencySupl) {
- case GNSS_CONFIG_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_YES:
- return 1;
- case GNSS_CONFIG_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_NO:
- default:
- return 0;
- }
- }
- uint32_t
- GnssAdapter::convertSuplEs(const GnssConfigSuplEmergencyServices suplEmergencyServices)
- {
- switch (suplEmergencyServices) {
- case GNSS_CONFIG_SUPL_EMERGENCY_SERVICES_YES:
- return 1;
- case GNSS_CONFIG_SUPL_EMERGENCY_SERVICES_NO:
- default:
- return 0;
- }
- }
- uint32_t
- GnssAdapter::convertSuplMode(const GnssConfigSuplModeMask suplModeMask)
- {
- uint32_t mask = 0;
- if (GNSS_CONFIG_SUPL_MODE_MSB_BIT & suplModeMask) {
- mask |= (1<<0);
- }
- if (GNSS_CONFIG_SUPL_MODE_MSA_BIT & suplModeMask) {
- mask |= (1<<1);
- }
- return mask;
- }
- void GnssAdapter::readNfwLockConfig()
- {
- char nfwCpPackageName[LOC_MAX_PARAM_STRING];
- char nfwSuplPackageName[LOC_MAX_PARAM_STRING];
- char nfwImsPackageName[LOC_MAX_PARAM_STRING];
- char nfwSimPackageName[LOC_MAX_PARAM_STRING];
- char nfwMdtPackageName[LOC_MAX_PARAM_STRING];
- char nfwTlocPackageName[LOC_MAX_PARAM_STRING];
- char nfwRlocPackageName[LOC_MAX_PARAM_STRING];
- char nfwV2xPackageName[LOC_MAX_PARAM_STRING];
- char nfwR1PackageName[LOC_MAX_PARAM_STRING];
- char nfwR2PackageName[LOC_MAX_PARAM_STRING];
- char nfwR3PackageName[LOC_MAX_PARAM_STRING];
- const loc_param_s_type nfw_packages_table[] =
- {
- { "NFW_CLIENT_CP", &nfwCpPackageName, NULL, 's' },
- { "NFW_CLIENT_SUPL", &nfwSuplPackageName, NULL, 's' },
- { "NFW_CLIENT_IMS", &nfwImsPackageName, NULL, 's' },
- { "NFW_CLIENT_SIM", &nfwSimPackageName, NULL, 's' },
- { "NFW_CLIENT_MDT", &nfwMdtPackageName, NULL, 's' },
- { "NFW_CLIENT_TLOC", &nfwTlocPackageName, NULL, 's' },
- { "NFW_CLIENT_RLOC", &nfwRlocPackageName, NULL, 's' },
- { "NFW_CLIENT_V2X", &nfwV2xPackageName, NULL, 's' },
- { "NFW_CLIENT_R1", &nfwR1PackageName, NULL, 's' },
- { "NFW_CLIENT_R2", &nfwR2PackageName, NULL, 's' },
- { "NFW_CLIENT_R3", &nfwR3PackageName, NULL, 's' },
- };
- UTIL_READ_CONF(LOC_PATH_GPS_CONF_STR, nfw_packages_table);
- mNfws[nfwImsPackageName] |= GNSS_CONFIG_GPS_LOCK_NFW_IMS;
- mNfws[nfwSimPackageName] |= GNSS_CONFIG_GPS_LOCK_NFW_SIM;
- mNfws[nfwMdtPackageName] |= GNSS_CONFIG_GPS_LOCK_NFW_MDT;
- mNfws[nfwTlocPackageName] |= GNSS_CONFIG_GPS_LOCK_NFW_TLOC;
- mNfws[nfwRlocPackageName] |= GNSS_CONFIG_GPS_LOCK_NFW_RLOC;
- mNfws[nfwV2xPackageName] |= GNSS_CONFIG_GPS_LOCK_NFW_V2X;
- mNfws[nfwR1PackageName] |= GNSS_CONFIG_GPS_LOCK_NFW_R1;
- mNfws[nfwR2PackageName] |= GNSS_CONFIG_GPS_LOCK_NFW_R2;
- mNfws[nfwR3PackageName] |= GNSS_CONFIG_GPS_LOCK_NFW_R3;
- mNfws[nfwSuplPackageName] |= GNSS_CONFIG_GPS_LOCK_NFW_SUPL;
- mNfws[nfwCpPackageName] |= GNSS_CONFIG_GPS_LOCK_NFW_CP;
- }
- void
- GnssAdapter::readConfigCommand()
- {
- LOC_LOGD("%s]: ", __func__);
- struct MsgReadConfig : public LocMsg {
- GnssAdapter* mAdapter;
- ContextBase& mContext;
- inline MsgReadConfig(GnssAdapter* adapter,
- ContextBase& context) :
- LocMsg(),
- mAdapter(adapter),
- mContext(context) {}
- inline virtual void proc() const {
- static bool confReadDone = false;
- if (!confReadDone) {
- confReadDone = true;
- // reads config into mContext->mGps_conf
- mContext.readConfig();
- mAdapter->readNfwLockConfig();
- }
- }
- };
- if (mContext != NULL) {
- sendMsg(new MsgReadConfig(this, *mContext));
- }
- }
- void
- GnssAdapter::setSuplHostServer(const char* server, int port, LocServerType type)
- {
- if (ContextBase::mGps_conf.AGPS_CONFIG_INJECT) {
- char serverUrl[MAX_URL_LEN] = {};
- int32_t length = -1;
- const char noHost[] = "NONE";
- if ((NULL == server) || (server[0] == 0) ||
- (strncasecmp(noHost, server, sizeof(noHost)) == 0)) {
- serverUrl[0] = '\0';
- length = 0;
- } else if (port > 0) {
- length = snprintf(serverUrl, sizeof(serverUrl), "%s:%u", server, port);
- }
- if (LOC_AGPS_SUPL_SERVER != type && LOC_AGPS_MO_SUPL_SERVER != type) {
- LOC_LOGe("Invalid type=%d", type);
- } else if (length >= 0) {
- if (LOC_AGPS_SUPL_SERVER == type) {
- getServerUrl().assign(serverUrl);
- strlcpy(ContextBase::mGps_conf.SUPL_HOST,
- (nullptr == server) ? serverUrl : server,
- LOC_MAX_PARAM_STRING);
- ContextBase::mGps_conf.SUPL_PORT = port;
- } else {
- if (strncasecmp(getMoServerUrl().c_str(), serverUrl, sizeof(serverUrl)) != 0) {
- getMoServerUrl().assign(serverUrl);
- }
- }
- }
- }
- }
- void
- GnssAdapter::setConfig()
- {
- LOC_LOGD("%s]: ", __func__);
- // set nmea mask type
- uint32_t mask = 0;
- if (NMEA_PROVIDER_MP == ContextBase::mGps_conf.NMEA_PROVIDER) {
- mask |= LOC_NMEA_ALL_GENERAL_SUPPORTED_MASK;
- if (ContextBase::mGps_conf.NMEA_TAG_BLOCK_GROUPING_ENABLED) {
- mask |= LOC_NMEA_MASK_TAGBLOCK_V02;
- }
- }
- if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_DEBUG_NMEA_V02)) {
- mask |= LOC_NMEA_MASK_DEBUG_V02;
- }
- if (mNmeaMask != mask) {
- mNmeaMask = mask;
- if (mNmeaMask) {
- for (auto it=mClientData.begin(); it != mClientData.end(); ++it) {
- if ((it->second.gnssNmeaCb != nullptr)) {
- updateEvtMask(LOC_API_ADAPTER_BIT_NMEA_1HZ_REPORT,
- LOC_REGISTRATION_MASK_ENABLED);
- break;
- }
- }
- }
- }
- std::string oldMoServerUrl = getMoServerUrl();
- setSuplHostServer(ContextBase::mGps_conf.SUPL_HOST,
- ContextBase::mGps_conf.SUPL_PORT,
- LOC_AGPS_SUPL_SERVER);
- setSuplHostServer(ContextBase::mGps_conf.MO_SUPL_HOST,
- ContextBase::mGps_conf.MO_SUPL_PORT,
- LOC_AGPS_MO_SUPL_SERVER);
- std::string moServerUrl = getMoServerUrl();
- std::string serverUrl = getServerUrl();
- // inject the configurations into modem
- loc_gps_cfg_s gpsConf = ContextBase::mGps_conf;
- loc_sap_cfg_s_type sapConf = ContextBase::mSap_conf;
- //cache the injected configuration with GnssConfigRequested struct
- GnssConfig gnssConfigRequested = {};
- gnssConfigRequested.flags |= GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT |
- GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT;
- /* Here we process an SSR. We need to set the GPS_LOCK to the proper values, as follows:
- 1. Q behavior. This is identified by mSupportNfwControl being 1. In this case
- ContextBase::mGps_conf.GPS_LOCK is a "state", meaning it should reflect the
- NV value. Therefore we will set the NV to ContextBase::mGps_conf.GPS_LOCK
- 2. P behavior. This is identified by mSupportNfwControl being 0. In this case
- ContextBase::mGps_conf.GPS_LOCK is a "configuration", meaning it should hold
- the "mask" for NI. There are two subcases:
- a. Location enabled in GUI (1 == getAfwControlId()). We need to set
- the NV to GNSS_CONFIG_GPS_LOCK_NONE (both MO and NI enabled)
- b. Location disabled in GUI (0 == getAfwControlId()). We need to set
- the NV to ContextBase::mGps_conf.GPS_LOCK (the "mask", which is SIM-card
- specific)
- */
- if (mSupportNfwControl || (0 == getAfwControlId())) {
- gnssConfigRequested.gpsLock = gpsConf.GPS_LOCK;
- } else {
- gnssConfigRequested.gpsLock = GNSS_CONFIG_GPS_LOCK_NONE;
- }
- gnssConfigRequested.flags |= GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT |
- GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT |
- GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT |
- GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT;
- gnssConfigRequested.suplVersion = mLocApi->convertSuplVersion(gpsConf.SUPL_VER);
- gnssConfigRequested.lppProfileMask = gpsConf.LPP_PROFILE;
- gnssConfigRequested.aGlonassPositionProtocolMask = gpsConf.A_GLONASS_POS_PROTOCOL_SELECT;
- if (gpsConf.LPPE_CP_TECHNOLOGY) {
- gnssConfigRequested.flags |= GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT;
- gnssConfigRequested.lppeControlPlaneMask =
- mLocApi->convertLppeCp(gpsConf.LPPE_CP_TECHNOLOGY);
- }
- if (gpsConf.LPPE_UP_TECHNOLOGY) {
- gnssConfigRequested.flags |= GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT;
- gnssConfigRequested.lppeUserPlaneMask =
- mLocApi->convertLppeUp(gpsConf.LPPE_UP_TECHNOLOGY);
- }
- gnssConfigRequested.blacklistedSvIds.assign(mBlacklistedSvIds.begin(),
- mBlacklistedSvIds.end());
- mLocApi->sendMsg(new LocApiMsg(
- [this, gpsConf, sapConf, oldMoServerUrl, moServerUrl,
- serverUrl, gnssConfigRequested] () mutable {
- gnssUpdateConfig(oldMoServerUrl, moServerUrl, serverUrl,
- gnssConfigRequested, gnssConfigRequested);
- // set nmea mask type
- uint32_t mask = 0;
- if (NMEA_PROVIDER_MP == gpsConf.NMEA_PROVIDER) {
- mask |= LOC_NMEA_ALL_GENERAL_SUPPORTED_MASK;
- if (gpsConf.NMEA_TAG_BLOCK_GROUPING_ENABLED) {
- mask |= LOC_NMEA_MASK_TAGBLOCK_V02;
- }
- }
- if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_DEBUG_NMEA_V02)) {
- mask |= LOC_NMEA_MASK_DEBUG_V02;
- }
- if (mask != 0) {
- mLocApi->setNMEATypesSync(mask);
- }
- // load tunc configuration from config file on first boot-up,
- // e.g.: adapter.mLocConfigInfo.tuncConfigInfo.isValid is false
- if (mLocConfigInfo.tuncConfigInfo.isValid == false) {
- mLocConfigInfo.tuncConfigInfo.isValid = true;
- mLocConfigInfo.tuncConfigInfo.enable =
- (gpsConf.CONSTRAINED_TIME_UNCERTAINTY_ENABLED == 1);
- mLocConfigInfo.tuncConfigInfo.tuncThresholdMs =
- (float)gpsConf.CONSTRAINED_TIME_UNCERTAINTY_THRESHOLD;
- mLocConfigInfo.tuncConfigInfo.energyBudget =
- gpsConf.CONSTRAINED_TIME_UNCERTAINTY_ENERGY_BUDGET;
- }
- mLocApi->setConstrainedTuncMode(
- mLocConfigInfo.tuncConfigInfo.enable,
- mLocConfigInfo.tuncConfigInfo.tuncThresholdMs,
- mLocConfigInfo.tuncConfigInfo.energyBudget);
- // load pace configuration from config file on first boot-up,
- // e.g.: adapter.mLocConfigInfo.paceConfigInfo.isValid is false
- if (mLocConfigInfo.paceConfigInfo.isValid == false) {
- mLocConfigInfo.paceConfigInfo.isValid = true;
- mLocConfigInfo.paceConfigInfo.enable =
- (gpsConf.POSITION_ASSISTED_CLOCK_ESTIMATOR_ENABLED==1);
- }
- mLocApi->setPositionAssistedClockEstimatorMode(
- mLocConfigInfo.paceConfigInfo.enable);
- // load robust location configuration from config file on first boot-up,
- // e.g.: adapter.mLocConfigInfo.robustLocationConfigInfo.isValid is false
- if (mLocConfigInfo.robustLocationConfigInfo.isValid == false) {
- mLocConfigInfo.robustLocationConfigInfo.isValid = true;
- bool robustLocationEnabled = (gpsConf.ROBUST_LOCATION_ENABLED & 0x01);
- bool robustLocationE911Enabled = robustLocationEnabled ?
- ((gpsConf.ROBUST_LOCATION_ENABLED & 0x02) != 0) : false;
- mLocConfigInfo.robustLocationConfigInfo.enable = robustLocationEnabled;
- mLocConfigInfo.robustLocationConfigInfo.enableFor911 = robustLocationE911Enabled;
- }
- mLocApi->configRobustLocation(
- mLocConfigInfo.robustLocationConfigInfo.enable,
- mLocConfigInfo.robustLocationConfigInfo.enableFor911);
- if (sapConf.GYRO_BIAS_RANDOM_WALK_VALID ||
- sapConf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY_VALID ||
- sapConf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY_VALID ||
- sapConf.RATE_RANDOM_WALK_SPECTRAL_DENSITY_VALID ||
- sapConf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY_VALID ) {
- mLocApi->setSensorPropertiesSync(
- sapConf.GYRO_BIAS_RANDOM_WALK_VALID,
- sapConf.GYRO_BIAS_RANDOM_WALK,
- sapConf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY_VALID,
- sapConf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY,
- sapConf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY_VALID,
- sapConf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY,
- sapConf.RATE_RANDOM_WALK_SPECTRAL_DENSITY_VALID,
- sapConf.RATE_RANDOM_WALK_SPECTRAL_DENSITY,
- sapConf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY_VALID,
- sapConf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY);
- }
- mLocApi->setSensorPerfControlConfigSync(
- sapConf.SENSOR_CONTROL_MODE,
- sapConf.SENSOR_ACCEL_SAMPLES_PER_BATCH,
- sapConf.SENSOR_ACCEL_BATCHES_PER_SEC,
- sapConf.SENSOR_GYRO_SAMPLES_PER_BATCH,
- sapConf.SENSOR_GYRO_BATCHES_PER_SEC,
- sapConf.SENSOR_ACCEL_SAMPLES_PER_BATCH_HIGH,
- sapConf.SENSOR_ACCEL_BATCHES_PER_SEC_HIGH,
- sapConf.SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH,
- sapConf.SENSOR_GYRO_BATCHES_PER_SEC_HIGH,
- sapConf.SENSOR_ALGORITHM_CONFIG_MASK);
- } ));
- // deal with Measurement Corrections
- if (true == mIsMeasCorrInterfaceOpen) {
- initMeasCorr(true);
- }
- }
- std::vector<LocationError> GnssAdapter::gnssUpdateConfig(const std::string& oldMoServerUrl,
- const std::string& moServerUrl, const std::string& serverUrl,
- GnssConfig& gnssConfigRequested, GnssConfig& gnssConfigNeedEngineUpdate, size_t count) {
- size_t index = 0;
- LocationError err = LOCATION_ERROR_SUCCESS;
- std::vector<LocationError> errsList = {err};
- if (count > 0) {
- errsList.insert(errsList.begin(), count, LOCATION_ERROR_SUCCESS);
- }
- int serverUrlLen = serverUrl.length();
- int moServerUrlLen = moServerUrl.length();
- if (!ContextBase::mGps_conf.AGPS_CONFIG_INJECT) {
- LOC_LOGd("AGPS_CONFIG_INJECT is 0. Not setting flags for AGPS configurations");
- gnssConfigRequested.flags &= ~(GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT |
- GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT |
- GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT |
- GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT |
- GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT |
- GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT);
- }
- if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT) {
- if (gnssConfigNeedEngineUpdate.flags & GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT) {
- err = mLocApi->setGpsLockSync(gnssConfigRequested.gpsLock);
- if (index < count) {
- errsList[index] = err;
- }
- }
- index++;
- }
- if (gnssConfigRequested.flags &
- GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT) {
- if (gnssConfigNeedEngineUpdate.flags &
- GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT) {
- if (gnssConfigNeedEngineUpdate.assistanceServer.type ==
- GNSS_ASSISTANCE_TYPE_SUPL) {
- err = mLocApi->setServerSync(
- serverUrl.c_str(), serverUrlLen, LOC_AGPS_SUPL_SERVER);
- if (index < count) {
- errsList[index] = err;
- }
- if (0 != oldMoServerUrl.compare(moServerUrl)) {
- LocationError locErr =
- mLocApi->setServerSync(moServerUrl.c_str(),
- moServerUrlLen,
- LOC_AGPS_MO_SUPL_SERVER);
- if (locErr != LOCATION_ERROR_SUCCESS) {
- LOC_LOGe("Error while setting MO SUPL_HOST server:%s",
- moServerUrl.c_str());
- }
- }
- } else if (gnssConfigNeedEngineUpdate.assistanceServer.type ==
- GNSS_ASSISTANCE_TYPE_C2K) {
- struct in_addr addr;
- struct hostent* hp;
- bool resolveAddrSuccess = true;
- hp = gethostbyname(
- gnssConfigNeedEngineUpdate.assistanceServer.hostName);
- if (hp != NULL) { /* DNS OK */
- memcpy(&addr, hp->h_addr_list[0], hp->h_length);
- } else {
- /* Try IP representation */
- if (inet_aton(
- gnssConfigNeedEngineUpdate.assistanceServer.hostName,
- &addr) == 0) {
- /* IP not valid */
- LOC_LOGE("%s]: hostname '%s' cannot be resolved ",
- __func__,
- gnssConfigNeedEngineUpdate.assistanceServer.hostName);
- if (index < count) {
- errsList[index] = LOCATION_ERROR_INVALID_PARAMETER;
- }
- } else {
- resolveAddrSuccess = false;
- }
- }
- if (resolveAddrSuccess) {
- unsigned int ip = htonl(addr.s_addr);
- err = mLocApi->setServerSync(ip,
- gnssConfigNeedEngineUpdate.assistanceServer.port,
- LOC_AGPS_CDMA_PDE_SERVER);
- if (index < count) {
- errsList[index] = err;
- }
- }
- }
- }
- index++;
- }
- if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT) {
- if (gnssConfigNeedEngineUpdate.flags &
- GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT) {
- err = mLocApi->setSUPLVersionSync(gnssConfigRequested.suplVersion);
- if (index < count) {
- errsList[index] = err;
- }
- }
- index++;
- }
- if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT) {
- if (gnssConfigNeedEngineUpdate.flags &
- GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT) {
- err = mLocApi->setLPPConfigSync(gnssConfigRequested.lppProfileMask);
- if (index < count) {
- errsList[index] = err;
- }
- }
- index++;
- }
- if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT) {
- if (gnssConfigNeedEngineUpdate.flags &
- GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT) {
- err = mLocApi->setLPPeProtocolCpSync(
- gnssConfigRequested.lppeControlPlaneMask);
- if (index < count) {
- errsList[index] = err;
- }
- }
- index++;
- }
- if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT) {
- if (gnssConfigNeedEngineUpdate.flags &
- GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT) {
- err = mLocApi->setLPPeProtocolUpSync(
- gnssConfigRequested.lppeUserPlaneMask);
- if (index < count) {
- errsList[index] = err;
- }
- }
- index++;
- }
- if (gnssConfigRequested.flags &
- GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT) {
- if (gnssConfigNeedEngineUpdate.flags &
- GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT) {
- err = mLocApi->setAGLONASSProtocolSync(
- gnssConfigRequested.aGlonassPositionProtocolMask);
- if (index < count) {
- errsList[index] = err;
- }
- }
- index++;
- }
- if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT) {
- // Check if feature is supported
- if (!ContextBase::isFeatureSupported(
- LOC_SUPPORTED_FEATURE_CONSTELLATION_ENABLEMENT_V02)) {
- LOC_LOGe("Feature constellation enablement not supported.");
- err = LOCATION_ERROR_NOT_SUPPORTED;
- } else {
- // Send the SV ID Config to Modem
- mBlacklistedSvIds.assign(gnssConfigRequested.blacklistedSvIds.begin(),
- gnssConfigRequested.blacklistedSvIds.end());
- err = gnssSvIdConfigUpdateSync(gnssConfigRequested.blacklistedSvIds);
- if (LOCATION_ERROR_SUCCESS != err) {
- LOC_LOGe("Failed to send config to modem, err %d", err);
- }
- }
- if (index < count) {
- errsList[index] = err;
- }
- index++;
- }
- if (gnssConfigRequested.flags &
- GNSS_CONFIG_FLAGS_EMERGENCY_EXTENSION_SECONDS_BIT) {
- if (gnssConfigNeedEngineUpdate.flags &
- GNSS_CONFIG_FLAGS_EMERGENCY_EXTENSION_SECONDS_BIT) {
- err = mLocApi->setEmergencyExtensionWindowSync(
- gnssConfigRequested.emergencyExtensionSeconds);
- if (index < count) {
- errsList[index] = err;
- }
- }
- index++;
- }
- if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_MIN_SV_ELEVATION_BIT) {
- GnssConfig gnssConfig = {};
- gnssConfig.flags = GNSS_CONFIG_FLAGS_MIN_SV_ELEVATION_BIT;
- gnssConfig.minSvElevation = gnssConfigRequested.minSvElevation;
- err = mLocApi->setParameterSync(gnssConfig);
- if (index < count) {
- errsList[index] = err;
- }
- index++;
- }
- return errsList;
- }
- uint32_t*
- GnssAdapter::gnssUpdateConfigCommand(const GnssConfig& config)
- {
- // count the number of bits set
- GnssConfigFlagsMask flagsCopy = config.flags;
- size_t count = 0;
- while (flagsCopy > 0) {
- if (flagsCopy & 1) {
- count++;
- }
- flagsCopy >>= 1;
- }
- std::string idsString = "[";
- uint32_t* ids = NULL;
- if (count > 0) {
- ids = new uint32_t[count];
- if (ids == nullptr) {
- LOC_LOGE("%s] new allocation failed, fatal error.", __func__);
- return nullptr;
- }
- for (size_t i=0; i < count; ++i) {
- ids[i] = generateSessionId();
- IF_LOC_LOGD {
- idsString += std::to_string(ids[i]) + " ";
- }
- }
- }
- idsString += "]";
- LOC_LOGD("%s]: ids %s flags 0x%X", __func__, idsString.c_str(), config.flags);
- struct MsgGnssUpdateConfig : public LocMsg {
- GnssAdapter& mAdapter;
- LocApiBase& mApi;
- GnssConfig mConfig;
- size_t mCount;
- uint32_t* mIds;
- inline MsgGnssUpdateConfig(GnssAdapter& adapter,
- LocApiBase& api,
- GnssConfig config,
- uint32_t* ids,
- size_t count) :
- LocMsg(),
- mAdapter(adapter),
- mApi(api),
- mConfig(config),
- mCount(count),
- mIds(nullptr) {
- if (mCount > 0) {
- mIds = new uint32_t[count];
- if (mIds) {
- for (uint32_t index = 0; index < count; index++) {
- mIds[index] = ids[index];
- }
- } else {
- LOC_LOGe("memory allocation for mIds failed");
- }
- }
- }
- inline MsgGnssUpdateConfig(const MsgGnssUpdateConfig& obj) :
- MsgGnssUpdateConfig(obj.mAdapter, obj.mApi, obj.mConfig,
- obj.mIds, obj.mCount) {}
- inline virtual ~MsgGnssUpdateConfig()
- {
- if (nullptr != mIds) delete[] mIds;
- }
- inline virtual void proc() const {
- if (!mAdapter.isEngineCapabilitiesKnown()) {
- mAdapter.mPendingMsgs.push_back(new MsgGnssUpdateConfig(*this));
- return;
- }
- GnssAdapter& adapter = mAdapter;
- size_t countOfConfigs = mCount;
- GnssConfig gnssConfigRequested = mConfig;
- GnssConfig gnssConfigNeedEngineUpdate = mConfig;
- std::vector<uint32_t> sessionIds;
- sessionIds.assign(mIds, mIds + mCount);
- std::vector<LocationError> errs(mCount, LOCATION_ERROR_SUCCESS);
- int index = 0;
- bool needSuspendResume = false;
- if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT) {
- GnssConfigGpsLock newGpsLock = gnssConfigRequested.gpsLock;
- newGpsLock |= GNSS_CONFIG_GPS_LOCK_MO;
- ContextBase::mGps_conf.GPS_LOCK = newGpsLock;
- /* If we get here it means that the changes in the framework to request for
- 'P' behavior were made, and therefore we need to "behave" as in 'P'
- However, we need to determine if enableCommand function has already been
- called, since it could get called before this function.*/
- if (0 != mAdapter.getAfwControlId()) {
- /* enableCommand function has already been called since getAfwControlId
- returns non zero. Now there are two possible cases:
- 1. This is the first time this function is called
- (mSupportNfwControl is true). We need to behave as in 'P', but
- for the first time, meaning MO was enabled, but NI was not, so
- we need to unlock NI
- 2. This is not the first time this function is called, meaning we
- are already behaving as in 'P'. No need to update the configuration
- in this case (return to 'P' code) */
- if (mAdapter.mSupportNfwControl) {
- // case 1 above
- newGpsLock = GNSS_CONFIG_GPS_LOCK_NONE;
- } else {
- // case 2 above
- gnssConfigNeedEngineUpdate.flags &= ~(GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT);
- }
- }
- gnssConfigRequested.gpsLock = newGpsLock;
- mAdapter.mSupportNfwControl = false;
- index++;
- }
- if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT) {
- uint32_t newSuplVersion =
- mAdapter.convertSuplVersion(gnssConfigRequested.suplVersion);
- ContextBase::mGps_conf.SUPL_VER = newSuplVersion;
- index++;
- }
- if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT) {
- if (GNSS_ASSISTANCE_TYPE_SUPL == mConfig.assistanceServer.type) {
- mAdapter.setSuplHostServer(mConfig.assistanceServer.hostName,
- mConfig.assistanceServer.port,
- LOC_AGPS_SUPL_SERVER);
- } else {
- LOC_LOGe("Not a valid gnss assistance type %u",
- mConfig.assistanceServer.type);
- errs.at(index) = LOCATION_ERROR_INVALID_PARAMETER;
- gnssConfigNeedEngineUpdate.flags &=
- ~(GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT);
- }
- index++;
- }
- if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT) {
- uint32_t newLppProfileMask = gnssConfigRequested.lppProfileMask;
- ContextBase::mGps_conf.LPP_PROFILE = newLppProfileMask;
- index++;
- }
- if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT) {
- uint32_t newLppeControlPlaneMask =
- mAdapter.convertLppeCp(gnssConfigRequested.lppeControlPlaneMask);
- ContextBase::mGps_conf.LPPE_CP_TECHNOLOGY = newLppeControlPlaneMask;
- index++;
- }
- if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT) {
- uint32_t newLppeUserPlaneMask =
- mAdapter.convertLppeUp(gnssConfigRequested.lppeUserPlaneMask);
- ContextBase::mGps_conf.LPPE_UP_TECHNOLOGY = newLppeUserPlaneMask;
- index++;
- }
- if (gnssConfigRequested.flags &
- GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT) {
- uint32_t newAGloProtMask =
- mAdapter.convertAGloProt(gnssConfigRequested.aGlonassPositionProtocolMask);
- ContextBase::mGps_conf.A_GLONASS_POS_PROTOCOL_SELECT = newAGloProtMask;
- index++;
- }
- if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT) {
- uint32_t newEP4ES = mAdapter.convertEP4ES(
- gnssConfigRequested.emergencyPdnForEmergencySupl);
- if (newEP4ES != ContextBase::mGps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL) {
- ContextBase::mGps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL = newEP4ES;
- }
- index++;
- }
- if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT) {
- uint32_t newSuplEs = mAdapter.convertSuplEs(
- gnssConfigRequested.suplEmergencyServices);
- if (newSuplEs != ContextBase::mGps_conf.SUPL_ES) {
- ContextBase::mGps_conf.SUPL_ES = newSuplEs;
- }
- index++;
- }
- if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_SUPL_MODE_BIT) {
- uint32_t newSuplMode = mAdapter.convertSuplMode(gnssConfigRequested.suplModeMask);
- ContextBase::mGps_conf.SUPL_MODE = newSuplMode;
- mAdapter.broadcastCapabilities(mAdapter.getCapabilities());
- index++;
- }
- if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_MIN_SV_ELEVATION_BIT) {
- needSuspendResume = true;
- index++;
- }
- if (needSuspendResume == true) {
- mAdapter.suspendSessions();
- }
- LocApiCollectiveResponse *configCollectiveResponse = new LocApiCollectiveResponse(
- *adapter.getContext(),
- [&adapter, sessionIds, countOfConfigs] (std::vector<LocationError> errs) {
- std::vector<uint32_t> ids(sessionIds);
- adapter.reportResponse(countOfConfigs, errs.data(), ids.data());
- });
- std::string moServerUrl = adapter.getMoServerUrl();
- std::string serverUrl = adapter.getServerUrl();
- mApi.sendMsg(new LocApiMsg(
- [&adapter, gnssConfigRequested, gnssConfigNeedEngineUpdate,
- moServerUrl, serverUrl, countOfConfigs, configCollectiveResponse,
- errs] () mutable {
- std::vector<LocationError> errsList = adapter.gnssUpdateConfig("",
- moServerUrl, serverUrl,
- gnssConfigRequested, gnssConfigNeedEngineUpdate, countOfConfigs);
- configCollectiveResponse->returnToSender(errsList);
- }));
- if (needSuspendResume == true) {
- mAdapter.restartSessions();
- }
- }
- };
- if (NULL != ids) {
- sendMsg(new MsgGnssUpdateConfig(*this, *mLocApi, config, ids, count));
- } else {
- LOC_LOGE("%s]: No GNSS config items to update", __func__);
- }
- return ids;
- }
- void
- GnssAdapter::gnssSvIdConfigUpdate(const std::vector<GnssSvIdSource>& blacklistedSvIds)
- {
- // Clear the existing config
- memset(&mGnssSvIdConfig, 0, sizeof(GnssSvIdConfig));
- // Convert the sv id lists to masks
- bool convertSuccess = convertToGnssSvIdConfig(blacklistedSvIds, mGnssSvIdConfig);
- // Now send to Modem if conversion successful
- if (convertSuccess) {
- gnssSvIdConfigUpdate();
- } else {
- LOC_LOGe("convertToGnssSvIdConfig failed");
- }
- }
- void
- GnssAdapter::gnssSvIdConfigUpdate()
- {
- LOC_LOGd("blacklist bds 0x%" PRIx64 ", glo 0x%" PRIx64
- ", qzss 0x%" PRIx64 ", gal 0x%" PRIx64 ", sbas 0x%" PRIx64 ", navic 0x%" PRIx64,
- mGnssSvIdConfig.bdsBlacklistSvMask, mGnssSvIdConfig.gloBlacklistSvMask,
- mGnssSvIdConfig.qzssBlacklistSvMask, mGnssSvIdConfig.galBlacklistSvMask,
- mGnssSvIdConfig.sbasBlacklistSvMask, mGnssSvIdConfig.navicBlacklistSvMask);
- // Now set required blacklisted SVs
- mLocApi->setBlacklistSv(mGnssSvIdConfig);
- }
- LocationError
- GnssAdapter::gnssSvIdConfigUpdateSync(const std::vector<GnssSvIdSource>& blacklistedSvIds)
- {
- // Clear the existing config
- memset(&mGnssSvIdConfig, 0, sizeof(GnssSvIdConfig));
- // Convert the sv id lists to masks
- convertToGnssSvIdConfig(blacklistedSvIds, mGnssSvIdConfig);
- // Now send to Modem
- return gnssSvIdConfigUpdateSync();
- }
- LocationError
- GnssAdapter::gnssSvIdConfigUpdateSync()
- {
- LOC_LOGd("blacklist bds 0x%" PRIx64 ", glo 0x%" PRIx64
- ", qzss 0x%" PRIx64 ", gal 0x%" PRIx64 ", sbas 0x%" PRIx64 ", navic 0x%" PRIx64,
- mGnssSvIdConfig.bdsBlacklistSvMask, mGnssSvIdConfig.gloBlacklistSvMask,
- mGnssSvIdConfig.qzssBlacklistSvMask, mGnssSvIdConfig.galBlacklistSvMask,
- mGnssSvIdConfig.sbasBlacklistSvMask, mGnssSvIdConfig.navicBlacklistSvMask);
- // Now set required blacklisted SVs
- return mLocApi->setBlacklistSvSync(mGnssSvIdConfig);
- }
- void
- GnssAdapter::gnssSecondaryBandConfigUpdate(LocApiResponse* locApiResponse)
- {
- LOC_LOGd("secondary band config, size %d, enabled constellation 0x%" PRIx64 ","
- "disabled constellation 0x%" PRIx64 "", mGnssSeconaryBandConfig.size,
- mGnssSeconaryBandConfig.enabledSvTypesMask,
- mGnssSeconaryBandConfig.blacklistedSvTypesMask);
- if (mGnssSeconaryBandConfig.size == sizeof(mGnssSeconaryBandConfig)) {
- // Now set required secondary band config
- mLocApi->configConstellationMultiBand(mGnssSeconaryBandConfig, locApiResponse);
- }
- }
- uint32_t*
- GnssAdapter::gnssGetConfigCommand(GnssConfigFlagsMask configMask) {
- // count the number of bits set
- GnssConfigFlagsMask flagsCopy = configMask;
- size_t count = 0;
- while (flagsCopy > 0) {
- if (flagsCopy & 1) {
- count++;
- }
- flagsCopy >>= 1;
- }
- std::string idsString = "[";
- uint32_t* ids = NULL;
- if (count > 0) {
- ids = new uint32_t[count];
- if (nullptr == ids) {
- LOC_LOGe("new allocation failed, fatal error.");
- return nullptr;
- }
- for (size_t i=0; i < count; ++i) {
- ids[i] = generateSessionId();
- IF_LOC_LOGD {
- idsString += std::to_string(ids[i]) + " ";
- }
- }
- }
- idsString += "]";
- LOC_LOGd("ids %s flags 0x%X", idsString.c_str(), configMask);
- struct MsgGnssGetConfig : public LocMsg {
- GnssAdapter& mAdapter;
- LocApiBase& mApi;
- GnssConfigFlagsMask mConfigMask;
- uint32_t* mIds;
- size_t mCount;
- inline MsgGnssGetConfig(GnssAdapter& adapter,
- LocApiBase& api,
- GnssConfigFlagsMask configMask,
- uint32_t* ids,
- size_t count) :
- LocMsg(),
- mAdapter(adapter),
- mApi(api),
- mConfigMask(configMask),
- mCount(count),
- mIds(nullptr) {
- if (mCount > 0) {
- mIds = new uint32_t[count];
- if (mIds) {
- for (uint32_t index = 0; index < count; index++) {
- mIds[index] = ids[index];
- }
- } else {
- LOC_LOGe("memory allocation for mIds failed");
- }
- }
- }
- inline MsgGnssGetConfig(const MsgGnssGetConfig& obj) :
- MsgGnssGetConfig(obj.mAdapter, obj.mApi, obj.mConfigMask,
- obj.mIds, obj.mCount) {}
- inline virtual ~MsgGnssGetConfig()
- {
- if (nullptr != mIds) delete[] mIds;
- }
- inline virtual void proc() const {
- if (!mAdapter.isEngineCapabilitiesKnown()) {
- mAdapter.mPendingMsgs.push_back(new MsgGnssGetConfig(*this));
- return;
- }
- LocationError* errs = new LocationError[mCount];
- LocationError err = LOCATION_ERROR_SUCCESS;
- uint32_t index = 0;
- if (nullptr == errs) {
- LOC_LOGE("%s] new allocation failed, fatal error.", __func__);
- return;
- }
- if (mConfigMask & GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT) {
- if (index < mCount) {
- errs[index++] = LOCATION_ERROR_NOT_SUPPORTED;
- }
- }
- if (mConfigMask & GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT) {
- if (index < mCount) {
- errs[index++] = LOCATION_ERROR_NOT_SUPPORTED;
- }
- }
- if (mConfigMask & GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT) {
- if (index < mCount) {
- errs[index++] = LOCATION_ERROR_NOT_SUPPORTED;
- }
- }
- if (mConfigMask & GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT) {
- if (index < mCount) {
- errs[index++] = LOCATION_ERROR_NOT_SUPPORTED;
- }
- }
- if (mConfigMask & GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT) {
- if (index < mCount) {
- errs[index++] = LOCATION_ERROR_NOT_SUPPORTED;
- }
- }
- if (mConfigMask & GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT) {
- if (index < mCount) {
- errs[index++] = LOCATION_ERROR_NOT_SUPPORTED;
- }
- }
- if (mConfigMask & GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT) {
- if (index < mCount) {
- errs[index++] = LOCATION_ERROR_NOT_SUPPORTED;
- }
- }
- if (mConfigMask & GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT) {
- if (index < mCount) {
- errs[index++] = LOCATION_ERROR_NOT_SUPPORTED;
- }
- }
- if (mConfigMask & GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT) {
- if (index < mCount) {
- errs[index++] = LOCATION_ERROR_NOT_SUPPORTED;
- }
- }
- if (mConfigMask & GNSS_CONFIG_FLAGS_SUPL_MODE_BIT) {
- err = LOCATION_ERROR_NOT_SUPPORTED;
- if (index < mCount) {
- errs[index++] = LOCATION_ERROR_NOT_SUPPORTED;
- }
- }
- if (mConfigMask & GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT) {
- // Check if feature is supported
- if (!ContextBase::isFeatureSupported(
- LOC_SUPPORTED_FEATURE_CONSTELLATION_ENABLEMENT_V02)) {
- LOC_LOGe("Feature not supported.");
- err = LOCATION_ERROR_NOT_SUPPORTED;
- } else {
- // Send request to Modem to fetch the config
- mApi.getBlacklistSv();
- err = LOCATION_ERROR_SUCCESS;
- }
- if (index < mCount) {
- errs[index++] = err;
- }
- }
- if (mConfigMask & GNSS_CONFIG_FLAGS_EMERGENCY_EXTENSION_SECONDS_BIT) {
- err = LOCATION_ERROR_NOT_SUPPORTED;
- if (index < mCount) {
- errs[index++] = LOCATION_ERROR_NOT_SUPPORTED;
- }
- }
- if (mConfigMask & GNSS_CONFIG_FLAGS_ROBUST_LOCATION_BIT) {
- uint32_t sessionId = *(mIds+index);
- LocApiResponse* locApiResponse =
- new LocApiResponse(*mAdapter.getContext(),
- [this, sessionId] (LocationError err) {
- mAdapter.reportResponse(err, sessionId);});
- if (!locApiResponse) {
- LOC_LOGe("memory alloc failed");
- mAdapter.reportResponse(LOCATION_ERROR_GENERAL_FAILURE, sessionId);
- } else {
- mApi.getRobustLocationConfig(sessionId, locApiResponse);
- }
- }
- if (mConfigMask & GNSS_CONFIG_FLAGS_MIN_GPS_WEEK_BIT) {
- uint32_t sessionId = *(mIds+index);
- LocApiResponse* locApiResponse =
- new LocApiResponse(*mAdapter.getContext(),
- [this, sessionId] (LocationError err) {
- mAdapter.reportResponse(err, sessionId);});
- if (!locApiResponse) {
- LOC_LOGe("memory alloc failed");
- mAdapter.reportResponse(LOCATION_ERROR_GENERAL_FAILURE, sessionId);
- } else {
- mApi.getMinGpsWeek(sessionId, locApiResponse);
- }
- }
- if (mConfigMask & GNSS_CONFIG_FLAGS_MIN_SV_ELEVATION_BIT) {
- uint32_t sessionId = *(mIds+index);
- LocApiResponse* locApiResponse =
- new LocApiResponse(*mAdapter.getContext(),
- [this, sessionId] (LocationError err) {
- mAdapter.reportResponse(err, sessionId);});
- if (!locApiResponse) {
- LOC_LOGe("memory alloc failed");
- mAdapter.reportResponse(LOCATION_ERROR_GENERAL_FAILURE, sessionId);
- } else {
- mApi.getParameter(sessionId, GNSS_CONFIG_FLAGS_MIN_SV_ELEVATION_BIT,
- locApiResponse);
- }
- }
- mAdapter.reportResponse(index, errs, mIds);
- delete[] errs;
- }
- };
- if (NULL != ids) {
- sendMsg(new MsgGnssGetConfig(*this, *mLocApi, configMask, ids, count));
- } else {
- LOC_LOGe("No GNSS config items to Get");
- }
- return ids;
- }
- bool
- GnssAdapter::convertToGnssSvIdConfig(
- const std::vector<GnssSvIdSource>& blacklistedSvIds, GnssSvIdConfig& config)
- {
- bool retVal = false;
- config.size = sizeof(GnssSvIdConfig);
- // Empty vector => Clear any previous blacklisted SVs
- if (0 == blacklistedSvIds.size()) {
- config.gloBlacklistSvMask = 0;
- config.bdsBlacklistSvMask = 0;
- config.qzssBlacklistSvMask = 0;
- config.galBlacklistSvMask = 0;
- config.sbasBlacklistSvMask = 0;
- config.navicBlacklistSvMask = 0;
- retVal = true;
- } else {
- // Parse the vector and convert SV IDs to mask values
- for (GnssSvIdSource source : blacklistedSvIds) {
- uint64_t* svMaskPtr = NULL;
- GnssSvId initialSvId = 0;
- uint16_t svIndexOffset = 0;
- switch(source.constellation) {
- case GNSS_SV_TYPE_GLONASS:
- svMaskPtr = &config.gloBlacklistSvMask;
- initialSvId = GNSS_SV_CONFIG_GLO_INITIAL_SV_ID;
- break;
- case GNSS_SV_TYPE_BEIDOU:
- svMaskPtr = &config.bdsBlacklistSvMask;
- initialSvId = GNSS_SV_CONFIG_BDS_INITIAL_SV_ID;
- break;
- case GNSS_SV_TYPE_QZSS:
- svMaskPtr = &config.qzssBlacklistSvMask;
- initialSvId = GNSS_SV_CONFIG_QZSS_INITIAL_SV_ID;
- break;
- case GNSS_SV_TYPE_GALILEO:
- svMaskPtr = &config.galBlacklistSvMask;
- initialSvId = GNSS_SV_CONFIG_GAL_INITIAL_SV_ID;
- break;
- case GNSS_SV_TYPE_SBAS:
- // SBAS does not support enable/disable whole constellation
- // so do not set up svTypeMask for SBAS
- svMaskPtr = &config.sbasBlacklistSvMask;
- // SBAS currently has two ranges, [120, 158] and [183, 191]
- if (0 == source.svId) {
- LOC_LOGd("blacklist all SBAS SV");
- } else if (source.svId >= GNSS_SV_CONFIG_SBAS_INITIAL2_SV_ID) {
- // handle SV id in range [183, 191]
- initialSvId = GNSS_SV_CONFIG_SBAS_INITIAL2_SV_ID;
- svIndexOffset = GNSS_SV_CONFIG_SBAS_INITIAL_SV_LENGTH;
- } else if ((source.svId >= GNSS_SV_CONFIG_SBAS_INITIAL_SV_ID) &&
- (source.svId < (GNSS_SV_CONFIG_SBAS_INITIAL_SV_ID +
- GNSS_SV_CONFIG_SBAS_INITIAL_SV_LENGTH))){
- // handle SV id in range of [120, 158]
- initialSvId = GNSS_SV_CONFIG_SBAS_INITIAL_SV_ID;
- } else {
- LOC_LOGe("invalid SBAS sv id %d", source.svId);
- svMaskPtr = nullptr;
- }
- break;
- case GNSS_SV_TYPE_NAVIC:
- svMaskPtr = &config.navicBlacklistSvMask;
- initialSvId = GNSS_SV_CONFIG_NAVIC_INITIAL_SV_ID;
- break;
- default:
- break;
- }
- if (NULL == svMaskPtr) {
- LOC_LOGe("Invalid constellation %d", source.constellation);
- } else {
- // SV ID 0 = All SV IDs
- if (0 == source.svId) {
- *svMaskPtr = GNSS_SV_CONFIG_ALL_BITS_ENABLED_MASK;
- } else if (source.svId < initialSvId || source.svId >= initialSvId + 64) {
- LOC_LOGe("Invalid sv id %d for sv type %d",
- source.svId, source.constellation);
- } else {
- uint32_t shiftCnt = source.svId + svIndexOffset - initialSvId;
- *svMaskPtr |= (1ULL << shiftCnt);
- }
- }
- }
- // Return true if any one source is valid
- if (0 != config.gloBlacklistSvMask ||
- 0 != config.bdsBlacklistSvMask ||
- 0 != config.galBlacklistSvMask ||
- 0 != config.qzssBlacklistSvMask ||
- 0 != config.sbasBlacklistSvMask ||
- 0 != config.navicBlacklistSvMask) {
- retVal = true;
- }
- }
- LOC_LOGd("blacklist bds 0x%" PRIx64 ", glo 0x%" PRIx64
- ", qzss 0x%" PRIx64 ", gal 0x%" PRIx64 ", sbas 0x%" PRIx64 ", navic 0x%" PRIx64,
- config.bdsBlacklistSvMask, config.gloBlacklistSvMask,
- config.qzssBlacklistSvMask, config.galBlacklistSvMask,
- config.sbasBlacklistSvMask, config.navicBlacklistSvMask);
- return retVal;
- }
- void GnssAdapter::convertFromGnssSvIdConfig(
- const GnssSvIdConfig& svConfig, std::vector<GnssSvIdSource>& blacklistedSvIds)
- {
- // Convert blacklisted SV mask values to vectors
- if (svConfig.bdsBlacklistSvMask) {
- convertGnssSvIdMaskToList(
- svConfig.bdsBlacklistSvMask, blacklistedSvIds,
- GNSS_SV_CONFIG_BDS_INITIAL_SV_ID, GNSS_SV_TYPE_BEIDOU);
- }
- if (svConfig.galBlacklistSvMask) {
- convertGnssSvIdMaskToList(
- svConfig.galBlacklistSvMask, blacklistedSvIds,
- GNSS_SV_CONFIG_GAL_INITIAL_SV_ID, GNSS_SV_TYPE_GALILEO);
- }
- if (svConfig.gloBlacklistSvMask) {
- convertGnssSvIdMaskToList(
- svConfig.gloBlacklistSvMask, blacklistedSvIds,
- GNSS_SV_CONFIG_GLO_INITIAL_SV_ID, GNSS_SV_TYPE_GLONASS);
- }
- if (svConfig.qzssBlacklistSvMask) {
- convertGnssSvIdMaskToList(
- svConfig.qzssBlacklistSvMask, blacklistedSvIds,
- GNSS_SV_CONFIG_QZSS_INITIAL_SV_ID, GNSS_SV_TYPE_QZSS);
- }
- if (svConfig.sbasBlacklistSvMask) {
- // SBAS - SV 120 to 158, maps to 0 to 38
- // SV 183 to 191, maps to 39 to 47
- uint64_t sbasBlacklistSvMask = svConfig.sbasBlacklistSvMask;
- // operate on 120 and 158 first
- sbasBlacklistSvMask <<= (64 - GNSS_SV_CONFIG_SBAS_INITIAL_SV_LENGTH);
- sbasBlacklistSvMask >>= (64 - GNSS_SV_CONFIG_SBAS_INITIAL_SV_LENGTH);
- convertGnssSvIdMaskToList(
- sbasBlacklistSvMask, blacklistedSvIds,
- GNSS_SV_CONFIG_SBAS_INITIAL_SV_ID, GNSS_SV_TYPE_SBAS);
- // operate on the second range
- sbasBlacklistSvMask = svConfig.sbasBlacklistSvMask;
- sbasBlacklistSvMask >>= GNSS_SV_CONFIG_SBAS_INITIAL_SV_LENGTH;
- convertGnssSvIdMaskToList(
- sbasBlacklistSvMask, blacklistedSvIds,
- GNSS_SV_CONFIG_SBAS_INITIAL2_SV_ID, GNSS_SV_TYPE_SBAS);
- }
- if (svConfig.navicBlacklistSvMask) {
- convertGnssSvIdMaskToList(
- svConfig.navicBlacklistSvMask, blacklistedSvIds,
- GNSS_SV_CONFIG_NAVIC_INITIAL_SV_ID, GNSS_SV_TYPE_NAVIC);
- }
- }
- void GnssAdapter::convertGnssSvIdMaskToList(
- uint64_t svIdMask, std::vector<GnssSvIdSource>& svIds,
- GnssSvId initialSvId, GnssSvType svType)
- {
- GnssSvIdSource source = {};
- source.size = sizeof(GnssSvIdSource);
- source.constellation = svType;
- // SV ID 0 => All SV IDs in mask
- if (GNSS_SV_CONFIG_ALL_BITS_ENABLED_MASK == svIdMask) {
- LOC_LOGd("blacklist all SVs in constellation %d", source.constellation);
- source.svId = 0;
- svIds.push_back(source);
- return;
- }
- // Convert each bit in svIdMask to vector entry
- uint32_t bitNumber = 0;
- while (svIdMask > 0) {
- if (svIdMask & 0x1) {
- source.svId = bitNumber + initialSvId;
- // SBAS has two ranges:
- // SBAS - SV 120 to 158, maps to 0 to 38
- // SV 183 to 191, maps to 39 to 47
- // #define GNSS_SV_CONFIG_SBAS_INITIAL_SV_ID 120
- // #define GNSS_SV_CONFIG_SBAS_INITIAL_SV_LENGTH 39
- // #define GNSS_SV_CONFIG_SBAS_INITIAL2_SV_ID 183
- if (svType == GNSS_SV_TYPE_SBAS) {
- if (bitNumber >= GNSS_SV_CONFIG_SBAS_INITIAL_SV_LENGTH) {
- source.svId = bitNumber - GNSS_SV_CONFIG_SBAS_INITIAL_SV_LENGTH +
- GNSS_SV_CONFIG_SBAS_INITIAL2_SV_ID;
- }
- }
- svIds.push_back(source);
- }
- bitNumber++;
- svIdMask >>= 1;
- }
- }
- void GnssAdapter::reportGnssSvIdConfigEvent(const GnssSvIdConfig& config)
- {
- struct MsgReportGnssSvIdConfig : public LocMsg {
- GnssAdapter& mAdapter;
- const GnssSvIdConfig mConfig;
- inline MsgReportGnssSvIdConfig(GnssAdapter& adapter,
- const GnssSvIdConfig& config) :
- LocMsg(),
- mAdapter(adapter),
- mConfig(config) {}
- inline virtual void proc() const {
- mAdapter.reportGnssSvIdConfig(mConfig);
- }
- };
- sendMsg(new MsgReportGnssSvIdConfig(*this, config));
- }
- void GnssAdapter::reportGnssSvIdConfig(const GnssSvIdConfig& svIdConfig)
- {
- GnssConfig config = {};
- config.size = sizeof(GnssConfig);
- // Invoke control clients config callback
- if (nullptr != mControlCallbacks.gnssConfigCb &&
- svIdConfig.size == sizeof(GnssSvIdConfig)) {
- convertFromGnssSvIdConfig(svIdConfig, config.blacklistedSvIds);
- if (config.blacklistedSvIds.size() > 0) {
- config.flags |= GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT;
- }
- LOC_LOGd("blacklist bds 0x%" PRIx64 ", glo 0x%" PRIx64 ", "
- "qzss 0x%" PRIx64 ", gal 0x%" PRIx64 ", sbas 0x%" PRIx64 ", navic 0x%" PRIx64,
- svIdConfig.bdsBlacklistSvMask, svIdConfig.gloBlacklistSvMask,
- svIdConfig.qzssBlacklistSvMask, svIdConfig.galBlacklistSvMask,
- svIdConfig.sbasBlacklistSvMask, svIdConfig.navicBlacklistSvMask);
- // use 0 session id to indicate that receiver does not yet care about session id
- mControlCallbacks.gnssConfigCb(0, config);
- } else {
- LOC_LOGe("Failed to report, size %d", (uint32_t)config.size);
- }
- }
- void
- GnssAdapter::gnssUpdateSvTypeConfigCommand(GnssSvTypeConfig config)
- {
- struct MsgGnssUpdateSvTypeConfig : public LocMsg {
- GnssAdapter* mAdapter;
- LocApiBase* mApi;
- GnssSvTypeConfig mConfig;
- inline MsgGnssUpdateSvTypeConfig(
- GnssAdapter* adapter,
- LocApiBase* api,
- GnssSvTypeConfig& config) :
- LocMsg(),
- mAdapter(adapter),
- mApi(api),
- mConfig(config) {}
- inline virtual void proc() const {
- if (!mAdapter->isEngineCapabilitiesKnown()) {
- mAdapter->mPendingMsgs.push_back(new MsgGnssUpdateSvTypeConfig(*this));
- return;
- }
- // Check if feature is supported
- if (!ContextBase::isFeatureSupported(
- LOC_SUPPORTED_FEATURE_CONSTELLATION_ENABLEMENT_V02)) {
- LOC_LOGe("Feature not supported.");
- } else {
- // Send update request to modem
- mAdapter->gnssSvTypeConfigUpdate(mConfig);
- }
- }
- };
- sendMsg(new MsgGnssUpdateSvTypeConfig(this, mLocApi, config));
- }
- void
- GnssAdapter::gnssSvTypeConfigUpdate(const GnssSvTypeConfig& config)
- {
- // Gather bits removed from enabled mask
- GnssSvTypesMask enabledRemoved = mGnssSvTypeConfig.enabledSvTypesMask &
- (mGnssSvTypeConfig.enabledSvTypesMask ^ config.enabledSvTypesMask);
- // Send reset if any constellation is removed from the enabled list
- bool sendReset = (enabledRemoved != 0);
- // Save new config and update
- gnssSetSvTypeConfig(config);
- gnssSvTypeConfigUpdate(sendReset);
- }
- void
- GnssAdapter::gnssSvTypeConfigUpdate(bool sendReset)
- {
- LOC_LOGd("size %" PRIu32" constellations blacklisted 0x%" PRIx64 ", enabled 0x%" PRIx64
- ", sendReset %d",
- mGnssSvTypeConfig.size, mGnssSvTypeConfig.blacklistedSvTypesMask,
- mGnssSvTypeConfig.enabledSvTypesMask, sendReset);
- LOC_LOGd("blacklist bds 0x%" PRIx64 ", glo 0x%" PRIx64
- ", qzss 0x%" PRIx64 ", gal 0x%" PRIx64 ", sbas 0x%" PRIx64 ", Navic 0x%" PRIx64,
- mGnssSvIdConfig.bdsBlacklistSvMask, mGnssSvIdConfig.gloBlacklistSvMask,
- mGnssSvIdConfig.qzssBlacklistSvMask, mGnssSvIdConfig.galBlacklistSvMask,
- mGnssSvIdConfig.sbasBlacklistSvMask, mGnssSvIdConfig.navicBlacklistSvMask);
- LOC_LOGd("blacklist bds 0x%" PRIx64 ", glo 0x%" PRIx64
- ", qzss 0x%" PRIx64 ", gal 0x%" PRIx64 ", sbas 0x%" PRIx64 ", Navic 0x%" PRIx64,
- mGnssSvIdConfig.bdsBlacklistSvMask, mGnssSvIdConfig.gloBlacklistSvMask,
- mGnssSvIdConfig.qzssBlacklistSvMask, mGnssSvIdConfig.galBlacklistSvMask,
- mGnssSvIdConfig.sbasBlacklistSvMask, mGnssSvIdConfig.navicBlacklistSvMask);
- if (mGnssSvTypeConfig.size == sizeof(mGnssSvTypeConfig)) {
- if (sendReset) {
- mLocApi->resetConstellationControl();
- }
- GnssSvIdConfig blacklistConfig = {};
- // Revert to previously blacklisted SVs for each enabled constellation
- blacklistConfig = mGnssSvIdConfig;
- // Blacklist all SVs for each disabled constellation
- if (mGnssSvTypeConfig.blacklistedSvTypesMask) {
- if (mGnssSvTypeConfig.blacklistedSvTypesMask & GNSS_SV_TYPES_MASK_GLO_BIT) {
- blacklistConfig.gloBlacklistSvMask = GNSS_SV_CONFIG_ALL_BITS_ENABLED_MASK;
- }
- if (mGnssSvTypeConfig.blacklistedSvTypesMask & GNSS_SV_TYPES_MASK_BDS_BIT) {
- blacklistConfig.bdsBlacklistSvMask = GNSS_SV_CONFIG_ALL_BITS_ENABLED_MASK;
- }
- if (mGnssSvTypeConfig.blacklistedSvTypesMask & GNSS_SV_TYPES_MASK_QZSS_BIT) {
- blacklistConfig.qzssBlacklistSvMask = GNSS_SV_CONFIG_ALL_BITS_ENABLED_MASK;
- }
- if (mGnssSvTypeConfig.blacklistedSvTypesMask & GNSS_SV_TYPES_MASK_GAL_BIT) {
- blacklistConfig.galBlacklistSvMask = GNSS_SV_CONFIG_ALL_BITS_ENABLED_MASK;
- }
- if (mGnssSvTypeConfig.blacklistedSvTypesMask & GNSS_SV_TYPES_MASK_NAVIC_BIT) {
- blacklistConfig.navicBlacklistSvMask = GNSS_SV_CONFIG_ALL_BITS_ENABLED_MASK;
- }
- }
- // Send blacklist info
- mLocApi->setBlacklistSv(blacklistConfig);
- // Send only enabled constellation config
- if (mGnssSvTypeConfig.enabledSvTypesMask) {
- GnssSvTypeConfig svTypeConfig = {sizeof(GnssSvTypeConfig), 0, 0};
- svTypeConfig.enabledSvTypesMask = mGnssSvTypeConfig.enabledSvTypesMask;
- mLocApi->setConstellationControl(svTypeConfig);
- }
- }
- }
- void
- GnssAdapter::gnssGetSvTypeConfigCommand(GnssSvTypeConfigCallback callback)
- {
- struct MsgGnssGetSvTypeConfig : public LocMsg {
- GnssAdapter* mAdapter;
- LocApiBase* mApi;
- GnssSvTypeConfigCallback mCallback;
- inline MsgGnssGetSvTypeConfig(
- GnssAdapter* adapter,
- LocApiBase* api,
- GnssSvTypeConfigCallback callback) :
- LocMsg(),
- mAdapter(adapter),
- mApi(api),
- mCallback(callback) {}
- inline virtual void proc() const {
- if (!mAdapter->isEngineCapabilitiesKnown()) {
- mAdapter->mPendingMsgs.push_back(new MsgGnssGetSvTypeConfig(*this));
- return;
- }
- if (!ContextBase::isFeatureSupported(
- LOC_SUPPORTED_FEATURE_CONSTELLATION_ENABLEMENT_V02)) {
- LOC_LOGe("Feature not supported.");
- } else {
- // Save the callback
- mAdapter->gnssSetSvTypeConfigCallback(mCallback);
- // Send GET request to modem
- mApi->getConstellationControl();
- }
- }
- };
- sendMsg(new MsgGnssGetSvTypeConfig(this, mLocApi, callback));
- }
- void
- GnssAdapter::gnssResetSvTypeConfigCommand()
- {
- struct MsgGnssResetSvTypeConfig : public LocMsg {
- GnssAdapter* mAdapter;
- LocApiBase* mApi;
- inline MsgGnssResetSvTypeConfig(
- GnssAdapter* adapter,
- LocApiBase* api) :
- LocMsg(),
- mAdapter(adapter),
- mApi(api) {}
- inline virtual void proc() const {
- if (!mAdapter->isEngineCapabilitiesKnown()) {
- mAdapter->mPendingMsgs.push_back(new MsgGnssResetSvTypeConfig(*this));
- return;
- }
- if (!ContextBase::isFeatureSupported(
- LOC_SUPPORTED_FEATURE_CONSTELLATION_ENABLEMENT_V02)) {
- LOC_LOGe("Feature not supported.");
- } else {
- // Reset constellation config
- mAdapter->gnssSetSvTypeConfig({sizeof(GnssSvTypeConfig), 0, 0});
- // Re-enforce SV blacklist config
- mAdapter->gnssSvIdConfigUpdate();
- // Send reset request to modem
- mApi->resetConstellationControl();
- }
- }
- };
- sendMsg(new MsgGnssResetSvTypeConfig(this, mLocApi));
- }
- void GnssAdapter::reportGnssSvTypeConfigEvent(const GnssSvTypeConfig& config)
- {
- struct MsgReportGnssSvTypeConfig : public LocMsg {
- GnssAdapter& mAdapter;
- const GnssSvTypeConfig mConfig;
- inline MsgReportGnssSvTypeConfig(GnssAdapter& adapter,
- const GnssSvTypeConfig& config) :
- LocMsg(),
- mAdapter(adapter),
- mConfig(config) {}
- inline virtual void proc() const {
- mAdapter.reportGnssSvTypeConfig(mConfig);
- }
- };
- sendMsg(new MsgReportGnssSvTypeConfig(*this, config));
- }
- void GnssAdapter::reportGnssSvTypeConfig(const GnssSvTypeConfig& config)
- {
- // Invoke Get SV Type Callback
- if (NULL != mGnssSvTypeConfigCb &&
- config.size == sizeof(GnssSvTypeConfig)) {
- LOC_LOGd("constellations blacklisted 0x%" PRIx64 ", enabled 0x%" PRIx64,
- config.blacklistedSvTypesMask, config.enabledSvTypesMask);
- mGnssSvTypeConfigCb(config);
- } else {
- LOC_LOGe("Failed to report, size %d", (uint32_t)config.size);
- }
- }
- void GnssAdapter::deleteAidingData(const GnssAidingData &data, uint32_t sessionId) {
- struct timespec bootDeleteAidingDataTime = {};
- int64_t bootDeleteTimeMs;
- if (clock_gettime(CLOCK_BOOTTIME, &bootDeleteAidingDataTime) == 0) {
- bootDeleteTimeMs = (int64_t)bootDeleteAidingDataTime.tv_sec * 1000;
- int64_t diffTimeBFirSecDelete = bootDeleteTimeMs - mLastDeleteAidingDataTime;
- if (diffTimeBFirSecDelete > DELETE_AIDING_DATA_EXPECTED_TIME_MS) {
- mLocApi->deleteAidingData(data, new LocApiResponse(*getContext(),
- [this, sessionId] (LocationError err) {
- reportResponse(err, sessionId);
- }));
- mLastDeleteAidingDataTime = bootDeleteTimeMs;
- }
- }
- }
- uint32_t
- GnssAdapter::gnssDeleteAidingDataCommand(GnssAidingData& data)
- {
- uint32_t sessionId = generateSessionId();
- LOC_LOGD("%s]: id %u", __func__, sessionId);
- struct MsgDeleteAidingData : public LocMsg {
- GnssAdapter& mAdapter;
- uint32_t mSessionId;
- GnssAidingData mData;
- inline MsgDeleteAidingData(GnssAdapter& adapter,
- uint32_t sessionId,
- GnssAidingData& data) :
- LocMsg(),
- mAdapter(adapter),
- mSessionId(sessionId),
- mData(data) {}
- inline virtual void proc() const {
- if ((mData.posEngineMask & STANDARD_POSITIONING_ENGINE) != 0) {
- mAdapter.deleteAidingData(mData, mSessionId);
- SystemStatus* s = mAdapter.getSystemStatus();
- if ((nullptr != s) && (mData.deleteAll)) {
- s->setDefaultGnssEngineStates();
- }
- }
- bool retVal = mAdapter.mEngHubProxy->gnssDeleteAidingData(mData);
- // When SPE engine is invoked, responseCb will be invoked
- // from QMI Loc API call.
- // When SPE engine is not invoked, we also need to deliver responseCb
- if ((mData.posEngineMask & STANDARD_POSITIONING_ENGINE) == 0) {
- LocationError err = LOCATION_ERROR_NOT_SUPPORTED;
- if (retVal == true) {
- err = LOCATION_ERROR_SUCCESS;
- }
- mAdapter.reportResponse(err, mSessionId);
- }
- }
- };
- sendMsg(new MsgDeleteAidingData(*this, sessionId, data));
- return sessionId;
- }
- void
- GnssAdapter::gnssUpdateXtraThrottleCommand(const bool enabled)
- {
- LOC_LOGD("%s] enabled:%d", __func__, enabled);
- struct UpdateXtraThrottleMsg : public LocMsg {
- GnssAdapter& mAdapter;
- const bool mEnabled;
- inline UpdateXtraThrottleMsg(GnssAdapter& adapter, const bool enabled) :
- LocMsg(),
- mAdapter(adapter),
- mEnabled(enabled) {}
- inline virtual void proc() const {
- mAdapter.mXtraObserver.updateXtraThrottle(mEnabled);
- }
- };
- sendMsg(new UpdateXtraThrottleMsg(*this, enabled));
- }
- void
- GnssAdapter::injectLocationCommand(double latitude, double longitude, float accuracy)
- {
- LOC_LOGD("%s]: latitude %8.4f longitude %8.4f accuracy %8.4f",
- __func__, latitude, longitude, accuracy);
- struct MsgInjectLocation : public LocMsg {
- GnssAdapter& mAdapter;
- LocApiBase& mApi;
- ContextBase& mContext;
- BlockCPIInfo& mBlockCPI;
- double mLatitude;
- double mLongitude;
- float mAccuracy;
- bool mOnDemandCpi;
- inline MsgInjectLocation(GnssAdapter& adapter,
- LocApiBase& api,
- ContextBase& context,
- BlockCPIInfo& blockCPIInfo,
- double latitude,
- double longitude,
- float accuracy,
- bool onDemandCpi) :
- LocMsg(),
- mAdapter(adapter),
- mApi(api),
- mContext(context),
- mBlockCPI(blockCPIInfo),
- mLatitude(latitude),
- mLongitude(longitude),
- mAccuracy(accuracy),
- mOnDemandCpi(onDemandCpi) {}
- inline virtual void proc() const {
- if ((uptimeMillis() <= mBlockCPI.blockedTillTsMs) &&
- (fabs(mLatitude-mBlockCPI.latitude) <= mBlockCPI.latLonDiffThreshold) &&
- (fabs(mLongitude-mBlockCPI.longitude) <= mBlockCPI.latLonDiffThreshold)) {
- LOC_LOGD("%s]: positon injection blocked: lat: %f, lon: %f, accuracy: %f",
- __func__, mLatitude, mLongitude, mAccuracy);
- } else {
- if ((mAdapter.mOdcpiStateMask & CIVIC_ADDRESS_REQ_ACTIVE) &&
- mAdapter.mAddressRequestCb != nullptr) {
- Location location = {};
- location.flags |= LOCATION_HAS_LAT_LONG_BIT;
- location.latitude = mLatitude;
- location.longitude = mLongitude;
- location.flags |= LOCATION_HAS_ACCURACY_BIT;
- location.accuracy = mAccuracy;
- mAdapter.mAddressRequestCb(location);
- }
- mApi.injectPosition(mLatitude, mLongitude, mAccuracy, mOnDemandCpi);
- }
- }
- };
- sendMsg(new MsgInjectLocation(*this, *mLocApi, *mContext, mBlockCPIInfo,
- latitude, longitude, accuracy,
- mOdcpiStateMask & ODCPI_REQ_ACTIVE));
- }
- void
- GnssAdapter::injectLocationExtCommand(const GnssLocationInfoNotification &locationInfo)
- {
- LOC_LOGd("latitude %8.4f longitude %8.4f accuracy %8.4f, tech mask 0x%x",
- locationInfo.location.latitude, locationInfo.location.longitude,
- locationInfo.location.accuracy, locationInfo.location.techMask);
- struct MsgInjectLocationExt : public LocMsg {
- LocApiBase& mApi;
- ContextBase& mContext;
- GnssLocationInfoNotification mLocationInfo;
- inline MsgInjectLocationExt(LocApiBase& api,
- ContextBase& context,
- GnssLocationInfoNotification locationInfo) :
- LocMsg(),
- mApi(api),
- mContext(context),
- mLocationInfo(locationInfo) {}
- inline virtual void proc() const {
- // false to indicate for none-ODCPI
- mApi.injectPosition(mLocationInfo, false);
- }
- };
- sendMsg(new MsgInjectLocationExt(*mLocApi, *mContext, locationInfo));
- }
- void
- GnssAdapter::injectTimeCommand(int64_t time, int64_t timeReference, int32_t uncertainty)
- {
- LOC_LOGD("%s]: time %lld timeReference %lld uncertainty %d",
- __func__, (long long)time, (long long)timeReference, uncertainty);
- struct MsgInjectTime : public LocMsg {
- LocApiBase& mApi;
- ContextBase& mContext;
- int64_t mTime;
- int64_t mTimeReference;
- int32_t mUncertainty;
- inline MsgInjectTime(LocApiBase& api,
- ContextBase& context,
- int64_t time,
- int64_t timeReference,
- int32_t uncertainty) :
- LocMsg(),
- mApi(api),
- mContext(context),
- mTime(time),
- mTimeReference(timeReference),
- mUncertainty(uncertainty) {}
- inline virtual void proc() const {
- mApi.setTime(mTime, mTimeReference, mUncertainty);
- }
- };
- sendMsg(new MsgInjectTime(*mLocApi, *mContext, time, timeReference, uncertainty));
- }
- // This command is to called to block the position to be injected to the modem.
- // This can happen for network position that comes from modem.
- void
- GnssAdapter::blockCPICommand(double latitude, double longitude,
- float accuracy, int blockDurationMsec,
- double latLonDiffThreshold)
- {
- struct MsgBlockCPI : public LocMsg {
- BlockCPIInfo& mDstCPIInfo;
- BlockCPIInfo mSrcCPIInfo;
- inline MsgBlockCPI(BlockCPIInfo& dstCPIInfo,
- BlockCPIInfo& srcCPIInfo) :
- mDstCPIInfo(dstCPIInfo),
- mSrcCPIInfo(srcCPIInfo) {}
- inline virtual void proc() const {
- // in the same hal thread, save the cpi to be blocked
- // the global variable
- mDstCPIInfo = mSrcCPIInfo;
- }
- };
- // construct the new block CPI info and queue on the same thread
- // for processing
- BlockCPIInfo blockCPIInfo;
- blockCPIInfo.latitude = latitude;
- blockCPIInfo.longitude = longitude;
- blockCPIInfo.accuracy = accuracy;
- blockCPIInfo.blockedTillTsMs = uptimeMillis() + blockDurationMsec;
- blockCPIInfo.latLonDiffThreshold = latLonDiffThreshold;
- LOC_LOGD("%s]: block CPI lat: %f, lon: %f ", __func__, latitude, longitude);
- // send a message to record down the coarse position
- // to be blocked from injection in the master copy (mBlockCPIInfo)
- sendMsg(new MsgBlockCPI(mBlockCPIInfo, blockCPIInfo));
- }
- void
- GnssAdapter::updateSystemPowerState(PowerStateType systemPowerState) {
- if (POWER_STATE_UNKNOWN != systemPowerState) {
- mSystemPowerState = systemPowerState;
- /*Manage active GNSS sessions based on power event*/
- switch (systemPowerState){
- case POWER_STATE_SUSPEND:
- case POWER_STATE_SHUTDOWN:
- suspendSessions();
- LOC_LOGd("Suspending all active sessions -- powerState: %d", systemPowerState);
- break;
- case POWER_STATE_RESUME:
- restartSessions(false);
- LOC_LOGd("Re-starting all active sessions -- powerState: %d", systemPowerState);
- break;
- default:
- break;
- } // switch
- mLocApi->updateSystemPowerState(mSystemPowerState);
- }
- }
- void
- GnssAdapter::updateSystemPowerStateCommand(PowerStateType systemPowerState) {
- LOC_LOGd("power event %d", systemPowerState);
- struct MsgUpdatePowerState : public LocMsg {
- GnssAdapter& mAdapter;
- PowerStateType mSystemPowerState;
- inline MsgUpdatePowerState(GnssAdapter& adapter,
- PowerStateType systemPowerState) :
- LocMsg(),
- mAdapter(adapter),
- mSystemPowerState(systemPowerState) {}
- inline virtual void proc() const {
- mAdapter.updateSystemPowerState(mSystemPowerState);
- }
- };
- sendMsg(new MsgUpdatePowerState(*this, systemPowerState));
- }
- void
- GnssAdapter::addClientCommand(LocationAPI* client, const LocationCallbacks& callbacks)
- {
- LOC_LOGD("%s]: client %p", __func__, client);
- struct MsgAddClient : public LocMsg {
- GnssAdapter& mAdapter;
- LocationAPI* mClient;
- const LocationCallbacks mCallbacks;
- inline MsgAddClient(GnssAdapter& adapter,
- LocationAPI* client,
- const LocationCallbacks& callbacks) :
- LocMsg(),
- mAdapter(adapter),
- mClient(client),
- mCallbacks(callbacks) {}
- inline virtual void proc() const {
- // check whether we need to notify client of cached location system info
- mAdapter.notifyClientOfCachedLocationSystemInfo(mClient, mCallbacks);
- mAdapter.saveClient(mClient, mCallbacks);
- }
- };
- sendMsg(new MsgAddClient(*this, client, callbacks));
- }
- void
- GnssAdapter::stopClientSessions(LocationAPI* client, bool eraseSession)
- {
- LOC_LOGD("%s]: client %p", __func__, client);
- /* Time-based Tracking */
- std::vector<LocationSessionKey> vTimeBasedTrackingClient;
- for (auto it : mTimeBasedTrackingSessions) {
- if (client == it.first.client) {
- vTimeBasedTrackingClient.emplace_back(it.first.client, it.first.id);
- }
- }
- for (auto key : vTimeBasedTrackingClient) {
- stopTimeBasedTrackingMultiplex(key.client, key.id);
- if (eraseSession)
- eraseTrackingSession(key.client, key.id);
- }
- /* Distance-based Tracking */
- for (auto it = mDistanceBasedTrackingSessions.begin();
- it != mDistanceBasedTrackingSessions.end(); /* no increment here*/) {
- if (client == it->first.client) {
- mLocApi->stopDistanceBasedTracking(it->first.id, new LocApiResponse(*getContext(),
- [this, client, id=it->first.id, eraseSession] (LocationError err) {
- if (LOCATION_ERROR_SUCCESS == err) {
- if (eraseSession)
- eraseTrackingSession(client, id);
- }
- }
- ));
- }
- ++it; // increment only when not erasing an iterator
- }
- }
- void
- GnssAdapter::updateClientsEventMask()
- {
- // need to register for leap second info
- // for proper nmea generation
- LOC_API_ADAPTER_EVENT_MASK_T mask = LOC_API_ADAPTER_BIT_LOC_SYSTEM_INFO |
- LOC_API_ADAPTER_BIT_EVENT_REPORT_INFO;
- for (auto it=mClientData.begin(); it != mClientData.end(); ++it) {
- if (it->second.trackingCb != nullptr ||
- it->second.gnssLocationInfoCb != nullptr ||
- it->second.engineLocationsInfoCb != nullptr) {
- mask |= LOC_API_ADAPTER_BIT_PARSED_POSITION_REPORT;
- }
- if (it->second.gnssSvCb != nullptr) {
- mask |= LOC_API_ADAPTER_BIT_SATELLITE_REPORT;
- }
- if ((it->second.gnssNmeaCb != nullptr) && (mNmeaMask)) {
- mask |= LOC_API_ADAPTER_BIT_NMEA_1HZ_REPORT;
- }
- if (it->second.gnssMeasurementsCb != nullptr) {
- mask |= LOC_API_ADAPTER_BIT_GNSS_MEASUREMENT;
- if (nullptr != mPowerIndicationCb) {
- /* If power reporting is requested this implies Android 'S' or higher,
- meaning we need to enable poly message (necessary for satellite
- PVT report). We do it this way since satellite PVT are reported
- in the measurements cb, they don't have their own cb, and we want
- to enable poly message only for Android 'S' or higher */
- mask |= LOC_API_ADAPTER_BIT_GNSS_SV_POLYNOMIAL_REPORT;
- }
- }
- if (it->second.gnssNHzMeasurementsCb != nullptr) {
- mask |= LOC_API_ADAPTER_BIT_GNSS_NHZ_MEASUREMENT;
- }
- if (it->second.gnssDataCb != nullptr) {
- mask |= LOC_API_ADAPTER_BIT_PARSED_POSITION_REPORT;
- mask |= LOC_API_ADAPTER_BIT_NMEA_1HZ_REPORT;
- updateNmeaMask(mNmeaMask | LOC_NMEA_MASK_DEBUG_V02);
- }
- }
- /*
- ** For Automotive use cases we need to enable MEASUREMENT, POLY and EPHEMERIS
- ** when QDR is enabled (e.g.: either enabled via conf file or
- ** engine hub is loaded successfully).
- ** Note: this need to be called from msg queue thread.
- */
- if((1 == ContextBase::mGps_conf.EXTERNAL_DR_ENABLED) ||
- (true == initEngHubProxy())) {
- mask |= LOC_API_ADAPTER_BIT_GNSS_MEASUREMENT;
- mask |= LOC_API_ADAPTER_BIT_GNSS_SV_POLYNOMIAL_REPORT;
- mask |= LOC_API_ADAPTER_BIT_PARSED_UNPROPAGATED_POSITION_REPORT;
- mask |= LOC_API_ADAPTER_BIT_GNSS_SV_EPHEMERIS_REPORT;
- // Nhz measurement bit is set based on callback from loc eng hub
- // for Nhz engines.
- mask |= checkMask(LOC_API_ADAPTER_BIT_GNSS_NHZ_MEASUREMENT);
- LOC_LOGd("Auto usecase, Enable MEAS/POLY/EPHEMERIS - mask 0x%" PRIx64 "",
- mask);
- }
- if (mAgpsManager.isRegistered()) {
- mask |= LOC_API_ADAPTER_BIT_LOCATION_SERVER_REQUEST;
- }
- // Add ODCPI handling
- if (nullptr != mOdcpiRequestCb) {
- mask |= LOC_API_ADAPTER_BIT_REQUEST_WIFI;
- }
- // need to register for leap second info
- // for proper nmea generation
- mask |= LOC_API_ADAPTER_BIT_LOC_SYSTEM_INFO;
- // always register for NI NOTIFY VERIFY to handle internally in HAL
- mask |= LOC_API_ADAPTER_BIT_NI_NOTIFY_VERIFY_REQUEST;
- // Enable the latency report
- if (mask & LOC_API_ADAPTER_BIT_GNSS_MEASUREMENT) {
- if (mLogger.isLogEnabled()) {
- mask |= LOC_API_ADAPTER_BIT_LATENCY_INFORMATION;
- }
- }
- updateEvtMask(mask, LOC_REGISTRATION_MASK_SET);
- }
- void
- GnssAdapter::handleEngineUpEvent()
- {
- LOC_LOGD("%s]: ", __func__);
- struct MsgHandleEngineUpEvent : public LocMsg {
- GnssAdapter& mAdapter;
- inline MsgHandleEngineUpEvent(GnssAdapter& adapter) :
- LocMsg(),
- mAdapter(adapter) {}
- virtual void proc() const {
- mAdapter.setEngineCapabilitiesKnown(true);
- mAdapter.broadcastCapabilities(mAdapter.getCapabilities());
- // must be called only after capabilities are known
- mAdapter.setConfig();
- mAdapter.gnssSvIdConfigUpdate();
- mAdapter.gnssSvTypeConfigUpdate();
- mAdapter.updateSystemPowerState(mAdapter.getSystemPowerState());
- mAdapter.gnssSecondaryBandConfigUpdate();
- // restart sessions only in power state resume
- if ((POWER_STATE_SUSPEND != mAdapter.mSystemPowerState) &&
- POWER_STATE_SHUTDOWN != mAdapter.mSystemPowerState) {
- mAdapter.restartSessions(true);
- }
- for (auto msg: mAdapter.mPendingMsgs) {
- mAdapter.sendMsg(msg);
- }
- mAdapter.mPendingMsgs.clear();
- mAdapter.initGnssPowerStatistics();
- }
- };
- readConfigCommand();
- sendMsg(new MsgHandleEngineUpEvent(*this));
- }
- void
- GnssAdapter::restartSessions(bool modemSSR)
- {
- LOC_LOGi(":enter");
- if (modemSSR) {
- // odcpi session is no longer active after restart
- mOdcpiStateMask = 0;
- }
- // SPE will be restarted now, so set this variable to false.
- mSPEAlreadyRunningAtHighestInterval = false;
- if (false == mTimeBasedTrackingSessions.empty()) {
- // inform engine hub that GNSS session is about to start
- mEngHubProxy->gnssSetFixMode(mLocPositionMode);
- mEngHubProxy->gnssStartFix();
- checkUpdateDgnssNtrip(false);
- }
- checkAndRestartSPESession();
- }
- void GnssAdapter::checkAndRestartSPESession()
- {
- LOC_LOGD("%s]: ", __func__);
- // SPE will be restarted now, so set this variable to false.
- mSPEAlreadyRunningAtHighestInterval = false;
- checkAndRestartTimeBasedSession();
- for (auto it = mDistanceBasedTrackingSessions.begin();
- it != mDistanceBasedTrackingSessions.end(); ++it) {
- mLocApi->startDistanceBasedTracking(it->first.id, it->second,
- new LocApiResponse(*getContext(),
- [] (LocationError /*err*/) {}));
- }
- }
- // suspend all on-going sessions
- void
- GnssAdapter::suspendSessions()
- {
- LOC_LOGi(":enter");
- if (!mTimeBasedTrackingSessions.empty()) {
- // inform engine hub that GNSS session has stopped
- mEngHubProxy->gnssStopFix();
- mLocApi->stopFix(nullptr);
- if (isDgnssNmeaRequired()) {
- mDgnssState &= ~DGNSS_STATE_NO_NMEA_PENDING;
- }
- stopDgnssNtrip();
- mPositionElapsedRealTimeCal.reset();
- mSPEAlreadyRunningAtHighestInterval = false;
- }
- }
- void GnssAdapter::checkAndRestartTimeBasedSession()
- {
- LOC_LOGD("%s]: ", __func__);
- if (!mTimeBasedTrackingSessions.empty()) {
- // get the LocationOptions that has the smallest interval, which should be the active one
- TrackingOptions smallestIntervalOptions; // size is zero until set for the first time
- TrackingOptions highestPowerTrackingOptions;
- memset(&smallestIntervalOptions, 0, sizeof(smallestIntervalOptions));
- memset(&highestPowerTrackingOptions, 0, sizeof(highestPowerTrackingOptions));
- for (auto it = mTimeBasedTrackingSessions.begin();
- it != mTimeBasedTrackingSessions.end(); ++it) {
- // size of zero means we havent set it yet
- if (0 == smallestIntervalOptions.size ||
- it->second.minInterval < smallestIntervalOptions.minInterval) {
- smallestIntervalOptions = it->second;
- }
- GnssPowerMode powerMode = it->second.powerMode;
- // Size of zero means we havent set it yet
- if (0 == highestPowerTrackingOptions.size ||
- (GNSS_POWER_MODE_INVALID != powerMode &&
- powerMode < highestPowerTrackingOptions.powerMode)) {
- highestPowerTrackingOptions = it->second;
- }
- }
- highestPowerTrackingOptions.setLocationOptions(smallestIntervalOptions);
- // want to run SPE session at a fixed min interval in some automotive scenarios
- if(!checkAndSetSPEToRunforNHz(highestPowerTrackingOptions)) {
- mLocApi->startTimeBasedTracking(highestPowerTrackingOptions, nullptr);
- }
- }
- }
- LocationCapabilitiesMask
- GnssAdapter::getCapabilities()
- {
- LocationCapabilitiesMask mask = 0;
- uint32_t carrierCapabilities = ContextBase::getCarrierCapabilities();
- // time based tracking always supported
- mask |= LOCATION_CAPABILITIES_TIME_BASED_TRACKING_BIT;
- // geofence always supported
- mask |= LOCATION_CAPABILITIES_GEOFENCE_BIT;
- if (carrierCapabilities & LOC_GPS_CAPABILITY_MSB) {
- mask |= LOCATION_CAPABILITIES_GNSS_MSB_BIT;
- }
- if (LOC_GPS_CAPABILITY_MSA & carrierCapabilities) {
- mask |= LOCATION_CAPABILITIES_GNSS_MSA_BIT;
- }
- if (ContextBase::isMessageSupported(LOC_API_ADAPTER_MESSAGE_DISTANCE_BASE_LOCATION_BATCHING)) {
- mask |= LOCATION_CAPABILITIES_TIME_BASED_BATCHING_BIT |
- LOCATION_CAPABILITIES_DISTANCE_BASED_BATCHING_BIT;
- }
- if (ContextBase::isMessageSupported(LOC_API_ADAPTER_MESSAGE_DISTANCE_BASE_TRACKING)) {
- mask |= LOCATION_CAPABILITIES_DISTANCE_BASED_TRACKING_BIT;
- }
- if (ContextBase::isMessageSupported(LOC_API_ADAPTER_MESSAGE_OUTDOOR_TRIP_BATCHING)) {
- mask |= LOCATION_CAPABILITIES_OUTDOOR_TRIP_BATCHING_BIT;
- }
- if (ContextBase::gnssConstellationConfig()) {
- mask |= LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT;
- }
- if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_DEBUG_NMEA_V02)) {
- mask |= LOCATION_CAPABILITIES_DEBUG_NMEA_BIT;
- }
- if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_CONSTELLATION_ENABLEMENT_V02)) {
- mask |= LOCATION_CAPABILITIES_CONSTELLATION_ENABLEMENT_BIT;
- }
- if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_AGPM_V02)) {
- mask |= LOCATION_CAPABILITIES_AGPM_BIT;
- }
- //Get QWES feature status mask
- mask |= ContextBase::getQwesFeatureStatus();
- return mask;
- }
- void
- GnssAdapter::notifyClientOfCachedLocationSystemInfo(
- LocationAPI* client, const LocationCallbacks& callbacks) {
- if (mLocSystemInfo.systemInfoMask) {
- // client need to be notified if client has not yet previously registered
- // for the info but now register for it.
- bool notifyClientOfSystemInfo = false;
- // check whether we need to notify client of cached location system info
- //
- // client need to be notified if client has not yet previously registered
- // for the info but now register for it.
- if (callbacks.locationSystemInfoCb) {
- notifyClientOfSystemInfo = true;
- auto it = mClientData.find(client);
- if (it != mClientData.end()) {
- LocationCallbacks oldCallbacks = it->second;
- if (oldCallbacks.locationSystemInfoCb) {
- notifyClientOfSystemInfo = false;
- }
- }
- }
- if (notifyClientOfSystemInfo) {
- callbacks.locationSystemInfoCb(mLocSystemInfo);
- }
- }
- }
- bool
- GnssAdapter::isTimeBasedTrackingSession(LocationAPI* client, uint32_t sessionId)
- {
- LocationSessionKey key(client, sessionId);
- return (mTimeBasedTrackingSessions.find(key) != mTimeBasedTrackingSessions.end());
- }
- bool
- GnssAdapter::isDistanceBasedTrackingSession(LocationAPI* client, uint32_t sessionId)
- {
- LocationSessionKey key(client, sessionId);
- return (mDistanceBasedTrackingSessions.find(key) != mDistanceBasedTrackingSessions.end());
- }
- bool
- GnssAdapter::hasCallbacksToStartTracking(LocationAPI* client)
- {
- bool allowed = false;
- auto it = mClientData.find(client);
- if (it != mClientData.end()) {
- if (it->second.trackingCb || it->second.gnssLocationInfoCb ||
- it->second.engineLocationsInfoCb || it->second.gnssMeasurementsCb ||
- it->second.gnssNHzMeasurementsCb || it->second.gnssDataCb ||
- it->second.gnssSvCb || it->second.gnssNmeaCb) {
- allowed = true;
- } else {
- LOC_LOGi("missing right callback to start tracking")
- }
- } else {
- LOC_LOGi("client %p not found", client)
- }
- return allowed;
- }
- bool
- GnssAdapter::isTrackingSession(LocationAPI* client, uint32_t sessionId)
- {
- LocationSessionKey key(client, sessionId);
- return (mTimeBasedTrackingSessions.find(key) != mTimeBasedTrackingSessions.end());
- }
- void
- GnssAdapter::reportPowerStateIfChanged()
- {
- bool newPowerOn = !mTimeBasedTrackingSessions.empty() ||
- !mDistanceBasedTrackingSessions.empty();
- if (newPowerOn != mPowerOn) {
- mPowerOn = newPowerOn;
- if (mPowerStateCb != nullptr) {
- mPowerStateCb(mPowerOn);
- }
- }
- }
- void
- GnssAdapter::getPowerStateChangesCommand(std::function<void(bool)> powerStateCb)
- {
- LOC_LOGD("%s]: ", __func__);
- struct MsgReportLocation : public LocMsg {
- GnssAdapter& mAdapter;
- std::function<void(bool)> mPowerStateCb;
- inline MsgReportLocation(GnssAdapter& adapter,
- std::function<void(bool)> powerStateCb) :
- LocMsg(),
- mAdapter(adapter),
- mPowerStateCb(powerStateCb) {}
- inline virtual void proc() const {
- mAdapter.savePowerStateCallback(mPowerStateCb);
- mPowerStateCb(mAdapter.getPowerState());
- }
- };
- sendMsg(new MsgReportLocation(*this, powerStateCb));
- }
- void
- GnssAdapter::saveTrackingSession(LocationAPI* client, uint32_t sessionId,
- const TrackingOptions& options)
- {
- LocationSessionKey key(client, sessionId);
- if ((options.minDistance > 0) &&
- ContextBase::isMessageSupported(LOC_API_ADAPTER_MESSAGE_DISTANCE_BASE_TRACKING)) {
- mDistanceBasedTrackingSessions[key] = options;
- } else {
- mTimeBasedTrackingSessions[key] = options;
- }
- reportPowerStateIfChanged();
- // notify SystemStatus the engine tracking status
- getSystemStatus()->setTracking(isInSession());
- }
- void
- GnssAdapter::eraseTrackingSession(LocationAPI* client, uint32_t sessionId)
- {
- LocationSessionKey key(client, sessionId);
- auto it = mTimeBasedTrackingSessions.find(key);
- if (it != mTimeBasedTrackingSessions.end()) {
- mTimeBasedTrackingSessions.erase(it);
- } else {
- auto itr = mDistanceBasedTrackingSessions.find(key);
- if (itr != mDistanceBasedTrackingSessions.end()) {
- mDistanceBasedTrackingSessions.erase(itr);
- }
- }
- reportPowerStateIfChanged();
- getSystemStatus()->setTracking(isInSession());
- }
- bool GnssAdapter::setLocPositionMode(const LocPosMode& mode) {
- if (!mLocPositionMode.equals(mode)) {
- mLocPositionMode = mode;
- return true;
- } else {
- return false;
- }
- }
- void
- GnssAdapter::reportResponse(LocationAPI* client, LocationError err, uint32_t sessionId)
- {
- LOC_LOGD("%s]: client %p id %u err %u", __func__, client, sessionId, err);
- auto it = mClientData.find(client);
- if (it != mClientData.end() && it->second.responseCb != nullptr) {
- it->second.responseCb(err, sessionId);
- } else {
- LOC_LOGW("%s]: client %p id %u not found in data", __func__, client, sessionId);
- }
- }
- void
- GnssAdapter::reportResponse(LocationError err, uint32_t sessionId)
- {
- LOC_LOGD("%s]: id %u err %u", __func__, sessionId, err);
- if (mControlCallbacks.size > 0 && mControlCallbacks.responseCb != nullptr) {
- mControlCallbacks.responseCb(err, sessionId);
- } else {
- LOC_LOGW("%s]: control client response callback not found", __func__);
- }
- }
- void
- GnssAdapter::reportResponse(size_t count, LocationError* errs, uint32_t* ids)
- {
- IF_LOC_LOGD {
- std::string idsString = "[";
- std::string errsString = "[";
- if (NULL != ids && NULL != errs) {
- for (size_t i=0; i < count; ++i) {
- idsString += std::to_string(ids[i]) + " ";
- errsString += std::to_string(errs[i]) + " ";
- }
- }
- idsString += "]";
- errsString += "]";
- LOC_LOGD("%s]: ids %s errs %s",
- __func__, idsString.c_str(), errsString.c_str());
- }
- if (mControlCallbacks.size > 0 && mControlCallbacks.collectiveResponseCb != nullptr) {
- mControlCallbacks.collectiveResponseCb(count, errs, ids);
- } else {
- LOC_LOGW("%s]: control client callback not found", __func__);
- }
- }
- uint32_t
- GnssAdapter::startTrackingCommand(LocationAPI* client, TrackingOptions& options)
- {
- uint32_t sessionId = generateSessionId();
- LOC_LOGD("%s]: client %p id %u minInterval %u minDistance %u mode %u powermode %u tbm %u",
- __func__, client, sessionId, options.minInterval, options.minDistance, options.mode,
- options.powerMode, options.tbm);
- struct MsgStartTracking : public LocMsg {
- GnssAdapter& mAdapter;
- LocApiBase& mApi;
- LocationAPI* mClient;
- uint32_t mSessionId;
- mutable TrackingOptions mOptions;
- inline MsgStartTracking(GnssAdapter& adapter,
- LocApiBase& api,
- LocationAPI* client,
- uint32_t sessionId,
- TrackingOptions options) :
- LocMsg(),
- mAdapter(adapter),
- mApi(api),
- mClient(client),
- mSessionId(sessionId),
- mOptions(options) {}
- inline virtual void proc() const {
- // distance based tracking will need to know engine capabilities before it can start
- if (!mAdapter.isEngineCapabilitiesKnown() && mOptions.minDistance > 0) {
- mAdapter.mPendingMsgs.push_back(new MsgStartTracking(*this));
- return;
- }
- LocationError err = LOCATION_ERROR_SUCCESS;
- if (!mAdapter.hasCallbacksToStartTracking(mClient)) {
- err = LOCATION_ERROR_CALLBACK_MISSING;
- } else if (0 == mOptions.size) {
- err = LOCATION_ERROR_INVALID_PARAMETER;
- } else {
- if (mOptions.minInterval < MIN_TRACKING_INTERVAL) {
- mOptions.minInterval = MIN_TRACKING_INTERVAL;
- }
- if (mOptions.minDistance > 0 &&
- ContextBase::isMessageSupported(
- LOC_API_ADAPTER_MESSAGE_DISTANCE_BASE_TRACKING)) {
- mAdapter.saveTrackingSession(mClient, mSessionId, mOptions);
- mApi.startDistanceBasedTracking(mSessionId, mOptions,
- new LocApiResponse(*mAdapter.getContext(),
- [&mAdapter = mAdapter, mSessionId = mSessionId, mClient = mClient]
- (LocationError err) {
- if (LOCATION_ERROR_SUCCESS != err) {
- mAdapter.eraseTrackingSession(mClient, mSessionId);
- }
- mAdapter.reportResponse(mClient, err, mSessionId);
- }));
- } else {
- if (GNSS_POWER_MODE_M4 == mOptions.powerMode &&
- mOptions.tbm > TRACKING_TBM_THRESHOLD_MILLIS) {
- LOC_LOGd("TBM (%d) > %d Falling back to M2 power mode",
- mOptions.tbm, TRACKING_TBM_THRESHOLD_MILLIS);
- mOptions.powerMode = GNSS_POWER_MODE_M2;
- }
- // Api doesn't support multiple clients for time based tracking, so mutiplex
- bool reportToClientWithNoWait =
- mAdapter.startTimeBasedTrackingMultiplex(mClient, mSessionId, mOptions);
- mAdapter.saveTrackingSession(mClient, mSessionId, mOptions);
- if (reportToClientWithNoWait) {
- mAdapter.reportResponse(mClient, LOCATION_ERROR_SUCCESS, mSessionId);
- }
- }
- }
- }
- };
- sendMsg(new MsgStartTracking(*this, *mLocApi, client, sessionId, options));
- return sessionId;
- }
- bool
- GnssAdapter::startTimeBasedTrackingMultiplex(LocationAPI* client, uint32_t sessionId,
- const TrackingOptions& options)
- {
- bool reportToClientWithNoWait = true;
- if (mTimeBasedTrackingSessions.empty()) {
- /*Reset previous NMEA reported time stamp */
- mPrevNmeaRptTimeNsec = 0;
- startTimeBasedTracking(client, sessionId, options);
- // need to wait for QMI callback
- reportToClientWithNoWait = false;
- } else {
- // find the smallest interval and powerMode
- TrackingOptions multiplexedOptions = {}; // size is 0 until set for the first time
- GnssPowerMode multiplexedPowerMode = GNSS_POWER_MODE_INVALID;
- memset(&multiplexedOptions, 0, sizeof(multiplexedOptions));
- for (auto it = mTimeBasedTrackingSessions.begin(); it != mTimeBasedTrackingSessions.end(); ++it) {
- // if not set or there is a new smallest interval, then set the new interval
- if (0 == multiplexedOptions.size ||
- it->second.minInterval < multiplexedOptions.minInterval) {
- multiplexedOptions = it->second;
- }
- // if session is not the one we are updating and either powerMode
- // is not set or there is a new smallest powerMode, then set the new powerMode
- if (GNSS_POWER_MODE_INVALID == multiplexedPowerMode ||
- it->second.powerMode < multiplexedPowerMode) {
- multiplexedPowerMode = it->second.powerMode;
- }
- }
- bool updateOptions = false;
- // if session we are starting has smaller interval then next smallest
- if (options.minInterval < multiplexedOptions.minInterval) {
- multiplexedOptions.minInterval = options.minInterval;
- updateOptions = true;
- }
- // if session we are starting has smaller powerMode then next smallest
- if (options.powerMode < multiplexedPowerMode) {
- multiplexedOptions.powerMode = options.powerMode;
- updateOptions = true;
- }
- if (updateOptions) {
- // restart time based tracking with the newly updated options
- startTimeBasedTracking(client, sessionId, multiplexedOptions);
- // need to wait for QMI callback
- reportToClientWithNoWait = false;
- }
- // else part: no QMI call is made, need to report back to client right away
- }
- return reportToClientWithNoWait;
- }
- void
- GnssAdapter::startTimeBasedTracking(LocationAPI* client, uint32_t sessionId,
- const TrackingOptions& trackingOptions)
- {
- LOC_LOGd("minInterval %u minDistance %u mode %u powermode %u tbm %u",
- trackingOptions.minInterval, trackingOptions.minDistance,
- trackingOptions.mode, trackingOptions.powerMode, trackingOptions.tbm);
- LocPosMode locPosMode = {};
- convertOptions(locPosMode, trackingOptions);
- // save position mode parameters
- setLocPositionMode(locPosMode);
- // inform engine hub that GNSS session is about to start
- mEngHubProxy->gnssSetFixMode(mLocPositionMode);
- mEngHubProxy->gnssStartFix();
- // want to run SPE session at a fixed min interval in some automotive scenarios
- // use a local copy of TrackingOptions as the TBF may get modified in the
- // checkAndSetSPEToRunforNHz function
- TrackingOptions tempOptions(trackingOptions);
- if (!checkAndSetSPEToRunforNHz(tempOptions)) {
- mLocApi->startTimeBasedTracking(tempOptions, new LocApiResponse(*getContext(),
- [this, client, sessionId] (LocationError err) {
- if (LOCATION_ERROR_SUCCESS != err) {
- eraseTrackingSession(client, sessionId);
- } else {
- checkUpdateDgnssNtrip(false);
- }
- reportResponse(client, err, sessionId);
- }
- ));
- } else {
- reportResponse(client, LOCATION_ERROR_SUCCESS, sessionId);
- }
- }
- void
- GnssAdapter::updateTracking(LocationAPI* client, uint32_t sessionId,
- const TrackingOptions& updatedOptions, const TrackingOptions& oldOptions)
- {
- LocPosMode locPosMode = {};
- convertOptions(locPosMode, updatedOptions);
- // save position mode parameters
- setLocPositionMode(locPosMode);
- // inform engine hub that GNSS session is about to start
- mEngHubProxy->gnssSetFixMode(mLocPositionMode);
- mEngHubProxy->gnssStartFix();
- // want to run SPE session at a fixed min interval in some automotive scenarios
- // use a local copy of TrackingOptions as the TBF may get modified in the
- // checkAndSetSPEToRunforNHz function
- TrackingOptions tempOptions(updatedOptions);
- if(!checkAndSetSPEToRunforNHz(tempOptions)) {
- mLocApi->startTimeBasedTracking(tempOptions, new LocApiResponse(*getContext(),
- [this, client, sessionId, oldOptions] (LocationError err) {
- if (LOCATION_ERROR_SUCCESS != err) {
- // restore the old LocationOptions
- saveTrackingSession(client, sessionId, oldOptions);
- }
- reportResponse(client, err, sessionId);
- }
- ));
- } else {
- reportResponse(client, LOCATION_ERROR_SUCCESS, sessionId);
- }
- }
- void
- GnssAdapter::updateTrackingOptionsCommand(LocationAPI* client, uint32_t id,
- TrackingOptions& options)
- {
- LOC_LOGD("%s]: client %p id %u minInterval %u mode %u",
- __func__, client, id, options.minInterval, options.mode);
- struct MsgUpdateTracking : public LocMsg {
- GnssAdapter& mAdapter;
- LocApiBase& mApi;
- LocationAPI* mClient;
- uint32_t mSessionId;
- mutable TrackingOptions mOptions;
- inline MsgUpdateTracking(GnssAdapter& adapter,
- LocApiBase& api,
- LocationAPI* client,
- uint32_t sessionId,
- TrackingOptions options) :
- LocMsg(),
- mAdapter(adapter),
- mApi(api),
- mClient(client),
- mSessionId(sessionId),
- mOptions(options) {}
- inline virtual void proc() const {
- // distance based tracking will need to know engine capabilities before it can start
- if (!mAdapter.isEngineCapabilitiesKnown() && mOptions.minDistance > 0) {
- mAdapter.mPendingMsgs.push_back(new MsgUpdateTracking(*this));
- return;
- }
- LocationError err = LOCATION_ERROR_SUCCESS;
- bool isTimeBased = mAdapter.isTimeBasedTrackingSession(mClient, mSessionId);
- bool isDistanceBased = mAdapter.isDistanceBasedTrackingSession(mClient, mSessionId);
- if (!isTimeBased && !isDistanceBased) {
- err = LOCATION_ERROR_ID_UNKNOWN;
- } else if (0 == mOptions.size) {
- err = LOCATION_ERROR_INVALID_PARAMETER;
- }
- if (LOCATION_ERROR_SUCCESS != err) {
- mAdapter.reportResponse(mClient, err, mSessionId);
- } else {
- if (GNSS_POWER_MODE_M4 == mOptions.powerMode &&
- mOptions.tbm > TRACKING_TBM_THRESHOLD_MILLIS) {
- LOC_LOGd("TBM (%d) > %d Falling back to M2 power mode",
- mOptions.tbm, TRACKING_TBM_THRESHOLD_MILLIS);
- mOptions.powerMode = GNSS_POWER_MODE_M2;
- }
- if (mOptions.minInterval < MIN_TRACKING_INTERVAL) {
- mOptions.minInterval = MIN_TRACKING_INTERVAL;
- }
- // Now update session as required
- if (isTimeBased && mOptions.minDistance > 0) {
- // switch from time based to distance based
- // Api doesn't support multiple clients for time based tracking, so mutiplex
- bool reportToClientWithNoWait =
- mAdapter.stopTimeBasedTrackingMultiplex(mClient, mSessionId);
- // erases the time based Session
- mAdapter.eraseTrackingSession(mClient, mSessionId);
- if (reportToClientWithNoWait) {
- mAdapter.reportResponse(mClient, LOCATION_ERROR_SUCCESS, mSessionId);
- }
- // saves as distance based Session
- mAdapter.saveTrackingSession(mClient, mSessionId, mOptions);
- mApi.startDistanceBasedTracking(mSessionId, mOptions,
- new LocApiResponse(*mAdapter.getContext(),
- [] (LocationError /*err*/) {}));
- } else if (isDistanceBased && mOptions.minDistance == 0) {
- // switch from distance based to time based
- mAdapter.eraseTrackingSession(mClient, mSessionId);
- mApi.stopDistanceBasedTracking(mSessionId, new LocApiResponse(
- *mAdapter.getContext(),
- [&mAdapter = mAdapter, mSessionId = mSessionId, mOptions = mOptions,
- mClient = mClient] (LocationError /*err*/) {
- // Api doesn't support multiple clients for time based tracking,
- // so mutiplex
- bool reportToClientWithNoWait =
- mAdapter.startTimeBasedTrackingMultiplex(mClient, mSessionId,
- mOptions);
- mAdapter.saveTrackingSession(mClient, mSessionId, mOptions);
- if (reportToClientWithNoWait) {
- mAdapter.reportResponse(mClient, LOCATION_ERROR_SUCCESS, mSessionId);
- }
- }));
- } else if (isTimeBased) {
- // update time based tracking
- // Api doesn't support multiple clients for time based tracking, so mutiplex
- bool reportToClientWithNoWait =
- mAdapter.updateTrackingMultiplex(mClient, mSessionId, mOptions);
- mAdapter.saveTrackingSession(mClient, mSessionId, mOptions);
- if (reportToClientWithNoWait) {
- mAdapter.reportResponse(mClient, err, mSessionId);
- }
- } else if (isDistanceBased) {
- // restart distance based tracking
- mApi.stopDistanceBasedTracking(mSessionId, new LocApiResponse(
- *mAdapter.getContext(),
- [&mAdapter = mAdapter, mSessionId = mSessionId, mOptions = mOptions,
- mClient = mClient, &mApi = mApi] (LocationError err) {
- if (LOCATION_ERROR_SUCCESS == err) {
- mApi.startDistanceBasedTracking(mSessionId, mOptions,
- new LocApiResponse(*mAdapter.getContext(),
- [&mAdapter, mClient, mSessionId, mOptions]
- (LocationError err) {
- if (LOCATION_ERROR_SUCCESS == err) {
- mAdapter.saveTrackingSession(mClient, mSessionId, mOptions);
- }
- mAdapter.reportResponse(mClient, err, mSessionId);
- }));
- }
- }));
- }
- }
- }
- };
- sendMsg(new MsgUpdateTracking(*this, *mLocApi, client, id, options));
- }
- bool
- GnssAdapter::updateTrackingMultiplex(LocationAPI* client, uint32_t id,
- const TrackingOptions& trackingOptions)
- {
- bool reportToClientWithNoWait = true;
- LocationSessionKey key(client, id);
- // get the session we are updating
- auto it = mTimeBasedTrackingSessions.find(key);
- // cache the clients existing LocationOptions
- TrackingOptions oldOptions = it->second;
- // if session we are updating exists and the minInterval or powerMode has changed
- if (it != mTimeBasedTrackingSessions.end() &&
- (it->second.minInterval != trackingOptions.minInterval ||
- it->second.powerMode != trackingOptions.powerMode)) {
- // find the smallest interval and powerMode, other than the session we are updating
- TrackingOptions multiplexedOptions = {}; // size is 0 until set for the first time
- GnssPowerMode multiplexedPowerMode = GNSS_POWER_MODE_INVALID;
- memset(&multiplexedOptions, 0, sizeof(multiplexedOptions));
- for (auto it2 = mTimeBasedTrackingSessions.begin();
- it2 != mTimeBasedTrackingSessions.end(); ++it2) {
- // if session is not the one we are updating and either interval
- // is not set or there is a new smallest interval, then set the new interval
- if (it2->first != key && (0 == multiplexedOptions.size ||
- it2->second.minInterval < multiplexedOptions.minInterval)) {
- multiplexedOptions = it2->second;
- }
- // if session is not the one we are updating and either powerMode
- // is not set or there is a new smallest powerMode, then set the new powerMode
- if (it2->first != key && (GNSS_POWER_MODE_INVALID == multiplexedPowerMode ||
- it2->second.powerMode < multiplexedPowerMode)) {
- multiplexedPowerMode = it2->second.powerMode;
- }
- // else part: no QMI call is made, need to report back to client right away
- }
- bool updateOptions = false;
- // if session we are updating has smaller interval then next smallest
- if (trackingOptions.minInterval < multiplexedOptions.minInterval) {
- multiplexedOptions.minInterval = trackingOptions.minInterval;
- updateOptions = true;
- }
- // if session we are updating has smaller powerMode then next smallest
- if (trackingOptions.powerMode < multiplexedPowerMode) {
- multiplexedOptions.powerMode = trackingOptions.powerMode;
- updateOptions = true;
- }
- // if only one session exists, then tracking should be updated with it
- if (1 == mTimeBasedTrackingSessions.size()) {
- multiplexedOptions = trackingOptions;
- updateOptions = true;
- }
- if (updateOptions) {
- // restart time based tracking with the newly updated options
- updateTracking(client, id, multiplexedOptions, oldOptions);
- // need to wait for QMI callback
- reportToClientWithNoWait = false;
- }
- }
- return reportToClientWithNoWait;
- }
- void
- GnssAdapter::stopTrackingCommand(LocationAPI* client, uint32_t id)
- {
- LOC_LOGD("%s]: client %p id %u", __func__, client, id);
- struct MsgStopTracking : public LocMsg {
- GnssAdapter& mAdapter;
- LocApiBase& mApi;
- LocationAPI* mClient;
- uint32_t mSessionId;
- inline MsgStopTracking(GnssAdapter& adapter,
- LocApiBase& api,
- LocationAPI* client,
- uint32_t sessionId) :
- LocMsg(),
- mAdapter(adapter),
- mApi(api),
- mClient(client),
- mSessionId(sessionId) {}
- inline virtual void proc() const {
- bool isTimeBased = mAdapter.isTimeBasedTrackingSession(mClient, mSessionId);
- bool isDistanceBased = mAdapter.isDistanceBasedTrackingSession(mClient, mSessionId);
- if (isTimeBased || isDistanceBased) {
- if (isTimeBased) {
- // Api doesn't support multiple clients for time based tracking, so mutiplex
- bool reportToClientWithNoWait =
- mAdapter.stopTimeBasedTrackingMultiplex(mClient, mSessionId);
- mAdapter.eraseTrackingSession(mClient, mSessionId);
- if (reportToClientWithNoWait) {
- mAdapter.reportResponse(mClient, LOCATION_ERROR_SUCCESS, mSessionId);
- }
- } else if (isDistanceBased) {
- mApi.stopDistanceBasedTracking(mSessionId, new LocApiResponse(
- *mAdapter.getContext(),
- [&mAdapter = mAdapter, mSessionId = mSessionId, mClient = mClient]
- (LocationError err) {
- if (LOCATION_ERROR_SUCCESS == err) {
- mAdapter.eraseTrackingSession(mClient, mSessionId);
- }
- mAdapter.reportResponse(mClient, err, mSessionId);
- }));
- }
- } else {
- mAdapter.reportResponse(mClient, LOCATION_ERROR_ID_UNKNOWN, mSessionId);
- }
- }
- };
- sendMsg(new MsgStopTracking(*this, *mLocApi, client, id));
- }
- bool
- GnssAdapter::stopTimeBasedTrackingMultiplex(LocationAPI* client, uint32_t id)
- {
- bool reportToClientWithNoWait = true;
- if (1 == mTimeBasedTrackingSessions.size()) {
- stopTracking(client, id);
- // need to wait for QMI callback
- reportToClientWithNoWait = false;
- } else {
- LocationSessionKey key(client, id);
- // get the session we are stopping
- auto it = mTimeBasedTrackingSessions.find(key);
- if (it != mTimeBasedTrackingSessions.end()) {
- // find the smallest interval and powerMode, other than the session we are stopping
- TrackingOptions multiplexedOptions = {}; // size is 0 until set for the first time
- GnssPowerMode multiplexedPowerMode = GNSS_POWER_MODE_INVALID;
- memset(&multiplexedOptions, 0, sizeof(multiplexedOptions));
- for (auto it2 = mTimeBasedTrackingSessions.begin();
- it2 != mTimeBasedTrackingSessions.end(); ++it2) {
- // if session is not the one we are stopping and either interval
- // is not set or there is a new smallest interval, then set the new interval
- if (it2->first != key && (0 == multiplexedOptions.size ||
- it2->second.minInterval < multiplexedOptions.minInterval)) {
- multiplexedOptions = it2->second;
- }
- // if session is not the one we are stopping and either powerMode
- // is not set or there is a new smallest powerMode, then set the new powerMode
- if (it2->first != key && (GNSS_POWER_MODE_INVALID == multiplexedPowerMode ||
- it2->second.powerMode < multiplexedPowerMode)) {
- multiplexedPowerMode = it2->second.powerMode;
- }
- }
- // if session we are stopping has smaller interval then next smallest or
- // if session we are stopping has smaller powerMode then next smallest
- if (it->second.minInterval < multiplexedOptions.minInterval ||
- it->second.powerMode < multiplexedPowerMode) {
- multiplexedOptions.powerMode = multiplexedPowerMode;
- // restart time based tracking with the newly updated options
- startTimeBasedTracking(client, id, multiplexedOptions);
- // need to wait for QMI callback
- reportToClientWithNoWait = false;
- }
- // else part: no QMI call is made, need to report back to client right away
- }
- }
- return reportToClientWithNoWait;
- }
- void
- GnssAdapter::stopTracking(LocationAPI* client, uint32_t id)
- {
- // inform engine hub that GNSS session has stopped
- mEngHubProxy->gnssStopFix();
- mLocApi->stopFix(new LocApiResponse(*getContext(),
- [this, client, id] (LocationError err) {
- reportResponse(client, err, id);
- }));
- if (isDgnssNmeaRequired()) {
- mDgnssState &= ~DGNSS_STATE_NO_NMEA_PENDING;
- }
- stopDgnssNtrip();
- mPositionElapsedRealTimeCal.reset();
- mSPEAlreadyRunningAtHighestInterval = false;
- }
- bool
- GnssAdapter::hasNiNotifyCallback(LocationAPI* client)
- {
- auto it = mClientData.find(client);
- return (it != mClientData.end() && it->second.gnssNiCb);
- }
- void
- GnssAdapter::gnssNiResponseCommand(LocationAPI* client,
- uint32_t id,
- GnssNiResponse response)
- {
- LOC_LOGD("%s]: client %p id %u response %u", __func__, client, id, response);
- struct MsgGnssNiResponse : public LocMsg {
- GnssAdapter& mAdapter;
- LocationAPI* mClient;
- uint32_t mSessionId;
- GnssNiResponse mResponse;
- inline MsgGnssNiResponse(GnssAdapter& adapter,
- LocationAPI* client,
- uint32_t sessionId,
- GnssNiResponse response) :
- LocMsg(),
- mAdapter(adapter),
- mClient(client),
- mSessionId(sessionId),
- mResponse(response) {}
- inline virtual void proc() const {
- NiData& niData = mAdapter.getNiData();
- LocationError err = LOCATION_ERROR_SUCCESS;
- if (!mAdapter.hasNiNotifyCallback(mClient)) {
- err = LOCATION_ERROR_ID_UNKNOWN;
- } else {
- NiSession* pSession = NULL;
- if (mSessionId == niData.sessionEs.reqID &&
- NULL != niData.sessionEs.rawRequest) {
- pSession = &niData.sessionEs;
- // ignore any SUPL NI non-Es session if a SUPL NI ES is accepted
- if (mResponse == GNSS_NI_RESPONSE_ACCEPT &&
- NULL != niData.session.rawRequest) {
- pthread_mutex_lock(&niData.session.tLock);
- niData.session.resp = GNSS_NI_RESPONSE_IGNORE;
- niData.session.respRecvd = true;
- pthread_cond_signal(&niData.session.tCond);
- pthread_mutex_unlock(&niData.session.tLock);
- }
- } else if (mSessionId == niData.session.reqID &&
- NULL != niData.session.rawRequest) {
- pSession = &niData.session;
- }
- if (pSession) {
- LOC_LOGI("%s]: gnssNiResponseCommand: send user mResponse %u for id %u",
- __func__, mResponse, mSessionId);
- pthread_mutex_lock(&pSession->tLock);
- pSession->resp = mResponse;
- pSession->respRecvd = true;
- pthread_cond_signal(&pSession->tCond);
- pthread_mutex_unlock(&pSession->tLock);
- } else {
- err = LOCATION_ERROR_ID_UNKNOWN;
- LOC_LOGE("%s]: gnssNiResponseCommand: id %u not an active session",
- __func__, mSessionId);
- }
- }
- mAdapter.reportResponse(mClient, err, mSessionId);
- }
- };
- sendMsg(new MsgGnssNiResponse(*this, client, id, response));
- }
- void
- GnssAdapter::gnssNiResponseCommand(GnssNiResponse response, void* rawRequest)
- {
- LOC_LOGD("%s]: response %u", __func__, response);
- struct MsgGnssNiResponse : public LocMsg {
- GnssAdapter& mAdapter;
- LocApiBase& mApi;
- const GnssNiResponse mResponse;
- const void* mPayload;
- inline MsgGnssNiResponse(GnssAdapter& adapter,
- LocApiBase& api,
- const GnssNiResponse response,
- const void* rawRequest) :
- LocMsg(),
- mAdapter(adapter),
- mApi(api),
- mResponse(response),
- mPayload(rawRequest) {}
- inline virtual ~MsgGnssNiResponse() {
- }
- inline virtual void proc() const {
- mApi.informNiResponse(mResponse, mPayload);
- }
- };
- sendMsg(new MsgGnssNiResponse(*this, *mLocApi, response, rawRequest));
- }
- uint32_t
- GnssAdapter::enableCommand(LocationTechnologyType techType)
- {
- uint32_t sessionId = generateSessionId();
- LOC_LOGD("%s]: id %u techType %u", __func__, sessionId, techType);
- struct MsgEnableGnss : public LocMsg {
- GnssAdapter& mAdapter;
- LocApiBase& mApi;
- ContextBase& mContext;
- uint32_t mSessionId;
- LocationTechnologyType mTechType;
- inline MsgEnableGnss(GnssAdapter& adapter,
- LocApiBase& api,
- ContextBase& context,
- uint32_t sessionId,
- LocationTechnologyType techType) :
- LocMsg(),
- mAdapter(adapter),
- mApi(api),
- mContext(context),
- mSessionId(sessionId),
- mTechType(techType) {}
- inline virtual void proc() const {
- LocationError err = LOCATION_ERROR_SUCCESS;
- uint32_t afwControlId = mAdapter.getAfwControlId();
- if (mTechType != LOCATION_TECHNOLOGY_TYPE_GNSS) {
- err = LOCATION_ERROR_INVALID_PARAMETER;
- } else if (afwControlId > 0) {
- err = LOCATION_ERROR_ALREADY_STARTED;
- } else {
- mContext.modemPowerVote(true);
- mAdapter.setAfwControlId(mSessionId);
- GnssConfigGpsLock gpsLock = GNSS_CONFIG_GPS_LOCK_NONE;
- if (mAdapter.mSupportNfwControl) {
- ContextBase::mGps_conf.GPS_LOCK &= GNSS_CONFIG_GPS_LOCK_NFW_ALL;
- gpsLock = ContextBase::mGps_conf.GPS_LOCK;
- }
- mApi.sendMsg(new LocApiMsg([&mApi = mApi, gpsLock]() {
- mApi.setGpsLockSync(gpsLock);
- }));
- mAdapter.mXtraObserver.updateLockStatus(gpsLock);
- }
- mAdapter.reportResponse(err, mSessionId);
- }
- };
- if (mContext != NULL) {
- sendMsg(new MsgEnableGnss(*this, *mLocApi, *mContext, sessionId, techType));
- } else {
- LOC_LOGE("%s]: Context is NULL", __func__);
- }
- return sessionId;
- }
- void
- GnssAdapter::disableCommand(uint32_t id)
- {
- LOC_LOGD("%s]: id %u", __func__, id);
- struct MsgDisableGnss : public LocMsg {
- GnssAdapter& mAdapter;
- LocApiBase& mApi;
- ContextBase& mContext;
- uint32_t mSessionId;
- inline MsgDisableGnss(GnssAdapter& adapter,
- LocApiBase& api,
- ContextBase& context,
- uint32_t sessionId) :
- LocMsg(),
- mAdapter(adapter),
- mApi(api),
- mContext(context),
- mSessionId(sessionId) {}
- inline virtual void proc() const {
- LocationError err = LOCATION_ERROR_SUCCESS;
- uint32_t afwControlId = mAdapter.getAfwControlId();
- if (afwControlId != mSessionId) {
- err = LOCATION_ERROR_ID_UNKNOWN;
- } else {
- mContext.modemPowerVote(false);
- mAdapter.setAfwControlId(0);
- if (mAdapter.mSupportNfwControl) {
- /* We need to disable MO (AFW) */
- ContextBase::mGps_conf.GPS_LOCK |= GNSS_CONFIG_GPS_LOCK_MO;
- }
- GnssConfigGpsLock gpsLock = ContextBase::mGps_conf.GPS_LOCK;
- mApi.sendMsg(new LocApiMsg([&mApi = mApi, gpsLock]() {
- mApi.setGpsLockSync(gpsLock);
- }));
- mAdapter.mXtraObserver.updateLockStatus(gpsLock);
- }
- mAdapter.reportResponse(err, mSessionId);
- }
- };
- if (mContext != NULL) {
- sendMsg(new MsgDisableGnss(*this, *mLocApi, *mContext, id));
- }
- }
- // This function computes the VRP based latitude, longitude and alittude, and
- // north, east and up velocity and save the result into EHubTechReport.
- void
- GnssAdapter::computeVRPBasedLla(const UlpLocation& loc, GpsLocationExtended& locExt,
- const LeverArmConfigInfo& leverArmConfigInfo) {
- float leverArm[3];
- float rollPitchYaw[3];
- double lla[3];
- uint16_t locFlags = loc.gpsLocation.flags;
- uint64_t locExtFlags = locExt.flags;
- // check for SPE fix
- if (!((locExtFlags & GPS_LOCATION_EXTENDED_HAS_OUTPUT_ENG_TYPE) &&
- (locExt.locOutputEngType == LOC_OUTPUT_ENGINE_SPE))){
- LOC_LOGv("not SPE fix, return");
- return;
- }
- // we can only do translation if we have VRP based lever ARM info
- LeverArmTypeMask leverArmFlags = leverArmConfigInfo.leverArmValidMask;
- if (!(leverArmFlags & LEVER_ARM_TYPE_GNSS_TO_VRP_BIT)) {
- LOC_LOGd("no VRP based lever ARM info");
- return;
- }
- leverArm[0] = leverArmConfigInfo.gnssToVRP.forwardOffsetMeters;
- leverArm[1] = leverArmConfigInfo.gnssToVRP.sidewaysOffsetMeters;
- leverArm[2] = leverArmConfigInfo.gnssToVRP.upOffsetMeters;
- if ((locFlags & LOC_GPS_LOCATION_HAS_LAT_LONG) &&
- (locFlags & LOC_GPS_LOCATION_HAS_ALTITUDE) &&
- (locFlags & LOCATION_HAS_BEARING_BIT)) {
- lla[0] = loc.gpsLocation.latitude * DEG2RAD;
- lla[1] = loc.gpsLocation.longitude * DEG2RAD;
- lla[2] = loc.gpsLocation.altitude;
- rollPitchYaw[0] = 0.0f;
- rollPitchYaw[1] = 0.0f;
- rollPitchYaw[2] = loc.gpsLocation.bearing * DEG2RAD;
- loc_convert_lla_gnss_to_vrp(lla, rollPitchYaw, leverArm);
- // assign the converted value into position report and
- // set up valid mask
- locExt.llaVRPBased.latitude = lla[0] * RAD2DEG;
- locExt.llaVRPBased.longitude = lla[1] * RAD2DEG;
- locExt.llaVRPBased.altitude = lla[2];
- locExt.flags |= GPS_LOCATION_EXTENDED_HAS_LLA_VRP_BASED;
- } else {
- LOC_LOGd("SPE fix missing latitude/longitude/alitutde");
- return;
- }
- }
- void
- GnssAdapter::reportPositionEvent(const UlpLocation& ulpLocation,
- const GpsLocationExtended& locationExtended,
- enum loc_sess_status status,
- LocPosTechMask techMask,
- GnssDataNotification* pDataNotify,
- int msInWeek)
- {
- // this position is from QMI LOC API, then send report to engine hub
- // also, send out SPE fix promptly to the clients that have registered
- // with SPE report
- LOC_LOGd("reportPositionEvent, eng type: %d, unpro %d, sess status %d msInWeek %d",
- locationExtended.locOutputEngType,
- ulpLocation.unpropagatedPosition, status, msInWeek);
- struct MsgReportSPEPosition : public LocMsg {
- GnssAdapter& mAdapter;
- mutable UlpLocation mUlpLocation;
- mutable GpsLocationExtended mLocationExtended;
- enum loc_sess_status mStatus;
- LocPosTechMask mTechMask;
- mutable GnssDataNotification mDataNotify;
- int mMsInWeek;
- inline MsgReportSPEPosition(GnssAdapter& adapter,
- const UlpLocation& ulpLocation,
- const GpsLocationExtended& locationExtended,
- enum loc_sess_status status,
- LocPosTechMask techMask,
- GnssDataNotification dataNotify,
- int msInWeek) :
- LocMsg(),
- mAdapter(adapter),
- mUlpLocation(ulpLocation),
- mLocationExtended(locationExtended),
- mStatus(status),
- mTechMask(techMask),
- mDataNotify(dataNotify),
- mMsInWeek(msInWeek) {}
- inline virtual void proc() const {
- if (mAdapter.mTimeBasedTrackingSessions.empty() &&
- mAdapter.mDistanceBasedTrackingSessions.empty()) {
- LOC_LOGd("reportPositionEvent, no session on-going, throw away the SPE reports");
- return;
- }
- if (false == mUlpLocation.unpropagatedPosition && mDataNotify.size != 0) {
- if (mMsInWeek >= 0) {
- mAdapter.getDataInformation((GnssDataNotification&)mDataNotify,
- mMsInWeek);
- }
- mAdapter.reportData(mDataNotify);
- }
- // save the association of GPS timestamp and qtimer tick cnt in PVT report
- mAdapter.mPositionElapsedRealTimeCal
- .saveGpsTimeAndQtimerPairInPvtReport(mLocationExtended);
- if (true == mAdapter.initEngHubProxy()){
- // send the SPE fix to engine hub
- mAdapter.mEngHubProxy->gnssReportPosition(mUlpLocation, mLocationExtended, mStatus);
- // report out all SPE fix if it is not propagated, even for failed fix
- if (false == mUlpLocation.unpropagatedPosition) {
- EngineLocationInfo engLocationInfo = {};
- engLocationInfo.location = mUlpLocation;
- engLocationInfo.locationExtended = mLocationExtended;
- engLocationInfo.sessionStatus = mStatus;
- // obtain the VRP based latitude/longitude/altitude for SPE fix
- computeVRPBasedLla(engLocationInfo.location,
- engLocationInfo.locationExtended,
- mAdapter.mLocConfigInfo.leverArmConfigInfo);
- mAdapter.reportEnginePositions(1, &engLocationInfo);
- }
- return;
- }
- // unpropagated report: is only for engine hub to consume and no need
- // to send out to the clients
- if (true == mUlpLocation.unpropagatedPosition) {
- return;
- }
- // extract bug report info - this returns true if consumed by systemstatus
- SystemStatus* s = mAdapter.getSystemStatus();
- if ((nullptr != s) &&
- ((LOC_SESS_SUCCESS == mStatus) || (LOC_SESS_INTERMEDIATE == mStatus))){
- s->eventPosition(mUlpLocation, mLocationExtended);
- }
- mAdapter.reportPosition(mUlpLocation, mLocationExtended, mStatus, mTechMask);
- }
- };
- if (mContext != NULL) {
- GnssDataNotification dataNotifyCopy = {};
- if (pDataNotify) {
- dataNotifyCopy = *pDataNotify;
- dataNotifyCopy.size = sizeof(dataNotifyCopy);
- }
- sendMsg(new MsgReportSPEPosition(*this, ulpLocation, locationExtended,
- status, techMask, dataNotifyCopy, msInWeek));
- }
- }
- void
- GnssAdapter::reportEnginePositionsEvent(unsigned int count,
- EngineLocationInfo* locationArr)
- {
- struct MsgReportEnginePositions : public LocMsg {
- GnssAdapter& mAdapter;
- unsigned int mCount;
- EngineLocationInfo mEngLocInfo[LOC_OUTPUT_ENGINE_COUNT];
- inline MsgReportEnginePositions(GnssAdapter& adapter,
- unsigned int count,
- EngineLocationInfo* locationArr) :
- LocMsg(),
- mAdapter(adapter),
- mCount(count) {
- if (mCount > LOC_OUTPUT_ENGINE_COUNT) {
- mCount = LOC_OUTPUT_ENGINE_COUNT;
- }
- if (mCount > 0) {
- memcpy(mEngLocInfo, locationArr, sizeof(EngineLocationInfo)*mCount);
- }
- }
- inline virtual void proc() const {
- mAdapter.reportEnginePositions(mCount, mEngLocInfo);
- }
- };
- sendMsg(new MsgReportEnginePositions(*this, count, locationArr));
- }
- bool
- GnssAdapter::needReportForAllClients(const UlpLocation& ulpLocation,
- enum loc_sess_status status,
- LocPosTechMask techMask) {
- bool reported = false;
- #ifdef USE_GLIB
- if (true == initEngHubProxy()) {
- reported = true;
- }
- #endif
- return reported || LocApiBase::needReport(ulpLocation, status, techMask);
- }
- bool GnssAdapter::needReportForClient(LocationAPI* client, enum loc_sess_status status) {
- if (LOC_SESS_SUCCESS == status || (client == nullptr && LOC_SESS_INTERMEDIATE == status &&
- mDistanceBasedTrackingSessions.size() > 0)) {
- return true;
- }
- if (status != LOC_SESS_FAILURE) {
- for (auto it = mDistanceBasedTrackingSessions.begin();
- it != mDistanceBasedTrackingSessions.end(); ++it) {
- if (it->first.client == client) { // Always report intermediate fixes to dbt clients
- return true;
- }
- }
- }
- for (auto it = mTimeBasedTrackingSessions.begin();
- it != mTimeBasedTrackingSessions.end(); ++it) {
- // report intermediate fix when TBT session allows, like flp;
- // report any fix (even failed fix) when TBT session allows, like LE.
- if ((it->first.client == client || client == nullptr) &&
- it->second.qualityLevelAccepted >= status) {
- return true;
- }
- }
- return false;
- }
- bool GnssAdapter::needToGenerateNmeaReport(const uint32_t &gpsTimeOfWeekMs,
- const struct timespec32_t &apTimeStamp)
- {
- bool retVal = false;
- uint64_t currentTimeNsec = 0;
- if (NMEA_PROVIDER_AP == ContextBase::mGps_conf.NMEA_PROVIDER && !mTimeBasedTrackingSessions.empty()) {
- currentTimeNsec = (apTimeStamp.tv_sec * BILLION_NSEC + apTimeStamp.tv_nsec);
- if ((GNSS_NMEA_REPORT_RATE_NHZ == ContextBase::sNmeaReportRate) ||
- (GPS_DEFAULT_FIX_INTERVAL_MS <= mLocPositionMode.min_interval)) {
- retVal = true;
- } else { /*tbf is less than 1000 milli-seconds and NMEA reporting rate is set to 1Hz */
- /* Always send NMEA string for first position report
- * Send when gpsTimeOfWeekMs is closely aligned with integer boundary
- */
- if ((0 == mPrevNmeaRptTimeNsec) ||
- (0 != gpsTimeOfWeekMs) && (NMEA_MIN_THRESHOLD_MSEC >= (gpsTimeOfWeekMs % 1000))) {
- retVal = true;
- } else {
- uint64_t timeDiffMsec = ((currentTimeNsec - mPrevNmeaRptTimeNsec) / 1000000);
- // Send when the delta time becomes >= 1 sec
- if (NMEA_MAX_THRESHOLD_MSEC <= timeDiffMsec) {
- retVal = true;
- }
- }
- }
- if (true == retVal) {
- mPrevNmeaRptTimeNsec = currentTimeNsec;
- }
- }
- return retVal;
- }
- void
- GnssAdapter::logLatencyInfo()
- {
- if (0 == mGnssLatencyInfoQueue.size()) {
- LOC_LOGv("mGnssLatencyInfoQueue.size is 0");
- return;
- }
- mGnssLatencyInfoQueue.front().hlosQtimer5 = getQTimerTickCount();
- if (0 == mGnssLatencyInfoQueue.front().hlosQtimer3) {
- /* if SPE from engine hub is not reported then hlosQtimer3 = 0, set it
- equal to hlosQtimer2 to make sense */
- LOC_LOGv("hlosQtimer3 is 0, setting it to hlosQtimer2");
- mGnssLatencyInfoQueue.front().hlosQtimer3 = mGnssLatencyInfoQueue.front().hlosQtimer2;
- }
- if (0 == mGnssLatencyInfoQueue.front().hlosQtimer4) {
- /* if PPE from engine hub is not reported then hlosQtimer4 = 0, set it
- equal to hlosQtimer3 to make sense */
- LOC_LOGv("hlosQtimer4 is 0, setting it to hlosQtimer3");
- mGnssLatencyInfoQueue.front().hlosQtimer4 = mGnssLatencyInfoQueue.front().hlosQtimer3;
- }
- if (mGnssLatencyInfoQueue.front().hlosQtimer4 < mGnssLatencyInfoQueue.front().hlosQtimer3) {
- /* hlosQtimer3 is timestamped when SPE from engine hub is reported,
- and hlosQtimer4 is timestamped when PPE from engine hub is reported.
- The order is random though, hence making sure the timestamps are sorted */
- LOC_LOGv("hlosQtimer4 is < hlosQtimer3, swapping them");
- std::swap(mGnssLatencyInfoQueue.front().hlosQtimer3,
- mGnssLatencyInfoQueue.front().hlosQtimer4);
- }
- LOC_LOGv("meQtimer1=%" PRIi64 " "
- "meQtimer2=%" PRIi64 " "
- "meQtimer3=%" PRIi64 " "
- "peQtimer1=%" PRIi64 " "
- "peQtimer2=%" PRIi64 " "
- "peQtimer3=%" PRIi64 " "
- "smQtimer1=%" PRIi64 " "
- "smQtimer2=%" PRIi64 " "
- "smQtimer3=%" PRIi64 " "
- "locMwQtimer=%" PRIi64 " "
- "hlosQtimer1=%" PRIi64 " "
- "hlosQtimer2=%" PRIi64 " "
- "hlosQtimer3=%" PRIi64 " "
- "hlosQtimer4=%" PRIi64 " "
- "hlosQtimer5=%" PRIi64 " ",
- mGnssLatencyInfoQueue.front().meQtimer1, mGnssLatencyInfoQueue.front().meQtimer2,
- mGnssLatencyInfoQueue.front().meQtimer3, mGnssLatencyInfoQueue.front().peQtimer1,
- mGnssLatencyInfoQueue.front().peQtimer2, mGnssLatencyInfoQueue.front().peQtimer3,
- mGnssLatencyInfoQueue.front().smQtimer1, mGnssLatencyInfoQueue.front().smQtimer2,
- mGnssLatencyInfoQueue.front().smQtimer3, mGnssLatencyInfoQueue.front().locMwQtimer,
- mGnssLatencyInfoQueue.front().hlosQtimer1, mGnssLatencyInfoQueue.front().hlosQtimer2,
- mGnssLatencyInfoQueue.front().hlosQtimer3, mGnssLatencyInfoQueue.front().hlosQtimer4,
- mGnssLatencyInfoQueue.front().hlosQtimer5);
- mLogger.log(mGnssLatencyInfoQueue.front());
- mGnssLatencyInfoQueue.pop();
- LOC_LOGv("mGnssLatencyInfoQueue.size after pop=%zu", mGnssLatencyInfoQueue.size());
- }
- // only fused report (when engine hub is enabled) or
- // SPE report (when engine hub is disabled) will reach this function
- void
- GnssAdapter::reportPosition(const UlpLocation& ulpLocation,
- const GpsLocationExtended& locationExtended,
- enum loc_sess_status status,
- LocPosTechMask techMask)
- {
- bool reportToAllClients = needReportForAllClients(ulpLocation, status, techMask);
- bool reportToAnyClient = needReportForAnyClient(status);
- if (reportToAllClients || reportToAnyClient) {
- GnssLocationInfoNotification locationInfo = {};
- convertLocationInfo(locationInfo, locationExtended, status);
- convertLocation(locationInfo.location, ulpLocation, locationExtended);
- fillElapsedRealTime(locationExtended, locationInfo.location);
- logLatencyInfo();
- for (auto it=mClientData.begin(); it != mClientData.end(); ++it) {
- if (reportToAllClients || needReportForClient(it->first, status)) {
- if (nullptr != it->second.gnssLocationInfoCb) {
- it->second.gnssLocationInfoCb(locationInfo);
- } else if ((nullptr != it->second.engineLocationsInfoCb) &&
- (false == initEngHubProxy())) {
- // if engine hub is disabled, this is SPE fix from modem
- // we need to mark one copy marked as fused and one copy marked as PPE
- // and dispatch it to the engineLocationsInfoCb
- GnssLocationInfoNotification engLocationsInfo[2];
- engLocationsInfo[0] = locationInfo;
- engLocationsInfo[0].locOutputEngType = LOC_OUTPUT_ENGINE_FUSED;
- engLocationsInfo[0].flags |= GNSS_LOCATION_INFO_OUTPUT_ENG_TYPE_BIT;
- engLocationsInfo[1] = locationInfo;
- it->second.engineLocationsInfoCb(2, engLocationsInfo);
- } else if (nullptr != it->second.trackingCb) {
- it->second.trackingCb(locationInfo.location);
- }
- }
- }
- mGnssSvIdUsedInPosAvail = false;
- mGnssMbSvIdUsedInPosAvail = false;
- if (reportToAllClients) {
- if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_GNSS_SV_USED_DATA) {
- mGnssSvIdUsedInPosAvail = true;
- mGnssSvIdUsedInPosition = locationExtended.gnss_sv_used_ids;
- if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_MULTIBAND) {
- mGnssMbSvIdUsedInPosAvail = true;
- mGnssMbSvIdUsedInPosition = locationExtended.gnss_mb_sv_used_ids;
- }
- }
- // if PACE is enabled
- if ((true == mLocConfigInfo.paceConfigInfo.isValid) &&
- (true == mLocConfigInfo.paceConfigInfo.enable)) {
- // If fix has sensor contribution, and it is fused fix with DRE engine
- // contributing to the fix, inject to modem
- if ((LOC_POS_TECH_MASK_SENSORS & techMask) &&
- (locationInfo.flags & GNSS_LOCATION_INFO_OUTPUT_ENG_TYPE_BIT) &&
- (locationInfo.locOutputEngType == LOC_OUTPUT_ENGINE_FUSED) &&
- (locationInfo.flags & GNSS_LOCATION_INFO_OUTPUT_ENG_MASK_BIT) &&
- (locationInfo.locOutputEngMask & DEAD_RECKONING_ENGINE)) {
- mLocApi->injectPosition(locationInfo, false);
- }
- }
- }
- }
- if (needToGenerateNmeaReport(locationExtended.gpsTime.gpsTimeOfWeekMs,
- locationExtended.timeStamp.apTimeStamp)) {
- /*Only BlankNMEA sentence needs to be processed and sent, if both lat, long is 0 &
- horReliability is not set. */
- bool blank_fix = ((0 == ulpLocation.gpsLocation.latitude) &&
- (0 == ulpLocation.gpsLocation.longitude) &&
- (LOC_RELIABILITY_NOT_SET == locationExtended.horizontal_reliability));
- uint8_t generate_nmea = (reportToAllClients && status != LOC_SESS_FAILURE && !blank_fix);
- bool custom_nmea_gga = (1 == ContextBase::mGps_conf.CUSTOM_NMEA_GGA_FIX_QUALITY_ENABLED);
- bool isTagBlockGroupingEnabled =
- (1 == ContextBase::mGps_conf.NMEA_TAG_BLOCK_GROUPING_ENABLED);
- std::vector<std::string> nmeaArraystr;
- int indexOfGGA = -1;
- loc_nmea_generate_pos(ulpLocation, locationExtended, mLocSystemInfo, generate_nmea,
- custom_nmea_gga, nmeaArraystr, indexOfGGA, isTagBlockGroupingEnabled);
- stringstream ss;
- for (auto itor = nmeaArraystr.begin(); itor != nmeaArraystr.end(); ++itor) {
- ss << *itor;
- }
- string s = ss.str();
- reportNmea(s.c_str(), s.length());
- /* DgnssNtrip */
- if (-1 != indexOfGGA && isDgnssNmeaRequired()) {
- mDgnssState |= DGNSS_STATE_NO_NMEA_PENDING;
- mStartDgnssNtripParams.nmea = std::move(nmeaArraystr[indexOfGGA]);
- bool isLocationValid = (0 != ulpLocation.gpsLocation.latitude) ||
- (0 != ulpLocation.gpsLocation.longitude);
- checkUpdateDgnssNtrip(isLocationValid);
- }
- }
- }
- void
- GnssAdapter::reportLatencyInfoEvent(const GnssLatencyInfo& gnssLatencyInfo)
- {
- struct MsgReportLatencyInfo : public LocMsg {
- GnssAdapter& mAdapter;
- GnssLatencyInfo mGnssLatencyInfo;
- inline MsgReportLatencyInfo(GnssAdapter& adapter,
- const GnssLatencyInfo& gnssLatencyInfo) :
- mGnssLatencyInfo(gnssLatencyInfo),
- mAdapter(adapter) {}
- inline virtual void proc() const {
- mAdapter.mGnssLatencyInfoQueue.push(mGnssLatencyInfo);
- LOC_LOGv("mGnssLatencyInfoQueue.size after push=%zu",
- mAdapter.mGnssLatencyInfoQueue.size());
- }
- };
- sendMsg(new MsgReportLatencyInfo(*this, gnssLatencyInfo));
- }
- void
- GnssAdapter::reportEnginePositions(unsigned int count,
- const EngineLocationInfo* locationArr)
- {
- bool needReportEnginePositions = false;
- for (auto it=mClientData.begin(); it != mClientData.end(); ++it) {
- if (nullptr != it->second.engineLocationsInfoCb) {
- needReportEnginePositions = true;
- break;
- }
- }
- GnssLocationInfoNotification locationInfo[LOC_OUTPUT_ENGINE_COUNT] = {};
- for (unsigned int i = 0; i < count; i++) {
- const EngineLocationInfo* engLocation = (locationArr+i);
- // if it is fused/default location, call reportPosition maintain legacy behavior
- if ((GPS_LOCATION_EXTENDED_HAS_OUTPUT_ENG_TYPE & engLocation->locationExtended.flags) &&
- (LOC_OUTPUT_ENGINE_FUSED == engLocation->locationExtended.locOutputEngType)) {
- reportPosition(engLocation->location,
- engLocation->locationExtended,
- engLocation->sessionStatus,
- engLocation->location.tech_mask);
- }
- if (needReportEnginePositions) {
- convertLocationInfo(locationInfo[i], engLocation->locationExtended,
- engLocation->sessionStatus);
- convertLocation(locationInfo[i].location,
- engLocation->location,
- engLocation->locationExtended);
- fillElapsedRealTime(engLocation->locationExtended,
- locationInfo[i].location);
- }
- }
- const EngineLocationInfo* engLocation = locationArr;
- LOC_LOGv("engLocation->locationExtended.locOutputEngType=%d",
- engLocation->locationExtended.locOutputEngType);
- if (0 != mGnssLatencyInfoQueue.size()) {
- if ((GPS_LOCATION_EXTENDED_HAS_OUTPUT_ENG_TYPE & engLocation->locationExtended.flags) &&
- (LOC_OUTPUT_ENGINE_SPE == engLocation->locationExtended.locOutputEngType)) {
- mGnssLatencyInfoQueue.front().hlosQtimer3 = getQTimerTickCount();
- LOC_LOGv("SPE hlosQtimer3=%" PRIi64 " ", mGnssLatencyInfoQueue.front().hlosQtimer3);
- }
- if ((GPS_LOCATION_EXTENDED_HAS_OUTPUT_ENG_TYPE & engLocation->locationExtended.flags) &&
- (LOC_OUTPUT_ENGINE_PPE == engLocation->locationExtended.locOutputEngType)) {
- mGnssLatencyInfoQueue.front().hlosQtimer4 = getQTimerTickCount();
- LOC_LOGv("PPE hlosQtimer4=%" PRIi64 " ", mGnssLatencyInfoQueue.front().hlosQtimer4);
- }
- }
- if (needReportEnginePositions) {
- for (auto it=mClientData.begin(); it != mClientData.end(); ++it) {
- if (nullptr != it->second.engineLocationsInfoCb &&
- needReportForClient(it->first, engLocation->sessionStatus)) {
- it->second.engineLocationsInfoCb(count, locationInfo);
- }
- }
- }
- }
- void
- GnssAdapter::reportSvEvent(const GnssSvNotification& svNotify)
- {
- struct MsgReportSv : public LocMsg {
- GnssAdapter& mAdapter;
- const GnssSvNotification mSvNotify;
- inline MsgReportSv(GnssAdapter& adapter,
- const GnssSvNotification& svNotify) :
- LocMsg(),
- mAdapter(adapter),
- mSvNotify(svNotify) {}
- inline virtual void proc() const {
- mAdapter.reportSv((GnssSvNotification&)mSvNotify);
- }
- };
- sendMsg(new MsgReportSv(*this, svNotify));
- }
- void
- GnssAdapter::reportSv(GnssSvNotification& svNotify)
- {
- int numSv = svNotify.count;
- uint16_t gnssSvId = 0;
- uint64_t svUsedIdMask = 0;
- for (int i=0; i < numSv; i++) {
- svUsedIdMask = 0;
- gnssSvId = svNotify.gnssSvs[i].svId;
- GnssSignalTypeMask signalTypeMask = svNotify.gnssSvs[i].gnssSignalTypeMask;
- switch (svNotify.gnssSvs[i].type) {
- case GNSS_SV_TYPE_GPS:
- if (mGnssSvIdUsedInPosAvail) {
- if (mGnssMbSvIdUsedInPosAvail) {
- switch (signalTypeMask) {
- case GNSS_SIGNAL_GPS_L1CA:
- svUsedIdMask = mGnssMbSvIdUsedInPosition.gps_l1ca_sv_used_ids_mask;
- break;
- case GNSS_SIGNAL_GPS_L1C:
- svUsedIdMask = mGnssMbSvIdUsedInPosition.gps_l1c_sv_used_ids_mask;
- break;
- case GNSS_SIGNAL_GPS_L2:
- svUsedIdMask = mGnssMbSvIdUsedInPosition.gps_l2_sv_used_ids_mask;
- break;
- case GNSS_SIGNAL_GPS_L5:
- svUsedIdMask = mGnssMbSvIdUsedInPosition.gps_l5_sv_used_ids_mask;
- break;
- }
- } else {
- svUsedIdMask = mGnssSvIdUsedInPosition.gps_sv_used_ids_mask;
- }
- }
- break;
- case GNSS_SV_TYPE_GLONASS:
- if (mGnssSvIdUsedInPosAvail) {
- if (mGnssMbSvIdUsedInPosAvail) {
- switch (signalTypeMask) {
- case GNSS_SIGNAL_GLONASS_G1:
- svUsedIdMask = mGnssMbSvIdUsedInPosition.glo_g1_sv_used_ids_mask;
- break;
- case GNSS_SIGNAL_GLONASS_G2:
- svUsedIdMask = mGnssMbSvIdUsedInPosition.glo_g2_sv_used_ids_mask;
- break;
- }
- } else {
- svUsedIdMask = mGnssSvIdUsedInPosition.glo_sv_used_ids_mask;
- }
- }
- // map the svid to respective constellation range 1..xx
- // then repective constellation svUsedIdMask map correctly to svid
- gnssSvId = gnssSvId - GLO_SV_PRN_MIN + 1;
- break;
- case GNSS_SV_TYPE_BEIDOU:
- if (mGnssSvIdUsedInPosAvail) {
- if (mGnssMbSvIdUsedInPosAvail) {
- switch (signalTypeMask) {
- case GNSS_SIGNAL_BEIDOU_B1I:
- svUsedIdMask = mGnssMbSvIdUsedInPosition.bds_b1i_sv_used_ids_mask;
- break;
- case GNSS_SIGNAL_BEIDOU_B1C:
- svUsedIdMask = mGnssMbSvIdUsedInPosition.bds_b1c_sv_used_ids_mask;
- break;
- case GNSS_SIGNAL_BEIDOU_B2I:
- svUsedIdMask = mGnssMbSvIdUsedInPosition.bds_b2i_sv_used_ids_mask;
- break;
- case GNSS_SIGNAL_BEIDOU_B2AI:
- svUsedIdMask = mGnssMbSvIdUsedInPosition.bds_b2ai_sv_used_ids_mask;
- break;
- case GNSS_SIGNAL_BEIDOU_B2AQ:
- svUsedIdMask = mGnssMbSvIdUsedInPosition.bds_b2aq_sv_used_ids_mask;
- break;
- }
- } else {
- svUsedIdMask = mGnssSvIdUsedInPosition.bds_sv_used_ids_mask;
- }
- }
- gnssSvId = gnssSvId - BDS_SV_PRN_MIN + 1;
- break;
- case GNSS_SV_TYPE_GALILEO:
- if (mGnssSvIdUsedInPosAvail) {
- if (mGnssMbSvIdUsedInPosAvail) {
- switch (signalTypeMask) {
- case GNSS_SIGNAL_GALILEO_E1:
- svUsedIdMask = mGnssMbSvIdUsedInPosition.gal_e1_sv_used_ids_mask;
- break;
- case GNSS_SIGNAL_GALILEO_E5A:
- svUsedIdMask = mGnssMbSvIdUsedInPosition.gal_e5a_sv_used_ids_mask;
- break;
- case GNSS_SIGNAL_GALILEO_E5B:
- svUsedIdMask = mGnssMbSvIdUsedInPosition.gal_e5b_sv_used_ids_mask;
- break;
- }
- } else {
- svUsedIdMask = mGnssSvIdUsedInPosition.gal_sv_used_ids_mask;
- }
- }
- gnssSvId = gnssSvId - GAL_SV_PRN_MIN + 1;
- break;
- case GNSS_SV_TYPE_QZSS:
- if (mGnssSvIdUsedInPosAvail) {
- if (mGnssMbSvIdUsedInPosAvail) {
- switch (signalTypeMask) {
- case GNSS_SIGNAL_QZSS_L1CA:
- svUsedIdMask = mGnssMbSvIdUsedInPosition.qzss_l1ca_sv_used_ids_mask;
- break;
- case GNSS_SIGNAL_QZSS_L1S:
- svUsedIdMask = mGnssMbSvIdUsedInPosition.qzss_l1s_sv_used_ids_mask;
- break;
- case GNSS_SIGNAL_QZSS_L2:
- svUsedIdMask = mGnssMbSvIdUsedInPosition.qzss_l2_sv_used_ids_mask;
- break;
- case GNSS_SIGNAL_QZSS_L5:
- svUsedIdMask = mGnssMbSvIdUsedInPosition.qzss_l5_sv_used_ids_mask;
- break;
- }
- } else {
- svUsedIdMask = mGnssSvIdUsedInPosition.qzss_sv_used_ids_mask;
- }
- }
- gnssSvId = gnssSvId - QZSS_SV_PRN_MIN + 1;
- break;
- case GNSS_SV_TYPE_NAVIC:
- if (mGnssSvIdUsedInPosAvail) {
- svUsedIdMask = mGnssSvIdUsedInPosition.navic_sv_used_ids_mask;
- }
- gnssSvId = gnssSvId - NAVIC_SV_PRN_MIN + 1;
- break;
- default:
- svUsedIdMask = 0;
- break;
- }
- // If SV ID was used in previous position fix, then set USED_IN_FIX
- // flag, else clear the USED_IN_FIX flag.
- if (svFitsMask(svUsedIdMask, gnssSvId) && (svUsedIdMask & (1ULL << (gnssSvId - 1)))) {
- svNotify.gnssSvs[i].gnssSvOptionsMask |= GNSS_SV_OPTIONS_USED_IN_FIX_BIT;
- }
- }
- for (auto it=mClientData.begin(); it != mClientData.end(); ++it) {
- if (nullptr != it->second.gnssSvCb) {
- it->second.gnssSvCb(svNotify);
- }
- }
- if (NMEA_PROVIDER_AP == ContextBase::mGps_conf.NMEA_PROVIDER &&
- !mTimeBasedTrackingSessions.empty()) {
- std::vector<std::string> nmeaArraystr;
- loc_nmea_generate_sv(svNotify, nmeaArraystr);
- stringstream ss;
- for (auto itor = nmeaArraystr.begin(); itor != nmeaArraystr.end(); ++itor) {
- ss << *itor;
- }
- string s = ss.str();
- reportNmea(s.c_str(), s.length());
- }
- mGnssSvIdUsedInPosAvail = false;
- mGnssMbSvIdUsedInPosAvail = false;
- // report to engine hub to deliver to registered plugin
- mEngHubProxy->gnssReportSv(svNotify);
- }
- void
- GnssAdapter::reportNmeaEvent(const char* nmea, size_t length)
- {
- if (NMEA_PROVIDER_AP == ContextBase::mGps_conf.NMEA_PROVIDER &&
- !loc_nmea_is_debug(nmea, length)) {
- return;
- }
- struct MsgReportNmea : public LocMsg {
- GnssAdapter& mAdapter;
- const char* mNmea;
- size_t mLength;
- inline MsgReportNmea(GnssAdapter& adapter,
- const char* nmea,
- size_t length) :
- LocMsg(),
- mAdapter(adapter),
- mNmea(new char[length+1]),
- mLength(length) {
- if (mNmea == nullptr) {
- LOC_LOGE("%s] new allocation failed, fatal error.", __func__);
- return;
- }
- strlcpy((char*)mNmea, nmea, length+1);
- }
- inline virtual ~MsgReportNmea()
- {
- delete[] mNmea;
- }
- inline virtual void proc() const {
- // extract bug report info - this returns true if consumed by systemstatus
- bool ret = false;
- SystemStatus* s = mAdapter.getSystemStatus();
- if (nullptr != s) {
- ret = s->setNmeaString(mNmea, mLength);
- }
- if (false == ret) {
- // forward NMEA message to upper layer
- mAdapter.reportNmea(mNmea, mLength);
- // DgnssNtrip
- mAdapter.reportGGAToNtrip(mNmea);
- }
- }
- };
- sendMsg(new MsgReportNmea(*this, nmea, length));
- }
- void
- GnssAdapter::reportNmea(const char* nmea, size_t length)
- {
- GnssNmeaNotification nmeaNotification = {};
- nmeaNotification.size = sizeof(GnssNmeaNotification);
- struct timeval tv;
- gettimeofday(&tv, (struct timezone *) NULL);
- int64_t now = tv.tv_sec * 1000LL + tv.tv_usec / 1000;
- nmeaNotification.timestamp = now;
- nmeaNotification.nmea = nmea;
- nmeaNotification.length = length;
- for (auto it=mClientData.begin(); it != mClientData.end(); ++it) {
- if (nullptr != it->second.gnssNmeaCb) {
- it->second.gnssNmeaCb(nmeaNotification);
- }
- }
- if (isNMEAPrintEnabled()) {
- LOC_LOGd("[%" PRId64 ", %zu] %s", now, length, nmea);
- }
- }
- void
- GnssAdapter::reportDataEvent(const GnssDataNotification& dataNotify,
- int msInWeek)
- {
- struct MsgReportData : public LocMsg {
- GnssAdapter& mAdapter;
- GnssDataNotification mDataNotify;
- int mMsInWeek;
- inline MsgReportData(GnssAdapter& adapter,
- const GnssDataNotification& dataNotify,
- int msInWeek) :
- LocMsg(),
- mAdapter(adapter),
- mDataNotify(dataNotify),
- mMsInWeek(msInWeek) {
- }
- inline virtual void proc() const {
- if (mMsInWeek >= 0) {
- mAdapter.getDataInformation((GnssDataNotification&)mDataNotify,
- mMsInWeek);
- }
- mAdapter.reportData((GnssDataNotification&)mDataNotify);
- }
- };
- sendMsg(new MsgReportData(*this, dataNotify, msInWeek));
- }
- void
- GnssAdapter::reportData(GnssDataNotification& dataNotify)
- {
- for (int sig = 0; sig < GNSS_LOC_MAX_NUMBER_OF_SIGNAL_TYPES; sig++) {
- if (GNSS_LOC_DATA_JAMMER_IND_BIT ==
- (dataNotify.gnssDataMask[sig] & GNSS_LOC_DATA_JAMMER_IND_BIT)) {
- LOC_LOGv("jammerInd[%d]=%f", sig, dataNotify.jammerInd[sig]);
- }
- if (GNSS_LOC_DATA_AGC_BIT ==
- (dataNotify.gnssDataMask[sig] & GNSS_LOC_DATA_AGC_BIT)) {
- LOC_LOGv("agc[%d]=%f", sig, dataNotify.agc[sig]);
- }
- }
- for (auto it = mClientData.begin(); it != mClientData.end(); ++it) {
- if (nullptr != it->second.gnssDataCb) {
- it->second.gnssDataCb(dataNotify);
- }
- }
- }
- bool
- GnssAdapter::requestNiNotifyEvent(const GnssNiNotification ¬ify, const void* data,
- const LocInEmergency emergencyState)
- {
- LOC_LOGI("%s]: notif_type: %d, timeout: %d, default_resp: %d"
- "requestor_id: %s (encoding: %d) text: %s text (encoding: %d) extras: %s "
- "emergencyState = %d",
- __func__, notify.type, notify.timeout, notify.timeoutResponse,
- notify.requestor, notify.requestorEncoding,
- notify.message, notify.messageEncoding, notify.extras,
- emergencyState);
- struct MsgReportNiNotify : public LocMsg {
- GnssAdapter& mAdapter;
- LocApiBase& mApi;
- const GnssNiNotification mNotify;
- const void* mData;
- const LocInEmergency mEmergencyState;
- inline MsgReportNiNotify(GnssAdapter& adapter,
- LocApiBase& api,
- const GnssNiNotification& notify,
- const void* data,
- const LocInEmergency emergencyState) :
- LocMsg(),
- mAdapter(adapter),
- mApi(api),
- mNotify(notify),
- mData(data),
- mEmergencyState(emergencyState) {}
- inline virtual void proc() const {
- bool bIsInEmergency = false;
- bool bInformNiAccept = false;
- bIsInEmergency = ((LOC_IN_EMERGENCY_UNKNOWN == mEmergencyState) && // older modems
- (mAdapter.getE911State(mNotify.type))) ||
- (LOC_IN_EMERGENCY_SET == mEmergencyState); // newer modems
- if ((mAdapter.mSupportNfwControl || 0 == mAdapter.getAfwControlId()) &&
- (GNSS_NI_TYPE_SUPL == mNotify.type || GNSS_NI_TYPE_EMERGENCY_SUPL == mNotify.type)
- && !bIsInEmergency &&
- !(GNSS_NI_OPTIONS_PRIVACY_OVERRIDE_BIT & mNotify.options) &&
- (GNSS_CONFIG_GPS_LOCK_NFW_SUPL & ContextBase::mGps_conf.GPS_LOCK) &&
- 1 == ContextBase::mGps_conf.NI_SUPL_DENY_ON_NFW_LOCKED) {
- /* If all these conditions are TRUE, then deny the NI Request:
- -'Q' Lock behavior OR 'P' Lock behavior and GNSS is Locked
- -NI SUPL Request type or NI SUPL Emergency Request type
- -NOT in an Emergency Call Session
- -NOT Privacy Override option
- -NFW is locked and config item NI_SUPL_DENY_ON_NFW_LOCKED = 1 */
- mApi.informNiResponse(GNSS_NI_RESPONSE_DENY, mData);
- } else if ((GNSS_NI_TYPE_SUPL == mNotify.type ||
- GNSS_NI_TYPE_EMERGENCY_SUPL == mNotify.type)
- && (GNSS_NI_OPTIONS_PRIVACY_OVERRIDE_BIT & mNotify.options)) {
- mApi.informNiResponse(GNSS_NI_RESPONSE_ACCEPT, mData);
- } else if (GNSS_NI_TYPE_EMERGENCY_SUPL == mNotify.type) {
- bInformNiAccept = bIsInEmergency ||
- (GNSS_CONFIG_SUPL_EMERGENCY_SERVICES_NO == ContextBase::mGps_conf.SUPL_ES);
- if (bInformNiAccept) {
- mAdapter.requestNiNotify(mNotify, mData, bInformNiAccept);
- } else {
- mApi.informNiResponse(GNSS_NI_RESPONSE_DENY, mData);
- }
- } else if (GNSS_NI_TYPE_CONTROL_PLANE == mNotify.type) {
- if (bIsInEmergency && (1 == ContextBase::mGps_conf.CP_MTLR_ES)) {
- mApi.informNiResponse(GNSS_NI_RESPONSE_ACCEPT, mData);
- } else {
- mAdapter.requestNiNotify(mNotify, mData, false);
- }
- } else {
- mAdapter.requestNiNotify(mNotify, mData, false);
- }
- }
- };
- sendMsg(new MsgReportNiNotify(*this, *mLocApi, notify, data, emergencyState));
- return true;
- }
- void
- GnssAdapter::reportLocationSystemInfoEvent(const LocationSystemInfo & locationSystemInfo) {
- // send system info to engine hub
- mEngHubProxy->gnssReportSystemInfo(locationSystemInfo);
- struct MsgLocationSystemInfo : public LocMsg {
- GnssAdapter& mAdapter;
- LocationSystemInfo mSystemInfo;
- inline MsgLocationSystemInfo(GnssAdapter& adapter,
- const LocationSystemInfo& systemInfo) :
- LocMsg(),
- mAdapter(adapter),
- mSystemInfo(systemInfo) {}
- inline virtual void proc() const {
- mAdapter.reportLocationSystemInfo(mSystemInfo);
- }
- };
- sendMsg(new MsgLocationSystemInfo(*this, locationSystemInfo));
- }
- void
- GnssAdapter::reportLocationSystemInfo(const LocationSystemInfo & locationSystemInfo) {
- // save the info into the master copy piece by piece, as other system info
- // may come at different time
- if (locationSystemInfo.systemInfoMask & LOCATION_SYS_INFO_LEAP_SECOND) {
- mLocSystemInfo.systemInfoMask |= LOCATION_SYS_INFO_LEAP_SECOND;
- const LeapSecondSystemInfo &srcLeapSecondSysInfo = locationSystemInfo.leapSecondSysInfo;
- LeapSecondSystemInfo &dstLeapSecondSysInfo = mLocSystemInfo.leapSecondSysInfo;
- if (srcLeapSecondSysInfo.leapSecondInfoMask &
- LEAP_SECOND_SYS_INFO_CURRENT_LEAP_SECONDS_BIT) {
- dstLeapSecondSysInfo.leapSecondInfoMask |=
- LEAP_SECOND_SYS_INFO_CURRENT_LEAP_SECONDS_BIT;
- dstLeapSecondSysInfo.leapSecondCurrent = srcLeapSecondSysInfo.leapSecondCurrent;
- }
- // once leap second change event is complete, modem may send up event invalidate the leap
- // second change info while AP is still processing report during leap second transition
- // so, we choose to keep this info around even though it is old
- if (srcLeapSecondSysInfo.leapSecondInfoMask & LEAP_SECOND_SYS_INFO_LEAP_SECOND_CHANGE_BIT) {
- dstLeapSecondSysInfo.leapSecondInfoMask |= LEAP_SECOND_SYS_INFO_LEAP_SECOND_CHANGE_BIT;
- dstLeapSecondSysInfo.leapSecondChangeInfo = srcLeapSecondSysInfo.leapSecondChangeInfo;
- }
- }
- // we received new info, inform client of the newly received info
- if (locationSystemInfo.systemInfoMask) {
- for (auto it=mClientData.begin(); it != mClientData.end(); ++it) {
- if (it->second.locationSystemInfoCb != nullptr) {
- it->second.locationSystemInfoCb(locationSystemInfo);
- }
- }
- }
- }
- static void* niThreadProc(void *args)
- {
- NiSession* pSession = (NiSession*)args;
- int rc = 0; /* return code from pthread calls */
- struct timespec present_time = {};
- struct timespec expire_time = {};
- pthread_mutex_lock(&pSession->tLock);
- /* Calculate absolute expire time */
- clock_gettime(CLOCK_REALTIME, &present_time);
- expire_time.tv_sec = present_time.tv_sec + pSession->respTimeLeft;
- expire_time.tv_nsec = present_time.tv_nsec;
- LOC_LOGD("%s]: time out set for abs time %ld with delay %d sec",
- __func__, (long)expire_time.tv_sec, pSession->respTimeLeft);
- while (!pSession->respRecvd) {
- rc = pthread_cond_timedwait(&pSession->tCond,
- &pSession->tLock,
- &expire_time);
- if (rc == ETIMEDOUT) {
- pSession->resp = GNSS_NI_RESPONSE_NO_RESPONSE;
- LOC_LOGD("%s]: time out after valting for specified time. Ret Val %d",
- __func__, rc);
- break;
- }
- }
- LOC_LOGD("%s]: Java layer has sent us a user response and return value from "
- "pthread_cond_timedwait = %d pSession->resp is %u", __func__, rc, pSession->resp);
- pSession->respRecvd = false; /* Reset the user response flag for the next session*/
- // adding this check to support modem restart, in which case, we need the thread
- // to exit without calling sending data. We made sure that rawRequest is NULL in
- // loc_eng_ni_reset_on_engine_restart()
- GnssAdapter* adapter = pSession->adapter;
- GnssNiResponse resp;
- void* rawRequest = NULL;
- bool sendResponse = false;
- if (NULL != pSession->rawRequest) {
- if (pSession->resp != GNSS_NI_RESPONSE_IGNORE) {
- resp = pSession->resp;
- rawRequest = pSession->rawRequest;
- sendResponse = true;
- } else {
- free(pSession->rawRequest);
- }
- pSession->rawRequest = NULL;
- }
- pthread_mutex_unlock(&pSession->tLock);
- pSession->respTimeLeft = 0;
- pSession->reqID = 0;
- if (sendResponse) {
- adapter->gnssNiResponseCommand(resp, rawRequest);
- }
- return NULL;
- }
- bool
- GnssAdapter::requestNiNotify(const GnssNiNotification& notify, const void* data,
- const bool bInformNiAccept)
- {
- NiSession* pSession = NULL;
- gnssNiCallback gnssNiCb = nullptr;
- for (auto it=mClientData.begin(); it != mClientData.end(); ++it) {
- if (nullptr != it->second.gnssNiCb) {
- gnssNiCb = it->second.gnssNiCb;
- break;
- }
- }
- if (nullptr == gnssNiCb) {
- if (GNSS_NI_TYPE_EMERGENCY_SUPL == notify.type) {
- if (bInformNiAccept) {
- mLocApi->informNiResponse(GNSS_NI_RESPONSE_ACCEPT, data);
- NiData& niData = getNiData();
- // ignore any SUPL NI non-Es session if a SUPL NI ES is accepted
- if (NULL != niData.session.rawRequest) {
- pthread_mutex_lock(&niData.session.tLock);
- niData.session.resp = GNSS_NI_RESPONSE_IGNORE;
- niData.session.respRecvd = true;
- pthread_cond_signal(&niData.session.tCond);
- pthread_mutex_unlock(&niData.session.tLock);
- }
- }
- }
- EXIT_LOG(%s, "no clients with gnssNiCb.");
- return false;
- }
- if (notify.type == GNSS_NI_TYPE_EMERGENCY_SUPL) {
- if (NULL != mNiData.sessionEs.rawRequest) {
- LOC_LOGI("%s]: supl es NI in progress, new supl es NI ignored, type: %d",
- __func__, notify.type);
- if (NULL != data) {
- free((void*)data);
- }
- } else {
- pSession = &mNiData.sessionEs;
- }
- } else {
- if (NULL != mNiData.session.rawRequest ||
- NULL != mNiData.sessionEs.rawRequest) {
- LOC_LOGI("%s]: supl NI in progress, new supl NI ignored, type: %d",
- __func__, notify.type);
- if (NULL != data) {
- free((void*)data);
- }
- } else {
- pSession = &mNiData.session;
- }
- }
- if (pSession) {
- /* Save request */
- pSession->rawRequest = (void*)data;
- pSession->reqID = ++mNiData.reqIDCounter;
- pSession->adapter = this;
- int sessionId = pSession->reqID;
- /* For robustness, spawn a thread at this point to timeout to clear up the notification
- * status, even though the OEM layer in java does not do so.
- **/
- pSession->respTimeLeft =
- 5 + (notify.timeout != 0 ? notify.timeout : LOC_NI_NO_RESPONSE_TIME);
- int rc = 0;
- rc = pthread_create(&pSession->thread, NULL, niThreadProc, pSession);
- if (rc) {
- LOC_LOGE("%s]: Loc NI thread is not created.", __func__);
- }
- pthread_setname_np(pSession->thread, "NiThread");
- rc = pthread_detach(pSession->thread);
- if (rc) {
- LOC_LOGE("%s]: Loc NI thread is not detached.", __func__);
- }
- if (nullptr != gnssNiCb) {
- gnssNiCb(sessionId, notify);
- }
- }
- return true;
- }
- void
- GnssAdapter::reportGnssMeasurementsEvent(const GnssMeasurements& gnssMeasurements,
- int msInWeek)
- {
- LOC_LOGD("%s]: msInWeek=%d", __func__, msInWeek);
- if (0 != gnssMeasurements.gnssMeasNotification.count) {
- struct MsgReportGnssMeasurementData : public LocMsg {
- GnssAdapter& mAdapter;
- GnssMeasurements mGnssMeasurements;
- inline MsgReportGnssMeasurementData(GnssAdapter& adapter,
- const GnssMeasurements& gnssMeasurements,
- int msInWeek) :
- LocMsg(),
- mAdapter(adapter),
- mGnssMeasurements(gnssMeasurements) {
- if (-1 != msInWeek) {
- mAdapter.getAgcInformation(mGnssMeasurements.gnssMeasNotification, msInWeek);
- }
- }
- inline virtual void proc() const {
- mAdapter.mPositionElapsedRealTimeCal.saveGpsTimeAndQtimerPairInMeasReport(
- mGnssMeasurements.gnssSvMeasurementSet);
- mAdapter.reportGnssMeasurementData(mGnssMeasurements.gnssMeasNotification);
- }
- };
- sendMsg(new MsgReportGnssMeasurementData(*this, gnssMeasurements, msInWeek));
- }
- mEngHubProxy->gnssReportSvMeasurement(gnssMeasurements.gnssSvMeasurementSet);
- if (mDGnssNeedReport) {
- reportDGnssDataUsable(gnssMeasurements.gnssSvMeasurementSet);
- }
- }
- void
- GnssAdapter::reportGnssMeasurementData(const GnssMeasurementsNotification& measurements)
- {
- for (auto it=mClientData.begin(); it != mClientData.end(); ++it) {
- if (!measurements.isNhz) {
- if (nullptr != it->second.gnssMeasurementsCb) {
- it->second.gnssMeasurementsCb(measurements);
- }
- } else { // nHz measurement
- if (nullptr != it->second.gnssNHzMeasurementsCb) {
- it->second.gnssNHzMeasurementsCb(measurements);
- }
- }
- }
- }
- void
- GnssAdapter::reportDGnssDataUsable(const GnssSvMeasurementSet &svMeasurementSet)
- {
- uint32_t i;
- bool preDGnssDataUsage = mDGnssDataUsage;
- mDGnssDataUsage = false;
- for (i = 0; i < svMeasurementSet.svMeasCount; i++) {
- const Gnss_SVMeasurementStructType& svMeas = svMeasurementSet.svMeas[i];
- if (svMeas.dgnssSvMeas.dgnssMeasStatus) {
- mDGnssDataUsage = true;
- break;
- }
- }
- if (mDGnssDataUsage != preDGnssDataUsage) {
- if (mCdfwInterface) {
- mCdfwInterface->reportUsable(mQDgnssListenerHDL, mDGnssDataUsage);
- }
- }
- }
- void
- GnssAdapter::reportSvPolynomialEvent(GnssSvPolynomial &svPolynomial)
- {
- LOC_LOGD("%s]: ", __func__);
- mEngHubProxy->gnssReportSvPolynomial(svPolynomial);
- }
- void
- GnssAdapter::reportSvEphemerisEvent(GnssSvEphemerisReport & svEphemeris)
- {
- LOC_LOGD("%s]:", __func__);
- mEngHubProxy->gnssReportSvEphemeris(svEphemeris);
- }
- bool
- GnssAdapter::requestOdcpiEvent(OdcpiRequestInfo& request)
- {
- struct MsgRequestOdcpi : public LocMsg {
- GnssAdapter& mAdapter;
- OdcpiRequestInfo mOdcpiRequest;
- inline MsgRequestOdcpi(GnssAdapter& adapter, OdcpiRequestInfo& request) :
- LocMsg(),
- mAdapter(adapter),
- mOdcpiRequest(request) {}
- inline virtual void proc() const {
- mAdapter.requestOdcpi(mOdcpiRequest);
- }
- };
- sendMsg(new MsgRequestOdcpi(*this, request));
- return true;
- }
- void GnssAdapter::requestOdcpi(const OdcpiRequestInfo& request)
- {
- if (nullptr != mOdcpiRequestCb) {
- bool sendEmergencyCallStatusEvent = false;
- LOC_LOGd("request: type %d, tbf %d, isEmergency %d"
- " requestActive: %d timerActive: %d",
- request.type, request.tbfMillis, request.isEmergencyMode,
- mOdcpiStateMask, mOdcpiTimer.isActive());
- // ODCPI START and ODCPI STOP from modem can come in quick succession
- // so the mOdcpiTimer helps avoid spamming the framework as well as
- // extending the odcpi session past 30 seconds if needed
- if (ODCPI_REQUEST_TYPE_START == request.type) {
- if (!(mOdcpiStateMask & ODCPI_REQ_ACTIVE) && false == mOdcpiTimer.isActive()) {
- mOdcpiRequestCb(request);
- mOdcpiStateMask |= ODCPI_REQ_ACTIVE;
- mOdcpiTimer.start();
- sendEmergencyCallStatusEvent = true;
- // if the current active odcpi session is non-emergency, and the new
- // odcpi request is emergency, replace the odcpi request with new request
- // and restart the timer
- } else if (false == mOdcpiRequest.isEmergencyMode &&
- true == request.isEmergencyMode) {
- mOdcpiRequestCb(request);
- mOdcpiStateMask |= ODCPI_REQ_ACTIVE;
- if (true == mOdcpiTimer.isActive()) {
- mOdcpiTimer.restart();
- } else {
- mOdcpiTimer.start();
- }
- sendEmergencyCallStatusEvent = true;
- // if ODCPI request is not active but the timer is active, then
- // just update the active state and wait for timer to expire
- // before requesting new ODCPI to avoid spamming ODCPI requests
- } else if (!(mOdcpiStateMask & ODCPI_REQ_ACTIVE) && true == mOdcpiTimer.isActive()) {
- mOdcpiStateMask |= ODCPI_REQ_ACTIVE;
- }
- mOdcpiRequest = request;
- //Check if Modem needs civic address
- if (mAddressRequestCb != nullptr && request.isCivicAddressRequired) {
- mOdcpiStateMask |= CIVIC_ADDRESS_REQ_ACTIVE;
- }
- // the request is being stopped, but allow timer to expire first
- // before stopping the timer just in case more ODCPI requests come
- // to avoid spamming more odcpi requests to the framework
- } else if (ODCPI_REQUEST_TYPE_STOP == request.type) {
- LOC_LOGd("request: type %d, isEmergency %d", request.type, request.isEmergencyMode);
- mOdcpiRequestCb(request);
- mOdcpiStateMask = 0;
- sendEmergencyCallStatusEvent = true;
- } else {
- LOC_LOGE("Invalid ODCPI request type..");
- }
- // Raise InEmergencyCall event
- if (sendEmergencyCallStatusEvent && request.isEmergencyMode) {
- SystemStatus* systemstatus = getSystemStatus();
- if (nullptr != systemstatus) {
- systemstatus->eventInEmergencyCall(0 != mOdcpiStateMask);
- } else {
- LOC_LOGe("Failed to get system status instance.");
- }
- }
- } else {
- LOC_LOGw("ODCPI request not supported");
- }
- }
- bool GnssAdapter::reportDeleteAidingDataEvent(GnssAidingData& aidingData)
- {
- LOC_LOGD("%s]:", __func__);
- mEngHubProxy->gnssDeleteAidingData(aidingData);
- return true;
- }
- bool GnssAdapter::reportKlobucharIonoModelEvent(GnssKlobucharIonoModel & ionoModel)
- {
- LOC_LOGD("%s]:", __func__);
- mEngHubProxy->gnssReportKlobucharIonoModel(ionoModel);
- return true;
- }
- bool GnssAdapter::reportGnssAdditionalSystemInfoEvent(
- GnssAdditionalSystemInfo & additionalSystemInfo)
- {
- LOC_LOGD("%s]:", __func__);
- mEngHubProxy->gnssReportAdditionalSystemInfo(additionalSystemInfo);
- return true;
- }
- bool GnssAdapter::reportQwesCapabilities(
- const std::unordered_map<LocationQwesFeatureType, bool> &featureMap)
- {
- struct MsgReportQwesFeatureStatus : public LocMsg {
- GnssAdapter& mAdapter;
- const std::unordered_map<LocationQwesFeatureType, bool> mFeatureMap;
- inline MsgReportQwesFeatureStatus(GnssAdapter& adapter,
- const std::unordered_map<LocationQwesFeatureType, bool> &featureMap) :
- LocMsg(),
- mAdapter(adapter),
- mFeatureMap(std::move(featureMap)) {}
- inline virtual void proc() const {
- LOC_LOGi("ReportQwesFeatureStatus before caps %" PRIx64 " ",
- mAdapter.getCapabilities());
- ContextBase::setQwesFeatureStatus(mFeatureMap);
- LOC_LOGi("ReportQwesFeatureStatus After caps %" PRIx64 " ",
- mAdapter.getCapabilities());
- mAdapter.broadcastCapabilities(mAdapter.getCapabilities());
- }
- };
- sendMsg(new MsgReportQwesFeatureStatus(*this, featureMap));
- return true;
- }
- void GnssAdapter::initOdcpiCommand(const OdcpiRequestCallback& callback,
- OdcpiPrioritytype priority)
- {
- struct MsgInitOdcpi : public LocMsg {
- GnssAdapter& mAdapter;
- OdcpiRequestCallback mOdcpiCb;
- OdcpiPrioritytype mPriority;
- inline MsgInitOdcpi(GnssAdapter& adapter,
- const OdcpiRequestCallback& callback,
- OdcpiPrioritytype priority) :
- LocMsg(),
- mAdapter(adapter),
- mOdcpiCb(callback), mPriority(priority){}
- inline virtual void proc() const {
- mAdapter.initOdcpi(mOdcpiCb, mPriority);
- }
- };
- sendMsg(new MsgInitOdcpi(*this, callback, priority));
- }
- void GnssAdapter::initOdcpi(const OdcpiRequestCallback& callback,
- OdcpiPrioritytype priority)
- {
- LOC_LOGd("In priority: %d, Curr priority: %d", priority, mCallbackPriority);
- if (priority >= mCallbackPriority) {
- mOdcpiRequestCb = callback;
- mCallbackPriority = priority;
- /* Register for WIFI request */
- updateEvtMask(LOC_API_ADAPTER_BIT_REQUEST_WIFI,
- LOC_REGISTRATION_MASK_ENABLED);
- }
- }
- void GnssAdapter::injectOdcpiCommand(const Location& location)
- {
- struct MsgInjectOdcpi : public LocMsg {
- GnssAdapter& mAdapter;
- Location mLocation;
- inline MsgInjectOdcpi(GnssAdapter& adapter, const Location& location, ContextBase& context):
- LocMsg(),
- mAdapter(adapter),
- mLocation(location) {
- // Update techMask to tell whether ALE FLP or Android FLP
- if (context.getLBSProxyBase()->getIzatFusedProviderOverride()) {
- mLocation.techMask |= LOCATION_TECHNOLOGY_HYBRID_ALE_BIT;
- }
- }
- inline virtual void proc() const {
- mAdapter.injectOdcpi(mLocation);
- }
- };
- sendMsg(new MsgInjectOdcpi(*this, location, *mContext));
- }
- void GnssAdapter::injectOdcpi(const Location& location)
- {
- LOC_LOGd("ODCPI Injection: requestActive: %d timerActive: %d"
- "lat %.7f long %.7f",
- mOdcpiStateMask, mOdcpiTimer.isActive(),
- location.latitude, location.longitude);
- if ((mOdcpiStateMask & CIVIC_ADDRESS_REQ_ACTIVE) && mAddressRequestCb != nullptr) {
- mAddressRequestCb(location);
- }
- mLocApi->injectPosition(location, true);
- }
- void GnssAdapter::setAddressRequestCbCommand(
- const std::function<void(const Location&)>& addressRequestCb)
- {
- struct MsgSetAddrReqCb : public LocMsg {
- GnssAdapter& mAdapter;
- std::function<void(const Location&)> mAddrReqCb;
- inline MsgSetAddrReqCb(GnssAdapter& adapter,
- const std::function<void(const Location&)>& addressRequestCb) :
- LocMsg(),
- mAdapter(adapter),
- mAddrReqCb(addressRequestCb){}
- inline virtual void proc() const {
- mAdapter.setAddressRequestCb(mAddrReqCb);
- }
- };
- sendMsg(new MsgSetAddrReqCb(*this, addressRequestCb));
- }
- void GnssAdapter::injectLocationAndAddrCommand(
- const Location& location, const GnssCivicAddress& addr)
- {
- struct MsgInjectLocAndAddr : public LocMsg {
- GnssAdapter& mAdapter;
- Location mLocation;
- GnssCivicAddress mAddress;
- inline MsgInjectLocAndAddr(GnssAdapter& adapter,
- const Location& location, const GnssCivicAddress& addr) :
- LocMsg(), mAdapter(adapter), mLocation(location), mAddress(addr) {}
- inline virtual void proc() const {
- LOC_LOGd("[%s] Location: %x, %" PRIu64 ", %f, %f, %f \n"
- "Address: adminArea: %s, countryCode: %s, countryName: %s,\n"
- "featureName: %s, latitude: %f, longitude: %f\n"
- "locale: %s, locality: %s, phone: %s, postalCode: %s\n"
- "premises: %s, subAdminArea: %s, subLocality: %s"
- "thoroughfare: %s, subThoroughfare: %s, url: %s", __func__,
- mLocation.flags, mLocation.timestamp,
- mLocation.latitude, mLocation.longitude,
- mLocation.accuracy, mAddress.adminArea.c_str(),
- mAddress.countryCode.c_str(), mAddress.countryName.c_str(),
- mAddress.featureName.c_str(), mAddress.latitude, mAddress.longitude,
- mAddress.locale.c_str(), mAddress.locality.c_str(),
- mAddress.phone.c_str(), mAddress.postalCode.c_str(),
- mAddress.premises.c_str(), mAddress.subAdminArea.c_str(),
- mAddress.subLocality.c_str(), mAddress.thoroughfare.c_str(),
- mAddress.subThoroughfare.c_str(), mAddress.url.c_str());
- mAdapter.injectLocationAndAddr(mLocation, mAddress);
- }
- };
- sendMsg(new MsgInjectLocAndAddr(*this, location, addr));
- }
- // Called in the context of LocTimer thread
- void OdcpiTimer::timeOutCallback()
- {
- if (nullptr != mAdapter) {
- mAdapter->odcpiTimerExpireEvent();
- }
- }
- // Called in the context of LocTimer thread
- void GnssAdapter::odcpiTimerExpireEvent()
- {
- struct MsgOdcpiTimerExpire : public LocMsg {
- GnssAdapter& mAdapter;
- inline MsgOdcpiTimerExpire(GnssAdapter& adapter) :
- LocMsg(),
- mAdapter(adapter) {}
- inline virtual void proc() const {
- mAdapter.odcpiTimerExpire();
- }
- };
- sendMsg(new MsgOdcpiTimerExpire(*this));
- }
- void GnssAdapter::odcpiTimerExpire()
- {
- LOC_LOGd("requestActive: %d timerActive: %d",
- mOdcpiStateMask, mOdcpiTimer.isActive());
- // if ODCPI request is still active after timer
- // expires, request again and restart timer
- if (mOdcpiStateMask & ODCPI_REQ_ACTIVE) {
- mOdcpiRequestCb(mOdcpiRequest);
- mOdcpiTimer.restart();
- } else {
- mOdcpiTimer.stop();
- }
- }
- void
- GnssAdapter::invokeGnssEnergyConsumedCallback(uint64_t energyConsumedSinceFirstBoot) {
- if (mGnssEnergyConsumedCb) {
- mGnssEnergyConsumedCb(energyConsumedSinceFirstBoot);
- mGnssEnergyConsumedCb = nullptr;
- }
- if (!mGnssPowerStatisticsInit) {
- /* We need to change the reference in case HAL process restarts (i.e. crashes)
- We maintain mBootReferenceEnergy value in the file system
- At the point mBootReferenceEnergy needs to get initialized we will use
- the following logic:
- if (boot time > 30 sec)
- use the value in the file system for mBootReferenceEnergy
- else
- use the value we get here from the modem for mBootReferenceEnergy */
- struct timespec currentTime = {};
- int64_t sinceBootTimeNanos = 0;
- FILE *fp = NULL;
- mBootReferenceEnergy = energyConsumedSinceFirstBoot;
- if (NULL != (fp = fopen("/data/vendor/location/energy.conf", "a+b"))) {
- rewind(fp);
- if (ElapsedRealtimeEstimator::getCurrentTime(currentTime, sinceBootTimeNanos)) {
- LOC_LOGv("sinceBootTimeNanos: %" PRIu64 " ", sinceBootTimeNanos);
- if ((uint32_t)(sinceBootTimeNanos / 1000000000) > 30) {
- int fr = fread(&mBootReferenceEnergy, sizeof(mBootReferenceEnergy), 1, fp);
- if (1 != fr) {
- mBootReferenceEnergy = energyConsumedSinceFirstBoot;
- LOC_LOGw("fread failed ferror(fp)=%d fr=%d", ferror(fp), fr);
- }
- } else {
- fwrite(&mBootReferenceEnergy, sizeof(mBootReferenceEnergy), 1, fp);
- }
- } else {
- LOC_LOGw("getCurrentTime failed");
- fwrite(&mBootReferenceEnergy, sizeof(mBootReferenceEnergy), 1, fp);
- }
- fclose(fp);
- } else {
- LOC_LOGw("fopen failed");
- }
- LOC_LOGd("mBootReferenceEnergy: %" PRIu64 " energyConsumedSinceFirstBoot: %" PRIu64 " ",
- mBootReferenceEnergy, energyConsumedSinceFirstBoot);
- mGnssPowerStatisticsInit = true;
- mPowerElapsedRealTimeCal.reset();
- } else if (nullptr != mPowerIndicationCb) {
- GnssPowerStatistics gnssPowerStatistics = {};
- gnssPowerStatistics.size = sizeof(GnssPowerStatistics);
- gnssPowerStatistics.totalEnergyMilliJoule =
- (double)(energyConsumedSinceFirstBoot - mBootReferenceEnergy) / 10.0;
- LOC_LOGv("energyConsumedSinceFirstBoot: %" PRId64", "
- " mBootReferenceEnergy: %" PRId64", "
- " gnssPowerStatistics.totalEnergyMilliJoule: %f",
- energyConsumedSinceFirstBoot,
- mBootReferenceEnergy,
- gnssPowerStatistics.totalEnergyMilliJoule);
- gnssPowerStatistics.elapsedRealTime =
- mPowerElapsedRealTimeCal.getElapsedRealtimeEstimateNanos(0, 0, 0);
- gnssPowerStatistics.elapsedRealTimeUnc =
- mPowerElapsedRealTimeCal.getElapsedRealtimeUncNanos();
- mPowerIndicationCb(gnssPowerStatistics);
- }
- }
- bool
- GnssAdapter::reportGnssEngEnergyConsumedEvent(uint64_t energyConsumedSinceFirstBoot){
- LOC_LOGd("energyConsumedSinceFirstBoot: %" PRIu64 " ", energyConsumedSinceFirstBoot);
- struct MsgReportGnssGnssEngEnergyConsumed : public LocMsg {
- GnssAdapter& mAdapter;
- uint64_t mGnssEnergyConsumedSinceFirstBoot;
- inline MsgReportGnssGnssEngEnergyConsumed(GnssAdapter& adapter,
- uint64_t energyConsumed) :
- LocMsg(),
- mAdapter(adapter),
- mGnssEnergyConsumedSinceFirstBoot(energyConsumed) {}
- inline virtual void proc() const {
- mAdapter.invokeGnssEnergyConsumedCallback(mGnssEnergyConsumedSinceFirstBoot);
- }
- };
- if (~0 != energyConsumedSinceFirstBoot) {
- sendMsg(new MsgReportGnssGnssEngEnergyConsumed(*this, energyConsumedSinceFirstBoot));
- } else {
- LOC_LOGe("energyConsumedSinceFirstBoot not valid!");
- }
- return true;
- }
- void GnssAdapter::initDefaultAgps() {
- LOC_LOGD("%s]: ", __func__);
- void *handle = nullptr;
- LocAgpsGetAgpsCbInfo getAgpsCbInfo =
- (LocAgpsGetAgpsCbInfo)dlGetSymFromLib(handle, "libloc_net_iface.so",
- "LocNetIfaceAgps_getAgpsCbInfo");
- // Below step is to make sure we init nativeAgpsHandler
- // for Android platforms only
- AgpsCbInfo cbInfo = {};
- if (nullptr != getAgpsCbInfo) {
- cbInfo = getAgpsCbInfo(agpsOpenResultCb, agpsCloseResultCb, this);
- } else {
- cbInfo = mNativeAgpsHandler.getAgpsCbInfo();
- }
- if (cbInfo.statusV4Cb == nullptr) {
- LOC_LOGE("%s]: statusV4Cb is nullptr!", __func__);
- dlclose(handle);
- return;
- }
- initAgps(cbInfo);
- }
- void GnssAdapter::initDefaultAgpsCommand() {
- LOC_LOGD("%s]: ", __func__);
- struct MsgInitDefaultAgps : public LocMsg {
- GnssAdapter& mAdapter;
- inline MsgInitDefaultAgps(GnssAdapter& adapter) :
- LocMsg(),
- mAdapter(adapter) {
- }
- inline virtual void proc() const {
- mAdapter.initDefaultAgps();
- }
- };
- sendMsg(new MsgInitDefaultAgps(*this));
- }
- /* INIT LOC AGPS MANAGER */
- void GnssAdapter::initAgps(const AgpsCbInfo& cbInfo) {
- LOC_LOGD("%s]:cbInfo.atlType - %d", __func__, cbInfo.atlType);
- if (!((ContextBase::mGps_conf.CAPABILITIES & LOC_GPS_CAPABILITY_MSB) ||
- (ContextBase::mGps_conf.CAPABILITIES & LOC_GPS_CAPABILITY_MSA))) {
- return;
- }
- mAgpsManager.createAgpsStateMachines(cbInfo);
- /* Register for AGPS event mask */
- updateEvtMask(LOC_API_ADAPTER_BIT_LOCATION_SERVER_REQUEST,
- LOC_REGISTRATION_MASK_ENABLED);
- }
- void GnssAdapter::initAgpsCommand(const AgpsCbInfo& cbInfo){
- LOC_LOGI("GnssAdapter::initAgpsCommand");
- /* Message to initialize AGPS module */
- struct AgpsMsgInit: public LocMsg {
- const AgpsCbInfo mCbInfo;
- GnssAdapter& mAdapter;
- inline AgpsMsgInit(const AgpsCbInfo& cbInfo,
- GnssAdapter& adapter) :
- LocMsg(), mCbInfo(cbInfo), mAdapter(adapter) {
- LOC_LOGV("AgpsMsgInit");
- }
- inline virtual void proc() const {
- LOC_LOGV("AgpsMsgInit::proc()");
- mAdapter.initAgps(mCbInfo);
- }
- };
- /* Send message to initialize AGPS Manager */
- sendMsg(new AgpsMsgInit(cbInfo, *this));
- }
- void GnssAdapter::initNfwCommand(const NfwCbInfo& cbInfo) {
- LOC_LOGi("GnssAdapter::initNfwCommand");
- /* Message to initialize NFW */
- struct MsgInitNfw : public LocMsg {
- const NfwCbInfo mCbInfo;
- GnssAdapter& mAdapter;
- inline MsgInitNfw(const NfwCbInfo& cbInfo,
- GnssAdapter& adapter) :
- LocMsg(), mCbInfo(cbInfo), mAdapter(adapter) {
- LOC_LOGv("MsgInitNfw");
- }
- inline virtual void proc() const {
- LOC_LOGv("MsgInitNfw::proc()");
- mAdapter.initNfw(mCbInfo);
- }
- };
- /* Send message to initialize NFW */
- sendMsg(new MsgInitNfw(cbInfo, *this));
- }
- void GnssAdapter::reportNfwNotificationEvent(GnssNfwNotification& notification) {
- LOC_LOGi("GnssAdapter::reportNfwNotificationEvent");
- struct MsgReportNfwNotification : public LocMsg {
- const GnssNfwNotification mNotification;
- GnssAdapter& mAdapter;
- inline MsgReportNfwNotification(const GnssNfwNotification& notification,
- GnssAdapter& adapter) :
- LocMsg(), mNotification(notification), mAdapter(adapter) {
- LOC_LOGv("MsgReportNfwNotification");
- }
- inline virtual void proc() const {
- LOC_LOGv("MsgReportNfwNotification::proc()");
- mAdapter.reportNfwNotification(mNotification);
- }
- };
- sendMsg(new MsgReportNfwNotification(notification, *this));
- }
- /* GnssAdapter::requestATL
- * Method triggered in QMI thread as part of handling below message:
- * eQMI_LOC_SERVER_REQUEST_OPEN_V02
- * Triggers the AGPS state machine to setup AGPS call for below WWAN types:
- * eQMI_LOC_WWAN_TYPE_INTERNET_V02
- * eQMI_LOC_WWAN_TYPE_AGNSS_V02
- * eQMI_LOC_WWAN_TYPE_AGNSS_EMERGENCY_V02 */
- bool GnssAdapter::requestATL(int connHandle, LocAGpsType agpsType,
- LocApnTypeMask apnTypeMask, LocSubId subId){
- LOC_LOGi("GnssAdapter::requestATL handle=%d agpsType=0x%X apnTypeMask=0x%X subId=%d",
- connHandle, agpsType, apnTypeMask, subId);
- sendMsg( new AgpsMsgRequestATL( &mAgpsManager, connHandle, (AGpsExtType)agpsType,
- apnTypeMask, subId));
- return true;
- }
- /* GnssAdapter::releaseATL
- * Method triggered in QMI thread as part of handling below message:
- * eQMI_LOC_SERVER_REQUEST_CLOSE_V02
- * Triggers teardown of an existing AGPS call */
- bool GnssAdapter::releaseATL(int connHandle){
- LOC_LOGI("GnssAdapter::releaseATL");
- /* Release SUPL/INTERNET/SUPL_ES ATL */
- struct AgpsMsgReleaseATL: public LocMsg {
- AgpsManager* mAgpsManager;
- int mConnHandle;
- inline AgpsMsgReleaseATL(AgpsManager* agpsManager, int connHandle) :
- LocMsg(), mAgpsManager(agpsManager), mConnHandle(connHandle) {
- LOC_LOGV("AgpsMsgReleaseATL");
- }
- inline virtual void proc() const {
- LOC_LOGV("AgpsMsgReleaseATL::proc()");
- mAgpsManager->releaseATL(mConnHandle);
- }
- };
- sendMsg( new AgpsMsgReleaseATL(&mAgpsManager, connHandle));
- return true;
- }
- void GnssAdapter::reportPdnTypeFromWds(int pdnType, AGpsExtType agpsType, std::string apnName,
- AGpsBearerType bearerType) {
- LOC_LOGd("pdnType from WDS QMI: %d, agpsType: %d, apnName: %s, bearerType: %d",
- pdnType, agpsType, apnName.c_str(), bearerType);
- struct MsgReportAtlPdn : public LocMsg {
- GnssAdapter& mAdapter;
- int mPdnType;
- AgpsManager* mAgpsManager;
- AGpsExtType mAgpsType;
- string mApnName;
- AGpsBearerType mBearerType;
- inline MsgReportAtlPdn(GnssAdapter& adapter, int pdnType,
- AgpsManager* agpsManager, AGpsExtType agpsType,
- const string& apnName, AGpsBearerType bearerType) :
- LocMsg(), mAgpsManager(agpsManager), mAgpsType(agpsType),
- mApnName(apnName), mBearerType(bearerType),
- mAdapter(adapter), mPdnType(pdnType) {}
- inline virtual void proc() const {
- mAgpsManager->reportAtlOpenSuccess(mAgpsType,
- const_cast<char*>(mApnName.c_str()),
- mApnName.length(), mPdnType<=0? mBearerType:mPdnType);
- }
- };
- AGpsBearerType atlPdnType = (pdnType+1) & 3; // convert WDS QMI pdn type to AgpsBearerType
- sendMsg(new MsgReportAtlPdn(*this, atlPdnType, &mAgpsManager,
- agpsType, apnName, bearerType));
- }
- void GnssAdapter::dataConnOpenCommand(
- AGpsExtType agpsType,
- const char* apnName, int apnLen, AGpsBearerType bearerType){
- LOC_LOGI("GnssAdapter::frameworkDataConnOpen");
- struct AgpsMsgAtlOpenSuccess: public LocMsg {
- GnssAdapter& mAdapter;
- AgpsManager* mAgpsManager;
- AGpsExtType mAgpsType;
- char* mApnName;
- AGpsBearerType mBearerType;
- inline AgpsMsgAtlOpenSuccess(GnssAdapter& adapter, AgpsManager* agpsManager,
- AGpsExtType agpsType, const char* apnName, int apnLen, AGpsBearerType bearerType) :
- LocMsg(), mAgpsManager(agpsManager), mAgpsType(agpsType), mApnName(
- new char[apnLen + 1]), mBearerType(bearerType), mAdapter(adapter) {
- LOC_LOGV("AgpsMsgAtlOpenSuccess");
- if (mApnName == nullptr) {
- LOC_LOGE("%s] new allocation failed, fatal error.", __func__);
- // Reporting the failure here
- mAgpsManager->reportAtlClosed(mAgpsType);
- return;
- }
- memcpy(mApnName, apnName, apnLen);
- mApnName[apnLen] = 0;
- }
- inline ~AgpsMsgAtlOpenSuccess() {
- delete[] mApnName;
- }
- inline virtual void proc() const {
- LOC_LOGv("AgpsMsgAtlOpenSuccess::proc()");
- string apn(mApnName);
- //Use QMI WDS API to query IP Protocol from modem profile
- void* libHandle = nullptr;
- getPdnTypeFromWds* getPdnTypeFunc = (getPdnTypeFromWds*)dlGetSymFromLib(libHandle,
- #ifdef USE_GLIB
- "libloc_api_wds.so", "_Z10getPdnTypeRKNSt7__cxx1112basic_string"\
- "IcSt11char_traitsIcESaIcEEESt8functionIFviEE");
- #else
- "libloc_api_wds.so", "_Z10getPdnTypeRKNSt3__112basic_stringIcNS_11char_traits"\
- "IcEENS_9allocatorIcEEEENS_8functionIFviEEE");
- #endif
- std::function<void(int)> wdsPdnTypeCb = std::bind(&GnssAdapter::reportPdnTypeFromWds,
- &mAdapter, std::placeholders::_1, mAgpsType, apn, mBearerType);
- if (getPdnTypeFunc != nullptr && apn.length() > 0) {
- LOC_LOGv("dlGetSymFromLib success");
- (*getPdnTypeFunc)(apn, wdsPdnTypeCb);
- } else {
- mAgpsManager->reportAtlOpenSuccess(mAgpsType, mApnName, apn.length(), mBearerType);
- }
- }
- };
- // Added inital length checks for apnlen check to avoid security issues
- // In case of failure reporting the same
- if (NULL == apnName || apnLen > MAX_APN_LEN || (strlen(apnName) != apnLen)) {
- LOC_LOGe("%s]: incorrect apnlen length or incorrect apnName", __func__);
- mAgpsManager.reportAtlClosed(agpsType);
- } else {
- sendMsg( new AgpsMsgAtlOpenSuccess(*this,
- &mAgpsManager, agpsType, apnName, apnLen, bearerType));
- }
- }
- void GnssAdapter::dataConnClosedCommand(AGpsExtType agpsType){
- LOC_LOGI("GnssAdapter::frameworkDataConnClosed");
- struct AgpsMsgAtlClosed: public LocMsg {
- AgpsManager* mAgpsManager;
- AGpsExtType mAgpsType;
- inline AgpsMsgAtlClosed(AgpsManager* agpsManager, AGpsExtType agpsType) :
- LocMsg(), mAgpsManager(agpsManager), mAgpsType(agpsType) {
- LOC_LOGV("AgpsMsgAtlClosed");
- }
- inline virtual void proc() const {
- LOC_LOGV("AgpsMsgAtlClosed::proc()");
- mAgpsManager->reportAtlClosed(mAgpsType);
- }
- };
- sendMsg( new AgpsMsgAtlClosed(&mAgpsManager, (AGpsExtType)agpsType));
- }
- void GnssAdapter::dataConnFailedCommand(AGpsExtType agpsType){
- LOC_LOGI("GnssAdapter::frameworkDataConnFailed");
- struct AgpsMsgAtlOpenFailed: public LocMsg {
- AgpsManager* mAgpsManager;
- AGpsExtType mAgpsType;
- inline AgpsMsgAtlOpenFailed(AgpsManager* agpsManager, AGpsExtType agpsType) :
- LocMsg(), mAgpsManager(agpsManager), mAgpsType(agpsType) {
- LOC_LOGV("AgpsMsgAtlOpenFailed");
- }
- inline virtual void proc() const {
- LOC_LOGV("AgpsMsgAtlOpenFailed::proc()");
- mAgpsManager->reportAtlOpenFailed(mAgpsType);
- }
- };
- sendMsg( new AgpsMsgAtlOpenFailed(&mAgpsManager, (AGpsExtType)agpsType));
- }
- void GnssAdapter::convertSatelliteInfo(std::vector<GnssDebugSatelliteInfo>& out,
- const GnssSvType& in_constellation,
- const SystemStatusReports& in)
- {
- uint64_t sv_mask = 0ULL;
- uint32_t svid_min = 0;
- uint32_t svid_num = 0;
- uint32_t svid_idx = 0;
- uint64_t eph_health_good_mask = 0ULL;
- uint64_t eph_health_bad_mask = 0ULL;
- uint64_t server_perdiction_available_mask = 0ULL;
- float server_perdiction_age = 0.0f;
- // set constellationi based parameters
- switch (in_constellation) {
- case GNSS_SV_TYPE_GPS:
- svid_min = GNSS_BUGREPORT_GPS_MIN;
- svid_num = GPS_NUM;
- svid_idx = 0;
- if (!in.mSvHealth.empty()) {
- eph_health_good_mask = in.mSvHealth.back().mGpsGoodMask;
- eph_health_bad_mask = in.mSvHealth.back().mGpsBadMask;
- }
- if (!in.mXtra.empty()) {
- server_perdiction_available_mask = in.mXtra.back().mGpsXtraValid;
- server_perdiction_age = (float)(in.mXtra.back().mGpsXtraAge);
- }
- break;
- case GNSS_SV_TYPE_GLONASS:
- svid_min = GNSS_BUGREPORT_GLO_MIN;
- svid_num = GLO_NUM;
- svid_idx = GPS_NUM;
- if (!in.mSvHealth.empty()) {
- eph_health_good_mask = in.mSvHealth.back().mGloGoodMask;
- eph_health_bad_mask = in.mSvHealth.back().mGloBadMask;
- }
- if (!in.mXtra.empty()) {
- server_perdiction_available_mask = in.mXtra.back().mGloXtraValid;
- server_perdiction_age = (float)(in.mXtra.back().mGloXtraAge);
- }
- break;
- case GNSS_SV_TYPE_QZSS:
- svid_min = GNSS_BUGREPORT_QZSS_MIN;
- svid_num = QZSS_NUM;
- svid_idx = GPS_NUM+GLO_NUM+BDS_NUM+GAL_NUM;
- if (!in.mSvHealth.empty()) {
- eph_health_good_mask = in.mSvHealth.back().mQzssGoodMask;
- eph_health_bad_mask = in.mSvHealth.back().mQzssBadMask;
- }
- if (!in.mXtra.empty()) {
- server_perdiction_available_mask = in.mXtra.back().mQzssXtraValid;
- server_perdiction_age = (float)(in.mXtra.back().mQzssXtraAge);
- }
- break;
- case GNSS_SV_TYPE_BEIDOU:
- svid_min = GNSS_BUGREPORT_BDS_MIN;
- svid_num = BDS_NUM;
- svid_idx = GPS_NUM+GLO_NUM;
- if (!in.mSvHealth.empty()) {
- eph_health_good_mask = in.mSvHealth.back().mBdsGoodMask;
- eph_health_bad_mask = in.mSvHealth.back().mBdsBadMask;
- }
- if (!in.mXtra.empty()) {
- server_perdiction_available_mask = in.mXtra.back().mBdsXtraValid;
- server_perdiction_age = (float)(in.mXtra.back().mBdsXtraAge);
- }
- break;
- case GNSS_SV_TYPE_GALILEO:
- svid_min = GNSS_BUGREPORT_GAL_MIN;
- svid_num = GAL_NUM;
- svid_idx = GPS_NUM+GLO_NUM+BDS_NUM;
- if (!in.mSvHealth.empty()) {
- eph_health_good_mask = in.mSvHealth.back().mGalGoodMask;
- eph_health_bad_mask = in.mSvHealth.back().mGalBadMask;
- }
- if (!in.mXtra.empty()) {
- server_perdiction_available_mask = in.mXtra.back().mGalXtraValid;
- server_perdiction_age = (float)(in.mXtra.back().mGalXtraAge);
- }
- break;
- case GNSS_SV_TYPE_NAVIC:
- svid_min = GNSS_BUGREPORT_NAVIC_MIN;
- svid_num = NAVIC_NUM;
- svid_idx = GPS_NUM+GLO_NUM+QZSS_NUM+BDS_NUM+GAL_NUM;
- if (!in.mSvHealth.empty()) {
- eph_health_good_mask = in.mSvHealth.back().mNavicGoodMask;
- eph_health_bad_mask = in.mSvHealth.back().mNavicBadMask;
- }
- if (!in.mXtra.empty()) {
- server_perdiction_available_mask = in.mXtra.back().mNavicXtraValid;
- server_perdiction_age = (float)(in.mXtra.back().mNavicXtraAge);
- }
- break;
- default:
- return;
- }
- // extract each sv info from systemstatus report
- for(uint32_t i=0; i<svid_num && (svid_idx+i)<SV_ALL_NUM; i++) {
- GnssDebugSatelliteInfo s = {};
- s.size = sizeof(s);
- s.svid = i + svid_min;
- s.constellation = in_constellation;
- if (!in.mNavData.empty()) {
- s.mEphemerisType = in.mNavData.back().mNav[svid_idx+i].mType;
- s.mEphemerisSource = in.mNavData.back().mNav[svid_idx+i].mSource;
- }
- else {
- s.mEphemerisType = GNSS_EPH_TYPE_UNKNOWN;
- s.mEphemerisSource = GNSS_EPH_SOURCE_UNKNOWN;
- }
- sv_mask = 0x1ULL << i;
- if (eph_health_good_mask & sv_mask) {
- s.mEphemerisHealth = GNSS_EPH_HEALTH_GOOD;
- }
- else if (eph_health_bad_mask & sv_mask) {
- s.mEphemerisHealth = GNSS_EPH_HEALTH_BAD;
- }
- else {
- s.mEphemerisHealth = GNSS_EPH_HEALTH_UNKNOWN;
- }
- if (!in.mNavData.empty()) {
- s.ephemerisAgeSeconds =
- (float)(in.mNavData.back().mNav[svid_idx+i].mAgeSec);
- }
- else {
- s.ephemerisAgeSeconds = 0.0f;
- }
- if (server_perdiction_available_mask & sv_mask) {
- s.serverPredictionIsAvailable = true;
- }
- else {
- s.serverPredictionIsAvailable = false;
- }
- s.serverPredictionAgeSeconds = server_perdiction_age;
- out.push_back(s);
- }
- return;
- }
- bool GnssAdapter::getDebugReport(GnssDebugReport& r)
- {
- LOC_LOGD("%s]: ", __func__);
- SystemStatus* systemstatus = getSystemStatus();
- if (nullptr == systemstatus) {
- return false;
- }
- SystemStatusReports reports;
- systemstatus->getReport(reports, true);
- r.size = sizeof(r);
- // location block
- r.mLocation.size = sizeof(r.mLocation);
- if(!reports.mLocation.empty() && reports.mLocation.back().mValid) {
- r.mLocation.mValid = true;
- r.mLocation.mLocation.latitude =
- reports.mLocation.back().mLocation.gpsLocation.latitude;
- r.mLocation.mLocation.longitude =
- reports.mLocation.back().mLocation.gpsLocation.longitude;
- r.mLocation.mLocation.altitude =
- reports.mLocation.back().mLocation.gpsLocation.altitude;
- r.mLocation.mLocation.speed =
- (double)(reports.mLocation.back().mLocation.gpsLocation.speed);
- r.mLocation.mLocation.bearing =
- (double)(reports.mLocation.back().mLocation.gpsLocation.bearing);
- r.mLocation.mLocation.accuracy =
- (double)(reports.mLocation.back().mLocation.gpsLocation.accuracy);
- r.mLocation.verticalAccuracyMeters =
- reports.mLocation.back().mLocationEx.vert_unc;
- r.mLocation.speedAccuracyMetersPerSecond =
- reports.mLocation.back().mLocationEx.speed_unc;
- r.mLocation.bearingAccuracyDegrees =
- reports.mLocation.back().mLocationEx.bearing_unc;
- r.mLocation.mUtcReported =
- reports.mLocation.back().mUtcReported;
- }
- else if(!reports.mBestPosition.empty() && reports.mBestPosition.back().mValid) {
- r.mLocation.mValid = true;
- r.mLocation.mLocation.latitude =
- (double)(reports.mBestPosition.back().mBestLat) * RAD2DEG;
- r.mLocation.mLocation.longitude =
- (double)(reports.mBestPosition.back().mBestLon) * RAD2DEG;
- r.mLocation.mLocation.altitude = reports.mBestPosition.back().mBestAlt;
- r.mLocation.mLocation.accuracy =
- (double)(reports.mBestPosition.back().mBestHepe);
- r.mLocation.mUtcReported = reports.mBestPosition.back().mUtcReported;
- }
- else {
- r.mLocation.mValid = false;
- }
- if (r.mLocation.mValid) {
- LOC_LOGV("getDebugReport - lat=%f lon=%f alt=%f speed=%f",
- r.mLocation.mLocation.latitude,
- r.mLocation.mLocation.longitude,
- r.mLocation.mLocation.altitude,
- r.mLocation.mLocation.speed);
- }
- // time block
- r.mTime.size = sizeof(r.mTime);
- if(!reports.mTimeAndClock.empty() && reports.mTimeAndClock.back().mTimeValid) {
- r.mTime.mValid = true;
- r.mTime.timeEstimate =
- (((int64_t)(reports.mTimeAndClock.back().mGpsWeek)*7 +
- GNSS_UTC_TIME_OFFSET)*24*60*60 -
- (int64_t)(reports.mTimeAndClock.back().mLeapSeconds))*1000ULL +
- (int64_t)(reports.mTimeAndClock.back().mGpsTowMs);
- if (reports.mTimeAndClock.back().mTimeUncNs > 0) {
- // TimeUncNs value is available
- r.mTime.timeUncertaintyNs =
- (float)(reports.mTimeAndClock.back().mLeapSecUnc)*1000.0f +
- (float)(reports.mTimeAndClock.back().mTimeUncNs);
- } else {
- // fall back to legacy TimeUnc
- r.mTime.timeUncertaintyNs =
- ((float)(reports.mTimeAndClock.back().mTimeUnc) +
- (float)(reports.mTimeAndClock.back().mLeapSecUnc))*1000.0f;
- }
- r.mTime.frequencyUncertaintyNsPerSec =
- (float)(reports.mTimeAndClock.back().mClockFreqBiasUnc);
- LOC_LOGV("getDebugReport - timeestimate=%" PRIu64 " unc=%f frequnc=%f",
- r.mTime.timeEstimate,
- r.mTime.timeUncertaintyNs, r.mTime.frequencyUncertaintyNsPerSec);
- }
- else {
- r.mTime.mValid = false;
- }
- // satellite info block
- convertSatelliteInfo(r.mSatelliteInfo, GNSS_SV_TYPE_GPS, reports);
- convertSatelliteInfo(r.mSatelliteInfo, GNSS_SV_TYPE_GLONASS, reports);
- convertSatelliteInfo(r.mSatelliteInfo, GNSS_SV_TYPE_QZSS, reports);
- convertSatelliteInfo(r.mSatelliteInfo, GNSS_SV_TYPE_BEIDOU, reports);
- convertSatelliteInfo(r.mSatelliteInfo, GNSS_SV_TYPE_GALILEO, reports);
- convertSatelliteInfo(r.mSatelliteInfo, GNSS_SV_TYPE_NAVIC, reports);
- LOC_LOGV("getDebugReport - satellite=%zu", r.mSatelliteInfo.size());
- return true;
- }
- /* get AGC information from system status and fill it */
- void
- GnssAdapter::getAgcInformation(GnssMeasurementsNotification& measurements, int msInWeek)
- {
- SystemStatus* systemstatus = getSystemStatus();
- if (nullptr != systemstatus) {
- SystemStatusReports reports = {};
- systemstatus->getReport(reports, true);
- if ((!reports.mRfAndParams.empty()) && (!reports.mTimeAndClock.empty()) &&
- (abs(msInWeek - (int)reports.mTimeAndClock.back().mGpsTowMs) < 2000)) {
- for (size_t i = 0; i < measurements.count; i++) {
- switch (measurements.measurements[i].svType) {
- case GNSS_SV_TYPE_GPS:
- case GNSS_SV_TYPE_QZSS:
- measurements.measurements[i].agcLevelDb =
- -(double)reports.mRfAndParams.back().mJammerGps;
- measurements.measurements[i].flags |=
- GNSS_MEASUREMENTS_DATA_AUTOMATIC_GAIN_CONTROL_BIT;
- break;
- case GNSS_SV_TYPE_GALILEO:
- measurements.measurements[i].agcLevelDb =
- -(double)reports.mRfAndParams.back().mJammerGal;
- measurements.measurements[i].flags |=
- GNSS_MEASUREMENTS_DATA_AUTOMATIC_GAIN_CONTROL_BIT;
- break;
- case GNSS_SV_TYPE_GLONASS:
- measurements.measurements[i].agcLevelDb =
- -(double)reports.mRfAndParams.back().mJammerGlo;
- measurements.measurements[i].flags |=
- GNSS_MEASUREMENTS_DATA_AUTOMATIC_GAIN_CONTROL_BIT;
- break;
- case GNSS_SV_TYPE_BEIDOU:
- measurements.measurements[i].agcLevelDb =
- -(double)reports.mRfAndParams.back().mJammerBds;
- measurements.measurements[i].flags |=
- GNSS_MEASUREMENTS_DATA_AUTOMATIC_GAIN_CONTROL_BIT;
- break;
- case GNSS_SV_TYPE_SBAS:
- case GNSS_SV_TYPE_UNKNOWN:
- default:
- break;
- }
- }
- }
- }
- }
- /* get Data information from system status and fill it */
- void
- GnssAdapter::getDataInformation(GnssDataNotification& data, int msInWeek)
- {
- SystemStatus* systemstatus = getSystemStatus();
- LOC_LOGV("%s]: msInWeek=%d", __func__, msInWeek);
- if (nullptr != systemstatus) {
- SystemStatusReports reports = {};
- systemstatus->getReport(reports, true);
- if ((!reports.mRfAndParams.empty()) && (!reports.mTimeAndClock.empty()) &&
- (abs(msInWeek - (int)reports.mTimeAndClock.back().mGpsTowMs) < 2000)) {
- for (int sig = GNSS_LOC_SIGNAL_TYPE_GPS_L1CA;
- sig < GNSS_LOC_MAX_NUMBER_OF_SIGNAL_TYPES; sig++) {
- data.gnssDataMask[sig] = 0;
- data.jammerInd[sig] = 0.0;
- data.agc[sig] = 0.0;
- }
- if (GNSS_INVALID_JAMMER_IND != reports.mRfAndParams.back().mJammerGps) {
- data.gnssDataMask[GNSS_LOC_SIGNAL_TYPE_GPS_L1CA] |=
- GNSS_LOC_DATA_AGC_BIT | GNSS_LOC_DATA_JAMMER_IND_BIT;
- data.agc[GNSS_LOC_SIGNAL_TYPE_GPS_L1CA] =
- -(double)reports.mRfAndParams.back().mJammerGps;
- data.jammerInd[GNSS_LOC_SIGNAL_TYPE_GPS_L1CA] =
- (double)reports.mRfAndParams.back().mJammerGps;
- data.gnssDataMask[GNSS_LOC_SIGNAL_TYPE_QZSS_L1CA] |=
- GNSS_LOC_DATA_AGC_BIT | GNSS_LOC_DATA_JAMMER_IND_BIT;
- data.agc[GNSS_LOC_SIGNAL_TYPE_QZSS_L1CA] =
- -(double)reports.mRfAndParams.back().mJammerGps;
- data.jammerInd[GNSS_LOC_SIGNAL_TYPE_QZSS_L1CA] =
- (double)reports.mRfAndParams.back().mJammerGps;
- data.gnssDataMask[GNSS_LOC_SIGNAL_TYPE_SBAS_L1_CA] |=
- GNSS_LOC_DATA_AGC_BIT | GNSS_LOC_DATA_JAMMER_IND_BIT;
- data.agc[GNSS_LOC_SIGNAL_TYPE_SBAS_L1_CA] =
- -(double)reports.mRfAndParams.back().mJammerGps;
- data.jammerInd[GNSS_LOC_SIGNAL_TYPE_SBAS_L1_CA] =
- (double)reports.mRfAndParams.back().mJammerGps;
- }
- if (GNSS_INVALID_JAMMER_IND != reports.mRfAndParams.back().mJammerGlo) {
- data.gnssDataMask[GNSS_LOC_SIGNAL_TYPE_GLONASS_G1] |=
- GNSS_LOC_DATA_AGC_BIT | GNSS_LOC_DATA_JAMMER_IND_BIT;
- data.agc[GNSS_LOC_SIGNAL_TYPE_GLONASS_G1] =
- -(double)reports.mRfAndParams.back().mJammerGlo;
- data.jammerInd[GNSS_LOC_SIGNAL_TYPE_GLONASS_G1] =
- (double)reports.mRfAndParams.back().mJammerGlo;
- }
- if (GNSS_INVALID_JAMMER_IND != reports.mRfAndParams.back().mJammerBds) {
- data.gnssDataMask[GNSS_LOC_SIGNAL_TYPE_BEIDOU_B1_I] |=
- GNSS_LOC_DATA_AGC_BIT | GNSS_LOC_DATA_JAMMER_IND_BIT;
- data.agc[GNSS_LOC_SIGNAL_TYPE_BEIDOU_B1_I] =
- -(double)reports.mRfAndParams.back().mJammerBds;
- data.jammerInd[GNSS_LOC_SIGNAL_TYPE_BEIDOU_B1_I] =
- (double)reports.mRfAndParams.back().mJammerBds;
- }
- if (GNSS_INVALID_JAMMER_IND != reports.mRfAndParams.back().mJammerGal) {
- data.gnssDataMask[GNSS_LOC_SIGNAL_TYPE_GALILEO_E1_C] |=
- GNSS_LOC_DATA_AGC_BIT | GNSS_LOC_DATA_JAMMER_IND_BIT;
- data.agc[GNSS_LOC_SIGNAL_TYPE_GALILEO_E1_C] =
- -(double)reports.mRfAndParams.back().mJammerGal;
- data.jammerInd[GNSS_LOC_SIGNAL_TYPE_GALILEO_E1_C] =
- (double)reports.mRfAndParams.back().mJammerGal;
- }
- }
- }
- }
- /* Callbacks registered with loc_net_iface library */
- static void agpsOpenResultCb (bool isSuccess, AGpsExtType agpsType, const char* apn,
- AGpsBearerType bearerType, void* userDataPtr) {
- LOC_LOGD("%s]: ", __func__);
- if (userDataPtr == nullptr) {
- LOC_LOGE("%s]: userDataPtr is nullptr.", __func__);
- return;
- }
- if (apn == nullptr) {
- LOC_LOGE("%s]: apn is nullptr.", __func__);
- return;
- }
- GnssAdapter* adapter = (GnssAdapter*)userDataPtr;
- if (isSuccess) {
- adapter->dataConnOpenCommand(agpsType, apn, strlen(apn), bearerType);
- } else {
- adapter->dataConnFailedCommand(agpsType);
- }
- }
- static void agpsCloseResultCb (bool isSuccess, AGpsExtType agpsType, void* userDataPtr) {
- LOC_LOGD("%s]: ", __func__);
- if (userDataPtr == nullptr) {
- LOC_LOGE("%s]: userDataPtr is nullptr.", __func__);
- return;
- }
- GnssAdapter* adapter = (GnssAdapter*)userDataPtr;
- if (isSuccess) {
- adapter->dataConnClosedCommand(agpsType);
- } else {
- adapter->dataConnFailedCommand(agpsType);
- }
- }
- void
- GnssAdapter::saveGnssEnergyConsumedCallback(GnssEnergyConsumedCallback energyConsumedCb) {
- mGnssEnergyConsumedCb = energyConsumedCb;
- }
- void
- GnssAdapter::getGnssEnergyConsumedCommand(GnssEnergyConsumedCallback energyConsumedCb) {
- struct MsgGetGnssEnergyConsumed : public LocMsg {
- GnssAdapter& mAdapter;
- LocApiBase& mApi;
- GnssEnergyConsumedCallback mEnergyConsumedCb;
- inline MsgGetGnssEnergyConsumed(GnssAdapter& adapter, LocApiBase& api,
- GnssEnergyConsumedCallback energyConsumedCb) :
- LocMsg(),
- mAdapter(adapter),
- mApi(api),
- mEnergyConsumedCb(energyConsumedCb){}
- inline virtual void proc() const {
- mAdapter.saveGnssEnergyConsumedCallback(mEnergyConsumedCb);
- mApi.getGnssEnergyConsumed();
- }
- };
- sendMsg(new MsgGetGnssEnergyConsumed(*this, *mLocApi, energyConsumedCb));
- }
- uint32_t GnssAdapter::getNfwControlBits(const std::vector<std::string>& enabledNfws) {
- uint32_t nfwControlBits = 0;
- for (auto& pkgName : enabledNfws) {
- auto nfw = mNfws.find(pkgName);
- if (mNfws.end() != nfw) {
- nfwControlBits |= nfw->second;
- }
- }
- nfwControlBits = ~nfwControlBits & GNSS_CONFIG_GPS_LOCK_NFW_ALL;
- LOC_LOGd("nfwControlBits=0x%X", nfwControlBits);
- return nfwControlBits;
- }
- void
- GnssAdapter::nfwControlCommand(std::vector<std::string>& enabledNfws) {
- struct MsgControlNfwLocationAccess : public LocMsg {
- GnssAdapter& mAdapter;
- LocApiBase& mApi;
- const std::vector<std::string> mEnabledNfws;
- inline MsgControlNfwLocationAccess(GnssAdapter& adapter, LocApiBase& api,
- const std::vector<std::string>& enabledNfws) :
- LocMsg(),
- mAdapter(adapter),
- mApi(api),
- mEnabledNfws(std::move(enabledNfws)) {}
- inline virtual void proc() const {
- if (!mAdapter.isEngineCapabilitiesKnown()) {
- mAdapter.mPendingMsgs.push_back(
- new MsgControlNfwLocationAccess(mAdapter, mApi, mEnabledNfws));
- return;
- }
- GnssConfigGpsLock gpsLock;
- uint32_t nfwControlBits;
- nfwControlBits = mAdapter.getNfwControlBits(mEnabledNfws);
- gpsLock = ContextBase::mGps_conf.GPS_LOCK;
- gpsLock &= GNSS_CONFIG_GPS_LOCK_MO;
- gpsLock |= nfwControlBits;
- ContextBase::mGps_conf.GPS_LOCK = gpsLock;
- LOC_LOGv("gpsLock = 0x%X nfwControlBits = 0x%X", gpsLock, nfwControlBits);
- mApi.sendMsg(new LocApiMsg([&mApi = mApi, gpsLock]() {
- mApi.setGpsLockSync((GnssConfigGpsLock)gpsLock);
- }));
- }
- };
- if (mSupportNfwControl) {
- sendMsg(new MsgControlNfwLocationAccess(*this, *mLocApi, enabledNfws));
- } else {
- LOC_LOGw("NFW control is not supported, do not use this for NFW");
- }
- }
- // Set tunc constrained mode, use 0 session id to indicate
- // that no callback is needed. Session id 0 is used for calls that
- // are not invoked from the integration api, e.g.: initial configuration
- // from the configure file
- void
- GnssAdapter::setConstrainedTunc(bool enable, float tuncConstraint,
- uint32_t energyBudget, uint32_t sessionId) {
- mLocConfigInfo.tuncConfigInfo.isValid = true;
- mLocConfigInfo.tuncConfigInfo.enable = enable;
- mLocConfigInfo.tuncConfigInfo.tuncThresholdMs = tuncConstraint;
- mLocConfigInfo.tuncConfigInfo.energyBudget = energyBudget;
- LocApiResponse* locApiResponse = nullptr;
- if (sessionId != 0) {
- locApiResponse =
- new LocApiResponse(*getContext(),
- [this, sessionId] (LocationError err) {
- reportResponse(err, sessionId);});
- if (!locApiResponse) {
- LOC_LOGe("memory alloc failed");
- }
- }
- mLocApi->setConstrainedTuncMode(
- enable, tuncConstraint, energyBudget, locApiResponse);
- }
- uint32_t
- GnssAdapter::setConstrainedTuncCommand (bool enable, float tuncConstraint,
- uint32_t energyBudget) {
- // generated session id will be none-zero
- uint32_t sessionId = generateSessionId();
- LOC_LOGd("session id %u", sessionId);
- struct MsgEnableTUNC : public LocMsg {
- GnssAdapter& mAdapter;
- uint32_t mSessionId;
- bool mEnable;
- float mTuncConstraint;
- uint32_t mEnergyBudget;
- inline MsgEnableTUNC(GnssAdapter& adapter,
- uint32_t sessionId,
- bool enable,
- float tuncConstraint,
- uint32_t energyBudget) :
- LocMsg(),
- mAdapter(adapter),
- mSessionId(sessionId),
- mEnable(enable),
- mTuncConstraint(tuncConstraint),
- mEnergyBudget(energyBudget) {}
- inline virtual void proc() const {
- mAdapter.setConstrainedTunc(mEnable, mTuncConstraint,
- mEnergyBudget, mSessionId);
- }
- };
- sendMsg(new MsgEnableTUNC(*this, sessionId, enable,
- tuncConstraint, energyBudget));
- return sessionId;
- }
- // Set position assisted clock estimator, use 0 session id to indicate
- // that no callback is needed. Session id 0 is used for calls that are
- // not invoked from the integration api, e.g.: initial configuration
- // from the configure file.
- void
- GnssAdapter::setPositionAssistedClockEstimator(bool enable,
- uint32_t sessionId) {
- mLocConfigInfo.paceConfigInfo.isValid = true;
- mLocConfigInfo.paceConfigInfo.enable = enable;
- LocApiResponse* locApiResponse = nullptr;
- if (sessionId != 0) {
- locApiResponse =
- new LocApiResponse(*getContext(),
- [this, sessionId] (LocationError err) {
- reportResponse(err, sessionId);});
- if (!locApiResponse) {
- LOC_LOGe("memory alloc failed");
- }
- }
- mLocApi->setPositionAssistedClockEstimatorMode(enable, locApiResponse);
- }
- uint32_t
- GnssAdapter::setPositionAssistedClockEstimatorCommand(bool enable) {
- // generated session id will be none-zero
- uint32_t sessionId = generateSessionId();
- LOC_LOGd("session id %u", sessionId);
- struct MsgEnablePACE : public LocMsg {
- GnssAdapter& mAdapter;
- uint32_t mSessionId;
- bool mEnable;
- inline MsgEnablePACE(GnssAdapter& adapter,
- uint32_t sessionId, bool enable) :
- LocMsg(),
- mAdapter(adapter),
- mSessionId(sessionId),
- mEnable(enable){}
- inline virtual void proc() const {
- mAdapter.setPositionAssistedClockEstimator(mEnable, mSessionId);
- }
- };
- sendMsg(new MsgEnablePACE(*this, sessionId, enable));
- return sessionId;
- }
- void GnssAdapter::gnssUpdateSvConfig(
- uint32_t sessionId, const GnssSvTypeConfig& constellationEnablementConfig,
- const GnssSvIdConfig& blacklistSvConfig) {
- // suspend all tracking sessions to apply the constellation config
- suspendSessions();
- if (constellationEnablementConfig.size == sizeof(constellationEnablementConfig)) {
- // check whether if any constellation is removed from the new config
- GnssSvTypesMask currentEnabledMask = mGnssSvTypeConfig.enabledSvTypesMask;
- GnssSvTypesMask newEnabledMask = constellationEnablementConfig.enabledSvTypesMask;
- GnssSvTypesMask enabledRemoved = currentEnabledMask & (currentEnabledMask ^ newEnabledMask);
- // Send reset if any constellation is removed from the enabled list
- if (enabledRemoved != 0) {
- mLocApi->resetConstellationControl();
- }
- // if the constellation config is valid, issue request to modem
- // to enable/disable constellation
- mLocApi->setConstellationControl(mGnssSvTypeConfig);
- } else if (constellationEnablementConfig.size == 0) {
- // when the size is not set, meaning reset to modem default
- mLocApi->resetConstellationControl();
- }
- // save the constellation settings to be used for modem SSR
- mGnssSvTypeConfig = constellationEnablementConfig;
- // handle blacklisted SV settings
- mGnssSvIdConfig = blacklistSvConfig;
- // process blacklist svs info
- mBlacklistedSvIds.clear();
- // need to save the balcklisted sv info into mBlacklistedSvIds as well
- convertFromGnssSvIdConfig(blacklistSvConfig, mBlacklistedSvIds);
- LocApiResponse* locApiResponse = new LocApiResponse(*getContext(),
- [this, sessionId] (LocationError err) {
- reportResponse(err, sessionId);});
- if (!locApiResponse) {
- LOC_LOGe("memory alloc failed");
- }
- mLocApi->setBlacklistSv(mGnssSvIdConfig, locApiResponse);
- // resume all tracking sessions after the constellation config has been applied
- restartSessions(false);
- }
- uint32_t
- GnssAdapter::gnssUpdateSvConfigCommand(
- const GnssSvTypeConfig& constellationEnablementConfig,
- const GnssSvIdConfig& blacklistSvConfig) {
- // generated session id will be none-zero
- uint32_t sessionId = generateSessionId();
- LOC_LOGd("session id %u", sessionId);
- struct MsgUpdateSvConfig : public LocMsg {
- GnssAdapter& mAdapter;
- uint32_t mSessionId;
- GnssSvTypeConfig mConstellationEnablementConfig;
- GnssSvIdConfig mBlacklistSvIdConfig;
- inline MsgUpdateSvConfig(GnssAdapter& adapter,
- uint32_t sessionId,
- const GnssSvTypeConfig& constellationEnablementConfig,
- const GnssSvIdConfig& blacklistSvConfig) :
- LocMsg(),
- mAdapter(adapter),
- mSessionId(sessionId),
- mConstellationEnablementConfig(constellationEnablementConfig),
- mBlacklistSvIdConfig(blacklistSvConfig) {}
- inline virtual void proc() const {
- mAdapter.gnssUpdateSvConfig(mSessionId, mConstellationEnablementConfig,
- mBlacklistSvIdConfig);
- }
- };
- if (sessionId != 0) {
- sendMsg(new MsgUpdateSvConfig(*this, sessionId, constellationEnablementConfig,
- blacklistSvConfig));
- }
- return sessionId;
- }
- void GnssAdapter::gnssUpdateSecondaryBandConfig(
- uint32_t sessionId, const GnssSvTypeConfig& secondaryBandConfig) {
- LocApiResponse* locApiResponse = new LocApiResponse(*getContext(),
- [this, sessionId] (LocationError err) {
- reportResponse(err, sessionId);});
- if (!locApiResponse) {
- LOC_LOGe("memory alloc failed");
- }
- // handle secondary band info
- mGnssSeconaryBandConfig = secondaryBandConfig;
- gnssSecondaryBandConfigUpdate(locApiResponse);
- }
- uint32_t
- GnssAdapter::gnssUpdateSecondaryBandConfigCommand(
- const GnssSvTypeConfig& secondaryBandConfig) {
- // generated session id will be none-zero
- uint32_t sessionId = generateSessionId();
- LOC_LOGd("session id %u", sessionId);
- struct MsgUpdateSecondaryBandConfig : public LocMsg {
- GnssAdapter& mAdapter;
- uint32_t mSessionId;
- GnssSvTypeConfig mSecondaryBandConfig;
- inline MsgUpdateSecondaryBandConfig(GnssAdapter& adapter,
- uint32_t sessionId,
- const GnssSvTypeConfig& secondaryBandConfig) :
- LocMsg(),
- mAdapter(adapter),
- mSessionId(sessionId),
- mSecondaryBandConfig(secondaryBandConfig) {}
- inline virtual void proc() const {
- mAdapter.gnssUpdateSecondaryBandConfig(mSessionId, mSecondaryBandConfig);
- }
- };
- if (sessionId != 0) {
- sendMsg(new MsgUpdateSecondaryBandConfig(*this, sessionId, secondaryBandConfig));
- }
- return sessionId;
- }
- // This function currently retrieves secondary band configuration
- // for constellation enablement/disablement.
- void
- GnssAdapter::gnssGetSecondaryBandConfig(uint32_t sessionId) {
- LocApiResponse* locApiResponse = new LocApiResponse(*getContext(),
- [this, sessionId] (LocationError err) {
- reportResponse(err, sessionId);});
- if (!locApiResponse) {
- LOC_LOGe("memory alloc failed");
- }
- mLocApi->getConstellationMultiBandConfig(sessionId, locApiResponse);
- }
- uint32_t
- GnssAdapter::gnssGetSecondaryBandConfigCommand() {
- // generated session id will be none-zero
- uint32_t sessionId = generateSessionId();
- LOC_LOGd("session id %u", sessionId);
- struct MsgGetSecondaryBandConfig : public LocMsg {
- GnssAdapter& mAdapter;
- uint32_t mSessionId;
- inline MsgGetSecondaryBandConfig(GnssAdapter& adapter,
- uint32_t sessionId) :
- LocMsg(),
- mAdapter(adapter),
- mSessionId(sessionId) {}
- inline virtual void proc() const {
- mAdapter.gnssGetSecondaryBandConfig(mSessionId);
- }
- };
- if (sessionId != 0) {
- sendMsg(new MsgGetSecondaryBandConfig(*this, sessionId));
- }
- return sessionId;
- }
- void
- GnssAdapter::configLeverArm(uint32_t sessionId,
- const LeverArmConfigInfo& configInfo) {
- LocationError err = LOCATION_ERROR_NOT_SUPPORTED;
- // save the lever ARM config info for translating SPE positions from
- // GNSS antenna based to VRP based
- if (configInfo.leverArmValidMask & LEVER_ARM_TYPE_GNSS_TO_VRP_BIT) {
- mLocConfigInfo.leverArmConfigInfo.leverArmValidMask |=
- LEVER_ARM_TYPE_GNSS_TO_VRP_BIT;
- mLocConfigInfo.leverArmConfigInfo.gnssToVRP = configInfo.gnssToVRP;
- err = LOCATION_ERROR_SUCCESS;
- }
- if (configInfo.leverArmValidMask & LEVER_ARM_TYPE_DR_IMU_TO_GNSS_BIT) {
- if (mDreIntEnabled && mEngHubProxy->configLeverArm(configInfo)) {
- err = LOCATION_ERROR_SUCCESS;
- }
- }
- reportResponse(err, sessionId);
- }
- uint32_t
- GnssAdapter::configLeverArmCommand(const LeverArmConfigInfo& configInfo) {
- // generated session id will be none-zero
- uint32_t sessionId = generateSessionId();
- LOC_LOGd("session id %u", sessionId);
- struct MsgConfigLeverArm : public LocMsg {
- GnssAdapter& mAdapter;
- uint32_t mSessionId;
- LeverArmConfigInfo mConfigInfo;
- inline MsgConfigLeverArm(GnssAdapter& adapter,
- uint32_t sessionId,
- const LeverArmConfigInfo& configInfo) :
- LocMsg(),
- mAdapter(adapter),
- mSessionId(sessionId),
- mConfigInfo(configInfo) {}
- inline virtual void proc() const {
- mAdapter.configLeverArm(mSessionId, mConfigInfo);
- }
- };
- sendMsg(new MsgConfigLeverArm(*this, sessionId, configInfo));
- return sessionId;
- }
- bool GnssAdapter::initMeasCorr(bool bSendCbWhenNotSupported) {
- LOC_LOGv("GnssAdapter::initMeasCorr");
- /* Message to initialize Measurement Corrections */
- struct MsgInitMeasCorr : public LocMsg {
- GnssAdapter& mAdapter;
- GnssMeasurementCorrectionsCapabilitiesMask mCapMask;
- inline MsgInitMeasCorr(GnssAdapter& adapter,
- GnssMeasurementCorrectionsCapabilitiesMask capMask) :
- LocMsg(), mAdapter(adapter), mCapMask(capMask) {
- LOC_LOGv("MsgInitMeasCorr");
- }
- inline virtual void proc() const {
- LOC_LOGv("MsgInitMeasCorr::proc()");
- mAdapter.mMeasCorrSetCapabilitiesCb(mCapMask);
- }
- };
- if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_MEASUREMENTS_CORRECTION)) {
- sendMsg(new MsgInitMeasCorr(*this, GNSS_MEAS_CORR_LOS_SATS |
- GNSS_MEAS_CORR_EXCESS_PATH_LENGTH | GNSS_MEAS_CORR_REFLECTING_PLANE));
- return true;
- } else {
- LOC_LOGv("MEASUREMENTS_CORRECTION feature is not supported in the modem");
- if (bSendCbWhenNotSupported) {
- sendMsg(new MsgInitMeasCorr(*this, 0));
- }
- return false;
- }
- }
- bool GnssAdapter::openMeasCorrCommand(const measCorrSetCapabilitiesCb setCapabilitiesCb) {
- LOC_LOGi("GnssAdapter::openMeasCorrCommand");
- /* Send message to initialize Measurement Corrections */
- mMeasCorrSetCapabilitiesCb = setCapabilitiesCb;
- mIsMeasCorrInterfaceOpen = true;
- if (isEngineCapabilitiesKnown()) {
- LOC_LOGv("Capabilities are known, proceed with measurement corrections init");
- return initMeasCorr(false);
- } else {
- LOC_LOGv("Capabilities are not known, wait for open");
- return true;
- }
- }
- bool GnssAdapter::measCorrSetCorrectionsCommand(const GnssMeasurementCorrections gnssMeasCorr) {
- LOC_LOGi("GnssAdapter::measCorrSetCorrectionsCommand");
- /* Message to set Measurement Corrections */
- struct MsgSetCorrectionsMeasCorr : public LocMsg {
- const GnssMeasurementCorrections mGnssMeasCorr;
- GnssAdapter& mAdapter;
- LocApiBase& mApi;
- inline MsgSetCorrectionsMeasCorr(
- const GnssMeasurementCorrections gnssMeasCorr,
- GnssAdapter& adapter,
- LocApiBase& api) :
- LocMsg(),
- mGnssMeasCorr(gnssMeasCorr),
- mAdapter(adapter),
- mApi(api) {
- LOC_LOGv("MsgSetCorrectionsMeasCorr");
- }
- inline virtual void proc() const {
- LOC_LOGv("MsgSetCorrectionsMeasCorr::proc()");
- mApi.setMeasurementCorrections(mGnssMeasCorr);
- }
- };
- if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_MEASUREMENTS_CORRECTION)) {
- sendMsg(new MsgSetCorrectionsMeasCorr(gnssMeasCorr, *this, *mLocApi));
- return true;
- } else {
- LOC_LOGw("Measurement Corrections are not supported!");
- return false;
- }
- }
- uint32_t GnssAdapter::antennaInfoInitCommand(const antennaInfoCb antennaInfoCallback) {
- LOC_LOGi("GnssAdapter::antennaInfoInitCommand");
- /* Message to initialize Antenna Information */
- struct MsgInitAi : public LocMsg {
- const antennaInfoCb mAntennaInfoCb;
- GnssAdapter& mAdapter;
- inline MsgInitAi(const antennaInfoCb antennaInfoCallback, GnssAdapter& adapter) :
- LocMsg(), mAntennaInfoCb(antennaInfoCallback), mAdapter(adapter) {
- LOC_LOGv("MsgInitAi");
- }
- inline virtual void proc() const {
- LOC_LOGv("MsgInitAi::proc()");
- mAdapter.reportGnssAntennaInformation(mAntennaInfoCb);
- }
- };
- if (mIsAntennaInfoInterfaceOpened) {
- return ANTENNA_INFO_ERROR_ALREADY_INIT;
- } else {
- mIsAntennaInfoInterfaceOpened = true;
- sendMsg(new MsgInitAi(antennaInfoCallback, *this));
- return ANTENNA_INFO_SUCCESS;
- }
- }
- void
- GnssAdapter::configRobustLocation(uint32_t sessionId,
- bool enable, bool enableForE911) {
- mLocConfigInfo.robustLocationConfigInfo.isValid = true;
- mLocConfigInfo.robustLocationConfigInfo.enable = enable;
- mLocConfigInfo.robustLocationConfigInfo.enableFor911 = enableForE911;
- LocApiResponse* locApiResponse = nullptr;
- if (sessionId != 0) {
- locApiResponse =
- new LocApiResponse(*getContext(),
- [this, sessionId] (LocationError err) {
- reportResponse(err, sessionId);});
- if (!locApiResponse) {
- LOC_LOGe("memory alloc failed");
- }
- }
- mLocApi->configRobustLocation(enable, enableForE911, locApiResponse);
- }
- uint32_t GnssAdapter::configRobustLocationCommand(
- bool enable, bool enableForE911) {
- // generated session id will be none-zero
- uint32_t sessionId = generateSessionId();
- LOC_LOGd("session id %u", sessionId);
- struct MsgConfigRobustLocation : public LocMsg {
- GnssAdapter& mAdapter;
- uint32_t mSessionId;
- bool mEnable;
- bool mEnableForE911;
- inline MsgConfigRobustLocation(GnssAdapter& adapter,
- uint32_t sessionId,
- bool enable,
- bool enableForE911) :
- LocMsg(),
- mAdapter(adapter),
- mSessionId(sessionId),
- mEnable(enable),
- mEnableForE911(enableForE911) {}
- inline virtual void proc() const {
- mAdapter.configRobustLocation(mSessionId, mEnable, mEnableForE911);
- }
- };
- sendMsg(new MsgConfigRobustLocation(*this, sessionId, enable, enableForE911));
- return sessionId;
- }
- void
- GnssAdapter::configMinGpsWeek(uint32_t sessionId, uint16_t minGpsWeek) {
- // suspend all sessions for modem to take the min GPS week config
- suspendSessions();
- LocApiResponse* locApiResponse = nullptr;
- if (sessionId != 0) {
- locApiResponse =
- new LocApiResponse(*getContext(),
- [this, sessionId] (LocationError err) {
- reportResponse(err, sessionId);});
- if (!locApiResponse) {
- LOC_LOGe("memory alloc failed");
- }
- }
- mLocApi->configMinGpsWeek(minGpsWeek, locApiResponse);
- // resume all tracking sessions after the min GPS week config
- // has been changed
- restartSessions(false);
- }
- uint32_t GnssAdapter::configMinGpsWeekCommand(uint16_t minGpsWeek) {
- // generated session id will be none-zero
- uint32_t sessionId = generateSessionId();
- LOC_LOGd("session id %u", sessionId);
- struct MsgConfigMinGpsWeek : public LocMsg {
- GnssAdapter& mAdapter;
- uint32_t mSessionId;
- uint16_t mMinGpsWeek;
- inline MsgConfigMinGpsWeek(GnssAdapter& adapter,
- uint32_t sessionId,
- uint16_t minGpsWeek) :
- LocMsg(),
- mAdapter(adapter),
- mSessionId(sessionId),
- mMinGpsWeek(minGpsWeek) {}
- inline virtual void proc() const {
- mAdapter.configMinGpsWeek(mSessionId, mMinGpsWeek);
- }
- };
- sendMsg(new MsgConfigMinGpsWeek(*this, sessionId, minGpsWeek));
- return sessionId;
- }
- uint32_t GnssAdapter::configDeadReckoningEngineParamsCommand(
- const DeadReckoningEngineConfig& dreConfig) {
- // generated session id will be none-zero
- uint32_t sessionId = generateSessionId();
- LOC_LOGd("session id %u", sessionId);
- struct MsgConfigDrEngine : public LocMsg {
- GnssAdapter& mAdapter;
- uint32_t mSessionId;
- DeadReckoningEngineConfig mDreConfig;
- inline MsgConfigDrEngine(GnssAdapter& adapter,
- uint32_t sessionId,
- const DeadReckoningEngineConfig& dreConfig) :
- LocMsg(),
- mAdapter(adapter),
- mSessionId(sessionId),
- mDreConfig(dreConfig) {}
- inline virtual void proc() const {
- LocationError err = LOCATION_ERROR_NOT_SUPPORTED;
- if (true == mAdapter.mEngHubProxy->configDeadReckoningEngineParams(mDreConfig)) {
- err = LOCATION_ERROR_SUCCESS;
- }
- mAdapter.reportResponse(err, mSessionId);
- }
- };
- sendMsg(new MsgConfigDrEngine(*this, sessionId, dreConfig));
- return sessionId;
- }
- uint32_t GnssAdapter::configEngineRunStateCommand(
- PositioningEngineMask engType, LocEngineRunState engState) {
- // generated session id will be none-zero
- uint32_t sessionId = generateSessionId();
- LOC_LOGe("session id %u, eng type 0x%x, eng state %d, dre enabled %d",
- sessionId, engType, engState, mDreIntEnabled);
- struct MsgConfigEngineRunState : public LocMsg {
- GnssAdapter& mAdapter;
- uint32_t mSessionId;
- PositioningEngineMask mEngType;
- LocEngineRunState mEngState;
- inline MsgConfigEngineRunState(GnssAdapter& adapter,
- uint32_t sessionId,
- PositioningEngineMask engType,
- LocEngineRunState engState) :
- LocMsg(),
- mAdapter(adapter),
- mSessionId(sessionId),
- mEngType(engType),
- mEngState(engState) {}
- inline virtual void proc() const {
- LocationError err = LOCATION_ERROR_NOT_SUPPORTED;
- // Currently, only DR engine supports pause/resume request
- if ((mEngType == DEAD_RECKONING_ENGINE) &&
- (mAdapter.mDreIntEnabled == true)) {
- if (true == mAdapter.mEngHubProxy->configEngineRunState(mEngType, mEngState)) {
- err = LOCATION_ERROR_SUCCESS;
- }
- }
- mAdapter.reportResponse(err, mSessionId);
- }
- };
- sendMsg(new MsgConfigEngineRunState(*this, sessionId, engType, engState));
- return sessionId;
- }
- uint32_t GnssAdapter::configOutputNmeaTypesCommand(GnssNmeaTypesMask enabledNmeaTypes) {
- // generated session id will be none-zero
- uint32_t sessionId = generateSessionId();
- LOC_LOGd("session id %u, enabled nmea = 0x%x", sessionId, enabledNmeaTypes);
- struct MsgConfigOutputNmeaType : public LocMsg {
- GnssAdapter& mAdapter;
- uint32_t mSessionId;
- GnssNmeaTypesMask mEnabledNmeaTypes;
- inline MsgConfigOutputNmeaType(GnssAdapter& adapter,
- uint32_t sessionId,
- GnssNmeaTypesMask enabledNmeaTypes) :
- LocMsg(),
- mAdapter(adapter),
- mSessionId(sessionId),
- mEnabledNmeaTypes(enabledNmeaTypes) {}
- inline virtual void proc() const {
- loc_nmea_config_output_types(mEnabledNmeaTypes);
- mAdapter.reportResponse(LOCATION_ERROR_SUCCESS, mSessionId);
- }
- };
- sendMsg(new MsgConfigOutputNmeaType(*this, sessionId, enabledNmeaTypes));
- return sessionId;
- }
- void GnssAdapter::powerIndicationInitCommand(const powerIndicationCb powerIndicationCallback) {
- LOC_LOGi("GnssAdapter::powerIndicationInitCommand");
- struct MsgPowerIndicationInit : public LocMsg {
- const powerIndicationCb mPowerIndicationCb;
- GnssAdapter& mAdapter;
- inline MsgPowerIndicationInit(const powerIndicationCb powerIndicationCallback,
- GnssAdapter& adapter) :
- LocMsg(), mPowerIndicationCb(powerIndicationCallback), mAdapter(adapter) {
- LOC_LOGv("MsgPowerIndicationInit");
- }
- inline virtual void proc() const {
- LOC_LOGv("MsgPowerIndicationInit::proc()");
- mAdapter.setPowerIndicationCb(mPowerIndicationCb);
- }
- };
- sendMsg(new MsgPowerIndicationInit(powerIndicationCallback, *this));
- }
- void GnssAdapter::powerIndicationRequestCommand() {
- LOC_LOGi("GnssAdapter::powerIndicationRequestCommand");
- struct MsgPowerIndicationRequest : public LocMsg {
- LocApiBase& mApi;
- inline MsgPowerIndicationRequest(LocApiBase& api) :
- LocMsg(), mApi(api) {
- LOC_LOGv("MsgPowerIndicationRequest");
- }
- inline virtual void proc() const {
- LOC_LOGv("MsgPowerIndicationRequest::proc()");
- mApi.getGnssEnergyConsumed();
- }
- };
- sendMsg(new MsgPowerIndicationRequest(*mLocApi));
- }
- void GnssAdapter::reportGnssConfigEvent(uint32_t sessionId, const GnssConfig& gnssConfig)
- {
- struct MsgReportGnssConfig : public LocMsg {
- GnssAdapter& mAdapter;
- uint32_t mSessionId;
- mutable GnssConfig mGnssConfig;
- inline MsgReportGnssConfig(GnssAdapter& adapter,
- uint32_t sessionId,
- const GnssConfig& gnssConfig) :
- LocMsg(),
- mAdapter(adapter),
- mSessionId(sessionId),
- mGnssConfig(gnssConfig) {}
- inline virtual void proc() const {
- // Invoke control clients config callback
- if (nullptr != mAdapter.mControlCallbacks.gnssConfigCb) {
- mAdapter.mControlCallbacks.gnssConfigCb(mSessionId, mGnssConfig);
- } else {
- LOC_LOGe("Failed to report, callback not registered");
- }
- }
- };
- sendMsg(new MsgReportGnssConfig(*this, sessionId, gnssConfig));
- }
- /* ==== Eng Hub Proxy ================================================================= */
- /* ======== UTILITIES ================================================================= */
- void
- GnssAdapter::initEngHubProxyCommand() {
- LOC_LOGd();
- struct MsgInitEngHubProxy : public LocMsg {
- GnssAdapter* mAdapter;
- inline MsgInitEngHubProxy(GnssAdapter* adapter) :
- LocMsg(),
- mAdapter(adapter) {}
- inline virtual void proc() const {
- mAdapter->initEngHubProxy();
- }
- };
- sendMsg(new MsgInitEngHubProxy(this));
- }
- bool
- GnssAdapter::initEngHubProxy() {
- static bool firstTime = true;
- static bool engHubLoadSuccessful = false;
- const char *error = nullptr;
- unsigned int processListLength = 0;
- loc_process_info_s_type* processInfoList = nullptr;
- do {
- // load eng hub only once
- if (firstTime == false) {
- break;
- }
- int rc = loc_read_process_conf(LOC_PATH_IZAT_CONF, &processListLength,
- &processInfoList);
- if (rc != 0) {
- LOC_LOGE("%s]: failed to parse conf file", __func__);
- break;
- }
- EngineServiceInfo engServiceInfo = {};
- bool pluginDaemonEnabled = false;
- // go over the conf table to see whether any plugin daemon is enabled
- for (unsigned int i = 0; i < processListLength; i++) {
- if ((strncmp(processInfoList[i].name[0], PROCESS_NAME_ENGINE_SERVICE,
- strlen(PROCESS_NAME_ENGINE_SERVICE)) == 0) &&
- (processInfoList[i].proc_status == ENABLED)) {
- pluginDaemonEnabled = true;
- if (processInfoList[i].args[1]!= nullptr) {
- // check if this is DRE-INT engine
- if (strncmp(processInfoList[i].args[1], "DRE-INT", sizeof("DRE-INT")) == 0) {
- mDreIntEnabled = true;
- } else if (strncmp(processInfoList[i].args[1], "PPE-INT",
- sizeof("PPE-INT")) == 0) {
- // check if this is PPE-INT engine
- engServiceInfo.ppeIntEnabled = true;
- }
- }
- }
- }
- // no plugin daemon is enabled for this platform,
- // check if external engine is present for which we need
- // libloc_eng_hub.so to be loaded
- if (pluginDaemonEnabled == false) {
- UTIL_READ_CONF(LOC_PATH_IZAT_CONF, izatConfParamTable);
- if (!loadEngHubForExternalEngine) {
- break;
- }
- }
- // load the engine hub .so, if the .so is not present
- // all EngHubProxyBase calls will turn into no-op.
- void *handle = nullptr;
- if ((handle = dlopen("libloc_eng_hub.so", RTLD_NOW)) == nullptr) {
- if ((error = dlerror()) != nullptr) {
- LOC_LOGE("%s]: libloc_eng_hub.so not found %s !", __func__, error);
- }
- break;
- }
- // prepare the callback functions
- // callback function for engine hub to report back position event
- GnssAdapterReportEnginePositionsEventCb reportPositionEventCb =
- [this](int count, EngineLocationInfo* locationArr) {
- // report from engine hub on behalf of PPE will be treated as fromUlp
- reportEnginePositionsEvent(count, locationArr);
- };
- // callback function for engine hub to request for complete aiding data
- GnssAdapterReqAidingDataCb reqAidingDataCb =
- [this] (const GnssAidingDataSvMask& svDataMask) {
- mLocApi->requestForAidingData(svDataMask);
- };
- GnssAdapterUpdateNHzRequirementCb updateNHzRequirementCb =
- [this] (bool nHzNeeded, bool nHzMeasNeeded) {
- if (nHzMeasNeeded &&
- (!checkMask(LOC_API_ADAPTER_BIT_GNSS_NHZ_MEASUREMENT))) {
- updateEvtMask(LOC_API_ADAPTER_BIT_GNSS_NHZ_MEASUREMENT,
- LOC_REGISTRATION_MASK_ENABLED);
- } else if (checkMask(LOC_API_ADAPTER_BIT_GNSS_NHZ_MEASUREMENT)) {
- updateEvtMask(LOC_API_ADAPTER_BIT_GNSS_NHZ_MEASUREMENT,
- LOC_REGISTRATION_MASK_DISABLED);
- }
- if (mNHzNeeded != nHzNeeded) {
- mNHzNeeded = nHzNeeded;
- checkAndRestartSPESession();
- }
- };
- GnssAdapterUpdateQwesFeatureStatusCb updateQwesFeatureStatusCb =
- [this] (const std::unordered_map<LocationQwesFeatureType, bool> &featureMap) {
- reportQwesCapabilities(featureMap);
- };
- getEngHubProxyFn* getter = (getEngHubProxyFn*) dlsym(handle, "getEngHubProxy");
- if(getter != nullptr) {
- // Wait for the script(rootdir/etc/init.qcom.rc) to create socket folder
- locUtilWaitForDir(SOCKET_DIR_EHUB);
- EngineHubProxyBase* hubProxy = (*getter) (mMsgTask, mSystemStatus->getOsObserver(),
- engServiceInfo, reportPositionEventCb, reqAidingDataCb,
- updateNHzRequirementCb, updateQwesFeatureStatusCb);
- if (hubProxy != nullptr) {
- mEngHubProxy = hubProxy;
- engHubLoadSuccessful = true;
- }
- }
- else {
- LOC_LOGD("%s]: entered, did not find function", __func__);
- }
- LOC_LOGD("%s]: first time initialization %d, returned %d",
- __func__, firstTime, engHubLoadSuccessful);
- } while (0);
- if (processInfoList != nullptr) {
- free (processInfoList);
- processInfoList = nullptr;
- }
- firstTime = false;
- return engHubLoadSuccessful;
- }
- std::vector<double>
- GnssAdapter::parseDoublesString(char* dString) {
- std::vector<double> dVector;
- char* tmp = NULL;
- char* substr;
- dVector.clear();
- for (substr = strtok_r(dString, " ", &tmp);
- substr != NULL;
- substr = strtok_r(NULL, " ", &tmp)) {
- dVector.push_back(std::stod(substr));
- }
- return dVector;
- }
- void GnssAdapter::initGnssPowerStatistics() {
- if (!mGnssPowerStatisticsInit) {
- mLocApi->getGnssEnergyConsumed();
- }
- }
- void
- GnssAdapter::reportGnssAntennaInformation(const antennaInfoCb antennaInfoCallback)
- {
- #define MAX_TEXT_WIDTH 50
- #define MAX_COLUMN_WIDTH 20
- /* parse antenna_corrections file and fill in
- a vector of GnssAntennaInformation data structure */
- std::vector<GnssAntennaInformation> gnssAntennaInformations;
- GnssAntennaInformation gnssAntennaInfo;
- uint32_t antennaInfoVectorSize;
- loc_param_s_type ant_info_vector_table[] =
- {
- { "ANTENNA_INFO_VECTOR_SIZE", &antennaInfoVectorSize, NULL, 'n' }
- };
- UTIL_READ_CONF(LOC_PATH_ANT_CORR, ant_info_vector_table);
- for (uint32_t i = 0; i < antennaInfoVectorSize; i++) {
- double carrierFrequencyMHz;
- char pcOffsetStr[LOC_MAX_PARAM_STRING];
- uint32_t numberOfRows = 0;
- uint32_t numberOfColumns = 0;
- uint32_t numberOfRowsSGC = 0;
- uint32_t numberOfColumnsSGC = 0;
- gnssAntennaInfo.phaseCenterVariationCorrectionMillimeters.clear();
- gnssAntennaInfo.phaseCenterVariationCorrectionUncertaintyMillimeters.clear();
- gnssAntennaInfo.signalGainCorrectionDbi.clear();
- gnssAntennaInfo.signalGainCorrectionUncertaintyDbi.clear();
- string s1 = "CARRIER_FREQUENCY_";
- s1 += to_string(i);
- string s2 = "PC_OFFSET_";
- s2 += to_string(i);
- string s3 = "NUMBER_OF_ROWS_";
- s3 += to_string(i);
- string s4 = "NUMBER_OF_COLUMNS_";
- s4 += to_string(i);
- string s5 = "NUMBER_OF_ROWS_SGC_";
- s5 += to_string(i);
- string s6 = "NUMBER_OF_COLUMNS_SGC_";
- s6 += to_string(i);
- gnssAntennaInfo.size = sizeof(gnssAntennaInfo);
- loc_param_s_type ant_cf_table[] =
- {
- { s1.c_str(), &carrierFrequencyMHz, NULL, 'f' },
- { s2.c_str(), &pcOffsetStr, NULL, 's' },
- { s3.c_str(), &numberOfRows, NULL, 'n' },
- { s4.c_str(), &numberOfColumns, NULL, 'n' },
- { s5.c_str(), &numberOfRowsSGC, NULL, 'n' },
- { s6.c_str(), &numberOfColumnsSGC, NULL, 'n' },
- };
- UTIL_READ_CONF(LOC_PATH_ANT_CORR, ant_cf_table);
- if (0 == numberOfRowsSGC) {
- numberOfRowsSGC = numberOfRows;
- }
- if (0 == numberOfColumnsSGC) {
- numberOfColumnsSGC = numberOfColumns;
- }
- gnssAntennaInfo.carrierFrequencyMHz = carrierFrequencyMHz;
- // now parse pcOffsetStr to get each entry
- std::vector<double> pcOffset;
- pcOffset = parseDoublesString(pcOffsetStr);
- gnssAntennaInfo.phaseCenterOffsetCoordinateMillimeters.size =
- sizeof(gnssAntennaInfo.phaseCenterOffsetCoordinateMillimeters);
- gnssAntennaInfo.phaseCenterOffsetCoordinateMillimeters.x = pcOffset[0];
- gnssAntennaInfo.phaseCenterOffsetCoordinateMillimeters.xUncertainty = pcOffset[1];
- gnssAntennaInfo.phaseCenterOffsetCoordinateMillimeters.y = pcOffset[2];
- gnssAntennaInfo.phaseCenterOffsetCoordinateMillimeters.yUncertainty = pcOffset[3];
- gnssAntennaInfo.phaseCenterOffsetCoordinateMillimeters.z = pcOffset[4];
- gnssAntennaInfo.phaseCenterOffsetCoordinateMillimeters.zUncertainty = pcOffset[5];
- uint16_t array_size = MAX_TEXT_WIDTH + MAX_COLUMN_WIDTH*numberOfColumns;
- uint16_t array_size_SGC = MAX_TEXT_WIDTH + MAX_COLUMN_WIDTH*numberOfColumnsSGC;
- for (uint32_t j = 0; j < numberOfRows; j++) {
- char pcVarCorrStr[array_size];
- char pcVarCorrUncStr[array_size];
- string s1 = "PC_VARIATION_CORRECTION_" + to_string(i) + "_ROW_";
- s1 += to_string(j);
- string s2 = "PC_VARIATION_CORRECTION_UNC_" + to_string(i) + "_ROW_";
- s2 += to_string(j);
- loc_param_s_type ant_row_table[] =
- {
- { s1.c_str(), &pcVarCorrStr, NULL, 's' },
- { s2.c_str(), &pcVarCorrUncStr, NULL, 's' },
- };
- UTIL_READ_CONF_LONG(LOC_PATH_ANT_CORR, ant_row_table, array_size);
- gnssAntennaInfo.phaseCenterVariationCorrectionMillimeters.push_back(
- parseDoublesString(pcVarCorrStr));
- gnssAntennaInfo.phaseCenterVariationCorrectionUncertaintyMillimeters.push_back(
- parseDoublesString(pcVarCorrUncStr));
- }
- for (uint32_t j = 0; j < numberOfRowsSGC; j++) {
- char sigGainCorrStr[array_size_SGC];
- char sigGainCorrUncStr[array_size_SGC];
- string s3 = "SIGNAL_GAIN_CORRECTION_" + to_string(i) + "_ROW_";
- s3 += to_string(j);
- string s4 = "SIGNAL_GAIN_CORRECTION_UNC_" + to_string(i) + "_ROW_";
- s4 += to_string(j);
- loc_param_s_type ant_row_table[] =
- {
- { s3.c_str(), &sigGainCorrStr, NULL, 's' },
- { s4.c_str(), &sigGainCorrUncStr, NULL, 's' },
- };
- UTIL_READ_CONF_LONG(LOC_PATH_ANT_CORR, ant_row_table, array_size_SGC);
- gnssAntennaInfo.signalGainCorrectionDbi.push_back(
- parseDoublesString(sigGainCorrStr));
- gnssAntennaInfo.signalGainCorrectionUncertaintyDbi.push_back(
- parseDoublesString(sigGainCorrUncStr));
- }
- gnssAntennaInformations.push_back(std::move(gnssAntennaInfo));
- }
- if (antennaInfoVectorSize > 0) {
- antennaInfoCallback(gnssAntennaInformations);
- }
- }
- /* ==== DGnss Usable Reporter ========================================================= */
- void GnssAdapter::initCDFWServiceCommand() {
- struct MsgInitCDFWService : public LocMsg {
- GnssAdapter* mAdapter;
- inline MsgInitCDFWService(GnssAdapter* adapter) :
- LocMsg(),
- mAdapter(adapter) {}
- inline virtual void proc() const {
- mAdapter->initCDFWService();
- }
- };
- sendMsg(new MsgInitCDFWService(this));
- }
- /* ======== UTILITIES ================================================================= */
- void GnssAdapter::initCDFWService()
- {
- LOC_LOGd("mCdfwInterface %p", mCdfwInterface);
- if (nullptr == mCdfwInterface) {
- void* libHandle = nullptr;
- const char* libName = "libcdfw.so";
- libHandle = nullptr;
- getCdfwInterface getter = (getCdfwInterface)dlGetSymFromLib(libHandle,
- libName, "getQCdfwInterface");
- if (nullptr == getter) {
- LOC_LOGe("dlGetSymFromLib getQCdfwInterface failed");
- } else {
- mCdfwInterface = getter();
- }
- if (nullptr != mCdfwInterface) {
- QDgnssSessionActiveCb qDgnssSessionActiveCb = [this] (bool sessionActive) {
- mDGnssNeedReport = sessionActive;
- };
- mCdfwInterface->startDgnssApiService(*mMsgTask);
- mQDgnssListenerHDL = mCdfwInterface->createUsableReporter(qDgnssSessionActiveCb);
- }
- }
- //Read Ntrip params form gps.conf on automobile PLs
- #ifdef USE_GLIB
- readPPENtripConfig();
- #endif
- }
- /*==== DGnss Ntrip Source ==========================================================*/
- void GnssAdapter::enablePPENtripStreamCommand(const GnssNtripConnectionParams& params,
- bool enableRTKEngine) {
- (void)enableRTKEngine; //future parameter, not used
- if (0 == params.size || params.hostNameOrIp.empty() || params.mountPoint.empty() ||
- params.username.empty() || params.password.empty()) {
- LOC_LOGe("Ntrip parameters are invalid!");
- return;
- }
- struct enableNtripMsg : public LocMsg {
- GnssAdapter& mAdapter;
- const GnssNtripConnectionParams mParams;
- inline enableNtripMsg(GnssAdapter& adapter,
- const GnssNtripConnectionParams& params) :
- LocMsg(),
- mAdapter(adapter),
- mParams(std::move(params)) {}
- inline virtual void proc() const {
- mAdapter.handleEnablePPENtrip(mParams);
- }
- };
- sendMsg(new enableNtripMsg(*this, params));
- }
- void GnssAdapter::handleEnablePPENtrip(const GnssNtripConnectionParams& params) {
- LOC_LOGd("%d %s %d %s %s %s %d mSendNmeaConsent %d",
- params.useSSL, params.hostNameOrIp.data(), params.port,
- params.mountPoint.data(), params.username.data(), params.password.data(),
- params.requiresNmeaLocation, mSendNmeaConsent);
- GnssNtripConnectionParams* pNtripParams = &(mStartDgnssNtripParams.ntripParams);
- if (pNtripParams->useSSL == params.useSSL &&
- 0 == pNtripParams->hostNameOrIp.compare(params.hostNameOrIp) &&
- pNtripParams->port == params.port &&
- 0 == pNtripParams->mountPoint.compare(params.mountPoint) &&
- 0 == pNtripParams->username.compare(params.username) &&
- 0 == pNtripParams->password.compare(params.password) &&
- pNtripParams->requiresNmeaLocation == params.requiresNmeaLocation &&
- mDgnssState & DGNSS_STATE_ENABLE_NTRIP_COMMAND) {
- LOC_LOGd("received same Ntrip param");
- return;
- }
- mDgnssState |= DGNSS_STATE_ENABLE_NTRIP_COMMAND;
- mDgnssState |= DGNSS_STATE_NO_NMEA_PENDING;
- mDgnssState &= ~DGNSS_STATE_NTRIP_SESSION_STARTED;
- mStartDgnssNtripParams.ntripParams = std::move(params);
- mStartDgnssNtripParams.nmea.clear();
- if (mSendNmeaConsent && pNtripParams->requiresNmeaLocation) {
- mDgnssState &= ~DGNSS_STATE_NO_NMEA_PENDING;
- mDgnssLastNmeaBootTimeMilli = 0;
- return;
- }
- checkUpdateDgnssNtrip(false);
- }
- void GnssAdapter::disablePPENtripStreamCommand() {
- struct disableNtripMsg : public LocMsg {
- GnssAdapter& mAdapter;
- inline disableNtripMsg(GnssAdapter& adapter) :
- LocMsg(),
- mAdapter(adapter) {}
- inline virtual void proc() const {
- mAdapter.handleDisablePPENtrip();
- }
- };
- sendMsg(new disableNtripMsg(*this));
- }
- void GnssAdapter::handleDisablePPENtrip() {
- mDgnssState &= ~DGNSS_STATE_ENABLE_NTRIP_COMMAND;
- mDgnssState |= DGNSS_STATE_NO_NMEA_PENDING;
- stopDgnssNtrip();
- }
- void GnssAdapter::checkUpdateDgnssNtrip(bool isLocationValid) {
- LOC_LOGd("isInSession %d mDgnssState 0x%x isLocationValid %d",
- isInSession(), mDgnssState, isLocationValid);
- if (isInSession()) {
- uint64_t curBootTime = getBootTimeMilliSec();
- if (mDgnssState == (DGNSS_STATE_ENABLE_NTRIP_COMMAND | DGNSS_STATE_NO_NMEA_PENDING)) {
- mDgnssState |= DGNSS_STATE_NTRIP_SESSION_STARTED;
- mXtraObserver.startDgnssSource(mStartDgnssNtripParams);
- if (isDgnssNmeaRequired()) {
- mDgnssLastNmeaBootTimeMilli = curBootTime;
- }
- } else if ((mDgnssState & DGNSS_STATE_NTRIP_SESSION_STARTED) && isLocationValid &&
- isDgnssNmeaRequired() &&
- curBootTime - mDgnssLastNmeaBootTimeMilli > DGNSS_RANGE_UPDATE_TIME_10MIN_IN_MILLI ) {
- mXtraObserver.updateNmeaToDgnssServer(mStartDgnssNtripParams.nmea);
- mDgnssLastNmeaBootTimeMilli = curBootTime;
- }
- }
- }
- void GnssAdapter::stopDgnssNtrip() {
- LOC_LOGd("isInSession %d mDgnssState 0x%x", isInSession(), mDgnssState);
- mStartDgnssNtripParams.nmea.clear();
- if (mDgnssState & DGNSS_STATE_NTRIP_SESSION_STARTED) {
- mDgnssState &= ~DGNSS_STATE_NTRIP_SESSION_STARTED;
- mXtraObserver.stopDgnssSource();
- }
- }
- void GnssAdapter::reportGGAToNtrip(const char* nmea) {
- #define POS_OF_GGA (3) //start position of "GGA"
- #define COMMAS_BEFORE_VALID (6) //"$GPGGA,,,,,,0,,,,,,,,*hh"
- if (!isDgnssNmeaRequired()) {
- return;
- }
- if (nullptr == nmea || 0 == strlen(nmea)) {
- return;
- }
- string nmeaString(nmea);
- size_t foundPos = nmeaString.find("GGA");
- size_t foundNth = 0;
- string GGAString;
- if (foundPos != string::npos && foundPos >= POS_OF_GGA) {
- size_t foundNextSentence = nmeaString.find("$", foundPos);
- if (foundNextSentence != string::npos) {
- /* remove other sentences after GGA */
- GGAString = nmeaString.substr(foundPos - POS_OF_GGA, foundNextSentence);
- } else {
- /* GGA is the last sentence */
- GGAString = nmeaString.substr(foundPos - POS_OF_GGA);
- }
- LOC_LOGd("GGAString %s", GGAString.c_str());
- foundPos = GGAString.find(",");
- while (foundPos != string::npos && foundNth < COMMAS_BEFORE_VALID) {
- foundPos++;
- foundNth++;
- foundPos = GGAString.find(",", foundPos);
- }
- if (COMMAS_BEFORE_VALID == foundNth && GGAString.at(foundPos-1) != '0') {
- mDgnssState |= DGNSS_STATE_NO_NMEA_PENDING;
- mStartDgnssNtripParams.nmea = std::move(GGAString);
- checkUpdateDgnssNtrip(true);
- }
- }
- return;
- }
- void GnssAdapter::readPPENtripConfig() {
- static char NtripParamsString[LOC_MAX_PARAM_STRING];
- if (mDgnssState & DGNSS_STATE_ENABLE_NTRIP_COMMAND) {
- return;
- }
- // A sample Ntrip_Params -> 199.106.116.10 5000 Avante_Ref CV2X 1234 0 0
- static loc_param_s_type gpsConfParamTable[] = {
- {"Ntrip_Params", &NtripParamsString, nullptr, 's'}
- };
- UTIL_READ_CONF(LOC_PATH_GPS_CONF, gpsConfParamTable);
- LOC_LOGd("Ntrip_Params=%s", NtripParamsString);
- if (0 == strlen(NtripParamsString)) {
- return;
- }
- // assign params to mStartDgnssNtripParams
- GnssNtripConnectionParams* pNtripParams = &(mStartDgnssNtripParams.ntripParams);
- string next(NtripParamsString);
- stringstream ss(next);
- #define GET_NEXT() getline(ss, next, ' '); \
- LOC_LOGd("%s", next.c_str());
- GET_NEXT();
- pNtripParams->hostNameOrIp = std::move(next);
- GET_NEXT();
- pNtripParams->port = std::stoi(next);
- GET_NEXT();
- pNtripParams->mountPoint = std::move(next);
- GET_NEXT();
- pNtripParams->username = std::move(next);
- GET_NEXT();
- pNtripParams->password = std::move(next);
- GET_NEXT();
- mSendNmeaConsent = true;
- GET_NEXT();
- pNtripParams->requiresNmeaLocation = next.compare("0") ? true : false;
- GET_NEXT();
- pNtripParams->useSSL = next.compare("0") ? true : false;
- LOC_LOGd("%d %s %d %s %s %s %d",
- pNtripParams->useSSL, pNtripParams->hostNameOrIp.data(), pNtripParams->port,
- pNtripParams->mountPoint.data(), pNtripParams->username.data(),
- pNtripParams->password.data(), pNtripParams->requiresNmeaLocation);
- /* set up state*/
- mDgnssState |= DGNSS_STATE_ENABLE_NTRIP_COMMAND;
- mDgnssState |= DGNSS_STATE_NO_NMEA_PENDING;
- mDgnssState &= ~DGNSS_STATE_NTRIP_SESSION_STARTED;
- mStartDgnssNtripParams.nmea.clear();
- if (pNtripParams->requiresNmeaLocation) {
- mDgnssState &= ~DGNSS_STATE_NO_NMEA_PENDING;
- }
- }
|