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