/* Copyright (c) 2012-2017, 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_TAG "LocSvc_Agps"

#include <Agps.h>
#include <platform_lib_includes.h>
#include <ContextBase.h>
#include <loc_timer.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);

            /* Send data request
             * The if condition below is added so that if the data call setup
             * fails for DS State Machine, we want to retry in released state.
             * for Agps State Machine, sendRsrcRequest() will always return
             * success. */
            if(requestOrReleaseDataConn(true) == 0){
                // If data request successful, move to pending state
                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;
                notifyEventToSubscriber(
                        AGPS_EVENT_UNSUBSCRIBE, mCurrentSubscriber, false);
            }
            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;
                notifyEventToSubscriber(
                        AGPS_EVENT_UNSUBSCRIBE, mCurrentSubscriber, false);
            }
            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:
            LOC_LOGE("Unexpected event RELEASED in state %d", mState);
            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 */
int AgpsStateMachine::requestOrReleaseDataConn(bool request){

    AgpsFrameworkInterface::AGnssStatusIpV4 nifRequest;
    memset(&nifRequest, 0, sizeof(nifRequest));

    nifRequest.type = (AgpsFrameworkInterface::AGnssType)mAgpsType;

    if(request){
        LOC_LOGD("AGPS Data Conn Request");
        nifRequest.status = (AgpsFrameworkInterface::AGnssStatusValue)
                                LOC_GPS_REQUEST_AGPS_DATA_CONN;
    }
    else{
        LOC_LOGD("AGPS Data Conn Release");
        nifRequest.status = (AgpsFrameworkInterface::AGnssStatusValue)
                                LOC_GPS_RELEASE_AGPS_DATA_CONN;
    }

    mAgpsManager->mFrameworkStatusV4Cb(nifRequest);
    return 0;
}

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(),
                    getBearer(), mAgpsType);
            break;

        case AGPS_EVENT_DENIED:
            mAgpsManager->mAtlOpenStatusCb(
                    subscriberToNotify->mConnHandle, 0, getAPN(),
                    getBearer(), mAgpsType);
            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;
    }

    if(apn == NULL || len <= 0){
        LOC_LOGD("Invalid apn len (%d) or null apn", len);
        mAPN = NULL;
        mAPNLen = 0;
    }

    if (NULL != apn) {
        mAPN = new char[len+1];
        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;
    }
}

/* --------------------------------------------------------------------
 *   DS State Machine Methods
 * -------------------------------------------------------------------*/
const int DSStateMachine::MAX_START_DATA_CALL_RETRIES = 4;
const int DSStateMachine::DATA_CALL_RETRY_DELAY_MSEC = 500;

/* Overridden method
 * DS SM needs to handle one scenario differently */
void DSStateMachine::processAgpsEvent(AgpsEvent event){

    LOC_LOGD("DSStateMachine::processAgpsEvent() %d", event);

    /* DS Client call setup APIs don't return failure/closure separately.
     * Hence we receive RELEASED event in both cases.
     * If we are in pending, we should consider RELEASED as DENIED */
    if(event == AGPS_EVENT_RELEASED && mState == AGPS_STATE_PENDING){

        LOC_LOGD("Translating RELEASED to DENIED event");
        event = AGPS_EVENT_DENIED;
    }

    /* Redirect process to base class */
    AgpsStateMachine::processAgpsEvent(event);
}

/* Timer Callback
 * For the retry timer started in case of DS Client call setup failure */
void delay_callback(void *callbackData, int result)
{
    LOC_LOGD("delay_callback(): cbData %p", callbackData);

    (void)result;

    if(callbackData == NULL) {
        LOC_LOGE("delay_callback(): NULL argument received !");
        return;
    }
    DSStateMachine* dsStateMachine = (DSStateMachine *)callbackData;
    dsStateMachine->retryCallback();
}

/* Invoked from Timer Callback
 * For the retry timer started in case of DS Client call setup failure */
void DSStateMachine :: retryCallback()
{
    LOC_LOGD("DSStateMachine::retryCallback()");

    /* Request SUPL ES
     * There must be at least one active subscriber in list */
    AgpsSubscriber* subscriber = getFirstSubscriber(false);
    if(subscriber == NULL) {

        LOC_LOGE("No active subscriber for DS Client call setup");
        return;
    }

    /* Send message to retry */
    mAgpsManager->mSendMsgToAdapterQueueFn(
            new AgpsMsgRequestATL(
                    mAgpsManager, subscriber->mConnHandle,
                    LOC_AGPS_TYPE_SUPL_ES));
}

/* Overridden method
 * Request or Release data connection
 * bool request :
 *      true  = Request data connection
 *      false = Release data connection */
