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