| /* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are |
| * met: |
| * * Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * * Redistributions in binary form must reproduce the above |
| * copyright notice, this list of conditions and the following |
| * disclaimer in the documentation and/or other materials provided |
| * with the distribution. |
| * * Neither the name of The Linux Foundation, nor the names of its |
| * contributors may be used to endorse or promote products derived |
| * from this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED |
| * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
| * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT |
| * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS |
| * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR |
| * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
| * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE |
| * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN |
| * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| * |
| */ |
| #define LOG_NDEBUG 0 |
| #define LOG_TAG "LocSvc_Agps" |
| |
| #include <Agps.h> |
| #include <loc_pla.h> |
| #include <ContextBase.h> |
| #include <loc_timer.h> |
| #include <inttypes.h> |
| |
| /* -------------------------------------------------------------------- |
| * AGPS State Machine Methods |
| * -------------------------------------------------------------------*/ |
| void AgpsStateMachine::processAgpsEvent(AgpsEvent event){ |
| |
| LOC_LOGD("processAgpsEvent(): SM %p, Event %d, State %d", |
| this, event, mState); |
| |
| switch (event) { |
| |
| case AGPS_EVENT_SUBSCRIBE: |
| processAgpsEventSubscribe(); |
| break; |
| |
| case AGPS_EVENT_UNSUBSCRIBE: |
| processAgpsEventUnsubscribe(); |
| break; |
| |
| case AGPS_EVENT_GRANTED: |
| processAgpsEventGranted(); |
| break; |
| |
| case AGPS_EVENT_RELEASED: |
| processAgpsEventReleased(); |
| break; |
| |
| case AGPS_EVENT_DENIED: |
| processAgpsEventDenied(); |
| break; |
| |
| default: |
| LOC_LOGE("Invalid Loc Agps Event"); |
| } |
| } |
| |
| void AgpsStateMachine::processAgpsEventSubscribe(){ |
| |
| switch (mState) { |
| |
| case AGPS_STATE_RELEASED: |
| /* Add subscriber to list |
| * No notifications until we get RSRC_GRANTED */ |
| addSubscriber(mCurrentSubscriber); |
| requestOrReleaseDataConn(true); |
| transitionState(AGPS_STATE_PENDING); |
| break; |
| |
| case AGPS_STATE_PENDING: |
| /* Already requested for data connection, |
| * do nothing until we get RSRC_GRANTED event; |
| * Just add this subscriber to the list, for notifications */ |
| addSubscriber(mCurrentSubscriber); |
| break; |
| |
| case AGPS_STATE_ACQUIRED: |
| /* We already have the data connection setup, |
| * Notify current subscriber with GRANTED event, |
| * And add it to the subscriber list for further notifications. */ |
| notifyEventToSubscriber(AGPS_EVENT_GRANTED, mCurrentSubscriber, false); |
| addSubscriber(mCurrentSubscriber); |
| break; |
| |
| case AGPS_STATE_RELEASING: |
| addSubscriber(mCurrentSubscriber); |
| break; |
| |
| default: |
| LOC_LOGE("Invalid state: %d", mState); |
| } |
| } |
| |
| void AgpsStateMachine::processAgpsEventUnsubscribe(){ |
| |
| switch (mState) { |
| |
| case AGPS_STATE_RELEASED: |
| notifyEventToSubscriber( |
| AGPS_EVENT_UNSUBSCRIBE, mCurrentSubscriber, false); |
| break; |
| |
| case AGPS_STATE_PENDING: |
| case AGPS_STATE_ACQUIRED: |
| /* If the subscriber wishes to wait for connection close, |
| * before being removed from list, move to inactive state |
| * and notify */ |
| if (mCurrentSubscriber->mWaitForCloseComplete) { |
| mCurrentSubscriber->mIsInactive = true; |
| } |
| else { |
| /* Notify only current subscriber and then delete it from |
| * subscriberList */ |
| notifyEventToSubscriber( |
| AGPS_EVENT_UNSUBSCRIBE, mCurrentSubscriber, true); |
| } |
| |
| /* If no subscribers in list, release data connection */ |
| if (mSubscriberList.empty()) { |
| transitionState(AGPS_STATE_RELEASED); |
| requestOrReleaseDataConn(false); |
| } |
| /* Some subscribers in list, but all inactive; |
| * Release data connection */ |
| else if(!anyActiveSubscribers()) { |
| transitionState(AGPS_STATE_RELEASING); |
| requestOrReleaseDataConn(false); |
| } |
| break; |
| |
| case AGPS_STATE_RELEASING: |
| /* If the subscriber wishes to wait for connection close, |
| * before being removed from list, move to inactive state |
| * and notify */ |
| if (mCurrentSubscriber->mWaitForCloseComplete) { |
| mCurrentSubscriber->mIsInactive = true; |
| } |
| else { |
| /* Notify only current subscriber and then delete it from |
| * subscriberList */ |
| notifyEventToSubscriber( |
| AGPS_EVENT_UNSUBSCRIBE, mCurrentSubscriber, true); |
| } |
| |
| /* If no subscribers in list, just move the state. |
| * Request for releasing data connection should already have been |
| * sent */ |
| if (mSubscriberList.empty()) { |
| transitionState(AGPS_STATE_RELEASED); |
| } |
| break; |
| |
| default: |
| LOC_LOGE("Invalid state: %d", mState); |
| } |
| } |
| |
| void AgpsStateMachine::processAgpsEventGranted(){ |
| |
| switch (mState) { |
| |
| case AGPS_STATE_RELEASED: |
| case AGPS_STATE_ACQUIRED: |
| case AGPS_STATE_RELEASING: |
| LOC_LOGE("Unexpected event GRANTED in state %d", mState); |
| break; |
| |
| case AGPS_STATE_PENDING: |
| // Move to acquired state |
| transitionState(AGPS_STATE_ACQUIRED); |
| notifyAllSubscribers( |
| AGPS_EVENT_GRANTED, false, |
| AGPS_NOTIFICATION_TYPE_FOR_ACTIVE_SUBSCRIBERS); |
| break; |
| |
| default: |
| LOC_LOGE("Invalid state: %d", mState); |
| } |
| } |
| |
| void AgpsStateMachine::processAgpsEventReleased(){ |
| |
| switch (mState) { |
| |
| case AGPS_STATE_RELEASED: |
| /* Subscriber list should be empty if we are in released state */ |
| if (!mSubscriberList.empty()) { |
| LOC_LOGE("Unexpected event RELEASED in RELEASED state"); |
| } |
| break; |
| |
| case AGPS_STATE_ACQUIRED: |
| /* Force release received */ |
| LOC_LOGW("Force RELEASED event in ACQUIRED state"); |
| transitionState(AGPS_STATE_RELEASED); |
| notifyAllSubscribers( |
| AGPS_EVENT_RELEASED, true, |
| AGPS_NOTIFICATION_TYPE_FOR_ALL_SUBSCRIBERS); |
| break; |
| |
| case AGPS_STATE_RELEASING: |
| /* Notify all inactive subscribers about the event */ |
| notifyAllSubscribers( |
| AGPS_EVENT_RELEASED, true, |
| AGPS_NOTIFICATION_TYPE_FOR_INACTIVE_SUBSCRIBERS); |
| |
| /* If we have active subscribers now, they must be waiting for |
| * data conn setup */ |
| if (anyActiveSubscribers()) { |
| transitionState(AGPS_STATE_PENDING); |
| requestOrReleaseDataConn(true); |
| } |
| /* No active subscribers, move to released state */ |
| else { |
| transitionState(AGPS_STATE_RELEASED); |
| } |
| break; |
| |
| case AGPS_STATE_PENDING: |
| /* NOOP */ |
| break; |
| |
| default: |
| LOC_LOGE("Invalid state: %d", mState); |
| } |
| } |
| |
| void AgpsStateMachine::processAgpsEventDenied(){ |
| |
| switch (mState) { |
| |
| case AGPS_STATE_RELEASED: |
| LOC_LOGE("Unexpected event DENIED in state %d", mState); |
| break; |
| |
| case AGPS_STATE_ACQUIRED: |
| /* NOOP */ |
| break; |
| |
| case AGPS_STATE_RELEASING: |
| /* Notify all inactive subscribers about the event */ |
| notifyAllSubscribers( |
| AGPS_EVENT_RELEASED, true, |
| AGPS_NOTIFICATION_TYPE_FOR_INACTIVE_SUBSCRIBERS); |
| |
| /* If we have active subscribers now, they must be waiting for |
| * data conn setup */ |
| if (anyActiveSubscribers()) { |
| transitionState(AGPS_STATE_PENDING); |
| requestOrReleaseDataConn(true); |
| } |
| /* No active subscribers, move to released state */ |
| else { |
| transitionState(AGPS_STATE_RELEASED); |
| } |
| break; |
| |
| case AGPS_STATE_PENDING: |
| transitionState(AGPS_STATE_RELEASED); |
| notifyAllSubscribers( |
| AGPS_EVENT_DENIED, true, |
| AGPS_NOTIFICATION_TYPE_FOR_ALL_SUBSCRIBERS); |
| break; |
| |
| default: |
| LOC_LOGE("Invalid state: %d", mState); |
| } |
| } |
| |
| /* Request or Release data connection |
| * bool request : |
| * true = Request data connection |
| * false = Release data connection */ |
| void AgpsStateMachine::requestOrReleaseDataConn(bool request){ |
| |
| AGnssExtStatusIpV4 nifRequest; |
| memset(&nifRequest, 0, sizeof(nifRequest)); |
| |
| nifRequest.type = mAgpsType; |
| nifRequest.apnTypeMask = mApnTypeMask; |
| if (request) { |
| LOC_LOGD("AGPS Data Conn Request mAgpsType=%d mApnTypeMask=0x%X", |
| mAgpsType, mApnTypeMask); |
| nifRequest.status = LOC_GPS_REQUEST_AGPS_DATA_CONN; |
| } |
| else{ |
| LOC_LOGD("AGPS Data Conn Release mAgpsType=%d mApnTypeMask=0x%X", |
| mAgpsType, mApnTypeMask); |
| nifRequest.status = LOC_GPS_RELEASE_AGPS_DATA_CONN; |
| } |
| |
| mFrameworkStatusV4Cb(nifRequest); |
| } |
| |
| void AgpsStateMachine::notifyAllSubscribers( |
| AgpsEvent event, bool deleteSubscriberPostNotify, |
| AgpsNotificationType notificationType){ |
| |
| LOC_LOGD("notifyAllSubscribers(): " |
| "SM %p, Event %d Delete %d Notification Type %d", |
| this, event, deleteSubscriberPostNotify, notificationType); |
| |
| std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin(); |
| while ( it != mSubscriberList.end() ) { |
| |
| AgpsSubscriber* subscriber = *it; |
| |
| if (notificationType == AGPS_NOTIFICATION_TYPE_FOR_ALL_SUBSCRIBERS || |
| (notificationType == AGPS_NOTIFICATION_TYPE_FOR_INACTIVE_SUBSCRIBERS && |
| subscriber->mIsInactive) || |
| (notificationType == AGPS_NOTIFICATION_TYPE_FOR_ACTIVE_SUBSCRIBERS && |
| !subscriber->mIsInactive)) { |
| |
| /* Deleting via this call would require another traversal |
| * through subscriber list, inefficient; hence pass in false*/ |
| notifyEventToSubscriber(event, subscriber, false); |
| |
| if (deleteSubscriberPostNotify) { |
| it = mSubscriberList.erase(it); |
| delete subscriber; |
| } else { |
| it++; |
| } |
| } else { |
| it++; |
| } |
| } |
| } |
| |
| void AgpsStateMachine::notifyEventToSubscriber( |
| AgpsEvent event, AgpsSubscriber* subscriberToNotify, |
| bool deleteSubscriberPostNotify) { |
| |
| LOC_LOGD("notifyEventToSubscriber(): " |
| "SM %p, Event %d Subscriber %p Delete %d", |
| this, event, subscriberToNotify, deleteSubscriberPostNotify); |
| |
| switch (event) { |
| |
| case AGPS_EVENT_GRANTED: |
| mAgpsManager->mAtlOpenStatusCb( |
| subscriberToNotify->mConnHandle, 1, getAPN(), getAPNLen(), |
| getBearer(), mAgpsType, mApnTypeMask); |
| break; |
| |
| case AGPS_EVENT_DENIED: |
| mAgpsManager->mAtlOpenStatusCb( |
| subscriberToNotify->mConnHandle, 0, getAPN(), getAPNLen(), |
| getBearer(), mAgpsType, mApnTypeMask); |
| break; |
| |
| case AGPS_EVENT_UNSUBSCRIBE: |
| case AGPS_EVENT_RELEASED: |
| mAgpsManager->mAtlCloseStatusCb(subscriberToNotify->mConnHandle, 1); |
| break; |
| |
| default: |
| LOC_LOGE("Invalid event %d", event); |
| } |
| |
| /* Search this subscriber in list and delete */ |
| if (deleteSubscriberPostNotify) { |
| deleteSubscriber(subscriberToNotify); |
| } |
| } |
| |
| void AgpsStateMachine::transitionState(AgpsState newState){ |
| |
| LOC_LOGD("transitionState(): SM %p, old %d, new %d", |
| this, mState, newState); |
| |
| mState = newState; |
| |
| // notify state transitions to all subscribers ? |
| } |
| |
| void AgpsStateMachine::addSubscriber(AgpsSubscriber* subscriberToAdd){ |
| |
| LOC_LOGD("addSubscriber(): SM %p, Subscriber %p", |
| this, subscriberToAdd); |
| |
| // Check if subscriber is already present in the current list |
| // If not, then add |
| std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin(); |
| for (; it != mSubscriberList.end(); it++) { |
| AgpsSubscriber* subscriber = *it; |
| if (subscriber->equals(subscriberToAdd)) { |
| LOC_LOGE("Subscriber already in list"); |
| return; |
| } |
| } |
| |
| AgpsSubscriber* cloned = subscriberToAdd->clone(); |
| LOC_LOGD("addSubscriber(): cloned subscriber: %p", cloned); |
| mSubscriberList.push_back(cloned); |
| } |
| |
| void AgpsStateMachine::deleteSubscriber(AgpsSubscriber* subscriberToDelete){ |
| |
| LOC_LOGD("deleteSubscriber(): SM %p, Subscriber %p", |
| this, subscriberToDelete); |
| |
| std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin(); |
| while ( it != mSubscriberList.end() ) { |
| |
| AgpsSubscriber* subscriber = *it; |
| if (subscriber && subscriber->equals(subscriberToDelete)) { |
| |
| it = mSubscriberList.erase(it); |
| delete subscriber; |
| } else { |
| it++; |
| } |
| } |
| } |
| |
| bool AgpsStateMachine::anyActiveSubscribers(){ |
| |
| std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin(); |
| for (; it != mSubscriberList.end(); it++) { |
| AgpsSubscriber* subscriber = *it; |
| if (!subscriber->mIsInactive) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| void AgpsStateMachine::setAPN(char* apn, unsigned int len){ |
| |
| if (NULL != mAPN) { |
| delete mAPN; |
| mAPN = NULL; |
| } |
| |
| if (NULL == apn || len > MAX_APN_LEN || strlen(apn) != len) { |
| LOC_LOGD("Invalid apn len (%d) or null apn", len); |
| mAPN = NULL; |
| mAPNLen = 0; |
| } else { |
| mAPN = new char[len+1]; |
| if (NULL != mAPN) { |
| memcpy(mAPN, apn, len); |
| mAPN[len] = '\0'; |
| mAPNLen = len; |
| } |
| } |
| } |
| |
| AgpsSubscriber* AgpsStateMachine::getSubscriber(int connHandle){ |
| |
| /* Go over the subscriber list */ |
| std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin(); |
| for (; it != mSubscriberList.end(); it++) { |
| AgpsSubscriber* subscriber = *it; |
| if (subscriber->mConnHandle == connHandle) { |
| return subscriber; |
| } |
| } |
| |
| /* Not found, return NULL */ |
| return NULL; |
| } |
| |
| AgpsSubscriber* AgpsStateMachine::getFirstSubscriber(bool isInactive){ |
| |
| /* Go over the subscriber list */ |
| std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin(); |
| for (; it != mSubscriberList.end(); it++) { |
| AgpsSubscriber* subscriber = *it; |
| if(subscriber->mIsInactive == isInactive) { |
| return subscriber; |
| } |
| } |
| |
| /* Not found, return NULL */ |
| return NULL; |
| } |
| |
| void AgpsStateMachine::dropAllSubscribers(){ |
| |
| LOC_LOGD("dropAllSubscribers(): SM %p", this); |
| |
| /* Go over the subscriber list */ |
| std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin(); |
| while ( it != mSubscriberList.end() ) { |
| AgpsSubscriber* subscriber = *it; |
| it = mSubscriberList.erase(it); |
| delete subscriber; |
| } |
| } |
| |
| /* -------------------------------------------------------------------- |
| * Loc AGPS Manager Methods |
| * -------------------------------------------------------------------*/ |
| |
| /* CREATE AGPS STATE MACHINES |
| * Must be invoked in Msg Handler context */ |
| void AgpsManager::createAgpsStateMachines(const AgpsCbInfo& cbInfo) { |
| |
| LOC_LOGD("AgpsManager::createAgpsStateMachines"); |
| |
| bool agpsCapable = |
| ((loc_core::ContextBase::mGps_conf.CAPABILITIES & LOC_GPS_CAPABILITY_MSA) || |
| (loc_core::ContextBase::mGps_conf.CAPABILITIES & LOC_GPS_CAPABILITY_MSB)); |
| |
| if (NULL == mInternetNif && (cbInfo.atlType & AGPS_ATL_TYPE_WWAN)) { |
| mInternetNif = new AgpsStateMachine(this, LOC_AGPS_TYPE_WWAN_ANY); |
| mInternetNif->registerFrameworkStatusCallback((AgnssStatusIpV4Cb)cbInfo.statusV4Cb); |
| LOC_LOGD("Internet NIF: %p", mInternetNif); |
| } |
| if (agpsCapable) { |
| if (NULL == mAgnssNif && (cbInfo.atlType & AGPS_ATL_TYPE_SUPL) && |
| (cbInfo.atlType & AGPS_ATL_TYPE_SUPL_ES)) { |
| mAgnssNif = new AgpsStateMachine(this, LOC_AGPS_TYPE_SUPL); |
| mAgnssNif->registerFrameworkStatusCallback((AgnssStatusIpV4Cb)cbInfo.statusV4Cb); |
| LOC_LOGD("AGNSS NIF: %p", mAgnssNif); |
| } |
| } |
| } |
| |
| AgpsStateMachine* AgpsManager::getAgpsStateMachine(AGpsExtType agpsType) { |
| |
| LOC_LOGD("AgpsManager::getAgpsStateMachine(): agpsType %d", agpsType); |
| |
| switch (agpsType) { |
| |
| case LOC_AGPS_TYPE_INVALID: |
| case LOC_AGPS_TYPE_SUPL: |
| case LOC_AGPS_TYPE_SUPL_ES: |
| if (mAgnssNif == NULL) { |
| LOC_LOGE("NULL AGNSS NIF !"); |
| } |
| return mAgnssNif; |
| case LOC_AGPS_TYPE_WWAN_ANY: |
| if (mInternetNif == NULL) { |
| LOC_LOGE("NULL Internet NIF !"); |
| } |
| return mInternetNif; |
| default: |
| return mInternetNif; |
| } |
| |
| LOC_LOGE("No SM found !"); |
| return NULL; |
| } |
| |
| void AgpsManager::requestATL(int connHandle, AGpsExtType agpsType, |
| LocApnTypeMask apnTypeMask){ |
| |
| LOC_LOGD("AgpsManager::requestATL(): connHandle %d, agpsType 0x%X apnTypeMask: 0x%X", |
| connHandle, agpsType, apnTypeMask); |
| |
| if (0 == loc_core::ContextBase::mGps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL && |
| LOC_AGPS_TYPE_SUPL_ES == agpsType) { |
| agpsType = LOC_AGPS_TYPE_SUPL; |
| apnTypeMask &= ~LOC_APN_TYPE_MASK_EMERGENCY; |
| apnTypeMask |= LOC_APN_TYPE_MASK_SUPL; |
| LOC_LOGD("Changed agpsType to non-emergency when USE_EMERGENCY... is 0" |
| "and removed LOC_APN_TYPE_MASK_EMERGENCY from apnTypeMask" |
| "agpsType 0x%X apnTypeMask : 0x%X", |
| agpsType, apnTypeMask); |
| } |
| AgpsStateMachine* sm = getAgpsStateMachine(agpsType); |
| |
| if (sm == NULL) { |
| |
| LOC_LOGE("No AGPS State Machine for agpsType: %d apnTypeMask: 0x%X", |
| agpsType, apnTypeMask); |
| mAtlOpenStatusCb( |
| connHandle, 0, NULL, 0, AGPS_APN_BEARER_INVALID, agpsType, apnTypeMask); |
| return; |
| } |
| sm->setType(agpsType); |
| sm->setApnTypeMask(apnTypeMask); |
| |
| /* Invoke AGPS SM processing */ |
| AgpsSubscriber subscriber(connHandle, true, false, apnTypeMask); |
| sm->setCurrentSubscriber(&subscriber); |
| /* Send subscriber event */ |
| sm->processAgpsEvent(AGPS_EVENT_SUBSCRIBE); |
| } |
| |
| void AgpsManager::releaseATL(int connHandle){ |
| |
| LOC_LOGD("AgpsManager::releaseATL(): connHandle %d", connHandle); |
| |
| /* First find the subscriber with specified handle. |
| * We need to search in all state machines. */ |
| AgpsStateMachine* sm = NULL; |
| AgpsSubscriber* subscriber = NULL; |
| |
| if (mAgnssNif && |
| (subscriber = mAgnssNif->getSubscriber(connHandle)) != NULL) { |
| sm = mAgnssNif; |
| } |
| else if (mInternetNif && |
| (subscriber = mInternetNif->getSubscriber(connHandle)) != NULL) { |
| sm = mInternetNif; |
| } |
| if (sm == NULL) { |
| LOC_LOGE("Subscriber with connHandle %d not found in any SM", |
| connHandle); |
| return; |
| } |
| |
| /* Now send unsubscribe event */ |
| sm->setCurrentSubscriber(subscriber); |
| sm->processAgpsEvent(AGPS_EVENT_UNSUBSCRIBE); |
| } |
| |
| void AgpsManager::reportAtlOpenSuccess( |
| AGpsExtType agpsType, char* apnName, int apnLen, |
| AGpsBearerType bearerType){ |
| |
| LOC_LOGD("AgpsManager::reportAtlOpenSuccess(): " |
| "AgpsType %d, APN [%s], Len %d, BearerType %d", |
| agpsType, apnName, apnLen, bearerType); |
| |
| /* Find the state machine instance */ |
| AgpsStateMachine* sm = getAgpsStateMachine(agpsType); |
| |
| /* Set bearer and apn info in state machine instance */ |
| sm->setBearer(bearerType); |
| sm->setAPN(apnName, apnLen); |
| |
| /* Send GRANTED event to state machine */ |
| sm->processAgpsEvent(AGPS_EVENT_GRANTED); |
| } |
| |
| void AgpsManager::reportAtlOpenFailed(AGpsExtType agpsType){ |
| |
| LOC_LOGD("AgpsManager::reportAtlOpenFailed(): AgpsType %d", agpsType); |
| |
| /* Fetch SM and send DENIED event */ |
| AgpsStateMachine* sm = getAgpsStateMachine(agpsType); |
| sm->processAgpsEvent(AGPS_EVENT_DENIED); |
| } |
| |
| void AgpsManager::reportAtlClosed(AGpsExtType agpsType){ |
| |
| LOC_LOGD("AgpsManager::reportAtlClosed(): AgpsType %d", agpsType); |
| |
| /* Fetch SM and send RELEASED event */ |
| AgpsStateMachine* sm = getAgpsStateMachine(agpsType); |
| sm->processAgpsEvent(AGPS_EVENT_RELEASED); |
| } |
| |
| void AgpsManager::handleModemSSR(){ |
| |
| LOC_LOGD("AgpsManager::handleModemSSR"); |
| |
| /* Drop subscribers from all state machines */ |
| if (mAgnssNif) { |
| mAgnssNif->dropAllSubscribers(); |
| } |
| if (mInternetNif) { |
| mInternetNif->dropAllSubscribers(); |
| } |
| } |