14035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
24035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin *
34035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin * Redistribution and use in source and binary forms, with or without
44035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin * modification, are permitted provided that the following conditions are
54035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin * met:
64035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin *     * Redistributions of source code must retain the above copyright
74035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin *       notice, this list of conditions and the following disclaimer.
84035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin *     * Redistributions in binary form must reproduce the above
94035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin *       copyright notice, this list of conditions and the following
104035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin *       disclaimer in the documentation and/or other materials provided
114035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin *       with the distribution.
124035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin *     * Neither the name of The Linux Foundation, nor the names of its
134035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin *       contributors may be used to endorse or promote products derived
144035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin *       from this software without specific prior written permission.
154035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin *
164035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
174035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
184035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
194035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
204035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
214035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
224035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
234035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
244035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
254035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
264035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
274035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin *
284035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin */
294035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
304035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin#define LOG_NDDEBUG 0
314035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin#define LOG_TAG "LocSvc_eng"
324035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
334035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin#include <loc_eng_agps.h>
344035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin#include <loc_eng_log.h>
354035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin#include <log_util.h>
364035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin#include <platform_lib_includes.h>
374035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin#include <loc_eng_dmn_conn_handler.h>
384035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin#include <loc_eng_dmn_conn.h>
394035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin#include <sys/time.h>
404035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
414035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin//======================================================================
424035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin// C callbacks
434035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin//======================================================================
444035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
454035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin// This is given to linked_list_add as the dealloc callback
464035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin// data -- an instance of Subscriber
474035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinstatic void deleteObj(void* data)
484035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin{
494035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    delete (Subscriber*)data;
504035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin}
514035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
524035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin// This is given to linked_list_search() as the comparison callback
534035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin// when the state manchine needs to process for particular subscriber
544035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin// fromCaller -- caller provides this obj
554035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin// fromList -- linked_list_search() function take this one from list
564035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinstatic bool hasSubscriber(void* fromCaller, void* fromList)
574035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin{
584035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    Notification* notification = (Notification*)fromCaller;
594035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    Subscriber* s1 = (Subscriber*)fromList;
604035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
614035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    return s1->forMe(*notification);
624035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin}
634035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
644035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin// This is gvien to linked_list_search() to notify subscriber objs
654035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin// when the state machine needs to inform all subscribers of resource
664035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin// status changes, e.g. when resource is GRANTED.
674035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin// fromCaller -- caller provides this ptr to a Notification obj.
684035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin// fromList -- linked_list_search() function take this one from list
694035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinstatic bool notifySubscriber(void* fromCaller, void* fromList)
704035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin{
714035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    Notification* notification = (Notification*)fromCaller;
724035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    Subscriber* s1 = (Subscriber*)fromList;
734035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
744035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    // we notify every subscriber indiscriminatively
754035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    // each subscriber decides if this notification is interesting.
764035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    return s1->notifyRsrcStatus(*notification) &&
774035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin           // if we do not want to delete the subscriber from the
784035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin           // the list, we must set this to false so this function
794035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin           // returns false
804035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin           notification->postNotifyDelete;
814035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin}
824035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
834035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin//======================================================================
844035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin// Notification
854035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin//======================================================================
864035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinconst int Notification::BROADCAST_ALL = 0x80000000;
874035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinconst int Notification::BROADCAST_ACTIVE = 0x80000001;
884035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinconst int Notification::BROADCAST_INACTIVE = 0x80000002;
894035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinconst unsigned char DSStateMachine::MAX_START_DATA_CALL_RETRIES = 4;
904035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinconst unsigned int DSStateMachine::DATA_CALL_RETRY_DELAY_MSEC = 500;
914035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin//======================================================================
924035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin// Subscriber:  BITSubscriber / ATLSubscriber / WIFISubscriber
934035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin//======================================================================
944035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinbool Subscriber::forMe(Notification &notification)
954035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin{
964035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    if (NULL != notification.rcver) {
974035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        return equals(notification.rcver);
984035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    } else {
994035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        return Notification::BROADCAST_ALL == notification.groupID ||
1004035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            (Notification::BROADCAST_ACTIVE == notification.groupID &&
1014035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin             !isInactive()) ||
1024035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            (Notification::BROADCAST_INACTIVE == notification.groupID &&
1034035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin             isInactive());
1044035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    }
1054035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin}
1064035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinbool BITSubscriber::equals(const Subscriber *s) const
1074035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin{
1084035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    BITSubscriber* bitS = (BITSubscriber*)s;
1094035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
1104035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    return (ID == bitS->ID &&
1114035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            (INADDR_NONE != (unsigned int)ID ||
1124035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin             0 == strncmp(mIPv6Addr, bitS->mIPv6Addr, sizeof(mIPv6Addr))));
1134035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin}
1144035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
1154035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinbool BITSubscriber::notifyRsrcStatus(Notification &notification)
1164035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin{
1174035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    bool notify = forMe(notification);
1184035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
1194035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    if (notify) {
1204035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        switch(notification.rsrcStatus)
1214035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        {
1224035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        case RSRC_UNSUBSCRIBE:
1234035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        case RSRC_RELEASED:
1244035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            loc_eng_dmn_conn_loc_api_server_data_conn(
1254035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin                LOC_ENG_IF_REQUEST_SENDER_ID_GPSONE_DAEMON,
1264035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin                GPSONE_LOC_API_IF_RELEASE_SUCCESS);
1274035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            break;
1284035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        case RSRC_DENIED:
1294035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            loc_eng_dmn_conn_loc_api_server_data_conn(
1304035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin                LOC_ENG_IF_REQUEST_SENDER_ID_GPSONE_DAEMON,
1314035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin                GPSONE_LOC_API_IF_FAILURE);
1324035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            break;
1334035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        case RSRC_GRANTED:
1344035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            loc_eng_dmn_conn_loc_api_server_data_conn(
1354035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin                LOC_ENG_IF_REQUEST_SENDER_ID_GPSONE_DAEMON,
1364035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin                GPSONE_LOC_API_IF_REQUEST_SUCCESS);
1374035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            break;
1384035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        default:
1394035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            notify = false;
1404035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        }
1414035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    }
1424035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
1434035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    return notify;
1444035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin}
1454035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
1464035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinbool ATLSubscriber::notifyRsrcStatus(Notification &notification)
1474035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin{
1484035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    bool notify = forMe(notification);
1494035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
1504035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    if (notify) {
1514035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        switch(notification.rsrcStatus)
1524035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        {
1534035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        case RSRC_UNSUBSCRIBE:
1544035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        case RSRC_RELEASED:
1554035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            ((LocEngAdapter*)mLocAdapter)->atlCloseStatus(ID, 1);
1564035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            break;
1574035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        case RSRC_DENIED:
1584035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        {
1594035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            AGpsExtType type = mBackwardCompatibleMode ?
1604035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin                              AGPS_TYPE_INVALID : mStateMachine->getType();
1614035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            ((LocEngAdapter*)mLocAdapter)->atlOpenStatus(ID, 0,
1624035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin                                            (char*)mStateMachine->getAPN(),
1634035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin                                            mStateMachine->getBearer(),
1644035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin                                            type);
1654035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        }
1664035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            break;
1674035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        case RSRC_GRANTED:
1684035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        {
1694035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            AGpsExtType type = mBackwardCompatibleMode ?
1704035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin                              AGPS_TYPE_INVALID : mStateMachine->getType();
1714035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            ((LocEngAdapter*)mLocAdapter)->atlOpenStatus(ID, 1,
1724035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin                                            (char*)mStateMachine->getAPN(),
1734035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin                                            mStateMachine->getBearer(),
1744035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin                                            type);
1754035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        }
1764035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            break;
1774035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        default:
1784035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            notify = false;
1794035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        }
1804035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    }
1814035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
1824035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    return notify;
1834035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin}
1844035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
1854035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinbool WIFISubscriber::notifyRsrcStatus(Notification &notification)
1864035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin{
1874035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    bool notify = forMe(notification);
1884035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
1894035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    if (notify) {
1904035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        switch(notification.rsrcStatus)
1914035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        {
1924035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        case RSRC_UNSUBSCRIBE:
1934035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            break;
1944035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        case RSRC_RELEASED:
1954035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            loc_eng_dmn_conn_loc_api_server_data_conn(
1964035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin                senderId,
1974035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin                GPSONE_LOC_API_IF_RELEASE_SUCCESS);
1984035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            break;
1994035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        case RSRC_DENIED:
2004035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            loc_eng_dmn_conn_loc_api_server_data_conn(
2014035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin                senderId,
2024035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin                GPSONE_LOC_API_IF_FAILURE);
2034035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            break;
2044035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        case RSRC_GRANTED:
2054035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            loc_eng_dmn_conn_loc_api_server_data_conn(
2064035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin                senderId,
2074035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin                GPSONE_LOC_API_IF_REQUEST_SUCCESS);
2084035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            break;
2094035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        default:
2104035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            notify = false;
2114035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        }
2124035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    }
2134035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
2144035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    return notify;
2154035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin}
2164035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinbool DSSubscriber::notifyRsrcStatus(Notification &notification)
2174035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin{
2184035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    bool notify = forMe(notification);
2194035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    LOC_LOGD("DSSubscriber::notifyRsrcStatus. notify:%d \n",(int)(notify));
2204035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    if(notify) {
2214035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        switch(notification.rsrcStatus) {
2224035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        case RSRC_UNSUBSCRIBE:
2234035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        case RSRC_RELEASED:
2244035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        case RSRC_DENIED:
2254035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        case RSRC_GRANTED:
2264035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            ((DSStateMachine *)mStateMachine)->informStatus(notification.rsrcStatus, ID);
2274035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            break;
2284035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        default:
2294035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            notify = false;
2304035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        }
2314035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    }
2324035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    return notify;
2334035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin}
2344035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinvoid DSSubscriber :: setInactive()
2354035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin{
2364035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    mIsInactive = true;
2374035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    ((DSStateMachine *)mStateMachine)->informStatus(RSRC_UNSUBSCRIBE, ID);
2384035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin}
2394035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin//======================================================================
2404035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin// AgpsState:  AgpsReleasedState / AgpsPendingState / AgpsAcquiredState
2414035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin//======================================================================
2424035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
2434035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin// AgpsReleasedState
2444035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinclass AgpsReleasedState : public AgpsState
2454035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin{
2464035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    friend class AgpsStateMachine;
2474035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
2484035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    inline AgpsReleasedState(AgpsStateMachine* stateMachine) :
2494035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        AgpsState(stateMachine)
2504035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    { mReleasedState = this; }
2514035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
2524035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    inline ~AgpsReleasedState() {}
2534035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinpublic:
2544035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    virtual AgpsState* onRsrcEvent(AgpsRsrcStatus event, void* data);
2554035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    inline virtual char* whoami() {return (char*)"AgpsReleasedState";}
2564035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin};
2574035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
2584035be28a255eaa5605dbd9abeb2340db584249cPatrick TjinAgpsState* AgpsReleasedState::onRsrcEvent(AgpsRsrcStatus event, void* data)
2594035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin{
2604035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    LOC_LOGD("AgpsReleasedState::onRsrcEvent; event:%d\n", (int)event);
2614035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    if (mStateMachine->hasSubscribers()) {
2624035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        LOC_LOGE("Error: %s subscriber list not empty!!!", whoami());
2634035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        // I don't know how to recover from it.  I am adding this rather
2644035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        // for debugging purpose.
2654035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    }
2664035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
2674035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    AgpsState* nextState = this;
2684035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    switch (event)
2694035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    {
2704035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    case RSRC_SUBSCRIBE:
2714035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    {
2724035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        // no notification until we get RSRC_GRANTED
2734035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        // but we need to add subscriber to the list
2744035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        mStateMachine->addSubscriber((Subscriber*)data);
2754035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        // request from connecivity service for NIF
2764035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        //The if condition is added so that if the data call setup fails
2774035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        //for DS State Machine, we want to retry in released state.
2784035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        //for AGps State Machine, sendRsrcRequest() will always return success
2794035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        if(!mStateMachine->sendRsrcRequest(GPS_REQUEST_AGPS_DATA_CONN)) {
2804035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            // move the state to PENDING
2814035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            nextState = mPendingState;
2824035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        }
2834035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    }
2844035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    break;
2854035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
2864035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    case RSRC_UNSUBSCRIBE:
2874035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    {
2884035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        // the list should really be empty, nothing to remove.
2894035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        // but we might as well just tell the client it is
2904035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        // unsubscribed.  False tolerance, right?
2914035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        Subscriber* subscriber = (Subscriber*) data;
2924035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        Notification notification(subscriber, event, false);
2934035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        subscriber->notifyRsrcStatus(notification);
2944035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    }
2954035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        // break;
2964035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    case RSRC_GRANTED:
2974035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    case RSRC_RELEASED:
2984035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    case RSRC_DENIED:
2994035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    default:
3004035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        LOC_LOGW("%s: unrecognized event %d", whoami(), event);
3014035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        // no state change.
3024035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        break;
3034035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    }
3044035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
3054035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    LOC_LOGD("onRsrcEvent, old state %s, new state %s, event %d",
3064035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin             whoami(), nextState->whoami(), event);
3074035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    return nextState;
3084035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin}
3094035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
3104035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin// AgpsPendingState
3114035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinclass AgpsPendingState : public AgpsState
3124035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin{
3134035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    friend class AgpsStateMachine;
3144035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
3154035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    inline AgpsPendingState(AgpsStateMachine* stateMachine) :
3164035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        AgpsState(stateMachine)
3174035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    { mPendingState = this; }
3184035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
3194035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    inline ~AgpsPendingState() {}
3204035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinpublic:
3214035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    virtual AgpsState* onRsrcEvent(AgpsRsrcStatus event, void* data);
3224035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    inline virtual char* whoami() {return (char*)"AgpsPendingState";}
3234035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin};
3244035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
3254035be28a255eaa5605dbd9abeb2340db584249cPatrick TjinAgpsState* AgpsPendingState::onRsrcEvent(AgpsRsrcStatus event, void* data)
3264035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin{
3274035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    AgpsState* nextState = this;;
3284035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    LOC_LOGD("AgpsPendingState::onRsrcEvent; event:%d\n", (int)event);
3294035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    switch (event)
3304035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    {
3314035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    case RSRC_SUBSCRIBE:
3324035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    {
3334035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        // already requested for NIF resource,
3344035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        // do nothing until we get RSRC_GRANTED indication
3354035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        // but we need to add subscriber to the list
3364035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        mStateMachine->addSubscriber((Subscriber*)data);
3374035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        // no state change.
3384035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    }
3394035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        break;
3404035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
3414035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    case RSRC_UNSUBSCRIBE:
3424035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    {
3434035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        Subscriber* subscriber = (Subscriber*) data;
3444035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        if (subscriber->waitForCloseComplete()) {
3454035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            subscriber->setInactive();
3464035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        } else {
3474035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            // auto notify this subscriber of the unsubscribe
3484035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            Notification notification(subscriber, event, true);
3494035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            mStateMachine->notifySubscribers(notification);
3504035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        }
3514035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
3524035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        // now check if there is any subscribers left
3534035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        if (!mStateMachine->hasSubscribers()) {
3544035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            // no more subscribers, move to RELEASED state
3554035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            nextState = mReleasedState;
3564035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
3574035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            // tell connecivity service we can release NIF
3584035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            mStateMachine->sendRsrcRequest(GPS_RELEASE_AGPS_DATA_CONN);
3594035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        } else if (!mStateMachine->hasActiveSubscribers()) {
3604035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            // only inactive subscribers, move to RELEASING state
3614035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            nextState = mReleasingState;
3624035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
3634035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            // tell connecivity service we can release NIF
3644035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            mStateMachine->sendRsrcRequest(GPS_RELEASE_AGPS_DATA_CONN);
3654035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        }
3664035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    }
3674035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    break;
3684035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
3694035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    case RSRC_GRANTED:
3704035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    {
3714035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        nextState = mAcquiredState;
3724035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        Notification notification(Notification::BROADCAST_ACTIVE, event, false);
3734035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        // notify all subscribers NIF resource GRANTED
3744035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        // by setting false, we keep subscribers on the linked list
3754035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        mStateMachine->notifySubscribers(notification);
3764035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    }
3774035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        break;
3784035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
3794035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    case RSRC_RELEASED:
3804035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        // no state change.
3814035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        // we are expecting either GRANTED or DENIED.  Handling RELEASED
3824035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        // may like break our state machine in race conditions.
3834035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        break;
3844035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
3854035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    case RSRC_DENIED:
3864035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    {
3874035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        nextState = mReleasedState;
3884035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        Notification notification(Notification::BROADCAST_ALL, event, true);
3894035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        // notify all subscribers NIF resource RELEASED or DENIED
3904035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        // by setting true, we remove subscribers from the linked list
3914035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        mStateMachine->notifySubscribers(notification);
3924035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    }
3934035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        break;
3944035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
3954035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    default:
3964035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        LOC_LOGE("%s: unrecognized event %d", whoami(), event);
3974035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        // no state change.
3984035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    }
3994035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
4004035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    LOC_LOGD("onRsrcEvent, old state %s, new state %s, event %d",
4014035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin             whoami(), nextState->whoami(), event);
4024035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    return nextState;
4034035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin}
4044035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
4054035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
4064035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinclass AgpsAcquiredState : public AgpsState
4074035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin{
4084035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    friend class AgpsStateMachine;
4094035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
4104035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    inline AgpsAcquiredState(AgpsStateMachine* stateMachine) :
4114035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        AgpsState(stateMachine)
4124035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    { mAcquiredState = this; }
4134035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
4144035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    inline ~AgpsAcquiredState() {}
4154035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinpublic:
4164035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    virtual AgpsState* onRsrcEvent(AgpsRsrcStatus event, void* data);
4174035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    inline virtual char* whoami() { return (char*)"AgpsAcquiredState"; }
4184035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin};
4194035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
4204035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
4214035be28a255eaa5605dbd9abeb2340db584249cPatrick TjinAgpsState* AgpsAcquiredState::onRsrcEvent(AgpsRsrcStatus event, void* data)
4224035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin{
4234035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    AgpsState* nextState = this;
4244035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    LOC_LOGD("AgpsAcquiredState::onRsrcEvent; event:%d\n", (int)event);
4254035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    switch (event)
4264035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    {
4274035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    case RSRC_SUBSCRIBE:
4284035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    {
4294035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        // we already have the NIF resource, simply notify subscriber
4304035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        Subscriber* subscriber = (Subscriber*) data;
4314035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        // we have rsrc in hand, so grant it right away
4324035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        Notification notification(subscriber, RSRC_GRANTED, false);
4334035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        subscriber->notifyRsrcStatus(notification);
4344035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        // add subscriber to the list
4354035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        mStateMachine->addSubscriber(subscriber);
4364035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        // no state change.
4374035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    }
4384035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        break;
4394035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
4404035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    case RSRC_UNSUBSCRIBE:
4414035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    {
4424035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        Subscriber* subscriber = (Subscriber*) data;
4434035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        if (subscriber->waitForCloseComplete()) {
4444035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            subscriber->setInactive();
4454035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        } else {
4464035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            // auto notify this subscriber of the unsubscribe
4474035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            Notification notification(subscriber, event, true);
4484035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            mStateMachine->notifySubscribers(notification);
4494035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        }
4504035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
4514035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        // now check if there is any subscribers left
4524035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        if (!mStateMachine->hasSubscribers()) {
4534035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            // no more subscribers, move to RELEASED state
4544035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            nextState = mReleasedState;
4554035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
4564035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            // tell connecivity service we can release NIF
4574035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            mStateMachine->sendRsrcRequest(GPS_RELEASE_AGPS_DATA_CONN);
4584035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        } else if (!mStateMachine->hasActiveSubscribers()) {
4594035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            // only inactive subscribers, move to RELEASING state
4604035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            nextState = mReleasingState;
4614035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
4624035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            // tell connecivity service we can release NIF
4634035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            mStateMachine->sendRsrcRequest(GPS_RELEASE_AGPS_DATA_CONN);
4644035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        }
4654035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    }
4664035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        break;
4674035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
4684035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    case RSRC_GRANTED:
4694035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        LOC_LOGW("%s: %d, RSRC_GRANTED already received", whoami(), event);
4704035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        // no state change.
4714035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        break;
4724035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
4734035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    case RSRC_RELEASED:
4744035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    {
4754035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        LOC_LOGW("%s: %d, a force rsrc release", whoami(), event);
4764035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        nextState = mReleasedState;
4774035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        Notification notification(Notification::BROADCAST_ALL, event, true);
4784035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        // by setting true, we remove subscribers from the linked list
4794035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        mStateMachine->notifySubscribers(notification);
4804035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    }
4814035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        break;
4824035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
4834035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    case RSRC_DENIED:
4844035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        // no state change.
4854035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        // we are expecting RELEASED.  Handling DENIED
4864035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        // may like break our state machine in race conditions.
4874035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        break;
4884035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
4894035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    default:
4904035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        LOC_LOGE("%s: unrecognized event %d", whoami(), event);
4914035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        // no state change.
4924035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    }
4934035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
4944035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    LOC_LOGD("onRsrcEvent, old state %s, new state %s, event %d",
4954035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin             whoami(), nextState->whoami(), event);
4964035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    return nextState;
4974035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin}
4984035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
4994035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin// AgpsPendingState
5004035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinclass AgpsReleasingState : public AgpsState
5014035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin{
5024035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    friend class AgpsStateMachine;
5034035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
5044035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    inline AgpsReleasingState(AgpsStateMachine* stateMachine) :
5054035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        AgpsState(stateMachine)
5064035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    { mReleasingState = this; }
5074035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
5084035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    inline ~AgpsReleasingState() {}
5094035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinpublic:
5104035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    virtual AgpsState* onRsrcEvent(AgpsRsrcStatus event, void* data);
5114035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    inline virtual char* whoami() {return (char*)"AgpsReleasingState";}
5124035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin};
5134035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
5144035be28a255eaa5605dbd9abeb2340db584249cPatrick TjinAgpsState* AgpsReleasingState::onRsrcEvent(AgpsRsrcStatus event, void* data)
5154035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin{
5164035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    AgpsState* nextState = this;;
5174035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    LOC_LOGD("AgpsReleasingState::onRsrcEvent; event:%d\n", (int)event);
5184035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
5194035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin   switch (event)
5204035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    {
5214035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    case RSRC_SUBSCRIBE:
5224035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    {
5234035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        // already requested for NIF resource,
5244035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        // do nothing until we get RSRC_GRANTED indication
5254035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        // but we need to add subscriber to the list
5264035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        mStateMachine->addSubscriber((Subscriber*)data);
5274035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        // no state change.
5284035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    }
5294035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        break;
5304035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
5314035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    case RSRC_UNSUBSCRIBE:
5324035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    {
5334035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        Subscriber* subscriber = (Subscriber*) data;
5344035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        if (subscriber->waitForCloseComplete()) {
5354035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            subscriber->setInactive();
5364035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        } else {
5374035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            // auto notify this subscriber of the unsubscribe
5384035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            Notification notification(subscriber, event, true);
5394035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            mStateMachine->notifySubscribers(notification);
5404035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        }
5414035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
5424035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        // now check if there is any subscribers left
5434035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        if (!mStateMachine->hasSubscribers()) {
5444035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            // no more subscribers, move to RELEASED state
5454035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            nextState = mReleasedState;
5464035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        }
5474035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    }
5484035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        break;
5494035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
5504035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    case RSRC_DENIED:
5514035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        // A race condition subscriber unsubscribes before AFW denies resource.
5524035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    case RSRC_RELEASED:
5534035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    {
5544035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        nextState = mAcquiredState;
5554035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        Notification notification(Notification::BROADCAST_INACTIVE, event, true);
5564035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        // notify all subscribers that are active NIF resource RELEASE
5574035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        // by setting false, we keep subscribers on the linked list
5584035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        mStateMachine->notifySubscribers(notification);
5594035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
5604035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        if (mStateMachine->hasActiveSubscribers()) {
5614035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            nextState = mPendingState;
5624035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            // request from connecivity service for NIF
5634035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            mStateMachine->sendRsrcRequest(GPS_REQUEST_AGPS_DATA_CONN);
5644035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        } else {
5654035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            nextState = mReleasedState;
5664035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        }
5674035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    }
5684035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        break;
5694035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
5704035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    case RSRC_GRANTED:
5714035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    default:
5724035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        LOC_LOGE("%s: unrecognized event %d", whoami(), event);
5734035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        // no state change.
5744035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    }
5754035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
5764035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    LOC_LOGD("onRsrcEvent, old state %s, new state %s, event %d",
5774035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin             whoami(), nextState->whoami(), event);
5784035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    return nextState;
5794035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin}
5804035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin//======================================================================
5814035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin//Servicer
5824035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin//======================================================================
5834035be28a255eaa5605dbd9abeb2340db584249cPatrick TjinServicer* Servicer :: getServicer(servicerType type, void *cb_func)
5844035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin{
5854035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    LOC_LOGD(" Enter getServicer type:%d\n", (int)type);
5864035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    switch(type) {
5874035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    case servicerTypeNoCbParam:
5884035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        return (new Servicer(cb_func));
5894035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    case servicerTypeExt:
5904035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        return (new ExtServicer(cb_func));
5914035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    case servicerTypeAgps:
5924035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        return (new AGpsServicer(cb_func));
5934035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    default:
5944035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        return NULL;
5954035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    }
5964035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin}
5974035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
5984035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinint Servicer :: requestRsrc(void *cb_data)
5994035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin{
6004035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    callback();
6014035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    return 0;
6024035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin}
6034035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
6044035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinint ExtServicer :: requestRsrc(void *cb_data)
6054035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin{
6064035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    int ret=-1;
6074035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    LOC_LOGD("Enter ExtServicer :: requestRsrc\n");
6084035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    ret = callbackExt(cb_data);
6094035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    LOC_LOGD("Exit ExtServicer :: requestRsrc\n");
6104035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    return(ret);
6114035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin}
6124035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
6134035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinint AGpsServicer :: requestRsrc(void *cb_data)
6144035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin{
6154035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    callbackAGps((AGpsStatus *)cb_data);
6164035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    return 0;
6174035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin}
6184035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
6194035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin//======================================================================
6204035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin// AgpsStateMachine
6214035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin//======================================================================
6224035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
6234035be28a255eaa5605dbd9abeb2340db584249cPatrick TjinAgpsStateMachine::AgpsStateMachine(servicerType servType,
6244035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin                                   void *cb_func,
6254035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin                                   AGpsExtType type,
6264035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin                                   bool enforceSingleSubscriber) :
6274035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    mStatePtr(new AgpsReleasedState(this)),mType(type),
6284035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    mAPN(NULL),
6294035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    mAPNLen(0),
6304035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    mBearer(AGPS_APN_BEARER_INVALID),
6314035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    mEnforceSingleSubscriber(enforceSingleSubscriber),
6324035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    mServicer(Servicer :: getServicer(servType, (void *)cb_func))
6334035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin{
6344035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    linked_list_init(&mSubscribers);
6354035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
6364035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    // setting up mReleasedState
6374035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    mStatePtr->mPendingState = new AgpsPendingState(this);
6384035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    mStatePtr->mAcquiredState = new AgpsAcquiredState(this);
6394035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    mStatePtr->mReleasingState = new AgpsReleasingState(this);
6404035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
6414035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    // setting up mAcquiredState
6424035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    mStatePtr->mAcquiredState->mReleasedState = mStatePtr;
6434035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    mStatePtr->mAcquiredState->mPendingState = mStatePtr->mPendingState;
6444035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    mStatePtr->mAcquiredState->mReleasingState = mStatePtr->mReleasingState;
6454035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
6464035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    // setting up mPendingState
6474035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    mStatePtr->mPendingState->mAcquiredState = mStatePtr->mAcquiredState;
6484035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    mStatePtr->mPendingState->mReleasedState = mStatePtr;
6494035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    mStatePtr->mPendingState->mReleasingState = mStatePtr->mReleasingState;
6504035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
6514035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    // setting up mReleasingState
6524035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    mStatePtr->mReleasingState->mReleasedState = mStatePtr;
6534035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    mStatePtr->mReleasingState->mPendingState = mStatePtr->mPendingState;
6544035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    mStatePtr->mReleasingState->mAcquiredState = mStatePtr->mAcquiredState;
6554035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin}
6564035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
6574035be28a255eaa5605dbd9abeb2340db584249cPatrick TjinAgpsStateMachine::~AgpsStateMachine()
6584035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin{
6594035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    dropAllSubscribers();
6604035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
6614035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    // free the 3 states.  We must read out all 3 pointers first.
6624035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    // Otherwise we run the risk of getting pointers from already
6634035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    // freed memory.
6644035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    AgpsState* acquiredState = mStatePtr->mAcquiredState;
6654035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    AgpsState* releasedState = mStatePtr->mReleasedState;
6664035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    AgpsState* pendindState = mStatePtr->mPendingState;
6674035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    AgpsState* releasingState = mStatePtr->mReleasingState;
6684035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
6694035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    delete acquiredState;
6704035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    delete releasedState;
6714035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    delete pendindState;
6724035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    delete releasingState;
6734035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    delete mServicer;
6744035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    linked_list_destroy(&mSubscribers);
6754035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
6764035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    if (NULL != mAPN) {
6774035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        delete[] mAPN;
6784035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        mAPN = NULL;
6794035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    }
6804035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin}
6814035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
6824035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinvoid AgpsStateMachine::setAPN(const char* apn, unsigned int len)
6834035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin{
6844035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    if (NULL != mAPN) {
6854035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        delete mAPN;
6864035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    }
6874035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
6884035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    if (NULL != apn) {
6894035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        mAPN = new char[len+1];
6904035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        memcpy(mAPN, apn, len);
6914035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        mAPN[len] = NULL;
6924035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
6934035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        mAPNLen = len;
6944035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    } else {
6954035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        mAPN = NULL;
6964035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        mAPNLen = 0;
6974035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    }
6984035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin}
6994035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
7004035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinvoid AgpsStateMachine::onRsrcEvent(AgpsRsrcStatus event)
7014035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin{
7024035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    switch (event)
7034035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    {
7044035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    case RSRC_GRANTED:
7054035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    case RSRC_RELEASED:
7064035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    case RSRC_DENIED:
7074035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        mStatePtr = mStatePtr->onRsrcEvent(event, NULL);
7084035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        break;
7094035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    default:
7104035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        LOC_LOGW("AgpsStateMachine: unrecognized event %d", event);
7114035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        break;
7124035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    }
7134035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin}
7144035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
7154035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinvoid AgpsStateMachine::notifySubscribers(Notification& notification) const
7164035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin{
7174035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    if (notification.postNotifyDelete) {
7184035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        // just any non NULL value to get started
7194035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        Subscriber* s = (Subscriber*)~0;
7204035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        while (NULL != s) {
7214035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            s = NULL;
7224035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            // if the last param sets to true, _search will delete
7234035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            // the node from the list for us.  But the problem is
7244035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            // once that is done, _search returns, leaving the
7254035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            // rest of the list unprocessed.  So we need a loop.
7264035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            linked_list_search(mSubscribers, (void**)&s, notifySubscriber,
7274035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin                               (void*)&notification, true);
7284035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            delete s;
7294035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        }
7304035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    } else {
7314035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        // no loop needed if it the last param sets to false, which
7324035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        // mean nothing gets deleted from the list.
7334035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        linked_list_search(mSubscribers, NULL, notifySubscriber,
7344035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin                           (void*)&notification, false);
7354035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    }
7364035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin}
7374035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
7384035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinvoid AgpsStateMachine::addSubscriber(Subscriber* subscriber) const
7394035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin{
7404035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    Subscriber* s = NULL;
7414035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    Notification notification((const Subscriber*)subscriber);
7424035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    linked_list_search(mSubscribers, (void**)&s,
7434035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin                       hasSubscriber, (void*)&notification, false);
7444035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
7454035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    if (NULL == s) {
7464035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        linked_list_add(mSubscribers, subscriber->clone(), deleteObj);
7474035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    }
7484035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin}
7494035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
7504035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinint AgpsStateMachine::sendRsrcRequest(AGpsStatusValue action) const
7514035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin{
7524035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    Subscriber* s = NULL;
7534035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    Notification notification(Notification::BROADCAST_ACTIVE);
7544035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    linked_list_search(mSubscribers, (void**)&s, hasSubscriber,
7554035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin                       (void*)&notification, false);
7564035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
7574035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    if ((NULL == s) == (GPS_RELEASE_AGPS_DATA_CONN == action)) {
7584035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        AGpsExtStatus nifRequest;
7594035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        nifRequest.size = sizeof(nifRequest);
7604035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        nifRequest.type = mType;
7614035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        nifRequest.status = action;
7624035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
7634035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        if (s == NULL) {
7644035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            nifRequest.ipv4_addr = INADDR_NONE;
7654035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            memset(&nifRequest.addr, 0,  sizeof(nifRequest.addr));
7664035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            nifRequest.ssid[0] = '\0';
7674035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            nifRequest.password[0] = '\0';
7684035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        } else {
7694035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            s->setIPAddresses(nifRequest.addr);
7704035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            s->setWifiInfo(nifRequest.ssid, nifRequest.password);
7714035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        }
7724035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
7734035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        CALLBACK_LOG_CALLFLOW("agps_cb", %s, loc_get_agps_status_name(action));
7744035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        mServicer->requestRsrc((void *)&nifRequest);
7754035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    }
7764035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    return 0;
7774035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin}
7784035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
7794035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinvoid AgpsStateMachine::subscribeRsrc(Subscriber *subscriber)
7804035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin{
7814035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin  if (mEnforceSingleSubscriber && hasSubscribers()) {
7824035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin      Notification notification(Notification::BROADCAST_ALL, RSRC_DENIED, true);
7834035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin      notifySubscriber(&notification, subscriber);
7844035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin  } else {
7854035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin      mStatePtr = mStatePtr->onRsrcEvent(RSRC_SUBSCRIBE, (void*)subscriber);
7864035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin  }
7874035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin}
7884035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
7894035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinbool AgpsStateMachine::unsubscribeRsrc(Subscriber *subscriber)
7904035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin{
7914035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    Subscriber* s = NULL;
7924035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    Notification notification((const Subscriber*)subscriber);
7934035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    linked_list_search(mSubscribers, (void**)&s,
7944035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin                       hasSubscriber, (void*)&notification, false);
7954035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
7964035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    if (NULL != s) {
7974035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        mStatePtr = mStatePtr->onRsrcEvent(RSRC_UNSUBSCRIBE, (void*)s);
7984035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        return true;
7994035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    }
8004035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    return false;
8014035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin}
8024035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
8034035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinbool AgpsStateMachine::hasActiveSubscribers() const
8044035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin{
8054035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    Subscriber* s = NULL;
8064035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    Notification notification(Notification::BROADCAST_ACTIVE);
8074035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    linked_list_search(mSubscribers, (void**)&s,
8084035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin                       hasSubscriber, (void*)&notification, false);
8094035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    return NULL != s;
8104035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin}
8114035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
8124035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin//======================================================================
8134035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin// DSStateMachine
8144035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin//======================================================================
8154035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinvoid delay_callback(void *callbackData, int result)
8164035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin{
8174035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    if(callbackData) {
8184035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        DSStateMachine *DSSMInstance = (DSStateMachine *)callbackData;
8194035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        DSSMInstance->retryCallback();
8204035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    }
8214035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    else {
8224035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        LOC_LOGE(" NULL argument received. Failing.\n");
8234035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        goto err;
8244035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    }
8254035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinerr:
8264035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    return;
8274035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin}
8284035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
8294035be28a255eaa5605dbd9abeb2340db584249cPatrick TjinDSStateMachine :: DSStateMachine(servicerType type, void *cb_func,
8304035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin                                 LocEngAdapter* adapterHandle):
8314035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    AgpsStateMachine(type, cb_func, AGPS_TYPE_INVALID,false),
8324035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    mLocAdapter(adapterHandle)
8334035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin{
8344035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    LOC_LOGD("%s:%d]: New DSStateMachine\n", __func__, __LINE__);
8354035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    mRetries = 0;
8364035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin}
8374035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
8384035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinvoid DSStateMachine :: retryCallback(void)
8394035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin{
8404035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    DSSubscriber *subscriber = NULL;
8414035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    Notification notification(Notification::BROADCAST_ACTIVE);
8424035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    linked_list_search(mSubscribers, (void**)&subscriber, hasSubscriber,
8434035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin                       (void*)&notification, false);
8444035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    if(subscriber)
8454035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        mLocAdapter->requestSuplES(subscriber->ID);
8464035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    else
8474035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        LOC_LOGE("DSStateMachine :: retryCallback: No subscriber found." \
8484035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin                 "Cannot retry data call\n");
8494035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    return;
8504035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin}
8514035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
8524035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinint DSStateMachine :: sendRsrcRequest(AGpsStatusValue action) const
8534035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin{
8544035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    DSSubscriber* s = NULL;
8554035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    dsCbData cbData;
8564035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    int ret=-1;
8574035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    int connHandle=-1;
8584035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    LOC_LOGD("Enter DSStateMachine :: sendRsrcRequest\n");
8594035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    Notification notification(Notification::BROADCAST_ACTIVE);
8604035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    linked_list_search(mSubscribers, (void**)&s, hasSubscriber,
8614035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin                       (void*)&notification, false);
8624035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    if(s) {
8634035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        connHandle = s->ID;
8644035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        LOC_LOGD("DSStateMachine :: sendRsrcRequest - subscriber found\n");
8654035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    }
8664035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    else
8674035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        LOC_LOGD("DSStateMachine :: sendRsrcRequest - No subscriber found\n");
8684035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
8694035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    cbData.action = action;
8704035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    cbData.mAdapter = mLocAdapter;
8714035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    ret = mServicer->requestRsrc((void *)&cbData);
8724035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    //Only the request to start data call returns a success/failure
8734035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    //The request to stop data call will always succeed
8744035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    //Hence, the below block will only be executed when the
8754035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    //request to start the data call fails
8764035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    switch(ret) {
8774035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    case LOC_API_ADAPTER_ERR_ENGINE_BUSY:
8784035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        LOC_LOGD("DSStateMachine :: sendRsrcRequest - Failure returned: %d\n",ret);
8794035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        ((DSStateMachine *)this)->incRetries();
8804035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        if(mRetries > MAX_START_DATA_CALL_RETRIES) {
8814035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            LOC_LOGE(" Failed to start Data call. Fallback to normal ATL SUPL\n");
8824035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            informStatus(RSRC_DENIED, connHandle);
8834035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        }
8844035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        else {
8854035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            if(loc_timer_start(DATA_CALL_RETRY_DELAY_MSEC, delay_callback, (void *)this)) {
8864035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin                LOC_LOGE("Error: Could not start delay thread\n");
8874035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin                ret = -1;
8884035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin                goto err;
8894035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            }
8904035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        }
8914035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        break;
8924035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    case LOC_API_ADAPTER_ERR_UNSUPPORTED:
8934035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        LOC_LOGE("No profile found for emergency call. Fallback to normal SUPL ATL\n");
8944035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        informStatus(RSRC_DENIED, connHandle);
8954035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        break;
8964035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    case LOC_API_ADAPTER_ERR_SUCCESS:
8974035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        LOC_LOGD("%s:%d]: Request to start data call sent\n", __func__, __LINE__);
8984035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        break;
8994035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    case -1:
9004035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        //One of the ways this case can be encountered is if the callback function
9014035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        //receives a null argument, it just exits with -1 error
9024035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        LOC_LOGE("Error: Something went wrong somewhere. Falling back to normal SUPL ATL\n");
9034035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        informStatus(RSRC_DENIED, connHandle);
9044035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        break;
9054035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    default:
9064035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        LOC_LOGE("%s:%d]: Unrecognized return value\n", __func__, __LINE__);
9074035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    }
9084035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinerr:
9094035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    LOC_LOGD("EXIT DSStateMachine :: sendRsrcRequest; ret = %d\n", ret);
9104035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    return ret;
9114035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin}
9124035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
9134035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinvoid DSStateMachine :: onRsrcEvent(AgpsRsrcStatus event)
9144035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin{
9154035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    void* currState = (void *)mStatePtr;
9164035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    LOC_LOGD("Enter DSStateMachine :: onRsrcEvent. event = %d\n", (int)event);
9174035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    switch (event)
9184035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    {
9194035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    case RSRC_GRANTED:
9204035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        LOC_LOGD("DSStateMachine :: onRsrcEvent RSRC_GRANTED\n");
9214035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        mStatePtr = mStatePtr->onRsrcEvent(event, NULL);
9224035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        break;
9234035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    case RSRC_RELEASED:
9244035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        LOC_LOGD("DSStateMachine :: onRsrcEvent RSRC_RELEASED\n");
9254035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        mStatePtr = mStatePtr->onRsrcEvent(event, NULL);
9264035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        //To handle the case where we get a RSRC_RELEASED in
9274035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        //pending state, we translate that to a RSRC_DENIED state
9284035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        //since the callback from DSI is either RSRC_GRANTED or RSRC_RELEASED
9294035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        //for when the call is connected or disconnected respectively.
9304035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        if((void *)mStatePtr != currState)
9314035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            break;
9324035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        else {
9334035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            event = RSRC_DENIED;
9344035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            LOC_LOGE(" Switching event to RSRC_DENIED\n");
9354035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        }
9364035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    case RSRC_DENIED:
9374035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        mStatePtr = mStatePtr->onRsrcEvent(event, NULL);
9384035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        break;
9394035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    default:
9404035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        LOC_LOGW("AgpsStateMachine: unrecognized event %d", event);
9414035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        break;
9424035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    }
9434035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    LOC_LOGD("Exit DSStateMachine :: onRsrcEvent. event = %d\n", (int)event);
9444035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin}
9454035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
9464035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinvoid DSStateMachine :: informStatus(AgpsRsrcStatus status, int ID) const
9474035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin{
9484035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    LOC_LOGD("DSStateMachine :: informStatus. Status=%d\n",(int)status);
9494035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    switch(status) {
9504035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    case RSRC_UNSUBSCRIBE:
9514035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        mLocAdapter->atlCloseStatus(ID, 1);
9524035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        break;
9534035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    case RSRC_RELEASED:
9544035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        mLocAdapter->closeDataCall();
9554035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        break;
9564035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    case RSRC_DENIED:
9574035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        ((DSStateMachine *)this)->mRetries = 0;
9584035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        mLocAdapter->requestATL(ID, AGPS_TYPE_SUPL);
9594035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        break;
9604035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    case RSRC_GRANTED:
9614035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        mLocAdapter->atlOpenStatus(ID, 1,
9624035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin                                                     NULL,
9634035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin                                                     AGPS_APN_BEARER_INVALID,
9644035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin                                                     AGPS_TYPE_INVALID);
9654035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        break;
9664035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    default:
9674035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        LOC_LOGW("DSStateMachine :: informStatus - unknown status");
9684035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    }
9694035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    return;
9704035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin}
971