int DSStateMachine::requestOrReleaseDataConn(bool request){

    LOC_LOGD("DSStateMachine::requestOrReleaseDataConn(): "
             "request %d", request);

    /* Release data connection required ? */
    if(!request && mAgpsManager->mDSClientStopDataCallFn){

        mAgpsManager->mDSClientStopDataCallFn();
        LOC_LOGD("DS Client release data call request sent !");
        return 0;
    }

    /* Setup data connection request
     * There must be at least one active subscriber in list */
    AgpsSubscriber* subscriber = getFirstSubscriber(false);
    if(subscriber == NULL) {

        LOC_LOGE("No active subscriber for DS Client call setup");
        return -1;
    }

    /* DS Client Fn registered ? */
    if(!mAgpsManager->mDSClientOpenAndStartDataCallFn){

        LOC_LOGE("DS Client start fn not registered, fallback to SUPL ATL");
        notifyEventToSubscriber(AGPS_EVENT_DENIED, subscriber, false);
        return -1;
    }

    /* Setup the call */
    int ret = mAgpsManager->mDSClientOpenAndStartDataCallFn();

    /* Check if data call start failed */
    switch (ret) {

        case LOC_API_ADAPTER_ERR_ENGINE_BUSY:
            LOC_LOGE("DS Client open call failed, err: %d", ret);
            mRetries++;
            if(mRetries > MAX_START_DATA_CALL_RETRIES) {

                LOC_LOGE("DS Client call retries exhausted, "
                         "falling back to normal SUPL ATL");
                notifyEventToSubscriber(AGPS_EVENT_DENIED, subscriber, false);
            }
            /* Retry DS Client call setup after some delay */
            else if(loc_timer_start(
                        DATA_CALL_RETRY_DELAY_MSEC, delay_callback, this)) {
                    LOC_LOGE("Error: Could not start delay thread\n");
                    return -1;
                }
            break;

        case LOC_API_ADAPTER_ERR_UNSUPPORTED:
            LOC_LOGE("No emergency profile found. Fall back to normal SUPL ATL");
            notifyEventToSubscriber(AGPS_EVENT_DENIED, subscriber, false);
            break;

        case LOC_API_ADAPTER_ERR_SUCCESS:
            LOC_LOGD("Request to start data call sent");
            break;

        default:
            LOC_LOGE("Unrecognized return value: %d", ret);
    }

    return ret;
}

void DSStateMachine::notifyEventToSubscriber(
        AgpsEvent event, AgpsSubscriber* subscriberToNotify,
        bool deleteSubscriberPostNotify) {

    LOC_LOGD("DSStateMachine::notifyEventToSubscriber(): "
             "SM %p, Event %d Subscriber %p Delete %d",
             this, event, subscriberToNotify, deleteSubscriberPostNotify);

    switch (event){

        case AGPS_EVENT_GRANTED:
            mAgpsManager->mAtlOpenStatusCb(
                    subscriberToNotify->mConnHandle, 1, NULL,
                    AGPS_APN_BEARER_INVALID, LOC_AGPS_TYPE_SUPL_ES);
            break;

        case AGPS_EVENT_DENIED:
            /* Now try with regular SUPL
             * We need to send request via message queue */
            mRetries = 0;
            mAgpsManager->mSendMsgToAdapterQueueFn(
                    new AgpsMsgRequestATL(
                            mAgpsManager, subscriberToNotify->mConnHandle,
                            LOC_AGPS_TYPE_SUPL));
            break;

        case AGPS_EVENT_UNSUBSCRIBE:
            mAgpsManager->mAtlCloseStatusCb(subscriberToNotify->mConnHandle, 1);
            break;

        case AGPS_EVENT_RELEASED:
            mAgpsManager->mDSClientCloseDataCallFn();
            mAgpsManager->mAtlCloseStatusCb(subscriberToNotify->mConnHandle, 1);
            break;

        default:
            LOC_LOGE("Invalid event %d", event);
    }

    /* Search this subscriber in list and delete */
    if (deleteSubscriberPostNotify) {
        deleteSubscriber(subscriberToNotify);
    }
}

/* --------------------------------------------------------------------
 *   Loc AGPS Manager Methods
 * -------------------------------------------------------------------*/

/* CREATE AGPS STATE MACHINES
 * Must be invoked in Msg Handler context */
void AgpsManager::createAgpsStateMachines() {

    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) {
        mInternetNif = new AgpsStateMachine(this, LOC_AGPS_TYPE_WWAN_ANY);
        LOC_LOGD("Internet NIF: %p", mInternetNif);
    }
    if (agpsCapable) {
        if (NULL == mAgnssNif) {
            mAgnssNif = new AgpsStateMachine(this, LOC_AGPS_TYPE_SUPL);
            LOC_LOGD("AGNSS NIF: %p", mAgnssNif);
        }
        if (NULL == mDsNif &&
                loc_core::ContextBase::mGps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL){

            if(!mDSClientInitFn){

                LOC_LOGE("DS Client Init Fn not registered !");
                return;
            }
            if(mDSClientInitFn(false) != 0){

                LOC_LOGE("Failed to init data service client");
                return;
            }
            mDsNif = new DSStateMachine(this);
            LOC_LOGD("DS NIF: %p", mDsNif);
        }
    }
}

