1e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
234ee09551764b045fdc02df754157473125edf60Kevin Tang *
334ee09551764b045fdc02df754157473125edf60Kevin Tang * Redistribution and use in source and binary forms, with or without
434ee09551764b045fdc02df754157473125edf60Kevin Tang * modification, are permitted provided that the following conditions are
534ee09551764b045fdc02df754157473125edf60Kevin Tang * met:
634ee09551764b045fdc02df754157473125edf60Kevin Tang *     * Redistributions of source code must retain the above copyright
734ee09551764b045fdc02df754157473125edf60Kevin Tang *       notice, this list of conditions and the following disclaimer.
834ee09551764b045fdc02df754157473125edf60Kevin Tang *     * Redistributions in binary form must reproduce the above
934ee09551764b045fdc02df754157473125edf60Kevin Tang *       copyright notice, this list of conditions and the following
1034ee09551764b045fdc02df754157473125edf60Kevin Tang *       disclaimer in the documentation and/or other materials provided
1134ee09551764b045fdc02df754157473125edf60Kevin Tang *       with the distribution.
12e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo *     * Neither the name of The Linux Foundation, nor the names of its
1334ee09551764b045fdc02df754157473125edf60Kevin Tang *       contributors may be used to endorse or promote products derived
1434ee09551764b045fdc02df754157473125edf60Kevin Tang *       from this software without specific prior written permission.
1534ee09551764b045fdc02df754157473125edf60Kevin Tang *
1634ee09551764b045fdc02df754157473125edf60Kevin Tang * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
1734ee09551764b045fdc02df754157473125edf60Kevin Tang * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1834ee09551764b045fdc02df754157473125edf60Kevin Tang * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
1934ee09551764b045fdc02df754157473125edf60Kevin Tang * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
2034ee09551764b045fdc02df754157473125edf60Kevin Tang * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2134ee09551764b045fdc02df754157473125edf60Kevin Tang * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2234ee09551764b045fdc02df754157473125edf60Kevin Tang * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
2334ee09551764b045fdc02df754157473125edf60Kevin Tang * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
2434ee09551764b045fdc02df754157473125edf60Kevin Tang * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
2534ee09551764b045fdc02df754157473125edf60Kevin Tang * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
2634ee09551764b045fdc02df754157473125edf60Kevin Tang * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2734ee09551764b045fdc02df754157473125edf60Kevin Tang *
2834ee09551764b045fdc02df754157473125edf60Kevin Tang */
2934ee09551764b045fdc02df754157473125edf60Kevin Tang
3034ee09551764b045fdc02df754157473125edf60Kevin Tang#define LOG_NDDEBUG 0
3134ee09551764b045fdc02df754157473125edf60Kevin Tang#define LOG_TAG "LocSvc_eng"
3234ee09551764b045fdc02df754157473125edf60Kevin Tang
3334ee09551764b045fdc02df754157473125edf60Kevin Tang#include <loc_eng_agps.h>
3434ee09551764b045fdc02df754157473125edf60Kevin Tang#include <loc_eng_log.h>
3534ee09551764b045fdc02df754157473125edf60Kevin Tang#include <log_util.h>
36e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo#include <platform_lib_includes.h>
3734ee09551764b045fdc02df754157473125edf60Kevin Tang#include <loc_eng_dmn_conn_handler.h>
3834ee09551764b045fdc02df754157473125edf60Kevin Tang#include <loc_eng_dmn_conn.h>
39e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo#include <sys/time.h>
4034ee09551764b045fdc02df754157473125edf60Kevin Tang
4134ee09551764b045fdc02df754157473125edf60Kevin Tang//======================================================================
4234ee09551764b045fdc02df754157473125edf60Kevin Tang// C callbacks
4334ee09551764b045fdc02df754157473125edf60Kevin Tang//======================================================================
4434ee09551764b045fdc02df754157473125edf60Kevin Tang
4534ee09551764b045fdc02df754157473125edf60Kevin Tang// This is given to linked_list_add as the dealloc callback
4634ee09551764b045fdc02df754157473125edf60Kevin Tang// data -- an instance of Subscriber
4734ee09551764b045fdc02df754157473125edf60Kevin Tangstatic void deleteObj(void* data)
4834ee09551764b045fdc02df754157473125edf60Kevin Tang{
4934ee09551764b045fdc02df754157473125edf60Kevin Tang    delete (Subscriber*)data;
5034ee09551764b045fdc02df754157473125edf60Kevin Tang}
5134ee09551764b045fdc02df754157473125edf60Kevin Tang
5234ee09551764b045fdc02df754157473125edf60Kevin Tang// This is given to linked_list_search() as the comparison callback
5334ee09551764b045fdc02df754157473125edf60Kevin Tang// when the state manchine needs to process for particular subscriber
5434ee09551764b045fdc02df754157473125edf60Kevin Tang// fromCaller -- caller provides this obj
5534ee09551764b045fdc02df754157473125edf60Kevin Tang// fromList -- linked_list_search() function take this one from list
5634ee09551764b045fdc02df754157473125edf60Kevin Tangstatic bool hasSubscriber(void* fromCaller, void* fromList)
5734ee09551764b045fdc02df754157473125edf60Kevin Tang{
5834ee09551764b045fdc02df754157473125edf60Kevin Tang    Notification* notification = (Notification*)fromCaller;
5934ee09551764b045fdc02df754157473125edf60Kevin Tang    Subscriber* s1 = (Subscriber*)fromList;
6034ee09551764b045fdc02df754157473125edf60Kevin Tang
6134ee09551764b045fdc02df754157473125edf60Kevin Tang    return s1->forMe(*notification);
6234ee09551764b045fdc02df754157473125edf60Kevin Tang}
6334ee09551764b045fdc02df754157473125edf60Kevin Tang
6434ee09551764b045fdc02df754157473125edf60Kevin Tang// This is gvien to linked_list_search() to notify subscriber objs
6534ee09551764b045fdc02df754157473125edf60Kevin Tang// when the state machine needs to inform all subscribers of resource
6634ee09551764b045fdc02df754157473125edf60Kevin Tang// status changes, e.g. when resource is GRANTED.
6734ee09551764b045fdc02df754157473125edf60Kevin Tang// fromCaller -- caller provides this ptr to a Notification obj.
6834ee09551764b045fdc02df754157473125edf60Kevin Tang// fromList -- linked_list_search() function take this one from list
6934ee09551764b045fdc02df754157473125edf60Kevin Tangstatic bool notifySubscriber(void* fromCaller, void* fromList)
7034ee09551764b045fdc02df754157473125edf60Kevin Tang{
7134ee09551764b045fdc02df754157473125edf60Kevin Tang    Notification* notification = (Notification*)fromCaller;
7234ee09551764b045fdc02df754157473125edf60Kevin Tang    Subscriber* s1 = (Subscriber*)fromList;
7334ee09551764b045fdc02df754157473125edf60Kevin Tang
7434ee09551764b045fdc02df754157473125edf60Kevin Tang    // we notify every subscriber indiscriminatively
7534ee09551764b045fdc02df754157473125edf60Kevin Tang    // each subscriber decides if this notification is interesting.
7634ee09551764b045fdc02df754157473125edf60Kevin Tang    return s1->notifyRsrcStatus(*notification) &&
7734ee09551764b045fdc02df754157473125edf60Kevin Tang           // if we do not want to delete the subscriber from the
7834ee09551764b045fdc02df754157473125edf60Kevin Tang           // the list, we must set this to false so this function
7934ee09551764b045fdc02df754157473125edf60Kevin Tang           // returns false
8034ee09551764b045fdc02df754157473125edf60Kevin Tang           notification->postNotifyDelete;
8134ee09551764b045fdc02df754157473125edf60Kevin Tang}
8234ee09551764b045fdc02df754157473125edf60Kevin Tang
8334ee09551764b045fdc02df754157473125edf60Kevin Tang//======================================================================
8434ee09551764b045fdc02df754157473125edf60Kevin Tang// Notification
8534ee09551764b045fdc02df754157473125edf60Kevin Tang//======================================================================
8634ee09551764b045fdc02df754157473125edf60Kevin Tangconst int Notification::BROADCAST_ALL = 0x80000000;
8734ee09551764b045fdc02df754157473125edf60Kevin Tangconst int Notification::BROADCAST_ACTIVE = 0x80000001;
8834ee09551764b045fdc02df754157473125edf60Kevin Tangconst int Notification::BROADCAST_INACTIVE = 0x80000002;
89e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russoconst unsigned char DSStateMachine::MAX_START_DATA_CALL_RETRIES = 4;
90e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russoconst unsigned int DSStateMachine::DATA_CALL_RETRY_DELAY_MSEC = 500;
9134ee09551764b045fdc02df754157473125edf60Kevin Tang//======================================================================
92e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo// Subscriber:  BITSubscriber / ATLSubscriber / WIFISubscriber
9334ee09551764b045fdc02df754157473125edf60Kevin Tang//======================================================================
9434ee09551764b045fdc02df754157473125edf60Kevin Tangbool Subscriber::forMe(Notification &notification)
9534ee09551764b045fdc02df754157473125edf60Kevin Tang{
9634ee09551764b045fdc02df754157473125edf60Kevin Tang    if (NULL != notification.rcver) {
9734ee09551764b045fdc02df754157473125edf60Kevin Tang        return equals(notification.rcver);
9834ee09551764b045fdc02df754157473125edf60Kevin Tang    } else {
9934ee09551764b045fdc02df754157473125edf60Kevin Tang        return Notification::BROADCAST_ALL == notification.groupID ||
10034ee09551764b045fdc02df754157473125edf60Kevin Tang            (Notification::BROADCAST_ACTIVE == notification.groupID &&
10134ee09551764b045fdc02df754157473125edf60Kevin Tang             !isInactive()) ||
10234ee09551764b045fdc02df754157473125edf60Kevin Tang            (Notification::BROADCAST_INACTIVE == notification.groupID &&
10334ee09551764b045fdc02df754157473125edf60Kevin Tang             isInactive());
10434ee09551764b045fdc02df754157473125edf60Kevin Tang    }
10534ee09551764b045fdc02df754157473125edf60Kevin Tang}
10634ee09551764b045fdc02df754157473125edf60Kevin Tangbool BITSubscriber::equals(const Subscriber *s) const
10734ee09551764b045fdc02df754157473125edf60Kevin Tang{
10834ee09551764b045fdc02df754157473125edf60Kevin Tang    BITSubscriber* bitS = (BITSubscriber*)s;
10934ee09551764b045fdc02df754157473125edf60Kevin Tang
11034ee09551764b045fdc02df754157473125edf60Kevin Tang    return (ID == bitS->ID &&
11134ee09551764b045fdc02df754157473125edf60Kevin Tang            (INADDR_NONE != (unsigned int)ID ||
112e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo             0 == strncmp(mIPv6Addr, bitS->mIPv6Addr, sizeof(mIPv6Addr))));
11334ee09551764b045fdc02df754157473125edf60Kevin Tang}
11434ee09551764b045fdc02df754157473125edf60Kevin Tang
11534ee09551764b045fdc02df754157473125edf60Kevin Tangbool BITSubscriber::notifyRsrcStatus(Notification &notification)
11634ee09551764b045fdc02df754157473125edf60Kevin Tang{
11734ee09551764b045fdc02df754157473125edf60Kevin Tang    bool notify = forMe(notification);
11834ee09551764b045fdc02df754157473125edf60Kevin Tang
11934ee09551764b045fdc02df754157473125edf60Kevin Tang    if (notify) {
12034ee09551764b045fdc02df754157473125edf60Kevin Tang        switch(notification.rsrcStatus)
12134ee09551764b045fdc02df754157473125edf60Kevin Tang        {
12234ee09551764b045fdc02df754157473125edf60Kevin Tang        case RSRC_UNSUBSCRIBE:
12334ee09551764b045fdc02df754157473125edf60Kevin Tang        case RSRC_RELEASED:
12434ee09551764b045fdc02df754157473125edf60Kevin Tang            loc_eng_dmn_conn_loc_api_server_data_conn(
125e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo                LOC_ENG_IF_REQUEST_SENDER_ID_GPSONE_DAEMON,
12634ee09551764b045fdc02df754157473125edf60Kevin Tang                GPSONE_LOC_API_IF_RELEASE_SUCCESS);
12734ee09551764b045fdc02df754157473125edf60Kevin Tang            break;
12834ee09551764b045fdc02df754157473125edf60Kevin Tang        case RSRC_DENIED:
12934ee09551764b045fdc02df754157473125edf60Kevin Tang            loc_eng_dmn_conn_loc_api_server_data_conn(
130e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo                LOC_ENG_IF_REQUEST_SENDER_ID_GPSONE_DAEMON,
13134ee09551764b045fdc02df754157473125edf60Kevin Tang                GPSONE_LOC_API_IF_FAILURE);
13234ee09551764b045fdc02df754157473125edf60Kevin Tang            break;
13334ee09551764b045fdc02df754157473125edf60Kevin Tang        case RSRC_GRANTED:
13434ee09551764b045fdc02df754157473125edf60Kevin Tang            loc_eng_dmn_conn_loc_api_server_data_conn(
135e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo                LOC_ENG_IF_REQUEST_SENDER_ID_GPSONE_DAEMON,
13634ee09551764b045fdc02df754157473125edf60Kevin Tang                GPSONE_LOC_API_IF_REQUEST_SUCCESS);
13734ee09551764b045fdc02df754157473125edf60Kevin Tang            break;
13834ee09551764b045fdc02df754157473125edf60Kevin Tang        default:
13934ee09551764b045fdc02df754157473125edf60Kevin Tang            notify = false;
14034ee09551764b045fdc02df754157473125edf60Kevin Tang        }
14134ee09551764b045fdc02df754157473125edf60Kevin Tang    }
14234ee09551764b045fdc02df754157473125edf60Kevin Tang
14334ee09551764b045fdc02df754157473125edf60Kevin Tang    return notify;
14434ee09551764b045fdc02df754157473125edf60Kevin Tang}
14534ee09551764b045fdc02df754157473125edf60Kevin Tang
14634ee09551764b045fdc02df754157473125edf60Kevin Tangbool ATLSubscriber::notifyRsrcStatus(Notification &notification)
14734ee09551764b045fdc02df754157473125edf60Kevin Tang{
14834ee09551764b045fdc02df754157473125edf60Kevin Tang    bool notify = forMe(notification);
14934ee09551764b045fdc02df754157473125edf60Kevin Tang
15034ee09551764b045fdc02df754157473125edf60Kevin Tang    if (notify) {
15134ee09551764b045fdc02df754157473125edf60Kevin Tang        switch(notification.rsrcStatus)
15234ee09551764b045fdc02df754157473125edf60Kevin Tang        {
15334ee09551764b045fdc02df754157473125edf60Kevin Tang        case RSRC_UNSUBSCRIBE:
15434ee09551764b045fdc02df754157473125edf60Kevin Tang        case RSRC_RELEASED:
155e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo            ((LocEngAdapter*)mLocAdapter)->atlCloseStatus(ID, 1);
15634ee09551764b045fdc02df754157473125edf60Kevin Tang            break;
15734ee09551764b045fdc02df754157473125edf60Kevin Tang        case RSRC_DENIED:
158e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        {
159e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo            AGpsExtType type = mBackwardCompatibleMode ?
160e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo                              AGPS_TYPE_INVALID : mStateMachine->getType();
161e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo            ((LocEngAdapter*)mLocAdapter)->atlOpenStatus(ID, 0,
16234ee09551764b045fdc02df754157473125edf60Kevin Tang                                            (char*)mStateMachine->getAPN(),
16334ee09551764b045fdc02df754157473125edf60Kevin Tang                                            mStateMachine->getBearer(),
164e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo                                            type);
165e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        }
16634ee09551764b045fdc02df754157473125edf60Kevin Tang            break;
16734ee09551764b045fdc02df754157473125edf60Kevin Tang        case RSRC_GRANTED:
168e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        {
169e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo            AGpsExtType type = mBackwardCompatibleMode ?
170e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo                              AGPS_TYPE_INVALID : mStateMachine->getType();
171e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo            ((LocEngAdapter*)mLocAdapter)->atlOpenStatus(ID, 1,
17234ee09551764b045fdc02df754157473125edf60Kevin Tang                                            (char*)mStateMachine->getAPN(),
17334ee09551764b045fdc02df754157473125edf60Kevin Tang                                            mStateMachine->getBearer(),
174e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo                                            type);
175e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        }
17634ee09551764b045fdc02df754157473125edf60Kevin Tang            break;
17734ee09551764b045fdc02df754157473125edf60Kevin Tang        default:
17834ee09551764b045fdc02df754157473125edf60Kevin Tang            notify = false;
17934ee09551764b045fdc02df754157473125edf60Kevin Tang        }
18034ee09551764b045fdc02df754157473125edf60Kevin Tang    }
18134ee09551764b045fdc02df754157473125edf60Kevin Tang
18234ee09551764b045fdc02df754157473125edf60Kevin Tang    return notify;
18334ee09551764b045fdc02df754157473125edf60Kevin Tang}
18434ee09551764b045fdc02df754157473125edf60Kevin Tang
185e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russobool WIFISubscriber::notifyRsrcStatus(Notification &notification)
186e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo{
187e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    bool notify = forMe(notification);
188e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
189e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    if (notify) {
190e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        switch(notification.rsrcStatus)
191e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        {
192e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        case RSRC_UNSUBSCRIBE:
193e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo            break;
194e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        case RSRC_RELEASED:
195e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo            loc_eng_dmn_conn_loc_api_server_data_conn(
196e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo                senderId,
197e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo                GPSONE_LOC_API_IF_RELEASE_SUCCESS);
198e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo            break;
199e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        case RSRC_DENIED:
200e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo            loc_eng_dmn_conn_loc_api_server_data_conn(
201e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo                senderId,
202e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo                GPSONE_LOC_API_IF_FAILURE);
203e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo            break;
204e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        case RSRC_GRANTED:
205e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo            loc_eng_dmn_conn_loc_api_server_data_conn(
206e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo                senderId,
207e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo                GPSONE_LOC_API_IF_REQUEST_SUCCESS);
208e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo            break;
209e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        default:
210e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo            notify = false;
211e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        }
212e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    }
21334ee09551764b045fdc02df754157473125edf60Kevin Tang
214e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    return notify;
215e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo}
216e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russobool DSSubscriber::notifyRsrcStatus(Notification &notification)
217e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo{
218e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    bool notify = forMe(notification);
219e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    LOC_LOGD("DSSubscriber::notifyRsrcStatus. notify:%d \n",(int)(notify));
220e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    if(notify) {
221e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        switch(notification.rsrcStatus) {
222e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        case RSRC_UNSUBSCRIBE:
223e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        case RSRC_RELEASED:
224e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        case RSRC_DENIED:
225e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        case RSRC_GRANTED:
226e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo            ((DSStateMachine *)mStateMachine)->informStatus(notification.rsrcStatus, ID);
227e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo            break;
228e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        default:
229e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo            notify = false;
230e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        }
231e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    }
232e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    return notify;
233e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo}
234e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russovoid DSSubscriber :: setInactive()
235e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo{
236e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    mIsInactive = true;
237e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    ((DSStateMachine *)mStateMachine)->informStatus(RSRC_UNSUBSCRIBE, ID);
238e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo}
23934ee09551764b045fdc02df754157473125edf60Kevin Tang//======================================================================
24034ee09551764b045fdc02df754157473125edf60Kevin Tang// AgpsState:  AgpsReleasedState / AgpsPendingState / AgpsAcquiredState
24134ee09551764b045fdc02df754157473125edf60Kevin Tang//======================================================================
24234ee09551764b045fdc02df754157473125edf60Kevin Tang
24334ee09551764b045fdc02df754157473125edf60Kevin Tang// AgpsReleasedState
24434ee09551764b045fdc02df754157473125edf60Kevin Tangclass AgpsReleasedState : public AgpsState
24534ee09551764b045fdc02df754157473125edf60Kevin Tang{
24634ee09551764b045fdc02df754157473125edf60Kevin Tang    friend class AgpsStateMachine;
24734ee09551764b045fdc02df754157473125edf60Kevin Tang
24834ee09551764b045fdc02df754157473125edf60Kevin Tang    inline AgpsReleasedState(AgpsStateMachine* stateMachine) :
24934ee09551764b045fdc02df754157473125edf60Kevin Tang        AgpsState(stateMachine)
25034ee09551764b045fdc02df754157473125edf60Kevin Tang    { mReleasedState = this; }
25134ee09551764b045fdc02df754157473125edf60Kevin Tang
25234ee09551764b045fdc02df754157473125edf60Kevin Tang    inline ~AgpsReleasedState() {}
25334ee09551764b045fdc02df754157473125edf60Kevin Tangpublic:
25434ee09551764b045fdc02df754157473125edf60Kevin Tang    virtual AgpsState* onRsrcEvent(AgpsRsrcStatus event, void* data);
25534ee09551764b045fdc02df754157473125edf60Kevin Tang    inline virtual char* whoami() {return (char*)"AgpsReleasedState";}
25634ee09551764b045fdc02df754157473125edf60Kevin Tang};
25734ee09551764b045fdc02df754157473125edf60Kevin Tang
25834ee09551764b045fdc02df754157473125edf60Kevin TangAgpsState* AgpsReleasedState::onRsrcEvent(AgpsRsrcStatus event, void* data)
25934ee09551764b045fdc02df754157473125edf60Kevin Tang{
260e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    LOC_LOGD("AgpsReleasedState::onRsrcEvent; event:%d\n", (int)event);
26134ee09551764b045fdc02df754157473125edf60Kevin Tang    if (mStateMachine->hasSubscribers()) {
26234ee09551764b045fdc02df754157473125edf60Kevin Tang        LOC_LOGE("Error: %s subscriber list not empty!!!", whoami());
26334ee09551764b045fdc02df754157473125edf60Kevin Tang        // I don't know how to recover from it.  I am adding this rather
26434ee09551764b045fdc02df754157473125edf60Kevin Tang        // for debugging purpose.
26534ee09551764b045fdc02df754157473125edf60Kevin Tang    }
26634ee09551764b045fdc02df754157473125edf60Kevin Tang
267e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    AgpsState* nextState = this;
26834ee09551764b045fdc02df754157473125edf60Kevin Tang    switch (event)
26934ee09551764b045fdc02df754157473125edf60Kevin Tang    {
27034ee09551764b045fdc02df754157473125edf60Kevin Tang    case RSRC_SUBSCRIBE:
27134ee09551764b045fdc02df754157473125edf60Kevin Tang    {
27234ee09551764b045fdc02df754157473125edf60Kevin Tang        // no notification until we get RSRC_GRANTED
27334ee09551764b045fdc02df754157473125edf60Kevin Tang        // but we need to add subscriber to the list
27434ee09551764b045fdc02df754157473125edf60Kevin Tang        mStateMachine->addSubscriber((Subscriber*)data);
27534ee09551764b045fdc02df754157473125edf60Kevin Tang        // request from connecivity service for NIF
276e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        //The if condition is added so that if the data call setup fails
277e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        //for DS State Machine, we want to retry in released state.
278e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        //for AGps State Machine, sendRsrcRequest() will always return success
279e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        if(!mStateMachine->sendRsrcRequest(GPS_REQUEST_AGPS_DATA_CONN)) {
280e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo            // move the state to PENDING
281e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo            nextState = mPendingState;
282e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        }
28334ee09551764b045fdc02df754157473125edf60Kevin Tang    }
284e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    break;
28534ee09551764b045fdc02df754157473125edf60Kevin Tang
28634ee09551764b045fdc02df754157473125edf60Kevin Tang    case RSRC_UNSUBSCRIBE:
28734ee09551764b045fdc02df754157473125edf60Kevin Tang    {
28834ee09551764b045fdc02df754157473125edf60Kevin Tang        // the list should really be empty, nothing to remove.
28934ee09551764b045fdc02df754157473125edf60Kevin Tang        // but we might as well just tell the client it is
29034ee09551764b045fdc02df754157473125edf60Kevin Tang        // unsubscribed.  False tolerance, right?
29134ee09551764b045fdc02df754157473125edf60Kevin Tang        Subscriber* subscriber = (Subscriber*) data;
29234ee09551764b045fdc02df754157473125edf60Kevin Tang        Notification notification(subscriber, event, false);
29334ee09551764b045fdc02df754157473125edf60Kevin Tang        subscriber->notifyRsrcStatus(notification);
29434ee09551764b045fdc02df754157473125edf60Kevin Tang    }
29534ee09551764b045fdc02df754157473125edf60Kevin Tang        // break;
29634ee09551764b045fdc02df754157473125edf60Kevin Tang    case RSRC_GRANTED:
29734ee09551764b045fdc02df754157473125edf60Kevin Tang    case RSRC_RELEASED:
29834ee09551764b045fdc02df754157473125edf60Kevin Tang    case RSRC_DENIED:
29934ee09551764b045fdc02df754157473125edf60Kevin Tang    default:
30034ee09551764b045fdc02df754157473125edf60Kevin Tang        LOC_LOGW("%s: unrecognized event %d", whoami(), event);
30134ee09551764b045fdc02df754157473125edf60Kevin Tang        // no state change.
30234ee09551764b045fdc02df754157473125edf60Kevin Tang        break;
30334ee09551764b045fdc02df754157473125edf60Kevin Tang    }
30434ee09551764b045fdc02df754157473125edf60Kevin Tang
30534ee09551764b045fdc02df754157473125edf60Kevin Tang    LOC_LOGD("onRsrcEvent, old state %s, new state %s, event %d",
30634ee09551764b045fdc02df754157473125edf60Kevin Tang             whoami(), nextState->whoami(), event);
30734ee09551764b045fdc02df754157473125edf60Kevin Tang    return nextState;
30834ee09551764b045fdc02df754157473125edf60Kevin Tang}
30934ee09551764b045fdc02df754157473125edf60Kevin Tang
31034ee09551764b045fdc02df754157473125edf60Kevin Tang// AgpsPendingState
31134ee09551764b045fdc02df754157473125edf60Kevin Tangclass AgpsPendingState : public AgpsState
31234ee09551764b045fdc02df754157473125edf60Kevin Tang{
31334ee09551764b045fdc02df754157473125edf60Kevin Tang    friend class AgpsStateMachine;
31434ee09551764b045fdc02df754157473125edf60Kevin Tang
31534ee09551764b045fdc02df754157473125edf60Kevin Tang    inline AgpsPendingState(AgpsStateMachine* stateMachine) :
31634ee09551764b045fdc02df754157473125edf60Kevin Tang        AgpsState(stateMachine)
31734ee09551764b045fdc02df754157473125edf60Kevin Tang    { mPendingState = this; }
31834ee09551764b045fdc02df754157473125edf60Kevin Tang
31934ee09551764b045fdc02df754157473125edf60Kevin Tang    inline ~AgpsPendingState() {}
32034ee09551764b045fdc02df754157473125edf60Kevin Tangpublic:
32134ee09551764b045fdc02df754157473125edf60Kevin Tang    virtual AgpsState* onRsrcEvent(AgpsRsrcStatus event, void* data);
32234ee09551764b045fdc02df754157473125edf60Kevin Tang    inline virtual char* whoami() {return (char*)"AgpsPendingState";}
32334ee09551764b045fdc02df754157473125edf60Kevin Tang};
32434ee09551764b045fdc02df754157473125edf60Kevin Tang
32534ee09551764b045fdc02df754157473125edf60Kevin TangAgpsState* AgpsPendingState::onRsrcEvent(AgpsRsrcStatus event, void* data)
32634ee09551764b045fdc02df754157473125edf60Kevin Tang{
32734ee09551764b045fdc02df754157473125edf60Kevin Tang    AgpsState* nextState = this;;
328e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    LOC_LOGD("AgpsPendingState::onRsrcEvent; event:%d\n", (int)event);
32934ee09551764b045fdc02df754157473125edf60Kevin Tang    switch (event)
33034ee09551764b045fdc02df754157473125edf60Kevin Tang    {
33134ee09551764b045fdc02df754157473125edf60Kevin Tang    case RSRC_SUBSCRIBE:
33234ee09551764b045fdc02df754157473125edf60Kevin Tang    {
33334ee09551764b045fdc02df754157473125edf60Kevin Tang        // already requested for NIF resource,
33434ee09551764b045fdc02df754157473125edf60Kevin Tang        // do nothing until we get RSRC_GRANTED indication
33534ee09551764b045fdc02df754157473125edf60Kevin Tang        // but we need to add subscriber to the list
33634ee09551764b045fdc02df754157473125edf60Kevin Tang        mStateMachine->addSubscriber((Subscriber*)data);
33734ee09551764b045fdc02df754157473125edf60Kevin Tang        // no state change.
33834ee09551764b045fdc02df754157473125edf60Kevin Tang    }
33934ee09551764b045fdc02df754157473125edf60Kevin Tang        break;
34034ee09551764b045fdc02df754157473125edf60Kevin Tang
34134ee09551764b045fdc02df754157473125edf60Kevin Tang    case RSRC_UNSUBSCRIBE:
34234ee09551764b045fdc02df754157473125edf60Kevin Tang    {
34334ee09551764b045fdc02df754157473125edf60Kevin Tang        Subscriber* subscriber = (Subscriber*) data;
34434ee09551764b045fdc02df754157473125edf60Kevin Tang        if (subscriber->waitForCloseComplete()) {
34534ee09551764b045fdc02df754157473125edf60Kevin Tang            subscriber->setInactive();
34634ee09551764b045fdc02df754157473125edf60Kevin Tang        } else {
34734ee09551764b045fdc02df754157473125edf60Kevin Tang            // auto notify this subscriber of the unsubscribe
34834ee09551764b045fdc02df754157473125edf60Kevin Tang            Notification notification(subscriber, event, true);
34934ee09551764b045fdc02df754157473125edf60Kevin Tang            mStateMachine->notifySubscribers(notification);
350e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        }
35134ee09551764b045fdc02df754157473125edf60Kevin Tang
352e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        // now check if there is any subscribers left
353e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        if (!mStateMachine->hasSubscribers()) {
354e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo            // no more subscribers, move to RELEASED state
355e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo            nextState = mReleasedState;
35634ee09551764b045fdc02df754157473125edf60Kevin Tang
357e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo            // tell connecivity service we can release NIF
358e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo            mStateMachine->sendRsrcRequest(GPS_RELEASE_AGPS_DATA_CONN);
359e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        } else if (!mStateMachine->hasActiveSubscribers()) {
360e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo            // only inactive subscribers, move to RELEASING state
361e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo            nextState = mReleasingState;
362e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
363e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo            // tell connecivity service we can release NIF
364e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo            mStateMachine->sendRsrcRequest(GPS_RELEASE_AGPS_DATA_CONN);
36534ee09551764b045fdc02df754157473125edf60Kevin Tang        }
36634ee09551764b045fdc02df754157473125edf60Kevin Tang    }
367e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    break;
36834ee09551764b045fdc02df754157473125edf60Kevin Tang
36934ee09551764b045fdc02df754157473125edf60Kevin Tang    case RSRC_GRANTED:
37034ee09551764b045fdc02df754157473125edf60Kevin Tang    {
37134ee09551764b045fdc02df754157473125edf60Kevin Tang        nextState = mAcquiredState;
37234ee09551764b045fdc02df754157473125edf60Kevin Tang        Notification notification(Notification::BROADCAST_ACTIVE, event, false);
37334ee09551764b045fdc02df754157473125edf60Kevin Tang        // notify all subscribers NIF resource GRANTED
37434ee09551764b045fdc02df754157473125edf60Kevin Tang        // by setting false, we keep subscribers on the linked list
37534ee09551764b045fdc02df754157473125edf60Kevin Tang        mStateMachine->notifySubscribers(notification);
37634ee09551764b045fdc02df754157473125edf60Kevin Tang    }
37734ee09551764b045fdc02df754157473125edf60Kevin Tang        break;
37834ee09551764b045fdc02df754157473125edf60Kevin Tang
37934ee09551764b045fdc02df754157473125edf60Kevin Tang    case RSRC_RELEASED:
38034ee09551764b045fdc02df754157473125edf60Kevin Tang        // no state change.
38134ee09551764b045fdc02df754157473125edf60Kevin Tang        // we are expecting either GRANTED or DENIED.  Handling RELEASED
38234ee09551764b045fdc02df754157473125edf60Kevin Tang        // may like break our state machine in race conditions.
38334ee09551764b045fdc02df754157473125edf60Kevin Tang        break;
38434ee09551764b045fdc02df754157473125edf60Kevin Tang
38534ee09551764b045fdc02df754157473125edf60Kevin Tang    case RSRC_DENIED:
38634ee09551764b045fdc02df754157473125edf60Kevin Tang    {
38734ee09551764b045fdc02df754157473125edf60Kevin Tang        nextState = mReleasedState;
38834ee09551764b045fdc02df754157473125edf60Kevin Tang        Notification notification(Notification::BROADCAST_ALL, event, true);
38934ee09551764b045fdc02df754157473125edf60Kevin Tang        // notify all subscribers NIF resource RELEASED or DENIED
39034ee09551764b045fdc02df754157473125edf60Kevin Tang        // by setting true, we remove subscribers from the linked list
39134ee09551764b045fdc02df754157473125edf60Kevin Tang        mStateMachine->notifySubscribers(notification);
39234ee09551764b045fdc02df754157473125edf60Kevin Tang    }
39334ee09551764b045fdc02df754157473125edf60Kevin Tang        break;
39434ee09551764b045fdc02df754157473125edf60Kevin Tang
39534ee09551764b045fdc02df754157473125edf60Kevin Tang    default:
39634ee09551764b045fdc02df754157473125edf60Kevin Tang        LOC_LOGE("%s: unrecognized event %d", whoami(), event);
39734ee09551764b045fdc02df754157473125edf60Kevin Tang        // no state change.
39834ee09551764b045fdc02df754157473125edf60Kevin Tang    }
39934ee09551764b045fdc02df754157473125edf60Kevin Tang
40034ee09551764b045fdc02df754157473125edf60Kevin Tang    LOC_LOGD("onRsrcEvent, old state %s, new state %s, event %d",
40134ee09551764b045fdc02df754157473125edf60Kevin Tang             whoami(), nextState->whoami(), event);
40234ee09551764b045fdc02df754157473125edf60Kevin Tang    return nextState;
40334ee09551764b045fdc02df754157473125edf60Kevin Tang}
40434ee09551764b045fdc02df754157473125edf60Kevin Tang
40534ee09551764b045fdc02df754157473125edf60Kevin Tang
40634ee09551764b045fdc02df754157473125edf60Kevin Tangclass AgpsAcquiredState : public AgpsState
40734ee09551764b045fdc02df754157473125edf60Kevin Tang{
40834ee09551764b045fdc02df754157473125edf60Kevin Tang    friend class AgpsStateMachine;
40934ee09551764b045fdc02df754157473125edf60Kevin Tang
41034ee09551764b045fdc02df754157473125edf60Kevin Tang    inline AgpsAcquiredState(AgpsStateMachine* stateMachine) :
41134ee09551764b045fdc02df754157473125edf60Kevin Tang        AgpsState(stateMachine)
41234ee09551764b045fdc02df754157473125edf60Kevin Tang    { mAcquiredState = this; }
41334ee09551764b045fdc02df754157473125edf60Kevin Tang
41434ee09551764b045fdc02df754157473125edf60Kevin Tang    inline ~AgpsAcquiredState() {}
41534ee09551764b045fdc02df754157473125edf60Kevin Tangpublic:
41634ee09551764b045fdc02df754157473125edf60Kevin Tang    virtual AgpsState* onRsrcEvent(AgpsRsrcStatus event, void* data);
41734ee09551764b045fdc02df754157473125edf60Kevin Tang    inline virtual char* whoami() { return (char*)"AgpsAcquiredState"; }
41834ee09551764b045fdc02df754157473125edf60Kevin Tang};
41934ee09551764b045fdc02df754157473125edf60Kevin Tang
42034ee09551764b045fdc02df754157473125edf60Kevin Tang
42134ee09551764b045fdc02df754157473125edf60Kevin TangAgpsState* AgpsAcquiredState::onRsrcEvent(AgpsRsrcStatus event, void* data)
42234ee09551764b045fdc02df754157473125edf60Kevin Tang{
42334ee09551764b045fdc02df754157473125edf60Kevin Tang    AgpsState* nextState = this;
424e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    LOC_LOGD("AgpsAcquiredState::onRsrcEvent; event:%d\n", (int)event);
42534ee09551764b045fdc02df754157473125edf60Kevin Tang    switch (event)
42634ee09551764b045fdc02df754157473125edf60Kevin Tang    {
42734ee09551764b045fdc02df754157473125edf60Kevin Tang    case RSRC_SUBSCRIBE:
42834ee09551764b045fdc02df754157473125edf60Kevin Tang    {
42934ee09551764b045fdc02df754157473125edf60Kevin Tang        // we already have the NIF resource, simply notify subscriber
43034ee09551764b045fdc02df754157473125edf60Kevin Tang        Subscriber* subscriber = (Subscriber*) data;
43134ee09551764b045fdc02df754157473125edf60Kevin Tang        // we have rsrc in hand, so grant it right away
43234ee09551764b045fdc02df754157473125edf60Kevin Tang        Notification notification(subscriber, RSRC_GRANTED, false);
43334ee09551764b045fdc02df754157473125edf60Kevin Tang        subscriber->notifyRsrcStatus(notification);
43434ee09551764b045fdc02df754157473125edf60Kevin Tang        // add subscriber to the list
43534ee09551764b045fdc02df754157473125edf60Kevin Tang        mStateMachine->addSubscriber(subscriber);
43634ee09551764b045fdc02df754157473125edf60Kevin Tang        // no state change.
43734ee09551764b045fdc02df754157473125edf60Kevin Tang    }
43834ee09551764b045fdc02df754157473125edf60Kevin Tang        break;
43934ee09551764b045fdc02df754157473125edf60Kevin Tang
44034ee09551764b045fdc02df754157473125edf60Kevin Tang    case RSRC_UNSUBSCRIBE:
44134ee09551764b045fdc02df754157473125edf60Kevin Tang    {
44234ee09551764b045fdc02df754157473125edf60Kevin Tang        Subscriber* subscriber = (Subscriber*) data;
44334ee09551764b045fdc02df754157473125edf60Kevin Tang        if (subscriber->waitForCloseComplete()) {
44434ee09551764b045fdc02df754157473125edf60Kevin Tang            subscriber->setInactive();
44534ee09551764b045fdc02df754157473125edf60Kevin Tang        } else {
44634ee09551764b045fdc02df754157473125edf60Kevin Tang            // auto notify this subscriber of the unsubscribe
44734ee09551764b045fdc02df754157473125edf60Kevin Tang            Notification notification(subscriber, event, true);
44834ee09551764b045fdc02df754157473125edf60Kevin Tang            mStateMachine->notifySubscribers(notification);
44934ee09551764b045fdc02df754157473125edf60Kevin Tang        }
45034ee09551764b045fdc02df754157473125edf60Kevin Tang
45134ee09551764b045fdc02df754157473125edf60Kevin Tang        // now check if there is any subscribers left
45234ee09551764b045fdc02df754157473125edf60Kevin Tang        if (!mStateMachine->hasSubscribers()) {
45334ee09551764b045fdc02df754157473125edf60Kevin Tang            // no more subscribers, move to RELEASED state
454e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo            nextState = mReleasedState;
45534ee09551764b045fdc02df754157473125edf60Kevin Tang
45634ee09551764b045fdc02df754157473125edf60Kevin Tang            // tell connecivity service we can release NIF
45734ee09551764b045fdc02df754157473125edf60Kevin Tang            mStateMachine->sendRsrcRequest(GPS_RELEASE_AGPS_DATA_CONN);
45834ee09551764b045fdc02df754157473125edf60Kevin Tang        } else if (!mStateMachine->hasActiveSubscribers()) {
459e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo            // only inactive subscribers, move to RELEASING state
460e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo            nextState = mReleasingState;
46134ee09551764b045fdc02df754157473125edf60Kevin Tang
46234ee09551764b045fdc02df754157473125edf60Kevin Tang            // tell connecivity service we can release NIF
46334ee09551764b045fdc02df754157473125edf60Kevin Tang            mStateMachine->sendRsrcRequest(GPS_RELEASE_AGPS_DATA_CONN);
46434ee09551764b045fdc02df754157473125edf60Kevin Tang        }
46534ee09551764b045fdc02df754157473125edf60Kevin Tang    }
46634ee09551764b045fdc02df754157473125edf60Kevin Tang        break;
46734ee09551764b045fdc02df754157473125edf60Kevin Tang
46834ee09551764b045fdc02df754157473125edf60Kevin Tang    case RSRC_GRANTED:
46934ee09551764b045fdc02df754157473125edf60Kevin Tang        LOC_LOGW("%s: %d, RSRC_GRANTED already received", whoami(), event);
47034ee09551764b045fdc02df754157473125edf60Kevin Tang        // no state change.
47134ee09551764b045fdc02df754157473125edf60Kevin Tang        break;
47234ee09551764b045fdc02df754157473125edf60Kevin Tang
47334ee09551764b045fdc02df754157473125edf60Kevin Tang    case RSRC_RELEASED:
47434ee09551764b045fdc02df754157473125edf60Kevin Tang    {
47534ee09551764b045fdc02df754157473125edf60Kevin Tang        LOC_LOGW("%s: %d, a force rsrc release", whoami(), event);
47634ee09551764b045fdc02df754157473125edf60Kevin Tang        nextState = mReleasedState;
47734ee09551764b045fdc02df754157473125edf60Kevin Tang        Notification notification(Notification::BROADCAST_ALL, event, true);
47834ee09551764b045fdc02df754157473125edf60Kevin Tang        // by setting true, we remove subscribers from the linked list
47934ee09551764b045fdc02df754157473125edf60Kevin Tang        mStateMachine->notifySubscribers(notification);
48034ee09551764b045fdc02df754157473125edf60Kevin Tang    }
48134ee09551764b045fdc02df754157473125edf60Kevin Tang        break;
48234ee09551764b045fdc02df754157473125edf60Kevin Tang
48334ee09551764b045fdc02df754157473125edf60Kevin Tang    case RSRC_DENIED:
48434ee09551764b045fdc02df754157473125edf60Kevin Tang        // no state change.
48534ee09551764b045fdc02df754157473125edf60Kevin Tang        // we are expecting RELEASED.  Handling DENIED
48634ee09551764b045fdc02df754157473125edf60Kevin Tang        // may like break our state machine in race conditions.
48734ee09551764b045fdc02df754157473125edf60Kevin Tang        break;
48834ee09551764b045fdc02df754157473125edf60Kevin Tang
48934ee09551764b045fdc02df754157473125edf60Kevin Tang    default:
49034ee09551764b045fdc02df754157473125edf60Kevin Tang        LOC_LOGE("%s: unrecognized event %d", whoami(), event);
49134ee09551764b045fdc02df754157473125edf60Kevin Tang        // no state change.
49234ee09551764b045fdc02df754157473125edf60Kevin Tang    }
49334ee09551764b045fdc02df754157473125edf60Kevin Tang
49434ee09551764b045fdc02df754157473125edf60Kevin Tang    LOC_LOGD("onRsrcEvent, old state %s, new state %s, event %d",
49534ee09551764b045fdc02df754157473125edf60Kevin Tang             whoami(), nextState->whoami(), event);
49634ee09551764b045fdc02df754157473125edf60Kevin Tang    return nextState;
49734ee09551764b045fdc02df754157473125edf60Kevin Tang}
49834ee09551764b045fdc02df754157473125edf60Kevin Tang
49934ee09551764b045fdc02df754157473125edf60Kevin Tang// AgpsPendingState
50034ee09551764b045fdc02df754157473125edf60Kevin Tangclass AgpsReleasingState : public AgpsState
50134ee09551764b045fdc02df754157473125edf60Kevin Tang{
50234ee09551764b045fdc02df754157473125edf60Kevin Tang    friend class AgpsStateMachine;
50334ee09551764b045fdc02df754157473125edf60Kevin Tang
50434ee09551764b045fdc02df754157473125edf60Kevin Tang    inline AgpsReleasingState(AgpsStateMachine* stateMachine) :
50534ee09551764b045fdc02df754157473125edf60Kevin Tang        AgpsState(stateMachine)
50634ee09551764b045fdc02df754157473125edf60Kevin Tang    { mReleasingState = this; }
50734ee09551764b045fdc02df754157473125edf60Kevin Tang
50834ee09551764b045fdc02df754157473125edf60Kevin Tang    inline ~AgpsReleasingState() {}
50934ee09551764b045fdc02df754157473125edf60Kevin Tangpublic:
51034ee09551764b045fdc02df754157473125edf60Kevin Tang    virtual AgpsState* onRsrcEvent(AgpsRsrcStatus event, void* data);
51134ee09551764b045fdc02df754157473125edf60Kevin Tang    inline virtual char* whoami() {return (char*)"AgpsReleasingState";}
51234ee09551764b045fdc02df754157473125edf60Kevin Tang};
51334ee09551764b045fdc02df754157473125edf60Kevin Tang
51434ee09551764b045fdc02df754157473125edf60Kevin TangAgpsState* AgpsReleasingState::onRsrcEvent(AgpsRsrcStatus event, void* data)
51534ee09551764b045fdc02df754157473125edf60Kevin Tang{
51634ee09551764b045fdc02df754157473125edf60Kevin Tang    AgpsState* nextState = this;;
517e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    LOC_LOGD("AgpsReleasingState::onRsrcEvent; event:%d\n", (int)event);
518e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
519e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo   switch (event)
52034ee09551764b045fdc02df754157473125edf60Kevin Tang    {
52134ee09551764b045fdc02df754157473125edf60Kevin Tang    case RSRC_SUBSCRIBE:
52234ee09551764b045fdc02df754157473125edf60Kevin Tang    {
52334ee09551764b045fdc02df754157473125edf60Kevin Tang        // already requested for NIF resource,
52434ee09551764b045fdc02df754157473125edf60Kevin Tang        // do nothing until we get RSRC_GRANTED indication
52534ee09551764b045fdc02df754157473125edf60Kevin Tang        // but we need to add subscriber to the list
52634ee09551764b045fdc02df754157473125edf60Kevin Tang        mStateMachine->addSubscriber((Subscriber*)data);
52734ee09551764b045fdc02df754157473125edf60Kevin Tang        // no state change.
52834ee09551764b045fdc02df754157473125edf60Kevin Tang    }
52934ee09551764b045fdc02df754157473125edf60Kevin Tang        break;
53034ee09551764b045fdc02df754157473125edf60Kevin Tang
53134ee09551764b045fdc02df754157473125edf60Kevin Tang    case RSRC_UNSUBSCRIBE:
53234ee09551764b045fdc02df754157473125edf60Kevin Tang    {
53334ee09551764b045fdc02df754157473125edf60Kevin Tang        Subscriber* subscriber = (Subscriber*) data;
53434ee09551764b045fdc02df754157473125edf60Kevin Tang        if (subscriber->waitForCloseComplete()) {
53534ee09551764b045fdc02df754157473125edf60Kevin Tang            subscriber->setInactive();
53634ee09551764b045fdc02df754157473125edf60Kevin Tang        } else {
53734ee09551764b045fdc02df754157473125edf60Kevin Tang            // auto notify this subscriber of the unsubscribe
53834ee09551764b045fdc02df754157473125edf60Kevin Tang            Notification notification(subscriber, event, true);
53934ee09551764b045fdc02df754157473125edf60Kevin Tang            mStateMachine->notifySubscribers(notification);
54034ee09551764b045fdc02df754157473125edf60Kevin Tang        }
54134ee09551764b045fdc02df754157473125edf60Kevin Tang
54234ee09551764b045fdc02df754157473125edf60Kevin Tang        // now check if there is any subscribers left
54334ee09551764b045fdc02df754157473125edf60Kevin Tang        if (!mStateMachine->hasSubscribers()) {
54434ee09551764b045fdc02df754157473125edf60Kevin Tang            // no more subscribers, move to RELEASED state
54534ee09551764b045fdc02df754157473125edf60Kevin Tang            nextState = mReleasedState;
54634ee09551764b045fdc02df754157473125edf60Kevin Tang        }
54734ee09551764b045fdc02df754157473125edf60Kevin Tang    }
54834ee09551764b045fdc02df754157473125edf60Kevin Tang        break;
54934ee09551764b045fdc02df754157473125edf60Kevin Tang
550e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    case RSRC_DENIED:
551e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        // A race condition subscriber unsubscribes before AFW denies resource.
55234ee09551764b045fdc02df754157473125edf60Kevin Tang    case RSRC_RELEASED:
55334ee09551764b045fdc02df754157473125edf60Kevin Tang    {
55434ee09551764b045fdc02df754157473125edf60Kevin Tang        nextState = mAcquiredState;
55534ee09551764b045fdc02df754157473125edf60Kevin Tang        Notification notification(Notification::BROADCAST_INACTIVE, event, true);
55634ee09551764b045fdc02df754157473125edf60Kevin Tang        // notify all subscribers that are active NIF resource RELEASE
55734ee09551764b045fdc02df754157473125edf60Kevin Tang        // by setting false, we keep subscribers on the linked list
55834ee09551764b045fdc02df754157473125edf60Kevin Tang        mStateMachine->notifySubscribers(notification);
55934ee09551764b045fdc02df754157473125edf60Kevin Tang
560e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        if (mStateMachine->hasActiveSubscribers()) {
56134ee09551764b045fdc02df754157473125edf60Kevin Tang            nextState = mPendingState;
56234ee09551764b045fdc02df754157473125edf60Kevin Tang            // request from connecivity service for NIF
56334ee09551764b045fdc02df754157473125edf60Kevin Tang            mStateMachine->sendRsrcRequest(GPS_REQUEST_AGPS_DATA_CONN);
56434ee09551764b045fdc02df754157473125edf60Kevin Tang        } else {
56534ee09551764b045fdc02df754157473125edf60Kevin Tang            nextState = mReleasedState;
56634ee09551764b045fdc02df754157473125edf60Kevin Tang        }
56734ee09551764b045fdc02df754157473125edf60Kevin Tang    }
56834ee09551764b045fdc02df754157473125edf60Kevin Tang        break;
56934ee09551764b045fdc02df754157473125edf60Kevin Tang
57034ee09551764b045fdc02df754157473125edf60Kevin Tang    case RSRC_GRANTED:
57134ee09551764b045fdc02df754157473125edf60Kevin Tang    default:
57234ee09551764b045fdc02df754157473125edf60Kevin Tang        LOC_LOGE("%s: unrecognized event %d", whoami(), event);
57334ee09551764b045fdc02df754157473125edf60Kevin Tang        // no state change.
57434ee09551764b045fdc02df754157473125edf60Kevin Tang    }
57534ee09551764b045fdc02df754157473125edf60Kevin Tang
57634ee09551764b045fdc02df754157473125edf60Kevin Tang    LOC_LOGD("onRsrcEvent, old state %s, new state %s, event %d",
57734ee09551764b045fdc02df754157473125edf60Kevin Tang             whoami(), nextState->whoami(), event);
57834ee09551764b045fdc02df754157473125edf60Kevin Tang    return nextState;
57934ee09551764b045fdc02df754157473125edf60Kevin Tang}
580e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo//======================================================================
581e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo//Servicer
582e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo//======================================================================
583e14a6c846df2ce4bb1847e4250991f7c52fd793dDante RussoServicer* Servicer :: getServicer(servicerType type, void *cb_func)
584e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo{
585e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    LOC_LOGD(" Enter getServicer type:%d\n", (int)type);
586e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    switch(type) {
587e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    case servicerTypeNoCbParam:
588e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        return (new Servicer(cb_func));
589e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    case servicerTypeExt:
590e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        return (new ExtServicer(cb_func));
591e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    case servicerTypeAgps:
592e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        return (new AGpsServicer(cb_func));
593e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    default:
594e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        return NULL;
595e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    }
596e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo}
59734ee09551764b045fdc02df754157473125edf60Kevin Tang
598e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russoint Servicer :: requestRsrc(void *cb_data)
599e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo{
600e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    callback();
601e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    return 0;
602e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo}
603e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
604e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russoint ExtServicer :: requestRsrc(void *cb_data)
605e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo{
606e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    int ret=-1;
607e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    LOC_LOGD("Enter ExtServicer :: requestRsrc\n");
608e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    ret = callbackExt(cb_data);
609e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    LOC_LOGD("Exit ExtServicer :: requestRsrc\n");
610e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    return(ret);
611e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo}
612e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
613e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russoint AGpsServicer :: requestRsrc(void *cb_data)
614e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo{
615e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    callbackAGps((AGpsStatus *)cb_data);
616e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    return 0;
617e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo}
61834ee09551764b045fdc02df754157473125edf60Kevin Tang
61934ee09551764b045fdc02df754157473125edf60Kevin Tang//======================================================================
62034ee09551764b045fdc02df754157473125edf60Kevin Tang// AgpsStateMachine
62134ee09551764b045fdc02df754157473125edf60Kevin Tang//======================================================================
62234ee09551764b045fdc02df754157473125edf60Kevin Tang
623e14a6c846df2ce4bb1847e4250991f7c52fd793dDante RussoAgpsStateMachine::AgpsStateMachine(servicerType servType,
624e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo                                   void *cb_func,
625e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo                                   AGpsExtType type,
626e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo                                   bool enforceSingleSubscriber) :
627e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    mStatePtr(new AgpsReleasedState(this)),mType(type),
62834ee09551764b045fdc02df754157473125edf60Kevin Tang    mAPN(NULL),
629e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    mAPNLen(0),
630e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    mBearer(AGPS_APN_BEARER_INVALID),
631e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    mEnforceSingleSubscriber(enforceSingleSubscriber),
632e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    mServicer(Servicer :: getServicer(servType, (void *)cb_func))
63334ee09551764b045fdc02df754157473125edf60Kevin Tang{
63434ee09551764b045fdc02df754157473125edf60Kevin Tang    linked_list_init(&mSubscribers);
63534ee09551764b045fdc02df754157473125edf60Kevin Tang
63634ee09551764b045fdc02df754157473125edf60Kevin Tang    // setting up mReleasedState
63734ee09551764b045fdc02df754157473125edf60Kevin Tang    mStatePtr->mPendingState = new AgpsPendingState(this);
63834ee09551764b045fdc02df754157473125edf60Kevin Tang    mStatePtr->mAcquiredState = new AgpsAcquiredState(this);
63934ee09551764b045fdc02df754157473125edf60Kevin Tang    mStatePtr->mReleasingState = new AgpsReleasingState(this);
64034ee09551764b045fdc02df754157473125edf60Kevin Tang
64134ee09551764b045fdc02df754157473125edf60Kevin Tang    // setting up mAcquiredState
64234ee09551764b045fdc02df754157473125edf60Kevin Tang    mStatePtr->mAcquiredState->mReleasedState = mStatePtr;
64334ee09551764b045fdc02df754157473125edf60Kevin Tang    mStatePtr->mAcquiredState->mPendingState = mStatePtr->mPendingState;
64434ee09551764b045fdc02df754157473125edf60Kevin Tang    mStatePtr->mAcquiredState->mReleasingState = mStatePtr->mReleasingState;
64534ee09551764b045fdc02df754157473125edf60Kevin Tang
64634ee09551764b045fdc02df754157473125edf60Kevin Tang    // setting up mPendingState
64734ee09551764b045fdc02df754157473125edf60Kevin Tang    mStatePtr->mPendingState->mAcquiredState = mStatePtr->mAcquiredState;
64834ee09551764b045fdc02df754157473125edf60Kevin Tang    mStatePtr->mPendingState->mReleasedState = mStatePtr;
64934ee09551764b045fdc02df754157473125edf60Kevin Tang    mStatePtr->mPendingState->mReleasingState = mStatePtr->mReleasingState;
65034ee09551764b045fdc02df754157473125edf60Kevin Tang
65134ee09551764b045fdc02df754157473125edf60Kevin Tang    // setting up mReleasingState
65234ee09551764b045fdc02df754157473125edf60Kevin Tang    mStatePtr->mReleasingState->mReleasedState = mStatePtr;
65334ee09551764b045fdc02df754157473125edf60Kevin Tang    mStatePtr->mReleasingState->mPendingState = mStatePtr->mPendingState;
65434ee09551764b045fdc02df754157473125edf60Kevin Tang    mStatePtr->mReleasingState->mAcquiredState = mStatePtr->mAcquiredState;
65534ee09551764b045fdc02df754157473125edf60Kevin Tang}
65634ee09551764b045fdc02df754157473125edf60Kevin Tang
65734ee09551764b045fdc02df754157473125edf60Kevin TangAgpsStateMachine::~AgpsStateMachine()
65834ee09551764b045fdc02df754157473125edf60Kevin Tang{
65934ee09551764b045fdc02df754157473125edf60Kevin Tang    dropAllSubscribers();
66034ee09551764b045fdc02df754157473125edf60Kevin Tang
66134ee09551764b045fdc02df754157473125edf60Kevin Tang    // free the 3 states.  We must read out all 3 pointers first.
66234ee09551764b045fdc02df754157473125edf60Kevin Tang    // Otherwise we run the risk of getting pointers from already
66334ee09551764b045fdc02df754157473125edf60Kevin Tang    // freed memory.
66434ee09551764b045fdc02df754157473125edf60Kevin Tang    AgpsState* acquiredState = mStatePtr->mAcquiredState;
66534ee09551764b045fdc02df754157473125edf60Kevin Tang    AgpsState* releasedState = mStatePtr->mReleasedState;
66634ee09551764b045fdc02df754157473125edf60Kevin Tang    AgpsState* pendindState = mStatePtr->mPendingState;
66734ee09551764b045fdc02df754157473125edf60Kevin Tang    AgpsState* releasingState = mStatePtr->mReleasingState;
66834ee09551764b045fdc02df754157473125edf60Kevin Tang
66934ee09551764b045fdc02df754157473125edf60Kevin Tang    delete acquiredState;
67034ee09551764b045fdc02df754157473125edf60Kevin Tang    delete releasedState;
67134ee09551764b045fdc02df754157473125edf60Kevin Tang    delete pendindState;
67234ee09551764b045fdc02df754157473125edf60Kevin Tang    delete releasingState;
673e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    delete mServicer;
67434ee09551764b045fdc02df754157473125edf60Kevin Tang    linked_list_destroy(&mSubscribers);
67534ee09551764b045fdc02df754157473125edf60Kevin Tang
67634ee09551764b045fdc02df754157473125edf60Kevin Tang    if (NULL != mAPN) {
67734ee09551764b045fdc02df754157473125edf60Kevin Tang        delete[] mAPN;
67834ee09551764b045fdc02df754157473125edf60Kevin Tang        mAPN = NULL;
67934ee09551764b045fdc02df754157473125edf60Kevin Tang    }
68034ee09551764b045fdc02df754157473125edf60Kevin Tang}
68134ee09551764b045fdc02df754157473125edf60Kevin Tang
68234ee09551764b045fdc02df754157473125edf60Kevin Tangvoid AgpsStateMachine::setAPN(const char* apn, unsigned int len)
68334ee09551764b045fdc02df754157473125edf60Kevin Tang{
68434ee09551764b045fdc02df754157473125edf60Kevin Tang    if (NULL != mAPN) {
68534ee09551764b045fdc02df754157473125edf60Kevin Tang        delete mAPN;
68634ee09551764b045fdc02df754157473125edf60Kevin Tang    }
68734ee09551764b045fdc02df754157473125edf60Kevin Tang
68834ee09551764b045fdc02df754157473125edf60Kevin Tang    if (NULL != apn) {
68934ee09551764b045fdc02df754157473125edf60Kevin Tang        mAPN = new char[len+1];
69034ee09551764b045fdc02df754157473125edf60Kevin Tang        memcpy(mAPN, apn, len);
69134ee09551764b045fdc02df754157473125edf60Kevin Tang        mAPN[len] = NULL;
69234ee09551764b045fdc02df754157473125edf60Kevin Tang
69334ee09551764b045fdc02df754157473125edf60Kevin Tang        mAPNLen = len;
69434ee09551764b045fdc02df754157473125edf60Kevin Tang    } else {
69534ee09551764b045fdc02df754157473125edf60Kevin Tang        mAPN = NULL;
69634ee09551764b045fdc02df754157473125edf60Kevin Tang        mAPNLen = 0;
69734ee09551764b045fdc02df754157473125edf60Kevin Tang    }
69834ee09551764b045fdc02df754157473125edf60Kevin Tang}
69934ee09551764b045fdc02df754157473125edf60Kevin Tang
70034ee09551764b045fdc02df754157473125edf60Kevin Tangvoid AgpsStateMachine::onRsrcEvent(AgpsRsrcStatus event)
70134ee09551764b045fdc02df754157473125edf60Kevin Tang{
70234ee09551764b045fdc02df754157473125edf60Kevin Tang    switch (event)
70334ee09551764b045fdc02df754157473125edf60Kevin Tang    {
70434ee09551764b045fdc02df754157473125edf60Kevin Tang    case RSRC_GRANTED:
70534ee09551764b045fdc02df754157473125edf60Kevin Tang    case RSRC_RELEASED:
70634ee09551764b045fdc02df754157473125edf60Kevin Tang    case RSRC_DENIED:
70734ee09551764b045fdc02df754157473125edf60Kevin Tang        mStatePtr = mStatePtr->onRsrcEvent(event, NULL);
70834ee09551764b045fdc02df754157473125edf60Kevin Tang        break;
70934ee09551764b045fdc02df754157473125edf60Kevin Tang    default:
71034ee09551764b045fdc02df754157473125edf60Kevin Tang        LOC_LOGW("AgpsStateMachine: unrecognized event %d", event);
71134ee09551764b045fdc02df754157473125edf60Kevin Tang        break;
71234ee09551764b045fdc02df754157473125edf60Kevin Tang    }
71334ee09551764b045fdc02df754157473125edf60Kevin Tang}
71434ee09551764b045fdc02df754157473125edf60Kevin Tang
71534ee09551764b045fdc02df754157473125edf60Kevin Tangvoid AgpsStateMachine::notifySubscribers(Notification& notification) const
71634ee09551764b045fdc02df754157473125edf60Kevin Tang{
71734ee09551764b045fdc02df754157473125edf60Kevin Tang    if (notification.postNotifyDelete) {
71834ee09551764b045fdc02df754157473125edf60Kevin Tang        // just any non NULL value to get started
71934ee09551764b045fdc02df754157473125edf60Kevin Tang        Subscriber* s = (Subscriber*)~0;
72034ee09551764b045fdc02df754157473125edf60Kevin Tang        while (NULL != s) {
72134ee09551764b045fdc02df754157473125edf60Kevin Tang            s = NULL;
72234ee09551764b045fdc02df754157473125edf60Kevin Tang            // if the last param sets to true, _search will delete
72334ee09551764b045fdc02df754157473125edf60Kevin Tang            // the node from the list for us.  But the problem is
72434ee09551764b045fdc02df754157473125edf60Kevin Tang            // once that is done, _search returns, leaving the
72534ee09551764b045fdc02df754157473125edf60Kevin Tang            // rest of the list unprocessed.  So we need a loop.
72634ee09551764b045fdc02df754157473125edf60Kevin Tang            linked_list_search(mSubscribers, (void**)&s, notifySubscriber,
72734ee09551764b045fdc02df754157473125edf60Kevin Tang                               (void*)&notification, true);
728e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo            delete s;
72934ee09551764b045fdc02df754157473125edf60Kevin Tang        }
73034ee09551764b045fdc02df754157473125edf60Kevin Tang    } else {
73134ee09551764b045fdc02df754157473125edf60Kevin Tang        // no loop needed if it the last param sets to false, which
73234ee09551764b045fdc02df754157473125edf60Kevin Tang        // mean nothing gets deleted from the list.
73334ee09551764b045fdc02df754157473125edf60Kevin Tang        linked_list_search(mSubscribers, NULL, notifySubscriber,
73434ee09551764b045fdc02df754157473125edf60Kevin Tang                           (void*)&notification, false);
73534ee09551764b045fdc02df754157473125edf60Kevin Tang    }
73634ee09551764b045fdc02df754157473125edf60Kevin Tang}
73734ee09551764b045fdc02df754157473125edf60Kevin Tang
73834ee09551764b045fdc02df754157473125edf60Kevin Tangvoid AgpsStateMachine::addSubscriber(Subscriber* subscriber) const
73934ee09551764b045fdc02df754157473125edf60Kevin Tang{
74034ee09551764b045fdc02df754157473125edf60Kevin Tang    Subscriber* s = NULL;
74134ee09551764b045fdc02df754157473125edf60Kevin Tang    Notification notification((const Subscriber*)subscriber);
74234ee09551764b045fdc02df754157473125edf60Kevin Tang    linked_list_search(mSubscribers, (void**)&s,
74334ee09551764b045fdc02df754157473125edf60Kevin Tang                       hasSubscriber, (void*)&notification, false);
74434ee09551764b045fdc02df754157473125edf60Kevin Tang
74534ee09551764b045fdc02df754157473125edf60Kevin Tang    if (NULL == s) {
74634ee09551764b045fdc02df754157473125edf60Kevin Tang        linked_list_add(mSubscribers, subscriber->clone(), deleteObj);
74734ee09551764b045fdc02df754157473125edf60Kevin Tang    }
74834ee09551764b045fdc02df754157473125edf60Kevin Tang}
74934ee09551764b045fdc02df754157473125edf60Kevin Tang
750e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russoint AgpsStateMachine::sendRsrcRequest(AGpsStatusValue action) const
75134ee09551764b045fdc02df754157473125edf60Kevin Tang{
75234ee09551764b045fdc02df754157473125edf60Kevin Tang    Subscriber* s = NULL;
753e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    Notification notification(Notification::BROADCAST_ACTIVE);
75434ee09551764b045fdc02df754157473125edf60Kevin Tang    linked_list_search(mSubscribers, (void**)&s, hasSubscriber,
75534ee09551764b045fdc02df754157473125edf60Kevin Tang                       (void*)&notification, false);
75634ee09551764b045fdc02df754157473125edf60Kevin Tang
75734ee09551764b045fdc02df754157473125edf60Kevin Tang    if ((NULL == s) == (GPS_RELEASE_AGPS_DATA_CONN == action)) {
758e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        AGpsExtStatus nifRequest;
75934ee09551764b045fdc02df754157473125edf60Kevin Tang        nifRequest.size = sizeof(nifRequest);
76034ee09551764b045fdc02df754157473125edf60Kevin Tang        nifRequest.type = mType;
76134ee09551764b045fdc02df754157473125edf60Kevin Tang        nifRequest.status = action;
76234ee09551764b045fdc02df754157473125edf60Kevin Tang
76334ee09551764b045fdc02df754157473125edf60Kevin Tang        if (s == NULL) {
76434ee09551764b045fdc02df754157473125edf60Kevin Tang            nifRequest.ipv4_addr = INADDR_NONE;
7650d00b9e0690547ad06eef43a5f1c77a31e8885dcDante Russo            memset(&nifRequest.addr, 0,  sizeof(nifRequest.addr));
766e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo            nifRequest.ssid[0] = '\0';
767e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo            nifRequest.password[0] = '\0';
76834ee09551764b045fdc02df754157473125edf60Kevin Tang        } else {
7690d00b9e0690547ad06eef43a5f1c77a31e8885dcDante Russo            s->setIPAddresses(nifRequest.addr);
770e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo            s->setWifiInfo(nifRequest.ssid, nifRequest.password);
77134ee09551764b045fdc02df754157473125edf60Kevin Tang        }
77234ee09551764b045fdc02df754157473125edf60Kevin Tang
77334ee09551764b045fdc02df754157473125edf60Kevin Tang        CALLBACK_LOG_CALLFLOW("agps_cb", %s, loc_get_agps_status_name(action));
774e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        mServicer->requestRsrc((void *)&nifRequest);
77534ee09551764b045fdc02df754157473125edf60Kevin Tang    }
776e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    return 0;
77734ee09551764b045fdc02df754157473125edf60Kevin Tang}
77834ee09551764b045fdc02df754157473125edf60Kevin Tang
77934ee09551764b045fdc02df754157473125edf60Kevin Tangvoid AgpsStateMachine::subscribeRsrc(Subscriber *subscriber)
78034ee09551764b045fdc02df754157473125edf60Kevin Tang{
781e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo  if (mEnforceSingleSubscriber && hasSubscribers()) {
782e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo      Notification notification(Notification::BROADCAST_ALL, RSRC_DENIED, true);
783e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo      notifySubscriber(&notification, subscriber);
784e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo  } else {
785e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo      mStatePtr = mStatePtr->onRsrcEvent(RSRC_SUBSCRIBE, (void*)subscriber);
786e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo  }
78734ee09551764b045fdc02df754157473125edf60Kevin Tang}
78834ee09551764b045fdc02df754157473125edf60Kevin Tang
78934ee09551764b045fdc02df754157473125edf60Kevin Tangbool AgpsStateMachine::unsubscribeRsrc(Subscriber *subscriber)
79034ee09551764b045fdc02df754157473125edf60Kevin Tang{
79134ee09551764b045fdc02df754157473125edf60Kevin Tang    Subscriber* s = NULL;
79234ee09551764b045fdc02df754157473125edf60Kevin Tang    Notification notification((const Subscriber*)subscriber);
79334ee09551764b045fdc02df754157473125edf60Kevin Tang    linked_list_search(mSubscribers, (void**)&s,
79434ee09551764b045fdc02df754157473125edf60Kevin Tang                       hasSubscriber, (void*)&notification, false);
79534ee09551764b045fdc02df754157473125edf60Kevin Tang
79634ee09551764b045fdc02df754157473125edf60Kevin Tang    if (NULL != s) {
79734ee09551764b045fdc02df754157473125edf60Kevin Tang        mStatePtr = mStatePtr->onRsrcEvent(RSRC_UNSUBSCRIBE, (void*)s);
79834ee09551764b045fdc02df754157473125edf60Kevin Tang        return true;
79934ee09551764b045fdc02df754157473125edf60Kevin Tang    }
80034ee09551764b045fdc02df754157473125edf60Kevin Tang    return false;
80134ee09551764b045fdc02df754157473125edf60Kevin Tang}
80234ee09551764b045fdc02df754157473125edf60Kevin Tang
80334ee09551764b045fdc02df754157473125edf60Kevin Tangbool AgpsStateMachine::hasActiveSubscribers() const
80434ee09551764b045fdc02df754157473125edf60Kevin Tang{
80534ee09551764b045fdc02df754157473125edf60Kevin Tang    Subscriber* s = NULL;
80634ee09551764b045fdc02df754157473125edf60Kevin Tang    Notification notification(Notification::BROADCAST_ACTIVE);
80734ee09551764b045fdc02df754157473125edf60Kevin Tang    linked_list_search(mSubscribers, (void**)&s,
80834ee09551764b045fdc02df754157473125edf60Kevin Tang                       hasSubscriber, (void*)&notification, false);
80934ee09551764b045fdc02df754157473125edf60Kevin Tang    return NULL != s;
81034ee09551764b045fdc02df754157473125edf60Kevin Tang}
811e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
812e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo//======================================================================
813e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo// DSStateMachine
814e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo//======================================================================
815e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russovoid delay_callback(void *callbackData, int result)
816e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo{
817e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    if(callbackData) {
818e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        DSStateMachine *DSSMInstance = (DSStateMachine *)callbackData;
819e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        DSSMInstance->retryCallback();
820e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    }
821e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    else {
822e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        LOC_LOGE(" NULL argument received. Failing.\n");
823e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        goto err;
824e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    }
825e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russoerr:
826e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    return;
827e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo}
828e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
829e14a6c846df2ce4bb1847e4250991f7c52fd793dDante RussoDSStateMachine :: DSStateMachine(servicerType type, void *cb_func,
830e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo                                 LocEngAdapter* adapterHandle):
831e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    AgpsStateMachine(type, cb_func, AGPS_TYPE_INVALID,false),
832e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    mLocAdapter(adapterHandle)
833e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo{
834e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    LOC_LOGD("%s:%d]: New DSStateMachine\n", __func__, __LINE__);
835e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    mRetries = 0;
836e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo}
837e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
838e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russovoid DSStateMachine :: retryCallback(void)
839e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo{
840e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    DSSubscriber *subscriber = NULL;
841e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    Notification notification(Notification::BROADCAST_ACTIVE);
842e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    linked_list_search(mSubscribers, (void**)&subscriber, hasSubscriber,
843e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo                       (void*)&notification, false);
844e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    if(subscriber)
845e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        mLocAdapter->requestSuplES(subscriber->ID);
846e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    else
847e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        LOC_LOGE("DSStateMachine :: retryCallback: No subscriber found." \
848e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo                 "Cannot retry data call\n");
849e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    return;
850e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo}
851e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
852e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russoint DSStateMachine :: sendRsrcRequest(AGpsStatusValue action) const
853e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo{
854e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    DSSubscriber* s = NULL;
855e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    dsCbData cbData;
856e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    int ret=-1;
857e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    int connHandle=-1;
858e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    LOC_LOGD("Enter DSStateMachine :: sendRsrcRequest\n");
859e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    Notification notification(Notification::BROADCAST_ACTIVE);
860e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    linked_list_search(mSubscribers, (void**)&s, hasSubscriber,
861e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo                       (void*)&notification, false);
862e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    if(s) {
863e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        connHandle = s->ID;
864e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        LOC_LOGD("DSStateMachine :: sendRsrcRequest - subscriber found\n");
865e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    }
866e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    else
867e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        LOC_LOGD("DSStateMachine :: sendRsrcRequest - No subscriber found\n");
868e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
869e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    cbData.action = action;
870e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    cbData.mAdapter = mLocAdapter;
871e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    ret = mServicer->requestRsrc((void *)&cbData);
872e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    //Only the request to start data call returns a success/failure
873e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    //The request to stop data call will always succeed
874e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    //Hence, the below block will only be executed when the
875e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    //request to start the data call fails
876e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    switch(ret) {
877e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    case LOC_API_ADAPTER_ERR_ENGINE_BUSY:
878e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        LOC_LOGD("DSStateMachine :: sendRsrcRequest - Failure returned: %d\n",ret);
879e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        ((DSStateMachine *)this)->incRetries();
880e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        if(mRetries > MAX_START_DATA_CALL_RETRIES) {
881e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo            LOC_LOGE(" Failed to start Data call. Fallback to normal ATL SUPL\n");
882e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo            informStatus(RSRC_DENIED, connHandle);
883e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        }
884e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        else {
885e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo            if(loc_timer_start(DATA_CALL_RETRY_DELAY_MSEC, delay_callback, (void *)this)) {
886e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo                LOC_LOGE("Error: Could not start delay thread\n");
887e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo                ret = -1;
888e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo                goto err;
889e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo            }
890e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        }
891e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        break;
892e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    case LOC_API_ADAPTER_ERR_UNSUPPORTED:
893e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        LOC_LOGE("No profile found for emergency call. Fallback to normal SUPL ATL\n");
894e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        informStatus(RSRC_DENIED, connHandle);
895e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        break;
896e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    case LOC_API_ADAPTER_ERR_SUCCESS:
897e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        LOC_LOGD("%s:%d]: Request to start data call sent\n", __func__, __LINE__);
898e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        break;
899e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    case -1:
900e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        //One of the ways this case can be encountered is if the callback function
901e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        //receives a null argument, it just exits with -1 error
902e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        LOC_LOGE("Error: Something went wrong somewhere. Falling back to normal SUPL ATL\n");
903e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        informStatus(RSRC_DENIED, connHandle);
904e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        break;
905e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    default:
906e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        LOC_LOGE("%s:%d]: Unrecognized return value\n", __func__, __LINE__);
907e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    }
908e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russoerr:
909e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    LOC_LOGD("EXIT DSStateMachine :: sendRsrcRequest; ret = %d\n", ret);
910e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    return ret;
911e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo}
912e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
913e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russovoid DSStateMachine :: onRsrcEvent(AgpsRsrcStatus event)
914e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo{
915e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    void* currState = (void *)mStatePtr;
916e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    LOC_LOGD("Enter DSStateMachine :: onRsrcEvent. event = %d\n", (int)event);
917e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    switch (event)
918e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    {
919e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    case RSRC_GRANTED:
920e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        LOC_LOGD("DSStateMachine :: onRsrcEvent RSRC_GRANTED\n");
921e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        mStatePtr = mStatePtr->onRsrcEvent(event, NULL);
922e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        break;
923e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    case RSRC_RELEASED:
924e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        LOC_LOGD("DSStateMachine :: onRsrcEvent RSRC_RELEASED\n");
925e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        mStatePtr = mStatePtr->onRsrcEvent(event, NULL);
926e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        //To handle the case where we get a RSRC_RELEASED in
927e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        //pending state, we translate that to a RSRC_DENIED state
928e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        //since the callback from DSI is either RSRC_GRANTED or RSRC_RELEASED
929e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        //for when the call is connected or disconnected respectively.
930e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        if((void *)mStatePtr != currState)
931e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo            break;
932e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        else {
933e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo            event = RSRC_DENIED;
934e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo            LOC_LOGE(" Switching event to RSRC_DENIED\n");
935e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        }
936e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    case RSRC_DENIED:
937e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        mStatePtr = mStatePtr->onRsrcEvent(event, NULL);
938e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        break;
939e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    default:
940e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        LOC_LOGW("AgpsStateMachine: unrecognized event %d", event);
941e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        break;
942e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    }
943e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    LOC_LOGD("Exit DSStateMachine :: onRsrcEvent. event = %d\n", (int)event);
944e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo}
945e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
946e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russovoid DSStateMachine :: informStatus(AgpsRsrcStatus status, int ID) const
947e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo{
948e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    LOC_LOGD("DSStateMachine :: informStatus. Status=%d\n",(int)status);
949e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    switch(status) {
950e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    case RSRC_UNSUBSCRIBE:
951e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        mLocAdapter->atlCloseStatus(ID, 1);
952e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        break;
953e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    case RSRC_RELEASED:
954e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        mLocAdapter->closeDataCall();
955e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        break;
956e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    case RSRC_DENIED:
957e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        ((DSStateMachine *)this)->mRetries = 0;
958e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        mLocAdapter->requestATL(ID, AGPS_TYPE_SUPL);
959e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        break;
960e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    case RSRC_GRANTED:
961e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        mLocAdapter->atlOpenStatus(ID, 1,
962e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo                                                     NULL,
963e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo                                                     AGPS_APN_BEARER_INVALID,
964e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo                                                     AGPS_TYPE_INVALID);
965e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        break;
966e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    default:
967e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        LOC_LOGW("DSStateMachine :: informStatus - unknown status");
968e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    }
969e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    return;
970e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo}
971