1 /* Copyright (c) 2012-2019, 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 #define LOG_NDEBUG 0
30 #define LOG_TAG "LocSvc_Agps"
31 
32 #include <Agps.h>
33 #include <loc_pla.h>
34 #include <ContextBase.h>
35 #include <loc_timer.h>
36 #include <inttypes.h>
37 
38 /* --------------------------------------------------------------------
39  *   AGPS State Machine Methods
40  * -------------------------------------------------------------------*/
processAgpsEvent(AgpsEvent event)41 void AgpsStateMachine::processAgpsEvent(AgpsEvent event){
42 
43     LOC_LOGD("processAgpsEvent(): SM %p, Event %d, State %d",
44                this, event, mState);
45 
46     switch (event) {
47 
48         case AGPS_EVENT_SUBSCRIBE:
49             processAgpsEventSubscribe();
50             break;
51 
52         case AGPS_EVENT_UNSUBSCRIBE:
53             processAgpsEventUnsubscribe();
54             break;
55 
56         case AGPS_EVENT_GRANTED:
57             processAgpsEventGranted();
58             break;
59 
60         case AGPS_EVENT_RELEASED:
61             processAgpsEventReleased();
62             break;
63 
64         case AGPS_EVENT_DENIED:
65             processAgpsEventDenied();
66             break;
67 
68         default:
69             LOC_LOGE("Invalid Loc Agps Event");
70     }
71 }
72 
processAgpsEventSubscribe()73 void AgpsStateMachine::processAgpsEventSubscribe(){
74 
75     switch (mState) {
76 
77         case AGPS_STATE_RELEASED:
78             /* Add subscriber to list
79              * No notifications until we get RSRC_GRANTED */
80             addSubscriber(mCurrentSubscriber);
81             requestOrReleaseDataConn(true);
82             transitionState(AGPS_STATE_PENDING);
83             break;
84 
85         case AGPS_STATE_PENDING:
86             /* Already requested for data connection,
87              * do nothing until we get RSRC_GRANTED event;
88              * Just add this subscriber to the list, for notifications */
89             addSubscriber(mCurrentSubscriber);
90             break;
91 
92         case AGPS_STATE_ACQUIRED:
93             /* We already have the data connection setup,
94              * Notify current subscriber with GRANTED event,
95              * And add it to the subscriber list for further notifications. */
96             notifyEventToSubscriber(AGPS_EVENT_GRANTED, mCurrentSubscriber, false);
97             addSubscriber(mCurrentSubscriber);
98             break;
99 
100         case AGPS_STATE_RELEASING:
101             addSubscriber(mCurrentSubscriber);
102             break;
103 
104         default:
105             LOC_LOGE("Invalid state: %d", mState);
106     }
107 }
108 
processAgpsEventUnsubscribe()109 void AgpsStateMachine::processAgpsEventUnsubscribe(){
110 
111     switch (mState) {
112 
113         case AGPS_STATE_RELEASED:
114             notifyEventToSubscriber(
115                     AGPS_EVENT_UNSUBSCRIBE, mCurrentSubscriber, false);
116             break;
117 
118         case AGPS_STATE_PENDING:
119         case AGPS_STATE_ACQUIRED:
120             /* If the subscriber wishes to wait for connection close,
121              * before being removed from list, move to inactive state
122              * and notify */
123             if (mCurrentSubscriber->mWaitForCloseComplete) {
124                 mCurrentSubscriber->mIsInactive = true;
125             }
126             else {
127                 /* Notify only current subscriber and then delete it from
128                  * subscriberList */
129                 notifyEventToSubscriber(
130                         AGPS_EVENT_UNSUBSCRIBE, mCurrentSubscriber, true);
131             }
132 
133             /* If no subscribers in list, release data connection */
134             if (mSubscriberList.empty()) {
135                 transitionState(AGPS_STATE_RELEASED);
136                 requestOrReleaseDataConn(false);
137             }
138             /* Some subscribers in list, but all inactive;
139              * Release data connection */
140             else if(!anyActiveSubscribers()) {
141                 transitionState(AGPS_STATE_RELEASING);
142                 requestOrReleaseDataConn(false);
143             }
144             break;
145 
146         case AGPS_STATE_RELEASING:
147             /* If the subscriber wishes to wait for connection close,
148              * before being removed from list, move to inactive state
149              * and notify */
150             if (mCurrentSubscriber->mWaitForCloseComplete) {
151                 mCurrentSubscriber->mIsInactive = true;
152             }
153             else {
154                 /* Notify only current subscriber and then delete it from
155                  * subscriberList */
156                 notifyEventToSubscriber(
157                         AGPS_EVENT_UNSUBSCRIBE, mCurrentSubscriber, true);
158             }
159 
160             /* If no subscribers in list, just move the state.
161              * Request for releasing data connection should already have been
162              * sent */
163             if (mSubscriberList.empty()) {
164                 transitionState(AGPS_STATE_RELEASED);
165             }
166             break;
167 
168         default:
169             LOC_LOGE("Invalid state: %d", mState);
170     }
171 }
172 
processAgpsEventGranted()173 void AgpsStateMachine::processAgpsEventGranted(){
174 
175     switch (mState) {
176 
177         case AGPS_STATE_RELEASED:
178         case AGPS_STATE_ACQUIRED:
179         case AGPS_STATE_RELEASING:
180             LOC_LOGE("Unexpected event GRANTED in state %d", mState);
181             break;
182 
183         case AGPS_STATE_PENDING:
184             // Move to acquired state
185             transitionState(AGPS_STATE_ACQUIRED);
186             notifyAllSubscribers(
187                     AGPS_EVENT_GRANTED, false,
188                     AGPS_NOTIFICATION_TYPE_FOR_ACTIVE_SUBSCRIBERS);
189             break;
190 
191         default:
192             LOC_LOGE("Invalid state: %d", mState);
193     }
194 }
195 
processAgpsEventReleased()196 void AgpsStateMachine::processAgpsEventReleased(){
197 
198     switch (mState) {
199 
200         case AGPS_STATE_RELEASED:
201             /* Subscriber list should be empty if we are in released state */
202             if (!mSubscriberList.empty()) {
203                 LOC_LOGE("Unexpected event RELEASED in RELEASED state");
204             }
205             break;
206 
207         case AGPS_STATE_ACQUIRED:
208             /* Force release received */
209             LOC_LOGW("Force RELEASED event in ACQUIRED state");
210             transitionState(AGPS_STATE_RELEASED);
211             notifyAllSubscribers(
212                     AGPS_EVENT_RELEASED, true,
213                     AGPS_NOTIFICATION_TYPE_FOR_ALL_SUBSCRIBERS);
214             break;
215 
216         case AGPS_STATE_RELEASING:
217             /* Notify all inactive subscribers about the event */
218             notifyAllSubscribers(
219                     AGPS_EVENT_RELEASED, true,
220                     AGPS_NOTIFICATION_TYPE_FOR_INACTIVE_SUBSCRIBERS);
221 
222             /* If we have active subscribers now, they must be waiting for
223              * data conn setup */
224             if (anyActiveSubscribers()) {
225                 transitionState(AGPS_STATE_PENDING);
226                 requestOrReleaseDataConn(true);
227             }
228             /* No active subscribers, move to released state */
229             else {
230                 transitionState(AGPS_STATE_RELEASED);
231             }
232             break;
233 
234         case AGPS_STATE_PENDING:
235             /* NOOP */
236             break;
237 
238         default:
239             LOC_LOGE("Invalid state: %d", mState);
240     }
241 }
242 
processAgpsEventDenied()243 void AgpsStateMachine::processAgpsEventDenied(){
244 
245     switch (mState) {
246 
247         case AGPS_STATE_RELEASED:
248             LOC_LOGE("Unexpected event DENIED in state %d", mState);
249             break;
250 
251         case AGPS_STATE_ACQUIRED:
252             /* NOOP */
253             break;
254 
255         case AGPS_STATE_RELEASING:
256             /* Notify all inactive subscribers about the event */
257             notifyAllSubscribers(
258                     AGPS_EVENT_RELEASED, true,
259                     AGPS_NOTIFICATION_TYPE_FOR_INACTIVE_SUBSCRIBERS);
260 
261             /* If we have active subscribers now, they must be waiting for
262              * data conn setup */
263             if (anyActiveSubscribers()) {
264                 transitionState(AGPS_STATE_PENDING);
265                 requestOrReleaseDataConn(true);
266             }
267             /* No active subscribers, move to released state */
268             else {
269                 transitionState(AGPS_STATE_RELEASED);
270             }
271             break;
272 
273         case AGPS_STATE_PENDING:
274             transitionState(AGPS_STATE_RELEASED);
275             notifyAllSubscribers(
276                     AGPS_EVENT_DENIED, true,
277                     AGPS_NOTIFICATION_TYPE_FOR_ALL_SUBSCRIBERS);
278             break;
279 
280         default:
281             LOC_LOGE("Invalid state: %d", mState);
282     }
283 }
284 
285 /* Request or Release data connection
286  * bool request :
287  *      true  = Request data connection
288  *      false = Release data connection */
requestOrReleaseDataConn(bool request)289 void AgpsStateMachine::requestOrReleaseDataConn(bool request){
290 
291     AGnssExtStatusIpV4 nifRequest;
292     memset(&nifRequest, 0, sizeof(nifRequest));
293 
294     nifRequest.type = mAgpsType;
295     nifRequest.apnTypeMask = mApnTypeMask;
296     if (request) {
297         LOC_LOGD("AGPS Data Conn Request mAgpsType=%d mApnTypeMask=0x%X",
298                  mAgpsType, mApnTypeMask);
299         nifRequest.status = LOC_GPS_REQUEST_AGPS_DATA_CONN;
300     }
301     else{
302         LOC_LOGD("AGPS Data Conn Release mAgpsType=%d mApnTypeMask=0x%X",
303                  mAgpsType, mApnTypeMask);
304         nifRequest.status = LOC_GPS_RELEASE_AGPS_DATA_CONN;
305     }
306 
307     mFrameworkStatusV4Cb(nifRequest);
308 }
309 
notifyAllSubscribers(AgpsEvent event,bool deleteSubscriberPostNotify,AgpsNotificationType notificationType)310 void AgpsStateMachine::notifyAllSubscribers(
311         AgpsEvent event, bool deleteSubscriberPostNotify,
312         AgpsNotificationType notificationType){
313 
314     LOC_LOGD("notifyAllSubscribers(): "
315             "SM %p, Event %d Delete %d Notification Type %d",
316             this, event, deleteSubscriberPostNotify, notificationType);
317 
318     std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin();
319     while ( it != mSubscriberList.end() ) {
320 
321         AgpsSubscriber* subscriber = *it;
322 
323         if (notificationType == AGPS_NOTIFICATION_TYPE_FOR_ALL_SUBSCRIBERS ||
324                 (notificationType == AGPS_NOTIFICATION_TYPE_FOR_INACTIVE_SUBSCRIBERS &&
325                         subscriber->mIsInactive) ||
326                 (notificationType == AGPS_NOTIFICATION_TYPE_FOR_ACTIVE_SUBSCRIBERS &&
327                         !subscriber->mIsInactive)) {
328 
329             /* Deleting via this call would require another traversal
330              * through subscriber list, inefficient; hence pass in false*/
331             notifyEventToSubscriber(event, subscriber, false);
332 
333             if (deleteSubscriberPostNotify) {
334                 it = mSubscriberList.erase(it);
335                 delete subscriber;
336             } else {
337                 it++;
338             }
339         } else {
340             it++;
341         }
342     }
343 }
344 
notifyEventToSubscriber(AgpsEvent event,AgpsSubscriber * subscriberToNotify,bool deleteSubscriberPostNotify)345 void AgpsStateMachine::notifyEventToSubscriber(
346         AgpsEvent event, AgpsSubscriber* subscriberToNotify,
347         bool deleteSubscriberPostNotify) {
348 
349     LOC_LOGD("notifyEventToSubscriber(): "
350             "SM %p, Event %d Subscriber %p Delete %d",
351             this, event, subscriberToNotify, deleteSubscriberPostNotify);
352 
353     switch (event) {
354 
355         case AGPS_EVENT_GRANTED:
356             mAgpsManager->mAtlOpenStatusCb(
357                     subscriberToNotify->mConnHandle, 1, getAPN(), getAPNLen(),
358                     getBearer(), mAgpsType, mApnTypeMask);
359             break;
360 
361         case AGPS_EVENT_DENIED:
362             mAgpsManager->mAtlOpenStatusCb(
363                     subscriberToNotify->mConnHandle, 0, getAPN(), getAPNLen(),
364                     getBearer(), mAgpsType, mApnTypeMask);
365             break;
366 
367         case AGPS_EVENT_UNSUBSCRIBE:
368         case AGPS_EVENT_RELEASED:
369             mAgpsManager->mAtlCloseStatusCb(subscriberToNotify->mConnHandle, 1);
370             break;
371 
372         default:
373             LOC_LOGE("Invalid event %d", event);
374     }
375 
376     /* Search this subscriber in list and delete */
377     if (deleteSubscriberPostNotify) {
378         deleteSubscriber(subscriberToNotify);
379     }
380 }
381 
transitionState(AgpsState newState)382 void AgpsStateMachine::transitionState(AgpsState newState){
383 
384     LOC_LOGD("transitionState(): SM %p, old %d, new %d",
385                this, mState, newState);
386 
387     mState = newState;
388 
389     // notify state transitions to all subscribers ?
390 }
391 
addSubscriber(AgpsSubscriber * subscriberToAdd)392 void AgpsStateMachine::addSubscriber(AgpsSubscriber* subscriberToAdd){
393 
394     LOC_LOGD("addSubscriber(): SM %p, Subscriber %p",
395                this, subscriberToAdd);
396 
397     // Check if subscriber is already present in the current list
398     // If not, then add
399     std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin();
400     for (; it != mSubscriberList.end(); it++) {
401         AgpsSubscriber* subscriber = *it;
402         if (subscriber->equals(subscriberToAdd)) {
403             LOC_LOGE("Subscriber already in list");
404             return;
405         }
406     }
407 
408     AgpsSubscriber* cloned = subscriberToAdd->clone();
409     LOC_LOGD("addSubscriber(): cloned subscriber: %p", cloned);
410     mSubscriberList.push_back(cloned);
411 }
412 
deleteSubscriber(AgpsSubscriber * subscriberToDelete)413 void AgpsStateMachine::deleteSubscriber(AgpsSubscriber* subscriberToDelete){
414 
415     LOC_LOGD("deleteSubscriber(): SM %p, Subscriber %p",
416                this, subscriberToDelete);
417 
418     std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin();
419     while ( it != mSubscriberList.end() ) {
420 
421         AgpsSubscriber* subscriber = *it;
422         if (subscriber && subscriber->equals(subscriberToDelete)) {
423 
424             it = mSubscriberList.erase(it);
425             delete subscriber;
426         } else {
427             it++;
428         }
429     }
430 }
431 
anyActiveSubscribers()432 bool AgpsStateMachine::anyActiveSubscribers(){
433 
434     std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin();
435     for (; it != mSubscriberList.end(); it++) {
436         AgpsSubscriber* subscriber = *it;
437         if (!subscriber->mIsInactive) {
438             return true;
439         }
440     }
441     return false;
442 }
443 
setAPN(char * apn,unsigned int len)444 void AgpsStateMachine::setAPN(char* apn, unsigned int len){
445 
446     if (NULL != mAPN) {
447         delete mAPN;
448         mAPN  = NULL;
449     }
450 
451     if (NULL == apn || len <= 0 || len > MAX_APN_LEN || strlen(apn) != len) {
452         LOC_LOGD("Invalid apn len (%d) or null apn", len);
453         mAPN = NULL;
454         mAPNLen = 0;
455     } else {
456         mAPN = new char[len+1];
457         if (NULL != mAPN) {
458             memcpy(mAPN, apn, len);
459             mAPN[len] = '\0';
460             mAPNLen = len;
461         }
462     }
463 }
464 
getSubscriber(int connHandle)465 AgpsSubscriber* AgpsStateMachine::getSubscriber(int connHandle){
466 
467     /* Go over the subscriber list */
468     std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin();
469     for (; it != mSubscriberList.end(); it++) {
470         AgpsSubscriber* subscriber = *it;
471         if (subscriber->mConnHandle == connHandle) {
472             return subscriber;
473         }
474     }
475 
476     /* Not found, return NULL */
477     return NULL;
478 }
479 
getFirstSubscriber(bool isInactive)480 AgpsSubscriber* AgpsStateMachine::getFirstSubscriber(bool isInactive){
481 
482     /* Go over the subscriber list */
483     std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin();
484     for (; it != mSubscriberList.end(); it++) {
485         AgpsSubscriber* subscriber = *it;
486         if(subscriber->mIsInactive == isInactive) {
487             return subscriber;
488         }
489     }
490 
491     /* Not found, return NULL */
492     return NULL;
493 }
494 
dropAllSubscribers()495 void AgpsStateMachine::dropAllSubscribers(){
496 
497     LOC_LOGD("dropAllSubscribers(): SM %p", this);
498 
499     /* Go over the subscriber list */
500     std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin();
501     while ( it != mSubscriberList.end() ) {
502         AgpsSubscriber* subscriber = *it;
503         it = mSubscriberList.erase(it);
504         delete subscriber;
505     }
506 }
507 
508 /* --------------------------------------------------------------------
509  *   Loc AGPS Manager Methods
510  * -------------------------------------------------------------------*/
511 
512 /* CREATE AGPS STATE MACHINES
513  * Must be invoked in Msg Handler context */
createAgpsStateMachines(const AgpsCbInfo & cbInfo)514 void AgpsManager::createAgpsStateMachines(const AgpsCbInfo& cbInfo) {
515 
516     LOC_LOGD("AgpsManager::createAgpsStateMachines");
517 
518     bool agpsCapable =
519             ((loc_core::ContextBase::mGps_conf.CAPABILITIES & LOC_GPS_CAPABILITY_MSA) ||
520                     (loc_core::ContextBase::mGps_conf.CAPABILITIES & LOC_GPS_CAPABILITY_MSB));
521 
522     if (NULL == mInternetNif && (cbInfo.atlType & AGPS_ATL_TYPE_WWAN)) {
523         mInternetNif = new AgpsStateMachine(this, LOC_AGPS_TYPE_WWAN_ANY);
524         mInternetNif->registerFrameworkStatusCallback((AgnssStatusIpV4Cb)cbInfo.statusV4Cb);
525         LOC_LOGD("Internet NIF: %p", mInternetNif);
526     }
527     if (agpsCapable) {
528         if (NULL == mAgnssNif && (cbInfo.atlType & AGPS_ATL_TYPE_SUPL) &&
529                 (cbInfo.atlType & AGPS_ATL_TYPE_SUPL_ES)) {
530             mAgnssNif = new AgpsStateMachine(this, LOC_AGPS_TYPE_SUPL);
531             mAgnssNif->registerFrameworkStatusCallback((AgnssStatusIpV4Cb)cbInfo.statusV4Cb);
532             LOC_LOGD("AGNSS NIF: %p", mAgnssNif);
533         }
534     }
535 }
536 
getAgpsStateMachine(AGpsExtType agpsType)537 AgpsStateMachine* AgpsManager::getAgpsStateMachine(AGpsExtType agpsType) {
538 
539     LOC_LOGD("AgpsManager::getAgpsStateMachine(): agpsType %d", agpsType);
540 
541     switch (agpsType) {
542 
543         case LOC_AGPS_TYPE_INVALID:
544         case LOC_AGPS_TYPE_SUPL:
545         case LOC_AGPS_TYPE_SUPL_ES:
546             if (mAgnssNif == NULL) {
547                 LOC_LOGE("NULL AGNSS NIF !");
548             }
549             return mAgnssNif;
550         case LOC_AGPS_TYPE_WWAN_ANY:
551             if (mInternetNif == NULL) {
552                 LOC_LOGE("NULL Internet NIF !");
553             }
554             return mInternetNif;
555         default:
556             return mInternetNif;
557     }
558 
559     LOC_LOGE("No SM found !");
560     return NULL;
561 }
562 
requestATL(int connHandle,AGpsExtType agpsType,LocApnTypeMask apnTypeMask)563 void AgpsManager::requestATL(int connHandle, AGpsExtType agpsType,
564                              LocApnTypeMask apnTypeMask){
565 
566     LOC_LOGD("AgpsManager::requestATL(): connHandle %d, agpsType 0x%X apnTypeMask: 0x%X",
567                connHandle, agpsType, apnTypeMask);
568 
569     if (0 == loc_core::ContextBase::mGps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL &&
570         LOC_AGPS_TYPE_SUPL_ES == agpsType) {
571         agpsType = LOC_AGPS_TYPE_SUPL;
572         apnTypeMask &= ~LOC_APN_TYPE_MASK_EMERGENCY;
573         apnTypeMask |= LOC_APN_TYPE_MASK_SUPL;
574         LOC_LOGD("Changed agpsType to non-emergency when USE_EMERGENCY... is 0"
575                  "and removed LOC_APN_TYPE_MASK_EMERGENCY from apnTypeMask"
576                  "agpsType 0x%X apnTypeMask : 0x%X",
577                  agpsType, apnTypeMask);
578     }
579     AgpsStateMachine* sm = getAgpsStateMachine(agpsType);
580 
581     if (sm == NULL) {
582 
583         LOC_LOGE("No AGPS State Machine for agpsType: %d apnTypeMask: 0x%X",
584                  agpsType, apnTypeMask);
585         mAtlOpenStatusCb(
586                 connHandle, 0, NULL, 0, AGPS_APN_BEARER_INVALID, agpsType, apnTypeMask);
587         return;
588     }
589     sm->setType(agpsType);
590     sm->setApnTypeMask(apnTypeMask);
591 
592     /* Invoke AGPS SM processing */
593     AgpsSubscriber subscriber(connHandle, false, false, apnTypeMask);
594     sm->setCurrentSubscriber(&subscriber);
595     /* Send subscriber event */
596     sm->processAgpsEvent(AGPS_EVENT_SUBSCRIBE);
597 }
598 
releaseATL(int connHandle)599 void AgpsManager::releaseATL(int connHandle){
600 
601     LOC_LOGD("AgpsManager::releaseATL(): connHandle %d", connHandle);
602 
603     /* First find the subscriber with specified handle.
604      * We need to search in all state machines. */
605     AgpsStateMachine* sm = NULL;
606     AgpsSubscriber* subscriber = NULL;
607 
608     if (mAgnssNif &&
609             (subscriber = mAgnssNif->getSubscriber(connHandle)) != NULL) {
610         sm = mAgnssNif;
611     }
612     else if (mInternetNif &&
613             (subscriber = mInternetNif->getSubscriber(connHandle)) != NULL) {
614         sm = mInternetNif;
615     }
616     if (sm == NULL) {
617         LOC_LOGE("Subscriber with connHandle %d not found in any SM",
618                     connHandle);
619         return;
620     }
621 
622     /* Now send unsubscribe event */
623     sm->setCurrentSubscriber(subscriber);
624     sm->processAgpsEvent(AGPS_EVENT_UNSUBSCRIBE);
625 }
626 
reportAtlOpenSuccess(AGpsExtType agpsType,char * apnName,int apnLen,AGpsBearerType bearerType)627 void AgpsManager::reportAtlOpenSuccess(
628         AGpsExtType agpsType, char* apnName, int apnLen,
629         AGpsBearerType bearerType){
630 
631     LOC_LOGD("AgpsManager::reportAtlOpenSuccess(): "
632              "AgpsType %d, APN [%s], Len %d, BearerType %d",
633              agpsType, apnName, apnLen, bearerType);
634 
635     /* Find the state machine instance */
636     AgpsStateMachine* sm = getAgpsStateMachine(agpsType);
637 
638     /* Set bearer and apn info in state machine instance */
639     sm->setBearer(bearerType);
640     sm->setAPN(apnName, apnLen);
641 
642     /* Send GRANTED event to state machine */
643     sm->processAgpsEvent(AGPS_EVENT_GRANTED);
644 }
645 
reportAtlOpenFailed(AGpsExtType agpsType)646 void AgpsManager::reportAtlOpenFailed(AGpsExtType agpsType){
647 
648     LOC_LOGD("AgpsManager::reportAtlOpenFailed(): AgpsType %d", agpsType);
649 
650     /* Fetch SM and send DENIED event */
651     AgpsStateMachine* sm = getAgpsStateMachine(agpsType);
652     sm->processAgpsEvent(AGPS_EVENT_DENIED);
653 }
654 
reportAtlClosed(AGpsExtType agpsType)655 void AgpsManager::reportAtlClosed(AGpsExtType agpsType){
656 
657     LOC_LOGD("AgpsManager::reportAtlClosed(): AgpsType %d", agpsType);
658 
659     /* Fetch SM and send RELEASED event */
660     AgpsStateMachine* sm = getAgpsStateMachine(agpsType);
661     sm->processAgpsEvent(AGPS_EVENT_RELEASED);
662 }
663 
handleModemSSR()664 void AgpsManager::handleModemSSR(){
665 
666     LOC_LOGD("AgpsManager::handleModemSSR");
667 
668     /* Drop subscribers from all state machines */
669     if (mAgnssNif) {
670         mAgnssNif->dropAllSubscribers();
671     }
672     if (mInternetNif) {
673         mInternetNif->dropAllSubscribers();
674     }
675 }
676