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