1ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
2ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo *
3ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo * Redistribution and use in source and binary forms, with or without
4ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo * modification, are permitted provided that the following conditions are
5ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo * met:
6ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo *     * Redistributions of source code must retain the above copyright
7ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo *       notice, this list of conditions and the following disclaimer.
8ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo *     * Redistributions in binary form must reproduce the above
9ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo *       copyright notice, this list of conditions and the following
10ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo *       disclaimer in the documentation and/or other materials provided
11ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo *       with the distribution.
12ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo *     * Neither the name of The Linux Foundation, nor the names of its
13ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo *       contributors may be used to endorse or promote products derived
14ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo *       from this software without specific prior written permission.
15ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo *
16ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo *
28ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo */
29ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
30ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo#define LOG_NDDEBUG 0
31ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo#define LOG_TAG "LocSvc_eng"
32ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
33ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo#include <loc_eng_agps.h>
34ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo#include <loc_eng_log.h>
35ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo#include <log_util.h>
36ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo#include <platform_lib_includes.h>
37ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo#include <loc_eng_dmn_conn_handler.h>
38ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo#include <loc_eng_dmn_conn.h>
39ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo#include <sys/time.h>
40ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
41ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo//======================================================================
42ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo// C callbacks
43ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo//======================================================================
44ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
45ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo// This is given to linked_list_add as the dealloc callback
46ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo// data -- an instance of Subscriber
47ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russostatic void deleteObj(void* data)
48ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo{
49ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    delete (Subscriber*)data;
50ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo}
51ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
52ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo// This is given to linked_list_search() as the comparison callback
53ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo// when the state manchine needs to process for particular subscriber
54ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo// fromCaller -- caller provides this obj
55ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo// fromList -- linked_list_search() function take this one from list
56ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russostatic bool hasSubscriber(void* fromCaller, void* fromList)
57ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo{
58ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    Notification* notification = (Notification*)fromCaller;
59ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    Subscriber* s1 = (Subscriber*)fromList;
60ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
61ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    return s1->forMe(*notification);
62ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo}
63ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
64ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo// This is gvien to linked_list_search() to notify subscriber objs
65ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo// when the state machine needs to inform all subscribers of resource
66ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo// status changes, e.g. when resource is GRANTED.
67ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo// fromCaller -- caller provides this ptr to a Notification obj.
68ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo// fromList -- linked_list_search() function take this one from list
69ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russostatic bool notifySubscriber(void* fromCaller, void* fromList)
70ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo{
71ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    Notification* notification = (Notification*)fromCaller;
72ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    Subscriber* s1 = (Subscriber*)fromList;
73ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
74ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    // we notify every subscriber indiscriminatively
75ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    // each subscriber decides if this notification is interesting.
76ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    return s1->notifyRsrcStatus(*notification) &&
77ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo           // if we do not want to delete the subscriber from the
78ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo           // the list, we must set this to false so this function
79ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo           // returns false
80ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo           notification->postNotifyDelete;
81ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo}
82ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
83ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo//======================================================================
84ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo// Notification
85ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo//======================================================================
86ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russoconst int Notification::BROADCAST_ALL = 0x80000000;
87ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russoconst int Notification::BROADCAST_ACTIVE = 0x80000001;
88ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russoconst int Notification::BROADCAST_INACTIVE = 0x80000002;
89ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russoconst unsigned char DSStateMachine::MAX_START_DATA_CALL_RETRIES = 4;
90ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russoconst unsigned int DSStateMachine::DATA_CALL_RETRY_DELAY_MSEC = 500;
91ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo//======================================================================
92ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo// Subscriber:  BITSubscriber / ATLSubscriber / WIFISubscriber
93ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo//======================================================================
94ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russobool Subscriber::forMe(Notification &notification)
95ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo{
96ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    if (NULL != notification.rcver) {
97ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        return equals(notification.rcver);
98ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    } else {
99ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        return Notification::BROADCAST_ALL == notification.groupID ||
100ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            (Notification::BROADCAST_ACTIVE == notification.groupID &&
101ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo             !isInactive()) ||
102ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            (Notification::BROADCAST_INACTIVE == notification.groupID &&
103ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo             isInactive());
104ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    }
105ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo}
106ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russobool BITSubscriber::equals(const Subscriber *s) const
107ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo{
108ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    BITSubscriber* bitS = (BITSubscriber*)s;
109ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
110ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    return (ID == bitS->ID &&
111ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            (INADDR_NONE != (unsigned int)ID ||
112ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo             0 == strncmp(mIPv6Addr, bitS->mIPv6Addr, sizeof(mIPv6Addr))));
113ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo}
114ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
115ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russobool BITSubscriber::notifyRsrcStatus(Notification &notification)
116ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo{
117ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    bool notify = forMe(notification);
118ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
119ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    if (notify) {
120ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        switch(notification.rsrcStatus)
121ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        {
122ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        case RSRC_UNSUBSCRIBE:
123ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        case RSRC_RELEASED:
124ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            loc_eng_dmn_conn_loc_api_server_data_conn(
125ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo                LOC_ENG_IF_REQUEST_SENDER_ID_GPSONE_DAEMON,
126ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo                GPSONE_LOC_API_IF_RELEASE_SUCCESS);
127ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            break;
128ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        case RSRC_DENIED:
129ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            loc_eng_dmn_conn_loc_api_server_data_conn(
130ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo                LOC_ENG_IF_REQUEST_SENDER_ID_GPSONE_DAEMON,
131ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo                GPSONE_LOC_API_IF_FAILURE);
132ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            break;
133ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        case RSRC_GRANTED:
134ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            loc_eng_dmn_conn_loc_api_server_data_conn(
135ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo                LOC_ENG_IF_REQUEST_SENDER_ID_GPSONE_DAEMON,
136ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo                GPSONE_LOC_API_IF_REQUEST_SUCCESS);
137ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            break;
138ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        default:
139ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            notify = false;
140ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        }
141ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    }
142ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
143ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    return notify;
144ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo}
145ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
146ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russobool ATLSubscriber::notifyRsrcStatus(Notification &notification)
147ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo{
148ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    bool notify = forMe(notification);
149ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
150ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    if (notify) {
151ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        switch(notification.rsrcStatus)
152ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        {
153ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        case RSRC_UNSUBSCRIBE:
154ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        case RSRC_RELEASED:
155ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            ((LocEngAdapter*)mLocAdapter)->atlCloseStatus(ID, 1);
156ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            break;
157ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        case RSRC_DENIED:
158ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        {
159ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            AGpsExtType type = mBackwardCompatibleMode ?
160ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo                              AGPS_TYPE_INVALID : mStateMachine->getType();
161ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            ((LocEngAdapter*)mLocAdapter)->atlOpenStatus(ID, 0,
162ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo                                            (char*)mStateMachine->getAPN(),
163ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo                                            mStateMachine->getBearer(),
164ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo                                            type);
165ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        }
166ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            break;
167ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        case RSRC_GRANTED:
168ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        {
169ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            AGpsExtType type = mBackwardCompatibleMode ?
170ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo                              AGPS_TYPE_INVALID : mStateMachine->getType();
171ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            ((LocEngAdapter*)mLocAdapter)->atlOpenStatus(ID, 1,
172ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo                                            (char*)mStateMachine->getAPN(),
173ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo                                            mStateMachine->getBearer(),
174ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo                                            type);
175ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        }
176ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            break;
177ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        default:
178ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            notify = false;
179ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        }
180ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    }
181ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
182ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    return notify;
183ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo}
184ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
185ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russobool WIFISubscriber::notifyRsrcStatus(Notification &notification)
186ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo{
187ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    bool notify = forMe(notification);
188ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
189ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    if (notify) {
190ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        switch(notification.rsrcStatus)
191ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        {
192ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        case RSRC_UNSUBSCRIBE:
193ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            break;
194ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        case RSRC_RELEASED:
195ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            loc_eng_dmn_conn_loc_api_server_data_conn(
196ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo                senderId,
197ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo                GPSONE_LOC_API_IF_RELEASE_SUCCESS);
198ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            break;
199ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        case RSRC_DENIED:
200ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            loc_eng_dmn_conn_loc_api_server_data_conn(
201ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo                senderId,
202ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo                GPSONE_LOC_API_IF_FAILURE);
203ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            break;
204ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        case RSRC_GRANTED:
205ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            loc_eng_dmn_conn_loc_api_server_data_conn(
206ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo                senderId,
207ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo                GPSONE_LOC_API_IF_REQUEST_SUCCESS);
208ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            break;
209ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        default:
210ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            notify = false;
211ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        }
212ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    }
213ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
214ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    return notify;
215ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo}
216ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russobool DSSubscriber::notifyRsrcStatus(Notification &notification)
217ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo{
218ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    bool notify = forMe(notification);
219ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    LOC_LOGD("DSSubscriber::notifyRsrcStatus. notify:%d \n",(int)(notify));
220ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    if(notify) {
221ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        switch(notification.rsrcStatus) {
222ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        case RSRC_UNSUBSCRIBE:
223ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        case RSRC_RELEASED:
224ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        case RSRC_DENIED:
225ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        case RSRC_GRANTED:
226ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            ((DSStateMachine *)mStateMachine)->informStatus(notification.rsrcStatus, ID);
227ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            break;
228ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        default:
229ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            notify = false;
230ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        }
231ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    }
232ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    return notify;
233ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo}
234ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russovoid DSSubscriber :: setInactive()
235ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo{
236ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    mIsInactive = true;
237ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    ((DSStateMachine *)mStateMachine)->informStatus(RSRC_UNSUBSCRIBE, ID);
238ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo}
239ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo//======================================================================
240ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo// AgpsState:  AgpsReleasedState / AgpsPendingState / AgpsAcquiredState
241ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo//======================================================================
242ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
243ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo// AgpsReleasedState
244ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russoclass AgpsReleasedState : public AgpsState
245ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo{
246ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    friend class AgpsStateMachine;
247ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
248ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    inline AgpsReleasedState(AgpsStateMachine* stateMachine) :
249ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        AgpsState(stateMachine)
250ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    { mReleasedState = this; }
251ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
252ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    inline ~AgpsReleasedState() {}
253ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russopublic:
254ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    virtual AgpsState* onRsrcEvent(AgpsRsrcStatus event, void* data);
255ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    inline virtual char* whoami() {return (char*)"AgpsReleasedState";}
256ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo};
257ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
258ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante RussoAgpsState* AgpsReleasedState::onRsrcEvent(AgpsRsrcStatus event, void* data)
259ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo{
260ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    LOC_LOGD("AgpsReleasedState::onRsrcEvent; event:%d\n", (int)event);
261ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    if (mStateMachine->hasSubscribers()) {
262ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        LOC_LOGE("Error: %s subscriber list not empty!!!", whoami());
263ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        // I don't know how to recover from it.  I am adding this rather
264ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        // for debugging purpose.
265ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    }
266ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
267ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    AgpsState* nextState = this;
268ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    switch (event)
269ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    {
270ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    case RSRC_SUBSCRIBE:
271ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    {
272ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        // no notification until we get RSRC_GRANTED
273ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        // but we need to add subscriber to the list
274ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        mStateMachine->addSubscriber((Subscriber*)data);
275ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        // request from connecivity service for NIF
276ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        //The if condition is added so that if the data call setup fails
277ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        //for DS State Machine, we want to retry in released state.
278ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        //for AGps State Machine, sendRsrcRequest() will always return success
279ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        if(!mStateMachine->sendRsrcRequest(GPS_REQUEST_AGPS_DATA_CONN)) {
280ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            // move the state to PENDING
281ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            nextState = mPendingState;
282ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        }
283ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    }
284ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    break;
285ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
286ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    case RSRC_UNSUBSCRIBE:
287ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    {
288ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        // the list should really be empty, nothing to remove.
289ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        // but we might as well just tell the client it is
290ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        // unsubscribed.  False tolerance, right?
291ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        Subscriber* subscriber = (Subscriber*) data;
292ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        Notification notification(subscriber, event, false);
293ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        subscriber->notifyRsrcStatus(notification);
294ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    }
295ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        // break;
296ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    case RSRC_GRANTED:
297ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    case RSRC_RELEASED:
298ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    case RSRC_DENIED:
299ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    default:
300ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        LOC_LOGW("%s: unrecognized event %d", whoami(), event);
301ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        // no state change.
302ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        break;
303ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    }
304ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
305ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    LOC_LOGD("onRsrcEvent, old state %s, new state %s, event %d",
306ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo             whoami(), nextState->whoami(), event);
307ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    return nextState;
308ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo}
309ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
310ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo// AgpsPendingState
311ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russoclass AgpsPendingState : public AgpsState
312ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo{
313ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    friend class AgpsStateMachine;
314ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
315ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    inline AgpsPendingState(AgpsStateMachine* stateMachine) :
316ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        AgpsState(stateMachine)
317ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    { mPendingState = this; }
318ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
319ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    inline ~AgpsPendingState() {}
320ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russopublic:
321ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    virtual AgpsState* onRsrcEvent(AgpsRsrcStatus event, void* data);
322ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    inline virtual char* whoami() {return (char*)"AgpsPendingState";}
323ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo};
324ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
325ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante RussoAgpsState* AgpsPendingState::onRsrcEvent(AgpsRsrcStatus event, void* data)
326ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo{
327ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    AgpsState* nextState = this;;
328ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    LOC_LOGD("AgpsPendingState::onRsrcEvent; event:%d\n", (int)event);
329ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    switch (event)
330ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    {
331ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    case RSRC_SUBSCRIBE:
332ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    {
333ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        // already requested for NIF resource,
334ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        // do nothing until we get RSRC_GRANTED indication
335ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        // but we need to add subscriber to the list
336ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        mStateMachine->addSubscriber((Subscriber*)data);
337ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        // no state change.
338ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    }
339ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        break;
340ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
341ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    case RSRC_UNSUBSCRIBE:
342ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    {
343ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        Subscriber* subscriber = (Subscriber*) data;
344ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        if (subscriber->waitForCloseComplete()) {
345ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            subscriber->setInactive();
346ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        } else {
347ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            // auto notify this subscriber of the unsubscribe
348ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            Notification notification(subscriber, event, true);
349ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            mStateMachine->notifySubscribers(notification);
350ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        }
351ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
352ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        // now check if there is any subscribers left
353ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        if (!mStateMachine->hasSubscribers()) {
354ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            // no more subscribers, move to RELEASED state
355ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            nextState = mReleasedState;
356ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
357ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            // tell connecivity service we can release NIF
358ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            mStateMachine->sendRsrcRequest(GPS_RELEASE_AGPS_DATA_CONN);
359ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        } else if (!mStateMachine->hasActiveSubscribers()) {
360ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            // only inactive subscribers, move to RELEASING state
361ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            nextState = mReleasingState;
362ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
363ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            // tell connecivity service we can release NIF
364ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            mStateMachine->sendRsrcRequest(GPS_RELEASE_AGPS_DATA_CONN);
365ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        }
366ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    }
367ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    break;
368ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
369ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    case RSRC_GRANTED:
370ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    {
371ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        nextState = mAcquiredState;
372ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        Notification notification(Notification::BROADCAST_ACTIVE, event, false);
373ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        // notify all subscribers NIF resource GRANTED
374ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        // by setting false, we keep subscribers on the linked list
375ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        mStateMachine->notifySubscribers(notification);
376ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    }
377ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        break;
378ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
379ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    case RSRC_RELEASED:
380ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        // no state change.
381ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        // we are expecting either GRANTED or DENIED.  Handling RELEASED
382ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        // may like break our state machine in race conditions.
383ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        break;
384ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
385ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    case RSRC_DENIED:
386ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    {
387ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        nextState = mReleasedState;
388ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        Notification notification(Notification::BROADCAST_ALL, event, true);
389ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        // notify all subscribers NIF resource RELEASED or DENIED
390ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        // by setting true, we remove subscribers from the linked list
391ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        mStateMachine->notifySubscribers(notification);
392ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    }
393ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        break;
394ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
395ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    default:
396ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        LOC_LOGE("%s: unrecognized event %d", whoami(), event);
397ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        // no state change.
398ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    }
399ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
400ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    LOC_LOGD("onRsrcEvent, old state %s, new state %s, event %d",
401ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo             whoami(), nextState->whoami(), event);
402ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    return nextState;
403ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo}
404ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
405ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
406ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russoclass AgpsAcquiredState : public AgpsState
407ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo{
408ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    friend class AgpsStateMachine;
409ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
410ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    inline AgpsAcquiredState(AgpsStateMachine* stateMachine) :
411ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        AgpsState(stateMachine)
412ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    { mAcquiredState = this; }
413ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
414ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    inline ~AgpsAcquiredState() {}
415ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russopublic:
416ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    virtual AgpsState* onRsrcEvent(AgpsRsrcStatus event, void* data);
417ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    inline virtual char* whoami() { return (char*)"AgpsAcquiredState"; }
418ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo};
419ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
420ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
421ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante RussoAgpsState* AgpsAcquiredState::onRsrcEvent(AgpsRsrcStatus event, void* data)
422ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo{
423ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    AgpsState* nextState = this;
424ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    LOC_LOGD("AgpsAcquiredState::onRsrcEvent; event:%d\n", (int)event);
425ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    switch (event)
426ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    {
427ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    case RSRC_SUBSCRIBE:
428ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    {
429ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        // we already have the NIF resource, simply notify subscriber
430ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        Subscriber* subscriber = (Subscriber*) data;
431ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        // we have rsrc in hand, so grant it right away
432ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        Notification notification(subscriber, RSRC_GRANTED, false);
433ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        subscriber->notifyRsrcStatus(notification);
434ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        // add subscriber to the list
435ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        mStateMachine->addSubscriber(subscriber);
436ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        // no state change.
437ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    }
438ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        break;
439ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
440ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    case RSRC_UNSUBSCRIBE:
441ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    {
442ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        Subscriber* subscriber = (Subscriber*) data;
443ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        if (subscriber->waitForCloseComplete()) {
444ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            subscriber->setInactive();
445ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        } else {
446ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            // auto notify this subscriber of the unsubscribe
447ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            Notification notification(subscriber, event, true);
448ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            mStateMachine->notifySubscribers(notification);
449ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        }
450ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
451ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        // now check if there is any subscribers left
452ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        if (!mStateMachine->hasSubscribers()) {
453ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            // no more subscribers, move to RELEASED state
454ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            nextState = mReleasedState;
455ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
456ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            // tell connecivity service we can release NIF
457ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            mStateMachine->sendRsrcRequest(GPS_RELEASE_AGPS_DATA_CONN);
458ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        } else if (!mStateMachine->hasActiveSubscribers()) {
459ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            // only inactive subscribers, move to RELEASING state
460ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            nextState = mReleasingState;
461ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
462ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            // tell connecivity service we can release NIF
463ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            mStateMachine->sendRsrcRequest(GPS_RELEASE_AGPS_DATA_CONN);
464ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        }
465ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    }
466ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        break;
467ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
468ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    case RSRC_GRANTED:
469ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        LOC_LOGW("%s: %d, RSRC_GRANTED already received", whoami(), event);
470ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        // no state change.
471ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        break;
472ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
473ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    case RSRC_RELEASED:
474ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    {
475ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        LOC_LOGW("%s: %d, a force rsrc release", whoami(), event);
476ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        nextState = mReleasedState;
477ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        Notification notification(Notification::BROADCAST_ALL, event, true);
478ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        // by setting true, we remove subscribers from the linked list
479ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        mStateMachine->notifySubscribers(notification);
480ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    }
481ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        break;
482ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
483ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    case RSRC_DENIED:
484ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        // no state change.
485ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        // we are expecting RELEASED.  Handling DENIED
486ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        // may like break our state machine in race conditions.
487ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        break;
488ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
489ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    default:
490ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        LOC_LOGE("%s: unrecognized event %d", whoami(), event);
491ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        // no state change.
492ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    }
493ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
494ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    LOC_LOGD("onRsrcEvent, old state %s, new state %s, event %d",
495ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo             whoami(), nextState->whoami(), event);
496ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    return nextState;
497ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo}
498ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
499ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo// AgpsPendingState
500ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russoclass AgpsReleasingState : public AgpsState
501ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo{
502ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    friend class AgpsStateMachine;
503ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
504ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    inline AgpsReleasingState(AgpsStateMachine* stateMachine) :
505ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        AgpsState(stateMachine)
506ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    { mReleasingState = this; }
507ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
508ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    inline ~AgpsReleasingState() {}
509ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russopublic:
510ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    virtual AgpsState* onRsrcEvent(AgpsRsrcStatus event, void* data);
511ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    inline virtual char* whoami() {return (char*)"AgpsReleasingState";}
512ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo};
513ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
514ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante RussoAgpsState* AgpsReleasingState::onRsrcEvent(AgpsRsrcStatus event, void* data)
515ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo{
516ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    AgpsState* nextState = this;;
517ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    LOC_LOGD("AgpsReleasingState::onRsrcEvent; event:%d\n", (int)event);
518ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
519ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo   switch (event)
520ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    {
521ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    case RSRC_SUBSCRIBE:
522ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    {
523ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        // already requested for NIF resource,
524ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        // do nothing until we get RSRC_GRANTED indication
525ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        // but we need to add subscriber to the list
526ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        mStateMachine->addSubscriber((Subscriber*)data);
527ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        // no state change.
528ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    }
529ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        break;
530ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
531ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    case RSRC_UNSUBSCRIBE:
532ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    {
533ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        Subscriber* subscriber = (Subscriber*) data;
534ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        if (subscriber->waitForCloseComplete()) {
535ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            subscriber->setInactive();
536ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        } else {
537ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            // auto notify this subscriber of the unsubscribe
538ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            Notification notification(subscriber, event, true);
539ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            mStateMachine->notifySubscribers(notification);
540ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        }
541ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
542ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        // now check if there is any subscribers left
543ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        if (!mStateMachine->hasSubscribers()) {
544ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            // no more subscribers, move to RELEASED state
545ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            nextState = mReleasedState;
546ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        }
547ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    }
548ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        break;
549ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
550ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    case RSRC_DENIED:
551ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        // A race condition subscriber unsubscribes before AFW denies resource.
552ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    case RSRC_RELEASED:
553ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    {
554ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        nextState = mAcquiredState;
555ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        Notification notification(Notification::BROADCAST_INACTIVE, event, true);
556ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        // notify all subscribers that are active NIF resource RELEASE
557ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        // by setting false, we keep subscribers on the linked list
558ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        mStateMachine->notifySubscribers(notification);
559ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
560ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        if (mStateMachine->hasActiveSubscribers()) {
561ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            nextState = mPendingState;
562ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            // request from connecivity service for NIF
563ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            mStateMachine->sendRsrcRequest(GPS_REQUEST_AGPS_DATA_CONN);
564ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        } else {
565ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            nextState = mReleasedState;
566ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        }
567ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    }
568ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        break;
569ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
570ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    case RSRC_GRANTED:
571ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    default:
572ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        LOC_LOGE("%s: unrecognized event %d", whoami(), event);
573ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        // no state change.
574ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    }
575ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
576ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    LOC_LOGD("onRsrcEvent, old state %s, new state %s, event %d",
577ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo             whoami(), nextState->whoami(), event);
578ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    return nextState;
579ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo}
580ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo//======================================================================
581ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo//Servicer
582ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo//======================================================================
583ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante RussoServicer* Servicer :: getServicer(servicerType type, void *cb_func)
584ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo{
585ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    LOC_LOGD(" Enter getServicer type:%d\n", (int)type);
586ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    switch(type) {
587ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    case servicerTypeNoCbParam:
588ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        return (new Servicer(cb_func));
589ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    case servicerTypeExt:
590ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        return (new ExtServicer(cb_func));
591ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    case servicerTypeAgps:
592ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        return (new AGpsServicer(cb_func));
593ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    default:
594ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        return NULL;
595ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    }
596ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo}
597ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
598ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russoint Servicer :: requestRsrc(void *cb_data)
599ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo{
600ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    callback();
601ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    return 0;
602ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo}
603ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
604ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russoint ExtServicer :: requestRsrc(void *cb_data)
605ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo{
606ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    int ret=-1;
607ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    LOC_LOGD("Enter ExtServicer :: requestRsrc\n");
608ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    ret = callbackExt(cb_data);
609ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    LOC_LOGD("Exit ExtServicer :: requestRsrc\n");
610ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    return(ret);
611ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo}
612ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
613ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russoint AGpsServicer :: requestRsrc(void *cb_data)
614ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo{
615ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    callbackAGps((AGpsStatus *)cb_data);
616ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    return 0;
617ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo}
618ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
619ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo//======================================================================
620ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo// AgpsStateMachine
621ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo//======================================================================
622ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
623ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante RussoAgpsStateMachine::AgpsStateMachine(servicerType servType,
624ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo                                   void *cb_func,
625ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo                                   AGpsExtType type,
626ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo                                   bool enforceSingleSubscriber) :
627ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    mStatePtr(new AgpsReleasedState(this)),mType(type),
628ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    mAPN(NULL),
629ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    mAPNLen(0),
630ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    mBearer(AGPS_APN_BEARER_INVALID),
631ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    mEnforceSingleSubscriber(enforceSingleSubscriber),
632ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    mServicer(Servicer :: getServicer(servType, (void *)cb_func))
633ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo{
634ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    linked_list_init(&mSubscribers);
635ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
636ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    // setting up mReleasedState
637ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    mStatePtr->mPendingState = new AgpsPendingState(this);
638ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    mStatePtr->mAcquiredState = new AgpsAcquiredState(this);
639ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    mStatePtr->mReleasingState = new AgpsReleasingState(this);
640ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
641ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    // setting up mAcquiredState
642ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    mStatePtr->mAcquiredState->mReleasedState = mStatePtr;
643ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    mStatePtr->mAcquiredState->mPendingState = mStatePtr->mPendingState;
644ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    mStatePtr->mAcquiredState->mReleasingState = mStatePtr->mReleasingState;
645ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
646ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    // setting up mPendingState
647ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    mStatePtr->mPendingState->mAcquiredState = mStatePtr->mAcquiredState;
648ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    mStatePtr->mPendingState->mReleasedState = mStatePtr;
649ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    mStatePtr->mPendingState->mReleasingState = mStatePtr->mReleasingState;
650ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
651ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    // setting up mReleasingState
652ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    mStatePtr->mReleasingState->mReleasedState = mStatePtr;
653ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    mStatePtr->mReleasingState->mPendingState = mStatePtr->mPendingState;
654ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    mStatePtr->mReleasingState->mAcquiredState = mStatePtr->mAcquiredState;
655ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo}
656ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
657ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante RussoAgpsStateMachine::~AgpsStateMachine()
658ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo{
659ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    dropAllSubscribers();
660ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
661ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    // free the 3 states.  We must read out all 3 pointers first.
662ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    // Otherwise we run the risk of getting pointers from already
663ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    // freed memory.
664ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    AgpsState* acquiredState = mStatePtr->mAcquiredState;
665ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    AgpsState* releasedState = mStatePtr->mReleasedState;
666ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    AgpsState* pendindState = mStatePtr->mPendingState;
667ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    AgpsState* releasingState = mStatePtr->mReleasingState;
668ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
669ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    delete acquiredState;
670ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    delete releasedState;
671ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    delete pendindState;
672ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    delete releasingState;
673ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    delete mServicer;
674ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    linked_list_destroy(&mSubscribers);
675ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
676ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    if (NULL != mAPN) {
677ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        delete[] mAPN;
678ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        mAPN = NULL;
679ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    }
680ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo}
681ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
682ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russovoid AgpsStateMachine::setAPN(const char* apn, unsigned int len)
683ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo{
684ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    if (NULL != mAPN) {
685ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        delete mAPN;
686ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    }
687ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
688ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    if (NULL != apn) {
689ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        mAPN = new char[len+1];
690ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        memcpy(mAPN, apn, len);
691ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        mAPN[len] = NULL;
692ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
693ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        mAPNLen = len;
694ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    } else {
695ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        mAPN = NULL;
696ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        mAPNLen = 0;
697ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    }
698ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo}
699ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
700ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russovoid AgpsStateMachine::onRsrcEvent(AgpsRsrcStatus event)
701ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo{
702ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    switch (event)
703ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    {
704ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    case RSRC_GRANTED:
705ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    case RSRC_RELEASED:
706ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    case RSRC_DENIED:
707ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        mStatePtr = mStatePtr->onRsrcEvent(event, NULL);
708ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        break;
709ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    default:
710ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        LOC_LOGW("AgpsStateMachine: unrecognized event %d", event);
711ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        break;
712ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    }
713ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo}
714ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
715ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russovoid AgpsStateMachine::notifySubscribers(Notification& notification) const
716ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo{
717ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    if (notification.postNotifyDelete) {
718ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        // just any non NULL value to get started
719ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        Subscriber* s = (Subscriber*)~0;
720ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        while (NULL != s) {
721ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            s = NULL;
722ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            // if the last param sets to true, _search will delete
723ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            // the node from the list for us.  But the problem is
724ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            // once that is done, _search returns, leaving the
725ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            // rest of the list unprocessed.  So we need a loop.
726ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            linked_list_search(mSubscribers, (void**)&s, notifySubscriber,
727ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo                               (void*)&notification, true);
728ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            delete s;
729ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        }
730ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    } else {
731ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        // no loop needed if it the last param sets to false, which
732ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        // mean nothing gets deleted from the list.
733ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        linked_list_search(mSubscribers, NULL, notifySubscriber,
734ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo                           (void*)&notification, false);
735ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    }
736ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo}
737ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
738ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russovoid AgpsStateMachine::addSubscriber(Subscriber* subscriber) const
739ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo{
740ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    Subscriber* s = NULL;
741ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    Notification notification((const Subscriber*)subscriber);
742ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    linked_list_search(mSubscribers, (void**)&s,
743ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo                       hasSubscriber, (void*)&notification, false);
744ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
745ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    if (NULL == s) {
746ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        linked_list_add(mSubscribers, subscriber->clone(), deleteObj);
747ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    }
748ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo}
749ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
750ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russoint AgpsStateMachine::sendRsrcRequest(AGpsStatusValue action) const
751ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo{
752ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    Subscriber* s = NULL;
753ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    Notification notification(Notification::BROADCAST_ACTIVE);
754ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    linked_list_search(mSubscribers, (void**)&s, hasSubscriber,
755ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo                       (void*)&notification, false);
756ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
757ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    if ((NULL == s) == (GPS_RELEASE_AGPS_DATA_CONN == action)) {
758ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        AGpsExtStatus nifRequest;
759ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        nifRequest.size = sizeof(nifRequest);
760ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        nifRequest.type = mType;
761ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        nifRequest.status = action;
762ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
763ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        if (s == NULL) {
764ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            nifRequest.ipv4_addr = INADDR_NONE;
765ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            nifRequest.ipv6_addr[0] = 0;
766ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            nifRequest.ssid[0] = '\0';
767ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            nifRequest.password[0] = '\0';
768ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        } else {
769ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            s->setIPAddresses(nifRequest.ipv4_addr, (char*)nifRequest.ipv6_addr);
770ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            s->setWifiInfo(nifRequest.ssid, nifRequest.password);
771ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        }
772ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
773ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        CALLBACK_LOG_CALLFLOW("agps_cb", %s, loc_get_agps_status_name(action));
774ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        mServicer->requestRsrc((void *)&nifRequest);
775ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    }
776ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    return 0;
777ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo}
778ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
779ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russovoid AgpsStateMachine::subscribeRsrc(Subscriber *subscriber)
780ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo{
781ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo  if (mEnforceSingleSubscriber && hasSubscribers()) {
782ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo      Notification notification(Notification::BROADCAST_ALL, RSRC_DENIED, true);
783ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo      notifySubscriber(&notification, subscriber);
784ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo  } else {
785ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo      mStatePtr = mStatePtr->onRsrcEvent(RSRC_SUBSCRIBE, (void*)subscriber);
786ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo  }
787ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo}
788ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
789ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russobool AgpsStateMachine::unsubscribeRsrc(Subscriber *subscriber)
790ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo{
791ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    Subscriber* s = NULL;
792ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    Notification notification((const Subscriber*)subscriber);
793ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    linked_list_search(mSubscribers, (void**)&s,
794ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo                       hasSubscriber, (void*)&notification, false);
795ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
796ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    if (NULL != s) {
797ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        mStatePtr = mStatePtr->onRsrcEvent(RSRC_UNSUBSCRIBE, (void*)s);
798ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        return true;
799ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    }
800ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    return false;
801ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo}
802ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
803ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russobool AgpsStateMachine::hasActiveSubscribers() const
804ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo{
805ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    Subscriber* s = NULL;
806ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    Notification notification(Notification::BROADCAST_ACTIVE);
807ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    linked_list_search(mSubscribers, (void**)&s,
808ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo                       hasSubscriber, (void*)&notification, false);
809ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    return NULL != s;
810ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo}
811ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
812ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo//======================================================================
813ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo// DSStateMachine
814ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo//======================================================================
815ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russovoid delay_callback(void *callbackData, int result)
816ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo{
817ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    if(callbackData) {
818ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        DSStateMachine *DSSMInstance = (DSStateMachine *)callbackData;
819ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        DSSMInstance->retryCallback();
820ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    }
821ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    else {
822ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        LOC_LOGE(" NULL argument received. Failing.\n");
823ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        goto err;
824ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    }
825ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russoerr:
826ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    return;
827ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo}
828ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
829ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante RussoDSStateMachine :: DSStateMachine(servicerType type, void *cb_func,
830ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo                                 LocEngAdapter* adapterHandle):
831ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    AgpsStateMachine(type, cb_func, AGPS_TYPE_INVALID,false),
832ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    mLocAdapter(adapterHandle)
833ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo{
834ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    LOC_LOGD("%s:%d]: New DSStateMachine\n", __func__, __LINE__);
835ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    mRetries = 0;
836ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo}
837ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
838ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russovoid DSStateMachine :: retryCallback(void)
839ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo{
840ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    DSSubscriber *subscriber = NULL;
841ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    Notification notification(Notification::BROADCAST_ACTIVE);
842ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    linked_list_search(mSubscribers, (void**)&subscriber, hasSubscriber,
843ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo                       (void*)&notification, false);
844ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    if(subscriber)
845ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        mLocAdapter->requestSuplES(subscriber->ID);
846ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    else
847ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        LOC_LOGE("DSStateMachine :: retryCallback: No subscriber found." \
848ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo                 "Cannot retry data call\n");
849ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    return;
850ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo}
851ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
852ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russoint DSStateMachine :: sendRsrcRequest(AGpsStatusValue action) const
853ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo{
854ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    DSSubscriber* s = NULL;
855ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    dsCbData cbData;
856ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    int ret=-1;
857ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    int connHandle=-1;
858ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    LOC_LOGD("Enter DSStateMachine :: sendRsrcRequest\n");
859ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    Notification notification(Notification::BROADCAST_ACTIVE);
860ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    linked_list_search(mSubscribers, (void**)&s, hasSubscriber,
861ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo                       (void*)&notification, false);
862ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    if(s) {
863ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        connHandle = s->ID;
864ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        LOC_LOGD("DSStateMachine :: sendRsrcRequest - subscriber found\n");
865ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    }
866ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    else
867ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        LOC_LOGD("DSStateMachine :: sendRsrcRequest - No subscriber found\n");
868ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
869ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    cbData.action = action;
870ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    cbData.mAdapter = mLocAdapter;
871ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    ret = mServicer->requestRsrc((void *)&cbData);
872ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    //Only the request to start data call returns a success/failure
873ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    //The request to stop data call will always succeed
874ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    //Hence, the below block will only be executed when the
875ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    //request to start the data call fails
876ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    switch(ret) {
877ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    case LOC_API_ADAPTER_ERR_ENGINE_BUSY:
878ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        LOC_LOGD("DSStateMachine :: sendRsrcRequest - Failure returned: %d\n",ret);
879ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        ((DSStateMachine *)this)->incRetries();
880ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        if(mRetries > MAX_START_DATA_CALL_RETRIES) {
881ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            LOC_LOGE(" Failed to start Data call. Fallback to normal ATL SUPL\n");
882ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            informStatus(RSRC_DENIED, connHandle);
883ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        }
884ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        else {
885ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            if(loc_timer_start(DATA_CALL_RETRY_DELAY_MSEC, delay_callback, (void *)this)) {
886ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo                LOC_LOGE("Error: Could not start delay thread\n");
887ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo                ret = -1;
888ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo                goto err;
889ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            }
890ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        }
891ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        break;
892ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    case LOC_API_ADAPTER_ERR_UNSUPPORTED:
893ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        LOC_LOGE("No profile found for emergency call. Fallback to normal SUPL ATL\n");
894ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        informStatus(RSRC_DENIED, connHandle);
895ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        break;
896ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    case LOC_API_ADAPTER_ERR_SUCCESS:
897ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        LOC_LOGD("%s:%d]: Request to start data call sent\n", __func__, __LINE__);
898ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        break;
899ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    case -1:
900ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        //One of the ways this case can be encountered is if the callback function
901ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        //receives a null argument, it just exits with -1 error
902ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        LOC_LOGE("Error: Something went wrong somewhere. Falling back to normal SUPL ATL\n");
903ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        informStatus(RSRC_DENIED, connHandle);
904ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        break;
905ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    default:
906ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        LOC_LOGE("%s:%d]: Unrecognized return value\n", __func__, __LINE__);
907ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    }
908ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russoerr:
909ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    LOC_LOGD("EXIT DSStateMachine :: sendRsrcRequest; ret = %d\n", ret);
910ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    return ret;
911ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo}
912ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
913ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russovoid DSStateMachine :: onRsrcEvent(AgpsRsrcStatus event)
914ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo{
915ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    void* currState = (void *)mStatePtr;
916ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    LOC_LOGD("Enter DSStateMachine :: onRsrcEvent. event = %d\n", (int)event);
917ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    switch (event)
918ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    {
919ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    case RSRC_GRANTED:
920ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        LOC_LOGD("DSStateMachine :: onRsrcEvent RSRC_GRANTED\n");
921ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        mStatePtr = mStatePtr->onRsrcEvent(event, NULL);
922ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        break;
923ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    case RSRC_RELEASED:
924ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        LOC_LOGD("DSStateMachine :: onRsrcEvent RSRC_RELEASED\n");
925ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        mStatePtr = mStatePtr->onRsrcEvent(event, NULL);
926ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        //To handle the case where we get a RSRC_RELEASED in
927ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        //pending state, we translate that to a RSRC_DENIED state
928ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        //since the callback from DSI is either RSRC_GRANTED or RSRC_RELEASED
929ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        //for when the call is connected or disconnected respectively.
930ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        if((void *)mStatePtr != currState)
931ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            break;
932ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        else {
933ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            event = RSRC_DENIED;
934ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo            LOC_LOGE(" Switching event to RSRC_DENIED\n");
935ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        }
936ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    case RSRC_DENIED:
937ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        mStatePtr = mStatePtr->onRsrcEvent(event, NULL);
938ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        break;
939ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    default:
940ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        LOC_LOGW("AgpsStateMachine: unrecognized event %d", event);
941ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        break;
942ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    }
943ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    LOC_LOGD("Exit DSStateMachine :: onRsrcEvent. event = %d\n", (int)event);
944ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo}
945ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo
946ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russovoid DSStateMachine :: informStatus(AgpsRsrcStatus status, int ID) const
947ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo{
948ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    LOC_LOGD("DSStateMachine :: informStatus. Status=%d\n",(int)status);
949ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    switch(status) {
950ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    case RSRC_UNSUBSCRIBE:
951ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        mLocAdapter->atlCloseStatus(ID, 1);
952ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        break;
953ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    case RSRC_RELEASED:
954ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        mLocAdapter->closeDataCall();
955ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        break;
956ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    case RSRC_DENIED:
957ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        ((DSStateMachine *)this)->mRetries = 0;
958ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        mLocAdapter->requestATL(ID, AGPS_TYPE_SUPL);
959ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        break;
960ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    case RSRC_GRANTED:
961ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        mLocAdapter->atlOpenStatus(ID, 1,
962ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo                                                     NULL,
963ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo                                                     AGPS_APN_BEARER_INVALID,
964ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo                                                     AGPS_TYPE_INVALID);
965ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        break;
966ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    default:
967ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo        LOC_LOGW("DSStateMachine :: informStatus - unknown status");
968ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    }
969ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo    return;
970ec6e5d3a2597d37d5b1d98911cb06218cdf19bf1Dante Russo}
971