18c2d3d5afc51d3f35150f748f263870367771b6fEd Tam/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
28c2d3d5afc51d3f35150f748f263870367771b6fEd Tam *
38c2d3d5afc51d3f35150f748f263870367771b6fEd Tam * Redistribution and use in source and binary forms, with or without
48c2d3d5afc51d3f35150f748f263870367771b6fEd Tam * modification, are permitted provided that the following conditions are
58c2d3d5afc51d3f35150f748f263870367771b6fEd Tam * met:
68c2d3d5afc51d3f35150f748f263870367771b6fEd Tam *     * Redistributions of source code must retain the above copyright
78c2d3d5afc51d3f35150f748f263870367771b6fEd Tam *       notice, this list of conditions and the following disclaimer.
88c2d3d5afc51d3f35150f748f263870367771b6fEd Tam *     * Redistributions in binary form must reproduce the above
98c2d3d5afc51d3f35150f748f263870367771b6fEd Tam *       copyright notice, this list of conditions and the following
108c2d3d5afc51d3f35150f748f263870367771b6fEd Tam *       disclaimer in the documentation and/or other materials provided
118c2d3d5afc51d3f35150f748f263870367771b6fEd Tam *       with the distribution.
128c2d3d5afc51d3f35150f748f263870367771b6fEd Tam *     * Neither the name of The Linux Foundation, nor the names of its
138c2d3d5afc51d3f35150f748f263870367771b6fEd Tam *       contributors may be used to endorse or promote products derived
148c2d3d5afc51d3f35150f748f263870367771b6fEd Tam *       from this software without specific prior written permission.
158c2d3d5afc51d3f35150f748f263870367771b6fEd Tam *
168c2d3d5afc51d3f35150f748f263870367771b6fEd Tam * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
178c2d3d5afc51d3f35150f748f263870367771b6fEd Tam * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
188c2d3d5afc51d3f35150f748f263870367771b6fEd Tam * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
198c2d3d5afc51d3f35150f748f263870367771b6fEd Tam * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
208c2d3d5afc51d3f35150f748f263870367771b6fEd Tam * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
218c2d3d5afc51d3f35150f748f263870367771b6fEd Tam * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
228c2d3d5afc51d3f35150f748f263870367771b6fEd Tam * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
238c2d3d5afc51d3f35150f748f263870367771b6fEd Tam * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
248c2d3d5afc51d3f35150f748f263870367771b6fEd Tam * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
258c2d3d5afc51d3f35150f748f263870367771b6fEd Tam * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
268c2d3d5afc51d3f35150f748f263870367771b6fEd Tam * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
278c2d3d5afc51d3f35150f748f263870367771b6fEd Tam *
288c2d3d5afc51d3f35150f748f263870367771b6fEd Tam */
298c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
308c2d3d5afc51d3f35150f748f263870367771b6fEd Tam#define LOG_NDDEBUG 0
318c2d3d5afc51d3f35150f748f263870367771b6fEd Tam#define LOG_TAG "LocSvc_eng"
328c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
338c2d3d5afc51d3f35150f748f263870367771b6fEd Tam#include <loc_eng_agps.h>
348c2d3d5afc51d3f35150f748f263870367771b6fEd Tam#include <loc_eng_log.h>
358c2d3d5afc51d3f35150f748f263870367771b6fEd Tam#include <log_util.h>
368c2d3d5afc51d3f35150f748f263870367771b6fEd Tam#include <platform_lib_includes.h>
378c2d3d5afc51d3f35150f748f263870367771b6fEd Tam#include <loc_eng_dmn_conn_handler.h>
388c2d3d5afc51d3f35150f748f263870367771b6fEd Tam#include <loc_eng_dmn_conn.h>
398c2d3d5afc51d3f35150f748f263870367771b6fEd Tam#include <sys/time.h>
408c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
418c2d3d5afc51d3f35150f748f263870367771b6fEd Tam//======================================================================
428c2d3d5afc51d3f35150f748f263870367771b6fEd Tam// C callbacks
438c2d3d5afc51d3f35150f748f263870367771b6fEd Tam//======================================================================
448c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
458c2d3d5afc51d3f35150f748f263870367771b6fEd Tam// This is given to linked_list_add as the dealloc callback
468c2d3d5afc51d3f35150f748f263870367771b6fEd Tam// data -- an instance of Subscriber
478c2d3d5afc51d3f35150f748f263870367771b6fEd Tamstatic void deleteObj(void* data)
488c2d3d5afc51d3f35150f748f263870367771b6fEd Tam{
498c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    delete (Subscriber*)data;
508c2d3d5afc51d3f35150f748f263870367771b6fEd Tam}
518c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
528c2d3d5afc51d3f35150f748f263870367771b6fEd Tam// This is given to linked_list_search() as the comparison callback
538c2d3d5afc51d3f35150f748f263870367771b6fEd Tam// when the state manchine needs to process for particular subscriber
548c2d3d5afc51d3f35150f748f263870367771b6fEd Tam// fromCaller -- caller provides this obj
558c2d3d5afc51d3f35150f748f263870367771b6fEd Tam// fromList -- linked_list_search() function take this one from list
568c2d3d5afc51d3f35150f748f263870367771b6fEd Tamstatic bool hasSubscriber(void* fromCaller, void* fromList)
578c2d3d5afc51d3f35150f748f263870367771b6fEd Tam{
588c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    Notification* notification = (Notification*)fromCaller;
598c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    Subscriber* s1 = (Subscriber*)fromList;
608c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
618c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    return s1->forMe(*notification);
628c2d3d5afc51d3f35150f748f263870367771b6fEd Tam}
638c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
648c2d3d5afc51d3f35150f748f263870367771b6fEd Tam// This is gvien to linked_list_search() to notify subscriber objs
658c2d3d5afc51d3f35150f748f263870367771b6fEd Tam// when the state machine needs to inform all subscribers of resource
668c2d3d5afc51d3f35150f748f263870367771b6fEd Tam// status changes, e.g. when resource is GRANTED.
678c2d3d5afc51d3f35150f748f263870367771b6fEd Tam// fromCaller -- caller provides this ptr to a Notification obj.
688c2d3d5afc51d3f35150f748f263870367771b6fEd Tam// fromList -- linked_list_search() function take this one from list
698c2d3d5afc51d3f35150f748f263870367771b6fEd Tamstatic bool notifySubscriber(void* fromCaller, void* fromList)
708c2d3d5afc51d3f35150f748f263870367771b6fEd Tam{
718c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    Notification* notification = (Notification*)fromCaller;
728c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    Subscriber* s1 = (Subscriber*)fromList;
738c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
748c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    // we notify every subscriber indiscriminatively
758c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    // each subscriber decides if this notification is interesting.
768c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    return s1->notifyRsrcStatus(*notification) &&
778c2d3d5afc51d3f35150f748f263870367771b6fEd Tam           // if we do not want to delete the subscriber from the
788c2d3d5afc51d3f35150f748f263870367771b6fEd Tam           // the list, we must set this to false so this function
798c2d3d5afc51d3f35150f748f263870367771b6fEd Tam           // returns false
808c2d3d5afc51d3f35150f748f263870367771b6fEd Tam           notification->postNotifyDelete;
818c2d3d5afc51d3f35150f748f263870367771b6fEd Tam}
828c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
838c2d3d5afc51d3f35150f748f263870367771b6fEd Tam//======================================================================
848c2d3d5afc51d3f35150f748f263870367771b6fEd Tam// Notification
858c2d3d5afc51d3f35150f748f263870367771b6fEd Tam//======================================================================
868c2d3d5afc51d3f35150f748f263870367771b6fEd Tamconst int Notification::BROADCAST_ALL = 0x80000000;
878c2d3d5afc51d3f35150f748f263870367771b6fEd Tamconst int Notification::BROADCAST_ACTIVE = 0x80000001;
888c2d3d5afc51d3f35150f748f263870367771b6fEd Tamconst int Notification::BROADCAST_INACTIVE = 0x80000002;
898c2d3d5afc51d3f35150f748f263870367771b6fEd Tamconst unsigned char DSStateMachine::MAX_START_DATA_CALL_RETRIES = 4;
908c2d3d5afc51d3f35150f748f263870367771b6fEd Tamconst unsigned int DSStateMachine::DATA_CALL_RETRY_DELAY_MSEC = 500;
918c2d3d5afc51d3f35150f748f263870367771b6fEd Tam//======================================================================
928c2d3d5afc51d3f35150f748f263870367771b6fEd Tam// Subscriber:  BITSubscriber / ATLSubscriber / WIFISubscriber
938c2d3d5afc51d3f35150f748f263870367771b6fEd Tam//======================================================================
948c2d3d5afc51d3f35150f748f263870367771b6fEd Tambool Subscriber::forMe(Notification &notification)
958c2d3d5afc51d3f35150f748f263870367771b6fEd Tam{
968c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    if (NULL != notification.rcver) {
978c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        return equals(notification.rcver);
988c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    } else {
998c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        return Notification::BROADCAST_ALL == notification.groupID ||
1008c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            (Notification::BROADCAST_ACTIVE == notification.groupID &&
1018c2d3d5afc51d3f35150f748f263870367771b6fEd Tam             !isInactive()) ||
1028c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            (Notification::BROADCAST_INACTIVE == notification.groupID &&
1038c2d3d5afc51d3f35150f748f263870367771b6fEd Tam             isInactive());
1048c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    }
1058c2d3d5afc51d3f35150f748f263870367771b6fEd Tam}
1068c2d3d5afc51d3f35150f748f263870367771b6fEd Tambool BITSubscriber::equals(const Subscriber *s) const
1078c2d3d5afc51d3f35150f748f263870367771b6fEd Tam{
1088c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    BITSubscriber* bitS = (BITSubscriber*)s;
1098c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
1108c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    return (ID == bitS->ID &&
1118c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            (INADDR_NONE != (unsigned int)ID ||
1128c2d3d5afc51d3f35150f748f263870367771b6fEd Tam             0 == strncmp(mIPv6Addr, bitS->mIPv6Addr, sizeof(mIPv6Addr))));
1138c2d3d5afc51d3f35150f748f263870367771b6fEd Tam}
1148c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
1158c2d3d5afc51d3f35150f748f263870367771b6fEd Tambool BITSubscriber::notifyRsrcStatus(Notification &notification)
1168c2d3d5afc51d3f35150f748f263870367771b6fEd Tam{
1178c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    bool notify = forMe(notification);
1188c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
1198c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    if (notify) {
1208c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        switch(notification.rsrcStatus)
1218c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        {
1228c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        case RSRC_UNSUBSCRIBE:
1238c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        case RSRC_RELEASED:
1248c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            loc_eng_dmn_conn_loc_api_server_data_conn(
1258c2d3d5afc51d3f35150f748f263870367771b6fEd Tam                LOC_ENG_IF_REQUEST_SENDER_ID_GPSONE_DAEMON,
1268c2d3d5afc51d3f35150f748f263870367771b6fEd Tam                GPSONE_LOC_API_IF_RELEASE_SUCCESS);
1278c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            break;
1288c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        case RSRC_DENIED:
1298c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            loc_eng_dmn_conn_loc_api_server_data_conn(
1308c2d3d5afc51d3f35150f748f263870367771b6fEd Tam                LOC_ENG_IF_REQUEST_SENDER_ID_GPSONE_DAEMON,
1318c2d3d5afc51d3f35150f748f263870367771b6fEd Tam                GPSONE_LOC_API_IF_FAILURE);
1328c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            break;
1338c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        case RSRC_GRANTED:
1348c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            loc_eng_dmn_conn_loc_api_server_data_conn(
1358c2d3d5afc51d3f35150f748f263870367771b6fEd Tam                LOC_ENG_IF_REQUEST_SENDER_ID_GPSONE_DAEMON,
1368c2d3d5afc51d3f35150f748f263870367771b6fEd Tam                GPSONE_LOC_API_IF_REQUEST_SUCCESS);
1378c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            break;
1388c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        default:
1398c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            notify = false;
1408c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        }
1418c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    }
1428c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
1438c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    return notify;
1448c2d3d5afc51d3f35150f748f263870367771b6fEd Tam}
1458c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
1468c2d3d5afc51d3f35150f748f263870367771b6fEd Tambool ATLSubscriber::notifyRsrcStatus(Notification &notification)
1478c2d3d5afc51d3f35150f748f263870367771b6fEd Tam{
1488c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    bool notify = forMe(notification);
1498c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
1508c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    if (notify) {
1518c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        switch(notification.rsrcStatus)
1528c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        {
1538c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        case RSRC_UNSUBSCRIBE:
1548c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        case RSRC_RELEASED:
1558c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            ((LocEngAdapter*)mLocAdapter)->atlCloseStatus(ID, 1);
1568c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            break;
1578c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        case RSRC_DENIED:
1588c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        {
1598c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            AGpsExtType type = mBackwardCompatibleMode ?
1608c2d3d5afc51d3f35150f748f263870367771b6fEd Tam                              AGPS_TYPE_INVALID : mStateMachine->getType();
1618c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            ((LocEngAdapter*)mLocAdapter)->atlOpenStatus(ID, 0,
1628c2d3d5afc51d3f35150f748f263870367771b6fEd Tam                                            (char*)mStateMachine->getAPN(),
1638c2d3d5afc51d3f35150f748f263870367771b6fEd Tam                                            mStateMachine->getBearer(),
1648c2d3d5afc51d3f35150f748f263870367771b6fEd Tam                                            type);
1658c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        }
1668c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            break;
1678c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        case RSRC_GRANTED:
1688c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        {
1698c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            AGpsExtType type = mBackwardCompatibleMode ?
1708c2d3d5afc51d3f35150f748f263870367771b6fEd Tam                              AGPS_TYPE_INVALID : mStateMachine->getType();
1718c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            ((LocEngAdapter*)mLocAdapter)->atlOpenStatus(ID, 1,
1728c2d3d5afc51d3f35150f748f263870367771b6fEd Tam                                            (char*)mStateMachine->getAPN(),
1738c2d3d5afc51d3f35150f748f263870367771b6fEd Tam                                            mStateMachine->getBearer(),
1748c2d3d5afc51d3f35150f748f263870367771b6fEd Tam                                            type);
1758c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        }
1768c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            break;
1778c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        default:
1788c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            notify = false;
1798c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        }
1808c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    }
1818c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
1828c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    return notify;
1838c2d3d5afc51d3f35150f748f263870367771b6fEd Tam}
1848c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
1858c2d3d5afc51d3f35150f748f263870367771b6fEd Tambool WIFISubscriber::notifyRsrcStatus(Notification &notification)
1868c2d3d5afc51d3f35150f748f263870367771b6fEd Tam{
1878c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    bool notify = forMe(notification);
1888c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
1898c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    if (notify) {
1908c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        switch(notification.rsrcStatus)
1918c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        {
1928c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        case RSRC_UNSUBSCRIBE:
1938c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            break;
1948c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        case RSRC_RELEASED:
1958c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            loc_eng_dmn_conn_loc_api_server_data_conn(
1968c2d3d5afc51d3f35150f748f263870367771b6fEd Tam                senderId,
1978c2d3d5afc51d3f35150f748f263870367771b6fEd Tam                GPSONE_LOC_API_IF_RELEASE_SUCCESS);
1988c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            break;
1998c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        case RSRC_DENIED:
2008c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            loc_eng_dmn_conn_loc_api_server_data_conn(
2018c2d3d5afc51d3f35150f748f263870367771b6fEd Tam                senderId,
2028c2d3d5afc51d3f35150f748f263870367771b6fEd Tam                GPSONE_LOC_API_IF_FAILURE);
2038c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            break;
2048c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        case RSRC_GRANTED:
2058c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            loc_eng_dmn_conn_loc_api_server_data_conn(
2068c2d3d5afc51d3f35150f748f263870367771b6fEd Tam                senderId,
2078c2d3d5afc51d3f35150f748f263870367771b6fEd Tam                GPSONE_LOC_API_IF_REQUEST_SUCCESS);
2088c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            break;
2098c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        default:
2108c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            notify = false;
2118c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        }
2128c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    }
2138c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
2148c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    return notify;
2158c2d3d5afc51d3f35150f748f263870367771b6fEd Tam}
2168c2d3d5afc51d3f35150f748f263870367771b6fEd Tambool DSSubscriber::notifyRsrcStatus(Notification &notification)
2178c2d3d5afc51d3f35150f748f263870367771b6fEd Tam{
2188c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    bool notify = forMe(notification);
2198c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    LOC_LOGD("DSSubscriber::notifyRsrcStatus. notify:%d \n",(int)(notify));
2208c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    if(notify) {
2218c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        switch(notification.rsrcStatus) {
2228c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        case RSRC_UNSUBSCRIBE:
2238c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        case RSRC_RELEASED:
2248c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        case RSRC_DENIED:
2258c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        case RSRC_GRANTED:
2268c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            ((DSStateMachine *)mStateMachine)->informStatus(notification.rsrcStatus, ID);
2278c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            break;
2288c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        default:
2298c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            notify = false;
2308c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        }
2318c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    }
2328c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    return notify;
2338c2d3d5afc51d3f35150f748f263870367771b6fEd Tam}
2348c2d3d5afc51d3f35150f748f263870367771b6fEd Tamvoid DSSubscriber :: setInactive()
2358c2d3d5afc51d3f35150f748f263870367771b6fEd Tam{
2368c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    mIsInactive = true;
2378c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    ((DSStateMachine *)mStateMachine)->informStatus(RSRC_UNSUBSCRIBE, ID);
2388c2d3d5afc51d3f35150f748f263870367771b6fEd Tam}
2398c2d3d5afc51d3f35150f748f263870367771b6fEd Tam//======================================================================
2408c2d3d5afc51d3f35150f748f263870367771b6fEd Tam// AgpsState:  AgpsReleasedState / AgpsPendingState / AgpsAcquiredState
2418c2d3d5afc51d3f35150f748f263870367771b6fEd Tam//======================================================================
2428c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
2438c2d3d5afc51d3f35150f748f263870367771b6fEd Tam// AgpsReleasedState
2448c2d3d5afc51d3f35150f748f263870367771b6fEd Tamclass AgpsReleasedState : public AgpsState
2458c2d3d5afc51d3f35150f748f263870367771b6fEd Tam{
2468c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    friend class AgpsStateMachine;
2478c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
2488c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    inline AgpsReleasedState(AgpsStateMachine* stateMachine) :
2498c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        AgpsState(stateMachine)
2508c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    { mReleasedState = this; }
2518c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
2528c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    inline ~AgpsReleasedState() {}
2538c2d3d5afc51d3f35150f748f263870367771b6fEd Tampublic:
2548c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    virtual AgpsState* onRsrcEvent(AgpsRsrcStatus event, void* data);
2558c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    inline virtual char* whoami() {return (char*)"AgpsReleasedState";}
2568c2d3d5afc51d3f35150f748f263870367771b6fEd Tam};
2578c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
2588c2d3d5afc51d3f35150f748f263870367771b6fEd TamAgpsState* AgpsReleasedState::onRsrcEvent(AgpsRsrcStatus event, void* data)
2598c2d3d5afc51d3f35150f748f263870367771b6fEd Tam{
2608c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    LOC_LOGD("AgpsReleasedState::onRsrcEvent; event:%d\n", (int)event);
2618c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    if (mStateMachine->hasSubscribers()) {
2628c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        LOC_LOGE("Error: %s subscriber list not empty!!!", whoami());
2638c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        // I don't know how to recover from it.  I am adding this rather
2648c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        // for debugging purpose.
2658c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    }
2668c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
2678c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    AgpsState* nextState = this;
2688c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    switch (event)
2698c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    {
2708c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    case RSRC_SUBSCRIBE:
2718c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    {
2728c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        // no notification until we get RSRC_GRANTED
2738c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        // but we need to add subscriber to the list
2748c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        mStateMachine->addSubscriber((Subscriber*)data);
2758c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        // request from connecivity service for NIF
2768c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        //The if condition is added so that if the data call setup fails
2778c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        //for DS State Machine, we want to retry in released state.
2788c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        //for AGps State Machine, sendRsrcRequest() will always return success
2798c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        if(!mStateMachine->sendRsrcRequest(GPS_REQUEST_AGPS_DATA_CONN)) {
2808c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            // move the state to PENDING
2818c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            nextState = mPendingState;
2828c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        }
2838c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    }
2848c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    break;
2858c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
2868c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    case RSRC_UNSUBSCRIBE:
2878c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    {
2888c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        // the list should really be empty, nothing to remove.
2898c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        // but we might as well just tell the client it is
2908c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        // unsubscribed.  False tolerance, right?
2918c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        Subscriber* subscriber = (Subscriber*) data;
2928c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        Notification notification(subscriber, event, false);
2938c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        subscriber->notifyRsrcStatus(notification);
2948c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    }
2958c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        // break;
2968c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    case RSRC_GRANTED:
2978c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    case RSRC_RELEASED:
2988c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    case RSRC_DENIED:
2998c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    default:
3008c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        LOC_LOGW("%s: unrecognized event %d", whoami(), event);
3018c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        // no state change.
3028c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        break;
3038c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    }
3048c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
3058c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    LOC_LOGD("onRsrcEvent, old state %s, new state %s, event %d",
3068c2d3d5afc51d3f35150f748f263870367771b6fEd Tam             whoami(), nextState->whoami(), event);
3078c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    return nextState;
3088c2d3d5afc51d3f35150f748f263870367771b6fEd Tam}
3098c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
3108c2d3d5afc51d3f35150f748f263870367771b6fEd Tam// AgpsPendingState
3118c2d3d5afc51d3f35150f748f263870367771b6fEd Tamclass AgpsPendingState : public AgpsState
3128c2d3d5afc51d3f35150f748f263870367771b6fEd Tam{
3138c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    friend class AgpsStateMachine;
3148c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
3158c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    inline AgpsPendingState(AgpsStateMachine* stateMachine) :
3168c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        AgpsState(stateMachine)
3178c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    { mPendingState = this; }
3188c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
3198c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    inline ~AgpsPendingState() {}
3208c2d3d5afc51d3f35150f748f263870367771b6fEd Tampublic:
3218c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    virtual AgpsState* onRsrcEvent(AgpsRsrcStatus event, void* data);
3228c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    inline virtual char* whoami() {return (char*)"AgpsPendingState";}
3238c2d3d5afc51d3f35150f748f263870367771b6fEd Tam};
3248c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
3258c2d3d5afc51d3f35150f748f263870367771b6fEd TamAgpsState* AgpsPendingState::onRsrcEvent(AgpsRsrcStatus event, void* data)
3268c2d3d5afc51d3f35150f748f263870367771b6fEd Tam{
3278c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    AgpsState* nextState = this;;
3288c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    LOC_LOGD("AgpsPendingState::onRsrcEvent; event:%d\n", (int)event);
3298c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    switch (event)
3308c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    {
3318c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    case RSRC_SUBSCRIBE:
3328c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    {
3338c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        // already requested for NIF resource,
3348c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        // do nothing until we get RSRC_GRANTED indication
3358c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        // but we need to add subscriber to the list
3368c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        mStateMachine->addSubscriber((Subscriber*)data);
3378c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        // no state change.
3388c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    }
3398c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        break;
3408c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
3418c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    case RSRC_UNSUBSCRIBE:
3428c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    {
3438c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        Subscriber* subscriber = (Subscriber*) data;
3448c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        if (subscriber->waitForCloseComplete()) {
3458c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            subscriber->setInactive();
3468c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        } else {
3478c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            // auto notify this subscriber of the unsubscribe
3488c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            Notification notification(subscriber, event, true);
3498c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            mStateMachine->notifySubscribers(notification);
3508c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        }
3518c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
3528c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        // now check if there is any subscribers left
3538c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        if (!mStateMachine->hasSubscribers()) {
3548c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            // no more subscribers, move to RELEASED state
3558c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            nextState = mReleasedState;
3568c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
3578c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            // tell connecivity service we can release NIF
3588c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            mStateMachine->sendRsrcRequest(GPS_RELEASE_AGPS_DATA_CONN);
3598c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        } else if (!mStateMachine->hasActiveSubscribers()) {
3608c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            // only inactive subscribers, move to RELEASING state
3618c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            nextState = mReleasingState;
3628c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
3638c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            // tell connecivity service we can release NIF
3648c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            mStateMachine->sendRsrcRequest(GPS_RELEASE_AGPS_DATA_CONN);
3658c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        }
3668c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    }
3678c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    break;
3688c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
3698c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    case RSRC_GRANTED:
3708c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    {
3718c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        nextState = mAcquiredState;
3728c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        Notification notification(Notification::BROADCAST_ACTIVE, event, false);
3738c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        // notify all subscribers NIF resource GRANTED
3748c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        // by setting false, we keep subscribers on the linked list
3758c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        mStateMachine->notifySubscribers(notification);
3768c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    }
3778c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        break;
3788c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
3798c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    case RSRC_RELEASED:
3808c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        // no state change.
3818c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        // we are expecting either GRANTED or DENIED.  Handling RELEASED
3828c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        // may like break our state machine in race conditions.
3838c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        break;
3848c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
3858c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    case RSRC_DENIED:
3868c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    {
3878c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        nextState = mReleasedState;
3888c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        Notification notification(Notification::BROADCAST_ALL, event, true);
3898c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        // notify all subscribers NIF resource RELEASED or DENIED
3908c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        // by setting true, we remove subscribers from the linked list
3918c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        mStateMachine->notifySubscribers(notification);
3928c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    }
3938c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        break;
3948c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
3958c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    default:
3968c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        LOC_LOGE("%s: unrecognized event %d", whoami(), event);
3978c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        // no state change.
3988c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    }
3998c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
4008c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    LOC_LOGD("onRsrcEvent, old state %s, new state %s, event %d",
4018c2d3d5afc51d3f35150f748f263870367771b6fEd Tam             whoami(), nextState->whoami(), event);
4028c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    return nextState;
4038c2d3d5afc51d3f35150f748f263870367771b6fEd Tam}
4048c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
4058c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
4068c2d3d5afc51d3f35150f748f263870367771b6fEd Tamclass AgpsAcquiredState : public AgpsState
4078c2d3d5afc51d3f35150f748f263870367771b6fEd Tam{
4088c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    friend class AgpsStateMachine;
4098c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
4108c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    inline AgpsAcquiredState(AgpsStateMachine* stateMachine) :
4118c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        AgpsState(stateMachine)
4128c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    { mAcquiredState = this; }
4138c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
4148c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    inline ~AgpsAcquiredState() {}
4158c2d3d5afc51d3f35150f748f263870367771b6fEd Tampublic:
4168c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    virtual AgpsState* onRsrcEvent(AgpsRsrcStatus event, void* data);
4178c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    inline virtual char* whoami() { return (char*)"AgpsAcquiredState"; }
4188c2d3d5afc51d3f35150f748f263870367771b6fEd Tam};
4198c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
4208c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
4218c2d3d5afc51d3f35150f748f263870367771b6fEd TamAgpsState* AgpsAcquiredState::onRsrcEvent(AgpsRsrcStatus event, void* data)
4228c2d3d5afc51d3f35150f748f263870367771b6fEd Tam{
4238c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    AgpsState* nextState = this;
4248c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    LOC_LOGD("AgpsAcquiredState::onRsrcEvent; event:%d\n", (int)event);
4258c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    switch (event)
4268c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    {
4278c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    case RSRC_SUBSCRIBE:
4288c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    {
4298c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        // we already have the NIF resource, simply notify subscriber
4308c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        Subscriber* subscriber = (Subscriber*) data;
4318c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        // we have rsrc in hand, so grant it right away
4328c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        Notification notification(subscriber, RSRC_GRANTED, false);
4338c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        subscriber->notifyRsrcStatus(notification);
4348c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        // add subscriber to the list
4358c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        mStateMachine->addSubscriber(subscriber);
4368c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        // no state change.
4378c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    }
4388c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        break;
4398c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
4408c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    case RSRC_UNSUBSCRIBE:
4418c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    {
4428c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        Subscriber* subscriber = (Subscriber*) data;
4438c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        if (subscriber->waitForCloseComplete()) {
4448c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            subscriber->setInactive();
4458c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        } else {
4468c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            // auto notify this subscriber of the unsubscribe
4478c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            Notification notification(subscriber, event, true);
4488c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            mStateMachine->notifySubscribers(notification);
4498c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        }
4508c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
4518c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        // now check if there is any subscribers left
4528c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        if (!mStateMachine->hasSubscribers()) {
4538c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            // no more subscribers, move to RELEASED state
4548c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            nextState = mReleasedState;
4558c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
4568c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            // tell connecivity service we can release NIF
4578c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            mStateMachine->sendRsrcRequest(GPS_RELEASE_AGPS_DATA_CONN);
4588c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        } else if (!mStateMachine->hasActiveSubscribers()) {
4598c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            // only inactive subscribers, move to RELEASING state
4608c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            nextState = mReleasingState;
4618c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
4628c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            // tell connecivity service we can release NIF
4638c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            mStateMachine->sendRsrcRequest(GPS_RELEASE_AGPS_DATA_CONN);
4648c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        }
4658c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    }
4668c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        break;
4678c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
4688c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    case RSRC_GRANTED:
4698c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        LOC_LOGW("%s: %d, RSRC_GRANTED already received", whoami(), event);
4708c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        // no state change.
4718c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        break;
4728c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
4738c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    case RSRC_RELEASED:
4748c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    {
4758c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        LOC_LOGW("%s: %d, a force rsrc release", whoami(), event);
4768c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        nextState = mReleasedState;
4778c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        Notification notification(Notification::BROADCAST_ALL, event, true);
4788c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        // by setting true, we remove subscribers from the linked list
4798c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        mStateMachine->notifySubscribers(notification);
4808c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    }
4818c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        break;
4828c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
4838c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    case RSRC_DENIED:
4848c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        // no state change.
4858c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        // we are expecting RELEASED.  Handling DENIED
4868c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        // may like break our state machine in race conditions.
4878c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        break;
4888c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
4898c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    default:
4908c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        LOC_LOGE("%s: unrecognized event %d", whoami(), event);
4918c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        // no state change.
4928c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    }
4938c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
4948c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    LOC_LOGD("onRsrcEvent, old state %s, new state %s, event %d",
4958c2d3d5afc51d3f35150f748f263870367771b6fEd Tam             whoami(), nextState->whoami(), event);
4968c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    return nextState;
4978c2d3d5afc51d3f35150f748f263870367771b6fEd Tam}
4988c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
4998c2d3d5afc51d3f35150f748f263870367771b6fEd Tam// AgpsPendingState
5008c2d3d5afc51d3f35150f748f263870367771b6fEd Tamclass AgpsReleasingState : public AgpsState
5018c2d3d5afc51d3f35150f748f263870367771b6fEd Tam{
5028c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    friend class AgpsStateMachine;
5038c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
5048c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    inline AgpsReleasingState(AgpsStateMachine* stateMachine) :
5058c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        AgpsState(stateMachine)
5068c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    { mReleasingState = this; }
5078c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
5088c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    inline ~AgpsReleasingState() {}
5098c2d3d5afc51d3f35150f748f263870367771b6fEd Tampublic:
5108c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    virtual AgpsState* onRsrcEvent(AgpsRsrcStatus event, void* data);
5118c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    inline virtual char* whoami() {return (char*)"AgpsReleasingState";}
5128c2d3d5afc51d3f35150f748f263870367771b6fEd Tam};
5138c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
5148c2d3d5afc51d3f35150f748f263870367771b6fEd TamAgpsState* AgpsReleasingState::onRsrcEvent(AgpsRsrcStatus event, void* data)
5158c2d3d5afc51d3f35150f748f263870367771b6fEd Tam{
5168c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    AgpsState* nextState = this;;
5178c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    LOC_LOGD("AgpsReleasingState::onRsrcEvent; event:%d\n", (int)event);
5188c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
5198c2d3d5afc51d3f35150f748f263870367771b6fEd Tam   switch (event)
5208c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    {
5218c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    case RSRC_SUBSCRIBE:
5228c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    {
5238c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        // already requested for NIF resource,
5248c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        // do nothing until we get RSRC_GRANTED indication
5258c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        // but we need to add subscriber to the list
5268c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        mStateMachine->addSubscriber((Subscriber*)data);
5278c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        // no state change.
5288c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    }
5298c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        break;
5308c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
5318c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    case RSRC_UNSUBSCRIBE:
5328c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    {
5338c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        Subscriber* subscriber = (Subscriber*) data;
5348c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        if (subscriber->waitForCloseComplete()) {
5358c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            subscriber->setInactive();
5368c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        } else {
5378c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            // auto notify this subscriber of the unsubscribe
5388c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            Notification notification(subscriber, event, true);
5398c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            mStateMachine->notifySubscribers(notification);
5408c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        }
5418c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
5428c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        // now check if there is any subscribers left
5438c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        if (!mStateMachine->hasSubscribers()) {
5448c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            // no more subscribers, move to RELEASED state
5458c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            nextState = mReleasedState;
5468c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        }
5478c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    }
5488c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        break;
5498c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
5508c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    case RSRC_DENIED:
5518c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        // A race condition subscriber unsubscribes before AFW denies resource.
5528c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    case RSRC_RELEASED:
5538c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    {
5548c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        nextState = mAcquiredState;
5558c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        Notification notification(Notification::BROADCAST_INACTIVE, event, true);
5568c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        // notify all subscribers that are active NIF resource RELEASE
5578c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        // by setting false, we keep subscribers on the linked list
5588c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        mStateMachine->notifySubscribers(notification);
5598c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
5608c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        if (mStateMachine->hasActiveSubscribers()) {
5618c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            nextState = mPendingState;
5628c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            // request from connecivity service for NIF
5638c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            mStateMachine->sendRsrcRequest(GPS_REQUEST_AGPS_DATA_CONN);
5648c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        } else {
5658c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            nextState = mReleasedState;
5668c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        }
5678c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    }
5688c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        break;
5698c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
5708c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    case RSRC_GRANTED:
5718c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    default:
5728c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        LOC_LOGE("%s: unrecognized event %d", whoami(), event);
5738c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        // no state change.
5748c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    }
5758c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
5768c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    LOC_LOGD("onRsrcEvent, old state %s, new state %s, event %d",
5778c2d3d5afc51d3f35150f748f263870367771b6fEd Tam             whoami(), nextState->whoami(), event);
5788c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    return nextState;
5798c2d3d5afc51d3f35150f748f263870367771b6fEd Tam}
5808c2d3d5afc51d3f35150f748f263870367771b6fEd Tam//======================================================================
5818c2d3d5afc51d3f35150f748f263870367771b6fEd Tam//Servicer
5828c2d3d5afc51d3f35150f748f263870367771b6fEd Tam//======================================================================
5838c2d3d5afc51d3f35150f748f263870367771b6fEd TamServicer* Servicer :: getServicer(servicerType type, void *cb_func)
5848c2d3d5afc51d3f35150f748f263870367771b6fEd Tam{
5858c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    LOC_LOGD(" Enter getServicer type:%d\n", (int)type);
5868c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    switch(type) {
5878c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    case servicerTypeNoCbParam:
5888c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        return (new Servicer(cb_func));
5898c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    case servicerTypeExt:
5908c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        return (new ExtServicer(cb_func));
5918c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    case servicerTypeAgps:
5928c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        return (new AGpsServicer(cb_func));
5938c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    default:
5948c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        return NULL;
5958c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    }
5968c2d3d5afc51d3f35150f748f263870367771b6fEd Tam}
5978c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
5988c2d3d5afc51d3f35150f748f263870367771b6fEd Tamint Servicer :: requestRsrc(void *cb_data)
5998c2d3d5afc51d3f35150f748f263870367771b6fEd Tam{
6008c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    callback();
6018c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    return 0;
6028c2d3d5afc51d3f35150f748f263870367771b6fEd Tam}
6038c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
6048c2d3d5afc51d3f35150f748f263870367771b6fEd Tamint ExtServicer :: requestRsrc(void *cb_data)
6058c2d3d5afc51d3f35150f748f263870367771b6fEd Tam{
6068c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    int ret=-1;
6078c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    LOC_LOGD("Enter ExtServicer :: requestRsrc\n");
6088c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    ret = callbackExt(cb_data);
6098c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    LOC_LOGD("Exit ExtServicer :: requestRsrc\n");
6108c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    return(ret);
6118c2d3d5afc51d3f35150f748f263870367771b6fEd Tam}
6128c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
6138c2d3d5afc51d3f35150f748f263870367771b6fEd Tamint AGpsServicer :: requestRsrc(void *cb_data)
6148c2d3d5afc51d3f35150f748f263870367771b6fEd Tam{
6158c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    callbackAGps((AGpsStatus *)cb_data);
6168c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    return 0;
6178c2d3d5afc51d3f35150f748f263870367771b6fEd Tam}
6188c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
6198c2d3d5afc51d3f35150f748f263870367771b6fEd Tam//======================================================================
6208c2d3d5afc51d3f35150f748f263870367771b6fEd Tam// AgpsStateMachine
6218c2d3d5afc51d3f35150f748f263870367771b6fEd Tam//======================================================================
6228c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
6238c2d3d5afc51d3f35150f748f263870367771b6fEd TamAgpsStateMachine::AgpsStateMachine(servicerType servType,
6248c2d3d5afc51d3f35150f748f263870367771b6fEd Tam                                   void *cb_func,
6258c2d3d5afc51d3f35150f748f263870367771b6fEd Tam                                   AGpsExtType type,
6268c2d3d5afc51d3f35150f748f263870367771b6fEd Tam                                   bool enforceSingleSubscriber) :
6278c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    mStatePtr(new AgpsReleasedState(this)),mType(type),
6288c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    mAPN(NULL),
6298c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    mAPNLen(0),
6308c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    mBearer(AGPS_APN_BEARER_INVALID),
6318c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    mEnforceSingleSubscriber(enforceSingleSubscriber),
6328c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    mServicer(Servicer :: getServicer(servType, (void *)cb_func))
6338c2d3d5afc51d3f35150f748f263870367771b6fEd Tam{
6348c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    linked_list_init(&mSubscribers);
6358c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
6368c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    // setting up mReleasedState
6378c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    mStatePtr->mPendingState = new AgpsPendingState(this);
6388c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    mStatePtr->mAcquiredState = new AgpsAcquiredState(this);
6398c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    mStatePtr->mReleasingState = new AgpsReleasingState(this);
6408c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
6418c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    // setting up mAcquiredState
6428c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    mStatePtr->mAcquiredState->mReleasedState = mStatePtr;
6438c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    mStatePtr->mAcquiredState->mPendingState = mStatePtr->mPendingState;
6448c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    mStatePtr->mAcquiredState->mReleasingState = mStatePtr->mReleasingState;
6458c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
6468c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    // setting up mPendingState
6478c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    mStatePtr->mPendingState->mAcquiredState = mStatePtr->mAcquiredState;
6488c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    mStatePtr->mPendingState->mReleasedState = mStatePtr;
6498c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    mStatePtr->mPendingState->mReleasingState = mStatePtr->mReleasingState;
6508c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
6518c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    // setting up mReleasingState
6528c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    mStatePtr->mReleasingState->mReleasedState = mStatePtr;
6538c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    mStatePtr->mReleasingState->mPendingState = mStatePtr->mPendingState;
6548c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    mStatePtr->mReleasingState->mAcquiredState = mStatePtr->mAcquiredState;
6558c2d3d5afc51d3f35150f748f263870367771b6fEd Tam}
6568c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
6578c2d3d5afc51d3f35150f748f263870367771b6fEd TamAgpsStateMachine::~AgpsStateMachine()
6588c2d3d5afc51d3f35150f748f263870367771b6fEd Tam{
6598c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    dropAllSubscribers();
6608c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
6618c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    // free the 3 states.  We must read out all 3 pointers first.
6628c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    // Otherwise we run the risk of getting pointers from already
6638c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    // freed memory.
6648c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    AgpsState* acquiredState = mStatePtr->mAcquiredState;
6658c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    AgpsState* releasedState = mStatePtr->mReleasedState;
6668c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    AgpsState* pendindState = mStatePtr->mPendingState;
6678c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    AgpsState* releasingState = mStatePtr->mReleasingState;
6688c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
6698c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    delete acquiredState;
6708c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    delete releasedState;
6718c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    delete pendindState;
6728c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    delete releasingState;
6738c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    delete mServicer;
6748c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    linked_list_destroy(&mSubscribers);
6758c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
6768c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    if (NULL != mAPN) {
6778c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        delete[] mAPN;
6788c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        mAPN = NULL;
6798c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    }
6808c2d3d5afc51d3f35150f748f263870367771b6fEd Tam}
6818c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
6828c2d3d5afc51d3f35150f748f263870367771b6fEd Tamvoid AgpsStateMachine::setAPN(const char* apn, unsigned int len)
6838c2d3d5afc51d3f35150f748f263870367771b6fEd Tam{
6848c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    if (NULL != mAPN) {
6858c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        delete mAPN;
6868c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    }
6878c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
6888c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    if (NULL != apn) {
6898c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        mAPN = new char[len+1];
6908c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        memcpy(mAPN, apn, len);
6919c86882a403ae0bc04bdb459f11d31d5a37843a6Yunlian Jiang        mAPN[len] = '\0';
6928c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
6938c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        mAPNLen = len;
6948c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    } else {
6958c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        mAPN = NULL;
6968c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        mAPNLen = 0;
6978c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    }
6988c2d3d5afc51d3f35150f748f263870367771b6fEd Tam}
6998c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
7008c2d3d5afc51d3f35150f748f263870367771b6fEd Tamvoid AgpsStateMachine::onRsrcEvent(AgpsRsrcStatus event)
7018c2d3d5afc51d3f35150f748f263870367771b6fEd Tam{
7028c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    switch (event)
7038c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    {
7048c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    case RSRC_GRANTED:
7058c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    case RSRC_RELEASED:
7068c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    case RSRC_DENIED:
7078c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        mStatePtr = mStatePtr->onRsrcEvent(event, NULL);
7088c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        break;
7098c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    default:
7108c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        LOC_LOGW("AgpsStateMachine: unrecognized event %d", event);
7118c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        break;
7128c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    }
7138c2d3d5afc51d3f35150f748f263870367771b6fEd Tam}
7148c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
7158c2d3d5afc51d3f35150f748f263870367771b6fEd Tamvoid AgpsStateMachine::notifySubscribers(Notification& notification) const
7168c2d3d5afc51d3f35150f748f263870367771b6fEd Tam{
7178c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    if (notification.postNotifyDelete) {
7188c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        // just any non NULL value to get started
7198c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        Subscriber* s = (Subscriber*)~0;
7208c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        while (NULL != s) {
7218c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            s = NULL;
7228c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            // if the last param sets to true, _search will delete
7238c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            // the node from the list for us.  But the problem is
7248c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            // once that is done, _search returns, leaving the
7258c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            // rest of the list unprocessed.  So we need a loop.
7268c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            linked_list_search(mSubscribers, (void**)&s, notifySubscriber,
7278c2d3d5afc51d3f35150f748f263870367771b6fEd Tam                               (void*)&notification, true);
7288c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            delete s;
7298c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        }
7308c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    } else {
7318c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        // no loop needed if it the last param sets to false, which
7328c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        // mean nothing gets deleted from the list.
7338c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        linked_list_search(mSubscribers, NULL, notifySubscriber,
7348c2d3d5afc51d3f35150f748f263870367771b6fEd Tam                           (void*)&notification, false);
7358c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    }
7368c2d3d5afc51d3f35150f748f263870367771b6fEd Tam}
7378c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
7388c2d3d5afc51d3f35150f748f263870367771b6fEd Tamvoid AgpsStateMachine::addSubscriber(Subscriber* subscriber) const
7398c2d3d5afc51d3f35150f748f263870367771b6fEd Tam{
7408c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    Subscriber* s = NULL;
7418c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    Notification notification((const Subscriber*)subscriber);
7428c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    linked_list_search(mSubscribers, (void**)&s,
7438c2d3d5afc51d3f35150f748f263870367771b6fEd Tam                       hasSubscriber, (void*)&notification, false);
7448c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
7458c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    if (NULL == s) {
7468c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        linked_list_add(mSubscribers, subscriber->clone(), deleteObj);
7478c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    }
7488c2d3d5afc51d3f35150f748f263870367771b6fEd Tam}
7498c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
7508c2d3d5afc51d3f35150f748f263870367771b6fEd Tamint AgpsStateMachine::sendRsrcRequest(AGpsStatusValue action) const
7518c2d3d5afc51d3f35150f748f263870367771b6fEd Tam{
7528c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    Subscriber* s = NULL;
7538c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    Notification notification(Notification::BROADCAST_ACTIVE);
7548c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    linked_list_search(mSubscribers, (void**)&s, hasSubscriber,
7558c2d3d5afc51d3f35150f748f263870367771b6fEd Tam                       (void*)&notification, false);
7568c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
7578c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    if ((NULL == s) == (GPS_RELEASE_AGPS_DATA_CONN == action)) {
7588c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        AGpsExtStatus nifRequest;
7598c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        nifRequest.size = sizeof(nifRequest);
7608c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        nifRequest.type = mType;
7618c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        nifRequest.status = action;
7628c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
7638c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        if (s == NULL) {
7648c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            nifRequest.ipv4_addr = INADDR_NONE;
7658c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            memset(&nifRequest.addr, 0,  sizeof(nifRequest.addr));
7668c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            nifRequest.ssid[0] = '\0';
7678c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            nifRequest.password[0] = '\0';
7688c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        } else {
7698c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            s->setIPAddresses(nifRequest.addr);
7708c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            s->setWifiInfo(nifRequest.ssid, nifRequest.password);
7718c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        }
7728c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
7738c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        CALLBACK_LOG_CALLFLOW("agps_cb", %s, loc_get_agps_status_name(action));
7748c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        mServicer->requestRsrc((void *)&nifRequest);
7758c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    }
7768c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    return 0;
7778c2d3d5afc51d3f35150f748f263870367771b6fEd Tam}
7788c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
7798c2d3d5afc51d3f35150f748f263870367771b6fEd Tamvoid AgpsStateMachine::subscribeRsrc(Subscriber *subscriber)
7808c2d3d5afc51d3f35150f748f263870367771b6fEd Tam{
7818c2d3d5afc51d3f35150f748f263870367771b6fEd Tam  if (mEnforceSingleSubscriber && hasSubscribers()) {
7828c2d3d5afc51d3f35150f748f263870367771b6fEd Tam      Notification notification(Notification::BROADCAST_ALL, RSRC_DENIED, true);
7838c2d3d5afc51d3f35150f748f263870367771b6fEd Tam      notifySubscriber(&notification, subscriber);
7848c2d3d5afc51d3f35150f748f263870367771b6fEd Tam  } else {
7858c2d3d5afc51d3f35150f748f263870367771b6fEd Tam      mStatePtr = mStatePtr->onRsrcEvent(RSRC_SUBSCRIBE, (void*)subscriber);
7868c2d3d5afc51d3f35150f748f263870367771b6fEd Tam  }
7878c2d3d5afc51d3f35150f748f263870367771b6fEd Tam}
7888c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
7898c2d3d5afc51d3f35150f748f263870367771b6fEd Tambool AgpsStateMachine::unsubscribeRsrc(Subscriber *subscriber)
7908c2d3d5afc51d3f35150f748f263870367771b6fEd Tam{
7918c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    Subscriber* s = NULL;
7928c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    Notification notification((const Subscriber*)subscriber);
7938c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    linked_list_search(mSubscribers, (void**)&s,
7948c2d3d5afc51d3f35150f748f263870367771b6fEd Tam                       hasSubscriber, (void*)&notification, false);
7958c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
7968c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    if (NULL != s) {
7978c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        mStatePtr = mStatePtr->onRsrcEvent(RSRC_UNSUBSCRIBE, (void*)s);
7988c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        return true;
7998c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    }
8008c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    return false;
8018c2d3d5afc51d3f35150f748f263870367771b6fEd Tam}
8028c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
8038c2d3d5afc51d3f35150f748f263870367771b6fEd Tambool AgpsStateMachine::hasActiveSubscribers() const
8048c2d3d5afc51d3f35150f748f263870367771b6fEd Tam{
8058c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    Subscriber* s = NULL;
8068c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    Notification notification(Notification::BROADCAST_ACTIVE);
8078c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    linked_list_search(mSubscribers, (void**)&s,
8088c2d3d5afc51d3f35150f748f263870367771b6fEd Tam                       hasSubscriber, (void*)&notification, false);
8098c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    return NULL != s;
8108c2d3d5afc51d3f35150f748f263870367771b6fEd Tam}
8118c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
8128c2d3d5afc51d3f35150f748f263870367771b6fEd Tam//======================================================================
8138c2d3d5afc51d3f35150f748f263870367771b6fEd Tam// DSStateMachine
8148c2d3d5afc51d3f35150f748f263870367771b6fEd Tam//======================================================================
8158c2d3d5afc51d3f35150f748f263870367771b6fEd Tamvoid delay_callback(void *callbackData, int result)
8168c2d3d5afc51d3f35150f748f263870367771b6fEd Tam{
8178c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    if(callbackData) {
8188c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        DSStateMachine *DSSMInstance = (DSStateMachine *)callbackData;
8198c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        DSSMInstance->retryCallback();
8208c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    }
8218c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    else {
8228c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        LOC_LOGE(" NULL argument received. Failing.\n");
8238c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        goto err;
8248c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    }
8258c2d3d5afc51d3f35150f748f263870367771b6fEd Tamerr:
8268c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    return;
8278c2d3d5afc51d3f35150f748f263870367771b6fEd Tam}
8288c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
8298c2d3d5afc51d3f35150f748f263870367771b6fEd TamDSStateMachine :: DSStateMachine(servicerType type, void *cb_func,
8308c2d3d5afc51d3f35150f748f263870367771b6fEd Tam                                 LocEngAdapter* adapterHandle):
8318c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    AgpsStateMachine(type, cb_func, AGPS_TYPE_INVALID,false),
8328c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    mLocAdapter(adapterHandle)
8338c2d3d5afc51d3f35150f748f263870367771b6fEd Tam{
8348c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    LOC_LOGD("%s:%d]: New DSStateMachine\n", __func__, __LINE__);
8358c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    mRetries = 0;
8368c2d3d5afc51d3f35150f748f263870367771b6fEd Tam}
8378c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
8388c2d3d5afc51d3f35150f748f263870367771b6fEd Tamvoid DSStateMachine :: retryCallback(void)
8398c2d3d5afc51d3f35150f748f263870367771b6fEd Tam{
8408c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    DSSubscriber *subscriber = NULL;
8418c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    Notification notification(Notification::BROADCAST_ACTIVE);
8428c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    linked_list_search(mSubscribers, (void**)&subscriber, hasSubscriber,
8438c2d3d5afc51d3f35150f748f263870367771b6fEd Tam                       (void*)&notification, false);
8448c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    if(subscriber)
8458c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        mLocAdapter->requestSuplES(subscriber->ID);
8468c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    else
8478c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        LOC_LOGE("DSStateMachine :: retryCallback: No subscriber found." \
8488c2d3d5afc51d3f35150f748f263870367771b6fEd Tam                 "Cannot retry data call\n");
8498c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    return;
8508c2d3d5afc51d3f35150f748f263870367771b6fEd Tam}
8518c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
8528c2d3d5afc51d3f35150f748f263870367771b6fEd Tamint DSStateMachine :: sendRsrcRequest(AGpsStatusValue action) const
8538c2d3d5afc51d3f35150f748f263870367771b6fEd Tam{
8548c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    DSSubscriber* s = NULL;
8558c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    dsCbData cbData;
8568c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    int ret=-1;
8578c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    int connHandle=-1;
8588c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    LOC_LOGD("Enter DSStateMachine :: sendRsrcRequest\n");
8598c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    Notification notification(Notification::BROADCAST_ACTIVE);
8608c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    linked_list_search(mSubscribers, (void**)&s, hasSubscriber,
8618c2d3d5afc51d3f35150f748f263870367771b6fEd Tam                       (void*)&notification, false);
8628c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    if(s) {
8638c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        connHandle = s->ID;
8648c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        LOC_LOGD("DSStateMachine :: sendRsrcRequest - subscriber found\n");
8658c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    }
8668c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    else
8678c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        LOC_LOGD("DSStateMachine :: sendRsrcRequest - No subscriber found\n");
8688c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
8698c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    cbData.action = action;
8708c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    cbData.mAdapter = mLocAdapter;
8718c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    ret = mServicer->requestRsrc((void *)&cbData);
8728c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    //Only the request to start data call returns a success/failure
8738c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    //The request to stop data call will always succeed
8748c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    //Hence, the below block will only be executed when the
8758c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    //request to start the data call fails
8768c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    switch(ret) {
8778c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    case LOC_API_ADAPTER_ERR_ENGINE_BUSY:
8788c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        LOC_LOGD("DSStateMachine :: sendRsrcRequest - Failure returned: %d\n",ret);
8798c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        ((DSStateMachine *)this)->incRetries();
8808c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        if(mRetries > MAX_START_DATA_CALL_RETRIES) {
8818c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            LOC_LOGE(" Failed to start Data call. Fallback to normal ATL SUPL\n");
8828c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            informStatus(RSRC_DENIED, connHandle);
8838c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        }
8848c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        else {
8858c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            if(loc_timer_start(DATA_CALL_RETRY_DELAY_MSEC, delay_callback, (void *)this)) {
8868c2d3d5afc51d3f35150f748f263870367771b6fEd Tam                LOC_LOGE("Error: Could not start delay thread\n");
8878c2d3d5afc51d3f35150f748f263870367771b6fEd Tam                ret = -1;
8888c2d3d5afc51d3f35150f748f263870367771b6fEd Tam                goto err;
8898c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            }
8908c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        }
8918c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        break;
8928c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    case LOC_API_ADAPTER_ERR_UNSUPPORTED:
8938c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        LOC_LOGE("No profile found for emergency call. Fallback to normal SUPL ATL\n");
8948c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        informStatus(RSRC_DENIED, connHandle);
8958c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        break;
8968c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    case LOC_API_ADAPTER_ERR_SUCCESS:
8978c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        LOC_LOGD("%s:%d]: Request to start data call sent\n", __func__, __LINE__);
8988c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        break;
8998c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    case -1:
9008c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        //One of the ways this case can be encountered is if the callback function
9018c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        //receives a null argument, it just exits with -1 error
9028c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        LOC_LOGE("Error: Something went wrong somewhere. Falling back to normal SUPL ATL\n");
9038c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        informStatus(RSRC_DENIED, connHandle);
9048c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        break;
9058c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    default:
9068c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        LOC_LOGE("%s:%d]: Unrecognized return value\n", __func__, __LINE__);
9078c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    }
9088c2d3d5afc51d3f35150f748f263870367771b6fEd Tamerr:
9098c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    LOC_LOGD("EXIT DSStateMachine :: sendRsrcRequest; ret = %d\n", ret);
9108c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    return ret;
9118c2d3d5afc51d3f35150f748f263870367771b6fEd Tam}
9128c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
9138c2d3d5afc51d3f35150f748f263870367771b6fEd Tamvoid DSStateMachine :: onRsrcEvent(AgpsRsrcStatus event)
9148c2d3d5afc51d3f35150f748f263870367771b6fEd Tam{
9158c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    void* currState = (void *)mStatePtr;
9168c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    LOC_LOGD("Enter DSStateMachine :: onRsrcEvent. event = %d\n", (int)event);
9178c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    switch (event)
9188c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    {
9198c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    case RSRC_GRANTED:
9208c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        LOC_LOGD("DSStateMachine :: onRsrcEvent RSRC_GRANTED\n");
9218c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        mStatePtr = mStatePtr->onRsrcEvent(event, NULL);
9228c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        break;
9238c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    case RSRC_RELEASED:
9248c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        LOC_LOGD("DSStateMachine :: onRsrcEvent RSRC_RELEASED\n");
9258c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        mStatePtr = mStatePtr->onRsrcEvent(event, NULL);
9268c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        //To handle the case where we get a RSRC_RELEASED in
9278c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        //pending state, we translate that to a RSRC_DENIED state
9288c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        //since the callback from DSI is either RSRC_GRANTED or RSRC_RELEASED
9298c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        //for when the call is connected or disconnected respectively.
9308c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        if((void *)mStatePtr != currState)
9318c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            break;
9328c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        else {
9338c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            event = RSRC_DENIED;
9348c2d3d5afc51d3f35150f748f263870367771b6fEd Tam            LOC_LOGE(" Switching event to RSRC_DENIED\n");
9358c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        }
9368c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    case RSRC_DENIED:
9378c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        mStatePtr = mStatePtr->onRsrcEvent(event, NULL);
9388c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        break;
9398c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    default:
9408c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        LOC_LOGW("AgpsStateMachine: unrecognized event %d", event);
9418c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        break;
9428c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    }
9438c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    LOC_LOGD("Exit DSStateMachine :: onRsrcEvent. event = %d\n", (int)event);
9448c2d3d5afc51d3f35150f748f263870367771b6fEd Tam}
9458c2d3d5afc51d3f35150f748f263870367771b6fEd Tam
9468c2d3d5afc51d3f35150f748f263870367771b6fEd Tamvoid DSStateMachine :: informStatus(AgpsRsrcStatus status, int ID) const
9478c2d3d5afc51d3f35150f748f263870367771b6fEd Tam{
9488c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    LOC_LOGD("DSStateMachine :: informStatus. Status=%d\n",(int)status);
9498c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    switch(status) {
9508c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    case RSRC_UNSUBSCRIBE:
9518c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        mLocAdapter->atlCloseStatus(ID, 1);
9528c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        break;
9538c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    case RSRC_RELEASED:
9548c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        mLocAdapter->closeDataCall();
9558c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        break;
9568c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    case RSRC_DENIED:
9578c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        ((DSStateMachine *)this)->mRetries = 0;
9588c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        mLocAdapter->requestATL(ID, AGPS_TYPE_SUPL);
9598c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        break;
9608c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    case RSRC_GRANTED:
9618c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        mLocAdapter->atlOpenStatus(ID, 1,
9628c2d3d5afc51d3f35150f748f263870367771b6fEd Tam                                                     NULL,
9638c2d3d5afc51d3f35150f748f263870367771b6fEd Tam                                                     AGPS_APN_BEARER_INVALID,
9648c2d3d5afc51d3f35150f748f263870367771b6fEd Tam                                                     AGPS_TYPE_INVALID);
9658c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        break;
9668c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    default:
9678c2d3d5afc51d3f35150f748f263870367771b6fEd Tam        LOC_LOGW("DSStateMachine :: informStatus - unknown status");
9688c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    }
9698c2d3d5afc51d3f35150f748f263870367771b6fEd Tam    return;
9708c2d3d5afc51d3f35150f748f263870367771b6fEd Tam}
971