• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
2  *
3  * Redistribution and use in source and binary forms, with or without
4  * modification, are permitted provided that the following conditions are
5  * met:
6  *     * Redistributions of source code must retain the above copyright
7  *       notice, this list of conditions and the following disclaimer.
8  *     * Redistributions in binary form must reproduce the above
9  *       copyright notice, this list of conditions and the following
10  *       disclaimer in the documentation and/or other materials provided
11  *       with the distribution.
12  *     * Neither the name of The Linux Foundation, nor the names of its
13  *       contributors may be used to endorse or promote products derived
14  *       from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  */
29 
30 #define LOG_TAG "LocSvc_Agps"
31 
32 #include <Agps.h>
33 #include <platform_lib_includes.h>
34 #include <ContextBase.h>
35 #include <loc_timer.h>
36 
37 /* --------------------------------------------------------------------
38  *   AGPS State Machine Methods
39  * -------------------------------------------------------------------*/
processAgpsEvent(AgpsEvent event)40 void AgpsStateMachine::processAgpsEvent(AgpsEvent event){
41 
42     LOC_LOGD("processAgpsEvent(): SM %p, Event %d, State %d",
43                this, event, mState);
44 
45     switch (event){
46 
47         case AGPS_EVENT_SUBSCRIBE:
48             processAgpsEventSubscribe();
49             break;
50 
51         case AGPS_EVENT_UNSUBSCRIBE:
52             processAgpsEventUnsubscribe();
53             break;
54 
55         case AGPS_EVENT_GRANTED:
56             processAgpsEventGranted();
57             break;
58 
59         case AGPS_EVENT_RELEASED:
60             processAgpsEventReleased();
61             break;
62 
63         case AGPS_EVENT_DENIED:
64             processAgpsEventDenied();
65             break;
66 
67         default:
68             LOC_LOGE("Invalid Loc Agps Event");
69     }
70 }
71 
processAgpsEventSubscribe()72 void AgpsStateMachine::processAgpsEventSubscribe(){
73 
74     switch (mState){
75 
76         case AGPS_STATE_RELEASED:
77             /* Add subscriber to list
78              * No notifications until we get RSRC_GRANTED */
79             addSubscriber(mCurrentSubscriber);
80 
81             /* Send data request
82              * The if condition below is added so that if the data call setup
83              * fails for DS State Machine, we want to retry in released state.
84              * for Agps State Machine, sendRsrcRequest() will always return
85              * success. */
86             if(requestOrReleaseDataConn(true) == 0){
87                 // If data request successful, move to pending state
88                 transitionState(AGPS_STATE_PENDING);
89             }
90             break;
91 
92         case AGPS_STATE_PENDING:
93             /* Already requested for data connection,
94              * do nothing until we get RSRC_GRANTED event;
95              * Just add this subscriber to the list, for notifications */
96             addSubscriber(mCurrentSubscriber);
97             break;
98 
99         case AGPS_STATE_ACQUIRED:
100             /* We already have the data connection setup,
101              * Notify current subscriber with GRANTED event,
102              * And add it to the subscriber list for further notifications. */
103             notifyEventToSubscriber(AGPS_EVENT_GRANTED, mCurrentSubscriber, false);
104             addSubscriber(mCurrentSubscriber);
105             break;
106 
107         case AGPS_STATE_RELEASING:
108             addSubscriber(mCurrentSubscriber);
109             break;
110 
111         default:
112             LOC_LOGE("Invalid state: %d", mState);
113     }
114 }
115 
processAgpsEventUnsubscribe()116 void AgpsStateMachine::processAgpsEventUnsubscribe(){
117 
118     switch (mState){
119 
120         case AGPS_STATE_RELEASED:
121             notifyEventToSubscriber(
122                     AGPS_EVENT_UNSUBSCRIBE, mCurrentSubscriber, false);
123             break;
124 
125         case AGPS_STATE_PENDING:
126         case AGPS_STATE_ACQUIRED:
127             /* If the subscriber wishes to wait for connection close,
128              * before being removed from list, move to inactive state
129              * and notify */
130             if(mCurrentSubscriber->mWaitForCloseComplete){
131                 mCurrentSubscriber->mIsInactive = true;
132                 notifyEventToSubscriber(
133                         AGPS_EVENT_UNSUBSCRIBE, mCurrentSubscriber, false);
134             }
135             else{
136                 /* Notify only current subscriber and then delete it from
137                  * subscriberList */
138                 notifyEventToSubscriber(
139                         AGPS_EVENT_UNSUBSCRIBE, mCurrentSubscriber, true);
140             }
141 
142             /* If no subscribers in list, release data connection */
143             if(mSubscriberList.empty()){
144                 transitionState(AGPS_STATE_RELEASED);
145                 requestOrReleaseDataConn(false);
146             }
147             /* Some subscribers in list, but all inactive;
148              * Release data connection */
149             else if(!anyActiveSubscribers()){
150                 transitionState(AGPS_STATE_RELEASING);
151                 requestOrReleaseDataConn(false);
152             }
153             break;
154 
155         case AGPS_STATE_RELEASING:
156             /* If the subscriber wishes to wait for connection close,
157              * before being removed from list, move to inactive state
158              * and notify */
159             if(mCurrentSubscriber->mWaitForCloseComplete){
160                 mCurrentSubscriber->mIsInactive = true;
161                 notifyEventToSubscriber(
162                         AGPS_EVENT_UNSUBSCRIBE, mCurrentSubscriber, false);
163             }
164             else{
165                 /* Notify only current subscriber and then delete it from
166                  * subscriberList */
167                 notifyEventToSubscriber(
168                         AGPS_EVENT_UNSUBSCRIBE, mCurrentSubscriber, true);
169             }
170 
171             /* If no subscribers in list, just move the state.
172              * Request for releasing data connection should already have been
173              * sent */
174             if(mSubscriberList.empty()){
175                 transitionState(AGPS_STATE_RELEASED);
176             }
177             break;
178 
179         default:
180             LOC_LOGE("Invalid state: %d", mState);
181     }
182 }
183 
processAgpsEventGranted()184 void AgpsStateMachine::processAgpsEventGranted(){
185 
186     switch (mState){
187 
188         case AGPS_STATE_RELEASED:
189         case AGPS_STATE_ACQUIRED:
190         case AGPS_STATE_RELEASING:
191             LOC_LOGE("Unexpected event GRANTED in state %d", mState);
192             break;
193 
194         case AGPS_STATE_PENDING:
195             // Move to acquired state
196             transitionState(AGPS_STATE_ACQUIRED);
197             notifyAllSubscribers(
198                     AGPS_EVENT_GRANTED, false,
199                     AGPS_NOTIFICATION_TYPE_FOR_ACTIVE_SUBSCRIBERS);
200             break;
201 
202         default:
203             LOC_LOGE("Invalid state: %d", mState);
204     }
205 }
206 
processAgpsEventReleased()207 void AgpsStateMachine::processAgpsEventReleased(){
208 
209     switch (mState){
210 
211         case AGPS_STATE_RELEASED:
212             LOC_LOGE("Unexpected event RELEASED in state %d", mState);
213             break;
214 
215         case AGPS_STATE_ACQUIRED:
216             /* Force release received */
217             LOC_LOGW("Force RELEASED event in ACQUIRED state");
218             transitionState(AGPS_STATE_RELEASED);
219             notifyAllSubscribers(
220                     AGPS_EVENT_RELEASED, true,
221                     AGPS_NOTIFICATION_TYPE_FOR_ALL_SUBSCRIBERS);
222             break;
223 
224         case AGPS_STATE_RELEASING:
225             /* Notify all inactive subscribers about the event */
226             notifyAllSubscribers(
227                     AGPS_EVENT_RELEASED, true,
228                     AGPS_NOTIFICATION_TYPE_FOR_INACTIVE_SUBSCRIBERS);
229 
230             /* If we have active subscribers now, they must be waiting for
231              * data conn setup */
232             if(anyActiveSubscribers()){
233                 transitionState(AGPS_STATE_PENDING);
234                 requestOrReleaseDataConn(true);
235             }
236             /* No active subscribers, move to released state */
237             else{
238                 transitionState(AGPS_STATE_RELEASED);
239             }
240             break;
241 
242         case AGPS_STATE_PENDING:
243             /* NOOP */
244             break;
245 
246         default:
247             LOC_LOGE("Invalid state: %d", mState);
248     }
249 }
250 
processAgpsEventDenied()251 void AgpsStateMachine::processAgpsEventDenied(){
252 
253     switch (mState){
254 
255         case AGPS_STATE_RELEASED:
256             LOC_LOGE("Unexpected event DENIED in state %d", mState);
257             break;
258 
259         case AGPS_STATE_ACQUIRED:
260             /* NOOP */
261             break;
262 
263         case AGPS_STATE_RELEASING:
264             /* Notify all inactive subscribers about the event */
265             notifyAllSubscribers(
266                     AGPS_EVENT_RELEASED, true,
267                     AGPS_NOTIFICATION_TYPE_FOR_INACTIVE_SUBSCRIBERS);
268 
269             /* If we have active subscribers now, they must be waiting for
270              * data conn setup */
271             if(anyActiveSubscribers()){
272                 transitionState(AGPS_STATE_PENDING);
273                 requestOrReleaseDataConn(true);
274             }
275             /* No active subscribers, move to released state */
276             else{
277                 transitionState(AGPS_STATE_RELEASED);
278             }
279             break;
280 
281         case AGPS_STATE_PENDING:
282             transitionState(AGPS_STATE_RELEASED);
283             notifyAllSubscribers(
284                     AGPS_EVENT_DENIED, true,
285                     AGPS_NOTIFICATION_TYPE_FOR_ALL_SUBSCRIBERS);
286             break;
287 
288         default:
289             LOC_LOGE("Invalid state: %d", mState);
290     }
291 }
292 
293 /* Request or Release data connection
294  * bool request :
295  *      true  = Request data connection
296  *      false = Release data connection */
requestOrReleaseDataConn(bool request)297 int AgpsStateMachine::requestOrReleaseDataConn(bool request){
298 
299     AgpsFrameworkInterface::AGnssStatusIpV4 nifRequest;
300     memset(&nifRequest, 0, sizeof(nifRequest));
301 
302     nifRequest.type = (AgpsFrameworkInterface::AGnssType)mAgpsType;
303 
304     if(request){
305         LOC_LOGD("AGPS Data Conn Request");
306         nifRequest.status = (AgpsFrameworkInterface::AGnssStatusValue)
307                                 LOC_GPS_REQUEST_AGPS_DATA_CONN;
308     }
309     else{
310         LOC_LOGD("AGPS Data Conn Release");
311         nifRequest.status = (AgpsFrameworkInterface::AGnssStatusValue)
312                                 LOC_GPS_RELEASE_AGPS_DATA_CONN;
313     }
314 
315     mAgpsManager->mFrameworkStatusV4Cb(nifRequest);
316     return 0;
317 }
318 
notifyAllSubscribers(AgpsEvent event,bool deleteSubscriberPostNotify,AgpsNotificationType notificationType)319 void AgpsStateMachine::notifyAllSubscribers(
320         AgpsEvent event, bool deleteSubscriberPostNotify,
321         AgpsNotificationType notificationType){
322 
323     LOC_LOGD("notifyAllSubscribers(): "
324             "SM %p, Event %d Delete %d Notification Type %d",
325             this, event, deleteSubscriberPostNotify, notificationType);
326 
327     std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin();
328     while ( it != mSubscriberList.end() ){
329 
330         AgpsSubscriber* subscriber = *it;
331 
332         if(notificationType == AGPS_NOTIFICATION_TYPE_FOR_ALL_SUBSCRIBERS ||
333                 (notificationType == AGPS_NOTIFICATION_TYPE_FOR_INACTIVE_SUBSCRIBERS &&
334                         subscriber->mIsInactive) ||
335                 (notificationType == AGPS_NOTIFICATION_TYPE_FOR_ACTIVE_SUBSCRIBERS &&
336                         !subscriber->mIsInactive)) {
337 
338             /* Deleting via this call would require another traversal
339              * through subscriber list, inefficient; hence pass in false*/
340             notifyEventToSubscriber(event, subscriber, false);
341 
342             if(deleteSubscriberPostNotify){
343                 it = mSubscriberList.erase(it);
344                 delete subscriber;
345             } else{
346                 it++;
347             }
348         } else{
349             it++;
350         }
351     }
352 }
353 
notifyEventToSubscriber(AgpsEvent event,AgpsSubscriber * subscriberToNotify,bool deleteSubscriberPostNotify)354 void AgpsStateMachine::notifyEventToSubscriber(
355         AgpsEvent event, AgpsSubscriber* subscriberToNotify,
356         bool deleteSubscriberPostNotify) {
357 
358     LOC_LOGD("notifyEventToSubscriber(): "
359             "SM %p, Event %d Subscriber %p Delete %d",
360             this, event, subscriberToNotify, deleteSubscriberPostNotify);
361 
362     switch (event){
363 
364         case AGPS_EVENT_GRANTED:
365             mAgpsManager->mAtlOpenStatusCb(
366                     subscriberToNotify->mConnHandle, 1, getAPN(),
367                     getBearer(), mAgpsType);
368             break;
369 
370         case AGPS_EVENT_DENIED:
371             mAgpsManager->mAtlOpenStatusCb(
372                     subscriberToNotify->mConnHandle, 0, getAPN(),
373                     getBearer(), mAgpsType);
374             break;
375 
376         case AGPS_EVENT_UNSUBSCRIBE:
377         case AGPS_EVENT_RELEASED:
378             mAgpsManager->mAtlCloseStatusCb(subscriberToNotify->mConnHandle, 1);
379             break;
380 
381         default:
382             LOC_LOGE("Invalid event %d", event);
383     }
384 
385     /* Search this subscriber in list and delete */
386     if (deleteSubscriberPostNotify) {
387         deleteSubscriber(subscriberToNotify);
388     }
389 }
390 
transitionState(AgpsState newState)391 void AgpsStateMachine::transitionState(AgpsState newState){
392 
393     LOC_LOGD("transitionState(): SM %p, old %d, new %d",
394                this, mState, newState);
395 
396     mState = newState;
397 
398     // notify state transitions to all subscribers ?
399 }
400 
addSubscriber(AgpsSubscriber * subscriberToAdd)401 void AgpsStateMachine::addSubscriber(AgpsSubscriber* subscriberToAdd){
402 
403     LOC_LOGD("addSubscriber(): SM %p, Subscriber %p",
404                this, subscriberToAdd);
405 
406     // Check if subscriber is already present in the current list
407     // If not, then add
408     std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin();
409     for(; it != mSubscriberList.end(); it++){
410         AgpsSubscriber* subscriber = *it;
411         if(subscriber->equals(subscriberToAdd)){
412             LOC_LOGE("Subscriber already in list");
413             return;
414         }
415     }
416 
417     AgpsSubscriber* cloned = subscriberToAdd->clone();
418     LOC_LOGD("addSubscriber(): cloned subscriber: %p", cloned);
419     mSubscriberList.push_back(cloned);
420 }
421 
deleteSubscriber(AgpsSubscriber * subscriberToDelete)422 void AgpsStateMachine::deleteSubscriber(AgpsSubscriber* subscriberToDelete){
423 
424     LOC_LOGD("deleteSubscriber(): SM %p, Subscriber %p",
425                this, subscriberToDelete);
426 
427     std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin();
428     while ( it != mSubscriberList.end() ) {
429 
430         AgpsSubscriber* subscriber = *it;
431         if(subscriber && subscriber->equals(subscriberToDelete)){
432 
433             it = mSubscriberList.erase(it);
434             delete subscriber;
435         }else{
436             it++;
437         }
438     }
439 }
440 
anyActiveSubscribers()441 bool AgpsStateMachine::anyActiveSubscribers(){
442 
443     std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin();
444     for(; it != mSubscriberList.end(); it++){
445         AgpsSubscriber* subscriber = *it;
446         if(!subscriber->mIsInactive){
447             return true;
448         }
449     }
450     return false;
451 }
452 
setAPN(char * apn,unsigned int len)453 void AgpsStateMachine::setAPN(char* apn, unsigned int len){
454 
455     if (NULL != mAPN) {
456         delete mAPN;
457     }
458 
459     if(apn == NULL || len <= 0){
460         LOC_LOGD("Invalid apn len (%d) or null apn", len);
461         mAPN = NULL;
462         mAPNLen = 0;
463     }
464 
465     if (NULL != apn) {
466         mAPN = new char[len+1];
467         memcpy(mAPN, apn, len);
468         mAPN[len] = '\0';
469         mAPNLen = len;
470     }
471 }
472 
getSubscriber(int connHandle)473 AgpsSubscriber* AgpsStateMachine::getSubscriber(int connHandle){
474 
475     /* Go over the subscriber list */
476     std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin();
477     for(; it != mSubscriberList.end(); it++){
478         AgpsSubscriber* subscriber = *it;
479         if(subscriber->mConnHandle == connHandle){
480             return subscriber;
481         }
482     }
483 
484     /* Not found, return NULL */
485     return NULL;
486 }
487 
getFirstSubscriber(bool isInactive)488 AgpsSubscriber* AgpsStateMachine::getFirstSubscriber(bool isInactive){
489 
490     /* Go over the subscriber list */
491     std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin();
492     for(; it != mSubscriberList.end(); it++){
493         AgpsSubscriber* subscriber = *it;
494         if(subscriber->mIsInactive == isInactive){
495             return subscriber;
496         }
497     }
498 
499     /* Not found, return NULL */
500     return NULL;
501 }
502 
dropAllSubscribers()503 void AgpsStateMachine::dropAllSubscribers(){
504 
505     LOC_LOGD("dropAllSubscribers(): SM %p", this);
506 
507     /* Go over the subscriber list */
508     std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin();
509     while ( it != mSubscriberList.end() ){
510         AgpsSubscriber* subscriber = *it;
511         it = mSubscriberList.erase(it);
512         delete subscriber;
513     }
514 }
515 
516 /* --------------------------------------------------------------------
517  *   DS State Machine Methods
518  * -------------------------------------------------------------------*/
519 const int DSStateMachine::MAX_START_DATA_CALL_RETRIES = 4;
520 const int DSStateMachine::DATA_CALL_RETRY_DELAY_MSEC = 500;
521 
522 /* Overridden method
523  * DS SM needs to handle one scenario differently */
processAgpsEvent(AgpsEvent event)524 void DSStateMachine::processAgpsEvent(AgpsEvent event){
525 
526     LOC_LOGD("DSStateMachine::processAgpsEvent() %d", event);
527 
528     /* DS Client call setup APIs don't return failure/closure separately.
529      * Hence we receive RELEASED event in both cases.
530      * If we are in pending, we should consider RELEASED as DENIED */
531     if(event == AGPS_EVENT_RELEASED && mState == AGPS_STATE_PENDING){
532 
533         LOC_LOGD("Translating RELEASED to DENIED event");
534         event = AGPS_EVENT_DENIED;
535     }
536 
537     /* Redirect process to base class */
538     AgpsStateMachine::processAgpsEvent(event);
539 }
540 
541 /* Timer Callback
542  * For the retry timer started in case of DS Client call setup failure */
delay_callback(void * callbackData,int result)543 void delay_callback(void *callbackData, int result)
544 {
545     LOC_LOGD("delay_callback(): cbData %p", callbackData);
546 
547     (void)result;
548 
549     if(callbackData == NULL) {
550         LOC_LOGE("delay_callback(): NULL argument received !");
551         return;
552     }
553     DSStateMachine* dsStateMachine = (DSStateMachine *)callbackData;
554     dsStateMachine->retryCallback();
555 }
556 
557 /* Invoked from Timer Callback
558  * For the retry timer started in case of DS Client call setup failure */
retryCallback()559 void DSStateMachine :: retryCallback()
560 {
561     LOC_LOGD("DSStateMachine::retryCallback()");
562 
563     /* Request SUPL ES
564      * There must be at least one active subscriber in list */
565     AgpsSubscriber* subscriber = getFirstSubscriber(false);
566     if(subscriber == NULL) {
567 
568         LOC_LOGE("No active subscriber for DS Client call setup");
569         return;
570     }
571 
572     /* Send message to retry */
573     mAgpsManager->mSendMsgToAdapterQueueFn(
574             new AgpsMsgRequestATL(
575                     mAgpsManager, subscriber->mConnHandle,
576                     LOC_AGPS_TYPE_SUPL_ES));
577 }
578 
579 /* Overridden method
580  * Request or Release data connection
581  * bool request :
582  *      true  = Request data connection
583  *      false = Release data connection */
requestOrReleaseDataConn(bool request)584 int DSStateMachine::requestOrReleaseDataConn(bool request){
585 
586     LOC_LOGD("DSStateMachine::requestOrReleaseDataConn(): "
587              "request %d", request);
588 
589     /* Release data connection required ? */
590     if(!request && mAgpsManager->mDSClientStopDataCallFn){
591 
592         mAgpsManager->mDSClientStopDataCallFn();
593         LOC_LOGD("DS Client release data call request sent !");
594         return 0;
595     }
596 
597     /* Setup data connection request
598      * There must be at least one active subscriber in list */
599     AgpsSubscriber* subscriber = getFirstSubscriber(false);
600     if(subscriber == NULL) {
601 
602         LOC_LOGE("No active subscriber for DS Client call setup");
603         return -1;
604     }
605 
606     /* DS Client Fn registered ? */
607     if(!mAgpsManager->mDSClientOpenAndStartDataCallFn){
608 
609         LOC_LOGE("DS Client start fn not registered, fallback to SUPL ATL");
610         notifyEventToSubscriber(AGPS_EVENT_DENIED, subscriber, false);
611         return -1;
612     }
613 
614     /* Setup the call */
615     int ret = mAgpsManager->mDSClientOpenAndStartDataCallFn();
616 
617     /* Check if data call start failed */
618     switch (ret) {
619 
620         case LOC_API_ADAPTER_ERR_ENGINE_BUSY:
621             LOC_LOGE("DS Client open call failed, err: %d", ret);
622             mRetries++;
623             if(mRetries > MAX_START_DATA_CALL_RETRIES) {
624 
625                 LOC_LOGE("DS Client call retries exhausted, "
626                          "falling back to normal SUPL ATL");
627                 notifyEventToSubscriber(AGPS_EVENT_DENIED, subscriber, false);
628             }
629             /* Retry DS Client call setup after some delay */
630             else if(loc_timer_start(
631                         DATA_CALL_RETRY_DELAY_MSEC, delay_callback, this)) {
632                     LOC_LOGE("Error: Could not start delay thread\n");
633                     return -1;
634                 }
635             break;
636 
637         case LOC_API_ADAPTER_ERR_UNSUPPORTED:
638             LOC_LOGE("No emergency profile found. Fall back to normal SUPL ATL");
639             notifyEventToSubscriber(AGPS_EVENT_DENIED, subscriber, false);
640             break;
641 
642         case LOC_API_ADAPTER_ERR_SUCCESS:
643             LOC_LOGD("Request to start data call sent");
644             break;
645 
646         default:
647             LOC_LOGE("Unrecognized return value: %d", ret);
648     }
649 
650     return ret;
651 }
652 
notifyEventToSubscriber(AgpsEvent event,AgpsSubscriber * subscriberToNotify,bool deleteSubscriberPostNotify)653 void DSStateMachine::notifyEventToSubscriber(
654         AgpsEvent event, AgpsSubscriber* subscriberToNotify,
655         bool deleteSubscriberPostNotify) {
656 
657     LOC_LOGD("DSStateMachine::notifyEventToSubscriber(): "
658              "SM %p, Event %d Subscriber %p Delete %d",
659              this, event, subscriberToNotify, deleteSubscriberPostNotify);
660 
661     switch (event){
662 
663         case AGPS_EVENT_GRANTED:
664             mAgpsManager->mAtlOpenStatusCb(
665                     subscriberToNotify->mConnHandle, 1, NULL,
666                     AGPS_APN_BEARER_INVALID, LOC_AGPS_TYPE_SUPL_ES);
667             break;
668 
669         case AGPS_EVENT_DENIED:
670             /* Now try with regular SUPL
671              * We need to send request via message queue */
672             mRetries = 0;
673             mAgpsManager->mSendMsgToAdapterQueueFn(
674                     new AgpsMsgRequestATL(
675                             mAgpsManager, subscriberToNotify->mConnHandle,
676                             LOC_AGPS_TYPE_SUPL));
677             break;
678 
679         case AGPS_EVENT_UNSUBSCRIBE:
680             mAgpsManager->mAtlCloseStatusCb(subscriberToNotify->mConnHandle, 1);
681             break;
682 
683         case AGPS_EVENT_RELEASED:
684             mAgpsManager->mDSClientCloseDataCallFn();
685             mAgpsManager->mAtlCloseStatusCb(subscriberToNotify->mConnHandle, 1);
686             break;
687 
688         default:
689             LOC_LOGE("Invalid event %d", event);
690     }
691 
692     /* Search this subscriber in list and delete */
693     if (deleteSubscriberPostNotify) {
694         deleteSubscriber(subscriberToNotify);
695     }
696 }
697 
698 /* --------------------------------------------------------------------
699  *   Loc AGPS Manager Methods
700  * -------------------------------------------------------------------*/
701 
702 /* CREATE AGPS STATE MACHINES
703  * Must be invoked in Msg Handler context */
createAgpsStateMachines()704 void AgpsManager::createAgpsStateMachines() {
705 
706     LOC_LOGD("AgpsManager::createAgpsStateMachines");
707 
708     bool agpsCapable =
709             ((loc_core::ContextBase::mGps_conf.CAPABILITIES & LOC_GPS_CAPABILITY_MSA) ||
710                     (loc_core::ContextBase::mGps_conf.CAPABILITIES & LOC_GPS_CAPABILITY_MSB));
711 
712     if (NULL == mInternetNif) {
713         mInternetNif = new AgpsStateMachine(this, LOC_AGPS_TYPE_WWAN_ANY);
714         LOC_LOGD("Internet NIF: %p", mInternetNif);
715     }
716     if (agpsCapable) {
717         if (NULL == mAgnssNif) {
718             mAgnssNif = new AgpsStateMachine(this, LOC_AGPS_TYPE_SUPL);
719             LOC_LOGD("AGNSS NIF: %p", mAgnssNif);
720         }
721         if (NULL == mDsNif &&
722                 loc_core::ContextBase::mGps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL){
723 
724             if(!mDSClientInitFn){
725 
726                 LOC_LOGE("DS Client Init Fn not registered !");
727                 return;
728             }
729             if(mDSClientInitFn(false) != 0){
730 
731                 LOC_LOGE("Failed to init data service client");
732                 return;
733             }
734             mDsNif = new DSStateMachine(this);
735             LOC_LOGD("DS NIF: %p", mDsNif);
736         }
737     }
738 }
739 
getAgpsStateMachine(AGpsExtType agpsType)740 AgpsStateMachine* AgpsManager::getAgpsStateMachine(AGpsExtType agpsType) {
741 
742     LOC_LOGD("AgpsManager::getAgpsStateMachine(): agpsType %d", agpsType);
743 
744     switch (agpsType) {
745 
746         case LOC_AGPS_TYPE_INVALID:
747         case LOC_AGPS_TYPE_SUPL:
748             if(mAgnssNif == NULL){
749                 LOC_LOGE("NULL AGNSS NIF !");
750             }
751             return mAgnssNif;
752 
753         case LOC_AGPS_TYPE_SUPL_ES:
754             if (loc_core::ContextBase::mGps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL) {
755                 if (mDsNif == NULL) {
756                     createAgpsStateMachines();
757                 }
758                 return mDsNif;
759             } else {
760                 return mAgnssNif;
761             }
762 
763         default:
764             return mInternetNif;
765     }
766 
767     LOC_LOGE("No SM found !");
768     return NULL;
769 }
770 
requestATL(int connHandle,AGpsExtType agpsType)771 void AgpsManager::requestATL(int connHandle, AGpsExtType agpsType){
772 
773     LOC_LOGD("AgpsManager::requestATL(): connHandle %d, agpsType %d",
774                connHandle, agpsType);
775 
776     AgpsStateMachine* sm = getAgpsStateMachine(agpsType);
777 
778     if(sm == NULL){
779 
780         LOC_LOGE("No AGPS State Machine for agpsType: %d", agpsType);
781         mAtlOpenStatusCb(
782                 connHandle, 0, NULL, AGPS_APN_BEARER_INVALID, agpsType);
783         return;
784     }
785 
786     /* Invoke AGPS SM processing */
787     AgpsSubscriber subscriber(connHandle, false, false);
788     sm->setCurrentSubscriber(&subscriber);
789 
790     /* If DS State Machine, wait for close complete */
791     if(agpsType == LOC_AGPS_TYPE_SUPL_ES){
792         subscriber.mWaitForCloseComplete = true;
793     }
794 
795     /* Send subscriber event */
796     sm->processAgpsEvent(AGPS_EVENT_SUBSCRIBE);
797 }
798 
releaseATL(int connHandle)799 void AgpsManager::releaseATL(int connHandle){
800 
801     LOC_LOGD("AgpsManager::releaseATL(): connHandle %d", connHandle);
802 
803     /* First find the subscriber with specified handle.
804      * We need to search in all state machines. */
805     AgpsStateMachine* sm = NULL;
806     AgpsSubscriber* subscriber = NULL;
807 
808     if (mAgnssNif &&
809             (subscriber = mAgnssNif->getSubscriber(connHandle)) != NULL) {
810         sm = mAgnssNif;
811     }
812     else if (mInternetNif &&
813             (subscriber = mInternetNif->getSubscriber(connHandle)) != NULL) {
814         sm = mInternetNif;
815     }
816     else if (mDsNif &&
817             (subscriber = mDsNif->getSubscriber(connHandle)) != NULL) {
818         sm = mDsNif;
819     }
820 
821     if(sm == NULL){
822         LOC_LOGE("Subscriber with connHandle %d not found in any SM",
823                     connHandle);
824         mAtlCloseStatusCb(connHandle, 0);
825         return;
826     }
827 
828     /* Now send unsubscribe event */
829     sm->setCurrentSubscriber(subscriber);
830     sm->processAgpsEvent(AGPS_EVENT_UNSUBSCRIBE);
831 }
832 
reportDataCallOpened()833 void AgpsManager::reportDataCallOpened(){
834 
835     LOC_LOGD("AgpsManager::reportDataCallOpened");
836 
837     if (mDsNif) {
838         mDsNif->processAgpsEvent(AGPS_EVENT_GRANTED);
839     }
840 }
841 
reportDataCallClosed()842 void AgpsManager::reportDataCallClosed(){
843 
844     LOC_LOGD("AgpsManager::reportDataCallClosed");
845 
846     if (mDsNif) {
847         mDsNif->processAgpsEvent(AGPS_EVENT_RELEASED);
848     }
849 }
850 
reportAtlOpenSuccess(AGpsExtType agpsType,char * apnName,int apnLen,LocApnIpType ipType)851 void AgpsManager::reportAtlOpenSuccess(
852         AGpsExtType agpsType, char* apnName, int apnLen,
853         LocApnIpType ipType){
854 
855     LOC_LOGD("AgpsManager::reportAtlOpenSuccess(): "
856              "AgpsType %d, APN [%s], Len %d, IPType %d",
857              agpsType, apnName, apnLen, ipType);
858 
859     /* Find the state machine instance */
860     AgpsStateMachine* sm = getAgpsStateMachine(agpsType);
861 
862     /* Convert LocApnIpType sent by framework to AGpsBearerType */
863     AGpsBearerType bearerType;
864     switch (ipType) {
865         case LOC_APN_IP_IPV4:
866             bearerType = AGPS_APN_BEARER_IPV4;
867             break;
868         case LOC_APN_IP_IPV6:
869             bearerType = AGPS_APN_BEARER_IPV6;
870             break;
871         case LOC_APN_IP_IPV4V6:
872             bearerType = AGPS_APN_BEARER_IPV4V6;
873             break;
874         default:
875             bearerType = AGPS_APN_BEARER_IPV4;
876             break;
877     }
878 
879     /* Set bearer and apn info in state machine instance */
880     sm->setBearer(bearerType);
881     sm->setAPN(apnName, apnLen);
882 
883     /* Send GRANTED event to state machine */
884     sm->processAgpsEvent(AGPS_EVENT_GRANTED);
885 }
886 
reportAtlOpenFailed(AGpsExtType agpsType)887 void AgpsManager::reportAtlOpenFailed(AGpsExtType agpsType){
888 
889     LOC_LOGD("AgpsManager::reportAtlOpenFailed(): AgpsType %d", agpsType);
890 
891     /* Fetch SM and send DENIED event */
892     AgpsStateMachine* sm = getAgpsStateMachine(agpsType);
893     sm->processAgpsEvent(AGPS_EVENT_DENIED);
894 }
895 
reportAtlClosed(AGpsExtType agpsType)896 void AgpsManager::reportAtlClosed(AGpsExtType agpsType){
897 
898     LOC_LOGD("AgpsManager::reportAtlClosed(): AgpsType %d", agpsType);
899 
900     /* Fetch SM and send RELEASED event */
901     AgpsStateMachine* sm = getAgpsStateMachine(agpsType);
902     sm->processAgpsEvent(AGPS_EVENT_RELEASED);
903 }
904 
handleModemSSR()905 void AgpsManager::handleModemSSR(){
906 
907     LOC_LOGD("AgpsManager::handleModemSSR");
908 
909     /* Drop subscribers from all state machines */
910     if (mAgnssNif){
911         mAgnssNif->dropAllSubscribers();
912     }
913     if (mInternetNif){
914         mInternetNif->dropAllSubscribers();
915     }
916     if(mDsNif){
917         mDsNif->dropAllSubscribers();
918     }
919 
920     // reinitialize DS client in SSR mode
921     if(loc_core::ContextBase::mGps_conf.
922             USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL){
923 
924         mDSClientStopDataCallFn();
925         mDSClientCloseDataCallFn();
926         mDSClientReleaseFn();
927 
928         mDSClientInitFn(true);
929     }
930 }
931 
ipTypeToBearerType(LocApnIpType ipType)932 AGpsBearerType AgpsUtils::ipTypeToBearerType(LocApnIpType ipType) {
933 
934     switch (ipType) {
935 
936         case LOC_APN_IP_IPV4:
937             return AGPS_APN_BEARER_IPV4;
938 
939         case LOC_APN_IP_IPV6:
940             return AGPS_APN_BEARER_IPV6;
941 
942         case LOC_APN_IP_IPV4V6:
943             return AGPS_APN_BEARER_IPV4V6;
944 
945         default:
946             return AGPS_APN_BEARER_IPV4;
947     }
948 }
949 
bearerTypeToIpType(AGpsBearerType bearerType)950 LocApnIpType AgpsUtils::bearerTypeToIpType(AGpsBearerType bearerType){
951 
952     switch (bearerType) {
953 
954         case AGPS_APN_BEARER_IPV4:
955             return LOC_APN_IP_IPV4;
956 
957         case AGPS_APN_BEARER_IPV6:
958             return LOC_APN_IP_IPV6;
959 
960         case AGPS_APN_BEARER_IPV4V6:
961             return LOC_APN_IP_IPV4V6;
962 
963         default:
964             return LOC_APN_IP_IPV4;
965     }
966 }
967