12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562 |
- /* 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.
- *
- */
- /*
- Changes from Qualcomm Innovation Center are provided under the following license:
- Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
- Redistribution and use in source and binary forms, with or without
- modification, are permitted (subject to the limitations in the
- disclaimer below) 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 Qualcomm Innovation Center, Inc. nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
- NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
- GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
- HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
- WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- IN NO EVENT SHALL THE COPYRIGHT HOLDER 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"
- #if defined (FEATURE_AUTOMOTIVE) || defined (FEATURE_NHZ_ENABLED)
- #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),
- mPowerIndicationCb(nullptr),
- mGnssPowerStatisticsInit(false),
- mBootReferenceEnergy(0),
- mPowerElapsedRealTimeCal(30000000),
- mIsMeasCorrInterfaceOpen(false),
- mQDgnssListenerHDL(nullptr),
- mCdfwInterface(nullptr),
- mDGnssNeedReport(false),
- mDGnssDataUsage(false),
- mOdcpiRequestCb(nullptr),
- mOdcpiStateMask(0),
- mCallbackPriority(OdcpiPrioritytype::ODCPI_HANDLER_PRIORITY_LOW),
- mOdcpiTimer(this),
- mOdcpiRequest(),
- mAddressRequestCb(nullptr),
- mLastDeleteAidingDataTime(0),
- mSystemStatus(SystemStatus::getInstance(mMsgTask)),
- mServerUrl(":"),
- mXtraObserver(mSystemStatus->getOsObserver(), mMsgTask),
- mLocSystemInfo{},
- mSystemPowerState(POWER_STATE_UNKNOWN),
- mBlockCPIInfo{},
- mPowerOn(false),
- mDreIntEnabled(false),
- mPositionElapsedRealTimeCal(30000000),
- mNativeAgpsHandler(mSystemStatus->getOsObserver(), *this),
- mGnssEnergyConsumedCb(nullptr),
- mPowerStateCb(nullptr),
- mSendNmeaConsent(false),
- mDgnssState(0),
- mDgnssLastNmeaBootTimeMilli(0)
- {
- 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, 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__);
- if (!ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_ENGINE_DEBUG_DATA)) {
- // 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;
- }
- }
- }
- }
- } else {
- // Modem does not provide noraml NMEA if ENGINE_DEBUG_DATA feature is available
- // ensuring AP to nmea generation in this case
- ContextBase::mGps_conf.NMEA_PROVIDER = NMEA_PROVIDER_AP;
- updateEvtMask(LOC_API_ADAPTER_BIT_ENGINE_DEBUG_DATA_REPORT, LOC_REGISTRATION_MASK_ENABLED);
- }
- 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 (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_ENGINE_DEBUG_DATA)) {
- mask |= LOC_API_ADAPTER_BIT_ENGINE_DEBUG_DATA_REPORT;
- } else {
- 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);
- // robust location to be disabled on bootup by default
- if (mLocConfigInfo.robustLocationConfigInfo.isValid == false) {
- mLocConfigInfo.robustLocationConfigInfo.isValid = true;
- mLocConfigInfo.robustLocationConfigInfo.enable = false;
- mLocConfigInfo.robustLocationConfigInfo.enableFor911 = false;
- }
- 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),
- mIds(nullptr),
- mCount(count) {
- 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 |
- LOC_API_ADAPTER_BIT_FEATURE_STATUS_UPDATE;
- 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 (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_ENGINE_DEBUG_DATA)) {
- mask |= LOC_API_ADAPTER_BIT_ENGINE_DEBUG_DATA_REPORT;
- } else {
- 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;
- if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_ENGINE_DEBUG_DATA)) {
- mask |= LOC_API_ADAPTER_BIT_ENGINE_DEBUG_DATA_REPORT;
- } else {
- 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->stopTimeBasedTracking(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;
- }
- if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_ENGINE_DEBUG_DATA)) {
- mask |= LOCATION_CAPABILITIES_ENGINE_DEBUG_DATA_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;
- }
- 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());
- mXtraObserver.notifySessionStart();
- }
- 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;
- }
- //if not set or there is a new higher qualityLevelAccepted, then set the higher one
- if (it->second.qualityLevelAccepted > multiplexedOptions.qualityLevelAccepted) {
- multiplexedOptions.qualityLevelAccepted = it->second.qualityLevelAccepted;
- }
- }
- 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 session we are starting has higher qualityLevelAccepted then next highest
- if (options.qualityLevelAccepted > multiplexedOptions.qualityLevelAccepted) {
- multiplexedOptions.qualityLevelAccepted = options.qualityLevelAccepted;
- 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();
- // client is nullptr when we want to stop any tracking session,
- // e.g. when suspend.
- mLocApi->stopTimeBasedTracking((nullptr == client) ? nullptr :
- 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 && LOC_SESS_SUCCESS == status && !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::reportEngDebugDataInfo(const GnssEngineDebugDataInfo& gnssEngineDebugDataInfo) {
- if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_ENGINE_DEBUG_DATA)) {
- LOC_LOGd("Recived Engine debug data info");
- SystemStatus* s = getSystemStatus();
- if (nullptr != s) {
- s->setEngineDebugDataInfo(gnssEngineDebugDataInfo);
- }
- }
- }
- void GnssAdapter::reportEngDebugDataInfoEvent(GnssEngineDebugDataInfo& gnssEngineDebugDataInfo) {
- struct MsgReportEngDebugDataInfo : public LocMsg {
- GnssAdapter& mAdapter;
- const GnssEngineDebugDataInfo mGnssEngineDebugDataInfo;
- inline MsgReportEngDebugDataInfo(GnssAdapter& adapter, GnssEngineDebugDataInfo&
- gnssEngineDebugDataInfo) : mAdapter(adapter),
- mGnssEngineDebugDataInfo(gnssEngineDebugDataInfo) {}
- inline virtual void proc() const {
- mAdapter.reportEngDebugDataInfo(mGnssEngineDebugDataInfo);
- }
- };
- sendMsg(new MsgReportEngDebugDataInfo(*this, gnssEngineDebugDataInfo));
- }
- void
- GnssAdapter::reportLatencyInfoEvent(const GnssLatencyInfo& gnssLatencyInfo)
- {
- struct MsgReportLatencyInfo : public LocMsg {
- GnssAdapter& mAdapter;
- GnssLatencyInfo mGnssLatencyInfo;
- inline MsgReportLatencyInfo(GnssAdapter& adapter,
- const GnssLatencyInfo& gnssLatencyInfo) :
- mAdapter(adapter),
- mGnssLatencyInfo(gnssLatencyInfo) {}
- 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 = elapsedRealtime();
- 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(), mAdapter(adapter), mPdnType(pdnType),
- mAgpsManager(agpsManager), mAgpsType(agpsType),
- mApnName(apnName), mBearerType(bearerType) {}
- 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(), mAdapter(adapter), mAgpsManager(agpsManager), mAgpsType(agpsType),
- mApnName(new char[apnLen + 1]), mBearerType(bearerType) {
- 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, false);
- 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, false);
- 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 / 100.0);
- 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 / 100.0);
- 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 / 100.0);
- 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 / 100.0);
- 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, false);
- 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 / 100.0);
- data.jammerInd[GNSS_LOC_SIGNAL_TYPE_GPS_L1CA] =
- ((double)reports.mRfAndParams.back().mJammerGps / 100.0);
- 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 / 100.0);
- data.jammerInd[GNSS_LOC_SIGNAL_TYPE_QZSS_L1CA] =
- ((double)reports.mRfAndParams.back().mJammerGps / 100.0);
- 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 / 100.0);
- data.jammerInd[GNSS_LOC_SIGNAL_TYPE_SBAS_L1_CA] =
- ((double)reports.mRfAndParams.back().mJammerGps / 100.0);
- }
- 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 / 100.0);
- data.jammerInd[GNSS_LOC_SIGNAL_TYPE_GLONASS_G1] =
- ((double)reports.mRfAndParams.back().mJammerGlo / 100.0);
- }
- 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 / 100.0);
- data.jammerInd[GNSS_LOC_SIGNAL_TYPE_BEIDOU_B1_I] =
- ((double)reports.mRfAndParams.back().mJammerBds / 100.0);
- }
- 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 / 100.0);
- data.jammerInd[GNSS_LOC_SIGNAL_TYPE_GALILEO_E1_C] =
- ((double)reports.mRfAndParams.back().mJammerGal / 100.0);
- }
- }
- }
- }
- /* 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);
- }
- };
- 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;
- }
- }
|