AgpsStateMachine* AgpsManager::getAgpsStateMachine(AGpsExtType agpsType) {

    LOC_LOGD("AgpsManager::getAgpsStateMachine(): agpsType %d", agpsType);

    switch (agpsType) {

        case LOC_AGPS_TYPE_INVALID:
        case LOC_AGPS_TYPE_SUPL:
            if(mAgnssNif == NULL){
                LOC_LOGE("NULL AGNSS NIF !");
            }
            return mAgnssNif;

        case LOC_AGPS_TYPE_SUPL_ES:
            if (loc_core::ContextBase::mGps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL) {
                if (mDsNif == NULL) {
                    createAgpsStateMachines();
                }
                return mDsNif;
            } else {
                return mAgnssNif;
            }

        default:
            return mInternetNif;
    }

    LOC_LOGE("No SM found !");
    return NULL;
}

void AgpsManager::requestATL(int connHandle, AGpsExtType agpsType){

    LOC_LOGD("AgpsManager::requestATL(): connHandle %d, agpsType %d",
               connHandle, agpsType);

    AgpsStateMachine* sm = getAgpsStateMachine(agpsType);

    if(sm == NULL){

        LOC_LOGE("No AGPS State Machine for agpsType: %d", agpsType);
        mAtlOpenStatusCb(
                connHandle, 0, NULL, AGPS_APN_BEARER_INVALID, agpsType);
        return;
    }

    /* Invoke AGPS SM processing */
    AgpsSubscriber subscriber(connHandle, false, false);
    sm->setCurrentSubscriber(&subscriber);

    /* If DS State Machine, wait for close complete */
    if(agpsType == LOC_AGPS_TYPE_SUPL_ES){
        subscriber.mWaitForCloseComplete = true;
    }

    /* 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;
    }
    else if (mDsNif &&
            (subscriber = mDsNif->getSubscriber(connHandle)) != NULL) {
        sm = mDsNif;
    }

    if(sm == NULL){
        LOC_LOGE("Subscriber with connHandle %d not found in any SM",
                    connHandle);
        mAtlCloseStatusCb(connHandle, 0);
        return;
    }

    /* Now send unsubscribe event */
    sm->setCurrentSubscriber(subscriber);
    sm->processAgpsEvent(AGPS_EVENT_UNSUBSCRIBE);
}

void AgpsManager::reportDataCallOpened(){

    LOC_LOGD("AgpsManager::reportDataCallOpened");

    if (mDsNif) {
        mDsNif->processAgpsEvent(AGPS_EVENT_GRANTED);
    }
}

void AgpsManager::reportDataCallClosed(){

    LOC_LOGD("AgpsManager::reportDataCallClosed");

    if (mDsNif) {
        mDsNif->processAgpsEvent(AGPS_EVENT_RELEASED);
    }
}

void AgpsManager::reportAtlOpenSuccess(
        AGpsExtType agpsType, char* apnName, int apnLen,
        LocApnIpType ipType){

    LOC_LOGD("AgpsManager::reportAtlOpenSuccess(): "
             "AgpsType %d, APN [%s], Len %d, IPType %d",
             agpsType, apnName, apnLen, ipType);

    /* Find the state machine instance */
    AgpsStateMachine* sm = getAgpsStateMachine(agpsType);

    /* Convert LocApnIpType sent by framework to AGpsBearerType */
    AGpsBearerType bearerType;
    switch (ipType) {
        case LOC_APN_IP_IPV4:
            bearerType = AGPS_APN_BEARER_IPV4;
            break;
        case LOC_APN_IP_IPV6:
            bearerType = AGPS_APN_BEARER_IPV6;
            break;
        case LOC_APN_IP_IPV4V6:
            bearerType = AGPS_APN_BEARER_IPV4V6;
            break;
        default:
            bearerType = AGPS_APN_BEARER_IPV4;
            break;
    }

    /* 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();
    }
    if(mDsNif){
        mDsNif->dropAllSubscribers();
    }

    // reinitialize DS client in SSR mode
    if(loc_core::ContextBase::mGps_conf.
            USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL){

        mDSClientStopDataCallFn();
        mDSClientCloseDataCallFn();
        mDSClientReleaseFn();

        mDSClientInitFn(true);
    }
}

AGpsBearerType AgpsUtils::ipTypeToBearerType(LocApnIpType ipType) {

    switch (ipType) {

        case LOC_APN_IP_IPV4:
            return AGPS_APN_BEARER_IPV4;

        case LOC_APN_IP_IPV6:
            return AGPS_APN_BEARER_IPV6;

        case LOC_APN_IP_IPV4V6:
            return AGPS_APN_BEARER_IPV4V6;

        default:
            return AGPS_APN_BEARER_IPV4;
    }
}

LocApnIpType AgpsUtils::bearerTypeToIpType(AGpsBearerType bearerType){

    switch (bearerType) {

        case AGPS_APN_BEARER_IPV4:
            return LOC_APN_IP_IPV4;

        case AGPS_APN_BEARER_IPV6:
            return LOC_APN_IP_IPV6;

        case AGPS_APN_BEARER_IPV4V6:
            return LOC_APN_IP_IPV4V6;

        default:
            return LOC_APN_IP_IPV4;
    }
}
