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 ¬ification) 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 ¬ification) 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 ¬ification) 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 ¬ification) 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 ¬ification) 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*)¬ification, 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*)¬ification, 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*)¬ification, 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*)¬ification, 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(¬ification, 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*)¬ification, 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*)¬ification, 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*)¬ification, 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*)¬ification, 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