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#ifndef __LOC_ENG_AGPS_H__ 3134ee09551764b045fdc02df754157473125edf60Kevin Tang#define __LOC_ENG_AGPS_H__ 3234ee09551764b045fdc02df754157473125edf60Kevin Tang 3334ee09551764b045fdc02df754157473125edf60Kevin Tang#include <stdbool.h> 3434ee09551764b045fdc02df754157473125edf60Kevin Tang#include <ctype.h> 3534ee09551764b045fdc02df754157473125edf60Kevin Tang#include <string.h> 3634ee09551764b045fdc02df754157473125edf60Kevin Tang#include <arpa/inet.h> 3734ee09551764b045fdc02df754157473125edf60Kevin Tang#include <hardware/gps.h> 38e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo#include <gps_extended.h> 39e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo#include <loc_core_log.h> 4034ee09551764b045fdc02df754157473125edf60Kevin Tang#include <linked_list.h> 41e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo#include <loc_timer.h> 42e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo#include <LocEngAdapter.h> 4334ee09551764b045fdc02df754157473125edf60Kevin Tang 4434ee09551764b045fdc02df754157473125edf60Kevin Tang// forward declaration 4534ee09551764b045fdc02df754157473125edf60Kevin Tangclass AgpsStateMachine; 4634ee09551764b045fdc02df754157473125edf60Kevin Tangclass Subscriber; 4734ee09551764b045fdc02df754157473125edf60Kevin Tang 4834ee09551764b045fdc02df754157473125edf60Kevin Tang// NIF resource events 4934ee09551764b045fdc02df754157473125edf60Kevin Tangtypedef enum { 5034ee09551764b045fdc02df754157473125edf60Kevin Tang RSRC_SUBSCRIBE, 5134ee09551764b045fdc02df754157473125edf60Kevin Tang RSRC_UNSUBSCRIBE, 5234ee09551764b045fdc02df754157473125edf60Kevin Tang RSRC_GRANTED, 5334ee09551764b045fdc02df754157473125edf60Kevin Tang RSRC_RELEASED, 5434ee09551764b045fdc02df754157473125edf60Kevin Tang RSRC_DENIED, 5534ee09551764b045fdc02df754157473125edf60Kevin Tang RSRC_STATUS_MAX 5634ee09551764b045fdc02df754157473125edf60Kevin Tang} AgpsRsrcStatus; 5734ee09551764b045fdc02df754157473125edf60Kevin Tang 58e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russotypedef enum { 59e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo servicerTypeNoCbParam, 60e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo servicerTypeAgps, 61e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo servicerTypeExt 62e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo}servicerType; 63e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo 64e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo//DS Callback struct 65e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russotypedef struct { 66e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo LocEngAdapter *mAdapter; 67e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo AGpsStatusValue action; 68e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo}dsCbData; 69e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo 7034ee09551764b045fdc02df754157473125edf60Kevin Tang// information bundle for subscribers 7134ee09551764b045fdc02df754157473125edf60Kevin Tangstruct Notification { 7234ee09551764b045fdc02df754157473125edf60Kevin Tang // goes to every subscriber 7334ee09551764b045fdc02df754157473125edf60Kevin Tang static const int BROADCAST_ALL; 7434ee09551764b045fdc02df754157473125edf60Kevin Tang // goes to every ACTIVE subscriber 7534ee09551764b045fdc02df754157473125edf60Kevin Tang static const int BROADCAST_ACTIVE; 7634ee09551764b045fdc02df754157473125edf60Kevin Tang // goes to every INACTIVE subscriber 7734ee09551764b045fdc02df754157473125edf60Kevin Tang static const int BROADCAST_INACTIVE; 7834ee09551764b045fdc02df754157473125edf60Kevin Tang 7934ee09551764b045fdc02df754157473125edf60Kevin Tang // go to a specific subscriber 8034ee09551764b045fdc02df754157473125edf60Kevin Tang const Subscriber* rcver; 8134ee09551764b045fdc02df754157473125edf60Kevin Tang // broadcast 8234ee09551764b045fdc02df754157473125edf60Kevin Tang const int groupID; 8334ee09551764b045fdc02df754157473125edf60Kevin Tang // the new resource status event 8434ee09551764b045fdc02df754157473125edf60Kevin Tang const AgpsRsrcStatus rsrcStatus; 8534ee09551764b045fdc02df754157473125edf60Kevin Tang // should the subscriber be deleted after the notification 8634ee09551764b045fdc02df754157473125edf60Kevin Tang const bool postNotifyDelete; 8734ee09551764b045fdc02df754157473125edf60Kevin Tang 8834ee09551764b045fdc02df754157473125edf60Kevin Tang // convenient constructor 8934ee09551764b045fdc02df754157473125edf60Kevin Tang inline Notification(const int broadcast, 9034ee09551764b045fdc02df754157473125edf60Kevin Tang const AgpsRsrcStatus status, 9134ee09551764b045fdc02df754157473125edf60Kevin Tang const bool deleteAfterwards) : 9234ee09551764b045fdc02df754157473125edf60Kevin Tang rcver(NULL), groupID(broadcast), rsrcStatus(status), 9334ee09551764b045fdc02df754157473125edf60Kevin Tang postNotifyDelete(deleteAfterwards) {} 9434ee09551764b045fdc02df754157473125edf60Kevin Tang 9534ee09551764b045fdc02df754157473125edf60Kevin Tang // convenient constructor 9634ee09551764b045fdc02df754157473125edf60Kevin Tang inline Notification(const Subscriber* subscriber, 9734ee09551764b045fdc02df754157473125edf60Kevin Tang const AgpsRsrcStatus status, 9834ee09551764b045fdc02df754157473125edf60Kevin Tang const bool deleteAfterwards) : 9934ee09551764b045fdc02df754157473125edf60Kevin Tang rcver(subscriber), groupID(-1), rsrcStatus(status), 10034ee09551764b045fdc02df754157473125edf60Kevin Tang postNotifyDelete(deleteAfterwards) {} 10134ee09551764b045fdc02df754157473125edf60Kevin Tang 10234ee09551764b045fdc02df754157473125edf60Kevin Tang // convenient constructor 10334ee09551764b045fdc02df754157473125edf60Kevin Tang inline Notification(const int broadcast) : 10434ee09551764b045fdc02df754157473125edf60Kevin Tang rcver(NULL), groupID(broadcast), rsrcStatus(RSRC_STATUS_MAX), 10534ee09551764b045fdc02df754157473125edf60Kevin Tang postNotifyDelete(false) {} 10634ee09551764b045fdc02df754157473125edf60Kevin Tang 10734ee09551764b045fdc02df754157473125edf60Kevin Tang // convenient constructor 10834ee09551764b045fdc02df754157473125edf60Kevin Tang inline Notification(const Subscriber* subscriber) : 10934ee09551764b045fdc02df754157473125edf60Kevin Tang rcver(subscriber), groupID(-1), rsrcStatus(RSRC_STATUS_MAX), 11034ee09551764b045fdc02df754157473125edf60Kevin Tang postNotifyDelete(false) {} 11134ee09551764b045fdc02df754157473125edf60Kevin Tang}; 11234ee09551764b045fdc02df754157473125edf60Kevin Tang 11334ee09551764b045fdc02df754157473125edf60Kevin Tangclass AgpsState { 11434ee09551764b045fdc02df754157473125edf60Kevin Tang // allows AgpsStateMachine to access private data 11534ee09551764b045fdc02df754157473125edf60Kevin Tang // no class members are public. We don't want 11634ee09551764b045fdc02df754157473125edf60Kevin Tang // anyone but state machine to use state. 11734ee09551764b045fdc02df754157473125edf60Kevin Tang friend class AgpsStateMachine; 118e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo friend class DSStateMachine; 11934ee09551764b045fdc02df754157473125edf60Kevin Tang // state transitions are done here. 12034ee09551764b045fdc02df754157473125edf60Kevin Tang // Each state implements its own transitions (of course). 12134ee09551764b045fdc02df754157473125edf60Kevin Tang inline virtual AgpsState* onRsrcEvent(AgpsRsrcStatus event, void* data) = 0; 12234ee09551764b045fdc02df754157473125edf60Kevin Tang 12334ee09551764b045fdc02df754157473125edf60Kevin Tangprotected: 12434ee09551764b045fdc02df754157473125edf60Kevin Tang // handle back to state machine 12534ee09551764b045fdc02df754157473125edf60Kevin Tang const AgpsStateMachine* mStateMachine; 12634ee09551764b045fdc02df754157473125edf60Kevin Tang // each state has pointers to all 3 states 12734ee09551764b045fdc02df754157473125edf60Kevin Tang // one of which is to itself. 12834ee09551764b045fdc02df754157473125edf60Kevin Tang AgpsState* mReleasedState; 12934ee09551764b045fdc02df754157473125edf60Kevin Tang AgpsState* mAcquiredState; 13034ee09551764b045fdc02df754157473125edf60Kevin Tang AgpsState* mPendingState; 13134ee09551764b045fdc02df754157473125edf60Kevin Tang AgpsState* mReleasingState; 13234ee09551764b045fdc02df754157473125edf60Kevin Tang 13334ee09551764b045fdc02df754157473125edf60Kevin Tang inline AgpsState(const AgpsStateMachine *stateMachine) : 13434ee09551764b045fdc02df754157473125edf60Kevin Tang mStateMachine(stateMachine), 13534ee09551764b045fdc02df754157473125edf60Kevin Tang mReleasedState(NULL), 13634ee09551764b045fdc02df754157473125edf60Kevin Tang mAcquiredState(NULL), 13734ee09551764b045fdc02df754157473125edf60Kevin Tang mPendingState(NULL), 13834ee09551764b045fdc02df754157473125edf60Kevin Tang mReleasingState(NULL) {} 13934ee09551764b045fdc02df754157473125edf60Kevin Tang virtual ~AgpsState() {} 14034ee09551764b045fdc02df754157473125edf60Kevin Tang 14134ee09551764b045fdc02df754157473125edf60Kevin Tangpublic: 14234ee09551764b045fdc02df754157473125edf60Kevin Tang // for logging purpose 14334ee09551764b045fdc02df754157473125edf60Kevin Tang inline virtual char* whoami() = 0; 14434ee09551764b045fdc02df754157473125edf60Kevin Tang}; 14534ee09551764b045fdc02df754157473125edf60Kevin Tang 146e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russoclass Servicer { 147e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo void (*callback)(void); 148e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russopublic: 149e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo static Servicer* getServicer(servicerType type, void *cb_func); 150e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo virtual int requestRsrc(void *cb_data); 151e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo Servicer() {} 152e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo Servicer(void *cb_func) 153e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo { callback = (void(*)(void))(cb_func); } 154e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo virtual ~Servicer(){} 155e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo inline virtual char *whoami() {return (char*)"Servicer";} 156e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo}; 157e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo 158e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russoclass ExtServicer : public Servicer { 159e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo int (*callbackExt)(void *cb_data); 160e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russopublic: 161e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo int requestRsrc(void *cb_data); 162e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo ExtServicer() {} 163e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo ExtServicer(void *cb_func) 164e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo { callbackExt = (int(*)(void *))(cb_func); } 165e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo virtual ~ExtServicer(){} 166e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo inline virtual char *whoami() {return (char*)"ExtServicer";} 167e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo}; 168e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo 169e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russoclass AGpsServicer : public Servicer { 170e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo void (*callbackAGps)(AGpsStatus* status); 171e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russopublic: 172e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo int requestRsrc(void *cb_data); 173e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo AGpsServicer() {} 174e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo AGpsServicer(void *cb_func) 175e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo { callbackAGps = (void(*)(AGpsStatus *))(cb_func); } 176e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo virtual ~AGpsServicer(){} 177e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo inline virtual char *whoami() {return (char*)"AGpsServicer";} 178e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo}; 179e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo 18034ee09551764b045fdc02df754157473125edf60Kevin Tangclass AgpsStateMachine { 181e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russoprotected: 182e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo // a linked list of subscribers. 183e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo void* mSubscribers; 184e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo //handle to whoever provides the service 185e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo Servicer *mServicer; 18634ee09551764b045fdc02df754157473125edf60Kevin Tang // allows AgpsState to access private data 18734ee09551764b045fdc02df754157473125edf60Kevin Tang // each state is really internal data to the 18834ee09551764b045fdc02df754157473125edf60Kevin Tang // state machine, so it should be able to 18934ee09551764b045fdc02df754157473125edf60Kevin Tang // access anything within the state machine. 19034ee09551764b045fdc02df754157473125edf60Kevin Tang friend class AgpsState; 19134ee09551764b045fdc02df754157473125edf60Kevin Tang // pointer to the current state. 19234ee09551764b045fdc02df754157473125edf60Kevin Tang AgpsState* mStatePtr; 193e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russoprivate: 194e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo // NIF type: AGNSS or INTERNET. 195e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo const AGpsExtType mType; 19634ee09551764b045fdc02df754157473125edf60Kevin Tang // apn to the NIF. Each state machine tracks 19734ee09551764b045fdc02df754157473125edf60Kevin Tang // resource state of a particular NIF. For each 19834ee09551764b045fdc02df754157473125edf60Kevin Tang // NIF, there is also an active APN. 19934ee09551764b045fdc02df754157473125edf60Kevin Tang char* mAPN; 20034ee09551764b045fdc02df754157473125edf60Kevin Tang // for convenience, we don't do strlen each time. 20134ee09551764b045fdc02df754157473125edf60Kevin Tang unsigned int mAPNLen; 20234ee09551764b045fdc02df754157473125edf60Kevin Tang // bear 20334ee09551764b045fdc02df754157473125edf60Kevin Tang AGpsBearerType mBearer; 20434ee09551764b045fdc02df754157473125edf60Kevin Tang // ipv4 address for routing 205e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo bool mEnforceSingleSubscriber; 20634ee09551764b045fdc02df754157473125edf60Kevin Tang 20734ee09551764b045fdc02df754157473125edf60Kevin Tangpublic: 208e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo AgpsStateMachine(servicerType servType, void *cb_func, 209e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo AGpsExtType type, bool enforceSingleSubscriber); 21034ee09551764b045fdc02df754157473125edf60Kevin Tang virtual ~AgpsStateMachine(); 21134ee09551764b045fdc02df754157473125edf60Kevin Tang 21234ee09551764b045fdc02df754157473125edf60Kevin Tang // self explanatory methods below 21334ee09551764b045fdc02df754157473125edf60Kevin Tang void setAPN(const char* apn, unsigned int len); 21434ee09551764b045fdc02df754157473125edf60Kevin Tang inline const char* getAPN() const { return (const char*)mAPN; } 21534ee09551764b045fdc02df754157473125edf60Kevin Tang inline void setBearer(AGpsBearerType bearer) { mBearer = bearer; } 21634ee09551764b045fdc02df754157473125edf60Kevin Tang inline AGpsBearerType getBearer() const { return mBearer; } 217e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo inline AGpsExtType getType() const { return (AGpsExtType)mType; } 21834ee09551764b045fdc02df754157473125edf60Kevin Tang 21934ee09551764b045fdc02df754157473125edf60Kevin Tang // someone, a ATL client or BIT, is asking for NIF 22034ee09551764b045fdc02df754157473125edf60Kevin Tang void subscribeRsrc(Subscriber *subscriber); 22134ee09551764b045fdc02df754157473125edf60Kevin Tang 22234ee09551764b045fdc02df754157473125edf60Kevin Tang // someone, a ATL client or BIT, is done with NIF 22334ee09551764b045fdc02df754157473125edf60Kevin Tang bool unsubscribeRsrc(Subscriber *subscriber); 22434ee09551764b045fdc02df754157473125edf60Kevin Tang 22534ee09551764b045fdc02df754157473125edf60Kevin Tang // add a subscriber in the linked list, if not already there. 22634ee09551764b045fdc02df754157473125edf60Kevin Tang void addSubscriber(Subscriber* subscriber) const; 22734ee09551764b045fdc02df754157473125edf60Kevin Tang 228e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo virtual void onRsrcEvent(AgpsRsrcStatus event); 22934ee09551764b045fdc02df754157473125edf60Kevin Tang 23034ee09551764b045fdc02df754157473125edf60Kevin Tang // put the data together and send the FW 231e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo virtual int sendRsrcRequest(AGpsStatusValue action) const; 23234ee09551764b045fdc02df754157473125edf60Kevin Tang 233e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo //if list is empty, linked_list_empty returns 1 234e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo //else if list is not empty, returns 0 235e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo //so hasSubscribers() returns 1 if list is not empty 236e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo //and returns 0 if list is empty 23734ee09551764b045fdc02df754157473125edf60Kevin Tang inline bool hasSubscribers() const 23834ee09551764b045fdc02df754157473125edf60Kevin Tang { return !linked_list_empty(mSubscribers); } 23934ee09551764b045fdc02df754157473125edf60Kevin Tang 24034ee09551764b045fdc02df754157473125edf60Kevin Tang bool hasActiveSubscribers() const; 24134ee09551764b045fdc02df754157473125edf60Kevin Tang 24234ee09551764b045fdc02df754157473125edf60Kevin Tang inline void dropAllSubscribers() const 24334ee09551764b045fdc02df754157473125edf60Kevin Tang { linked_list_flush(mSubscribers); } 24434ee09551764b045fdc02df754157473125edf60Kevin Tang 24534ee09551764b045fdc02df754157473125edf60Kevin Tang // private. Only a state gets to call this. 24634ee09551764b045fdc02df754157473125edf60Kevin Tang void notifySubscribers(Notification& notification) const; 247e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo 248e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo}; 249e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo 250e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russoclass DSStateMachine : public AgpsStateMachine { 251e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo static const unsigned char MAX_START_DATA_CALL_RETRIES; 252e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo static const unsigned int DATA_CALL_RETRY_DELAY_MSEC; 253e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo LocEngAdapter* mLocAdapter; 254e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo unsigned char mRetries; 255e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russopublic: 256e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo DSStateMachine(servicerType type, 257e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo void *cb_func, 258e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo LocEngAdapter* adapterHandle); 259e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo int sendRsrcRequest(AGpsStatusValue action) const; 260e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo void onRsrcEvent(AgpsRsrcStatus event); 261e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo void retryCallback(); 262e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo void informStatus(AgpsRsrcStatus status, int ID) const; 263e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo inline void incRetries() {mRetries++;} 264e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo inline virtual char *whoami() {return (char*)"DSStateMachine";} 26534ee09551764b045fdc02df754157473125edf60Kevin Tang}; 26634ee09551764b045fdc02df754157473125edf60Kevin Tang 26734ee09551764b045fdc02df754157473125edf60Kevin Tang// each subscriber is a AGPS client. In the case of ATL, there could be 26834ee09551764b045fdc02df754157473125edf60Kevin Tang// multiple clients from modem. In the case of BIT, there is only one 26934ee09551764b045fdc02df754157473125edf60Kevin Tang// cilent from BIT daemon. 27034ee09551764b045fdc02df754157473125edf60Kevin Tangstruct Subscriber { 271e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo const uint32_t ID; 27234ee09551764b045fdc02df754157473125edf60Kevin Tang const AgpsStateMachine* mStateMachine; 27334ee09551764b045fdc02df754157473125edf60Kevin Tang inline Subscriber(const int id, 27434ee09551764b045fdc02df754157473125edf60Kevin Tang const AgpsStateMachine* stateMachine) : 27534ee09551764b045fdc02df754157473125edf60Kevin Tang ID(id), mStateMachine(stateMachine) {} 27634ee09551764b045fdc02df754157473125edf60Kevin Tang inline virtual ~Subscriber() {} 27734ee09551764b045fdc02df754157473125edf60Kevin Tang 278e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo virtual void setIPAddresses(uint32_t &v4, char* v6) = 0; 2790d00b9e0690547ad06eef43a5f1c77a31e8885dcDante Russo virtual void setIPAddresses(struct sockaddr_storage& addr) = 0; 280e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo inline virtual void setWifiInfo(char* ssid, char* password) 281e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo { ssid[0] = 0; password[0] = 0; } 28234ee09551764b045fdc02df754157473125edf60Kevin Tang 28334ee09551764b045fdc02df754157473125edf60Kevin Tang inline virtual bool equals(const Subscriber *s) const 28434ee09551764b045fdc02df754157473125edf60Kevin Tang { return ID == s->ID; } 28534ee09551764b045fdc02df754157473125edf60Kevin Tang 28634ee09551764b045fdc02df754157473125edf60Kevin Tang // notifies a subscriber a new NIF resource status, usually 28734ee09551764b045fdc02df754157473125edf60Kevin Tang // either GRANTE, DENIED, or RELEASED 28834ee09551764b045fdc02df754157473125edf60Kevin Tang virtual bool notifyRsrcStatus(Notification ¬ification) = 0; 28934ee09551764b045fdc02df754157473125edf60Kevin Tang 29034ee09551764b045fdc02df754157473125edf60Kevin Tang virtual bool waitForCloseComplete() { return false; } 29134ee09551764b045fdc02df754157473125edf60Kevin Tang virtual void setInactive() {} 29234ee09551764b045fdc02df754157473125edf60Kevin Tang virtual bool isInactive() { return false; } 29334ee09551764b045fdc02df754157473125edf60Kevin Tang 29434ee09551764b045fdc02df754157473125edf60Kevin Tang virtual Subscriber* clone() = 0; 29534ee09551764b045fdc02df754157473125edf60Kevin Tang // checks if this notification is for me, i.e. 29634ee09551764b045fdc02df754157473125edf60Kevin Tang // either has my id, or has a broadcast id. 29734ee09551764b045fdc02df754157473125edf60Kevin Tang bool forMe(Notification ¬ification); 29834ee09551764b045fdc02df754157473125edf60Kevin Tang}; 29934ee09551764b045fdc02df754157473125edf60Kevin Tang 30034ee09551764b045fdc02df754157473125edf60Kevin Tang// BITSubscriber, created with requests from BIT daemon 30134ee09551764b045fdc02df754157473125edf60Kevin Tangstruct BITSubscriber : public Subscriber { 302e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo char mIPv6Addr[16]; 303e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo 30434ee09551764b045fdc02df754157473125edf60Kevin Tang inline BITSubscriber(const AgpsStateMachine* stateMachine, 30534ee09551764b045fdc02df754157473125edf60Kevin Tang unsigned int ipv4, char* ipv6) : 30634ee09551764b045fdc02df754157473125edf60Kevin Tang Subscriber(ipv4, stateMachine) 30734ee09551764b045fdc02df754157473125edf60Kevin Tang { 30834ee09551764b045fdc02df754157473125edf60Kevin Tang if (NULL == ipv6) { 309e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo mIPv6Addr[0] = 0; 31034ee09551764b045fdc02df754157473125edf60Kevin Tang } else { 311e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo memcpy(mIPv6Addr, ipv6, sizeof(mIPv6Addr)); 31234ee09551764b045fdc02df754157473125edf60Kevin Tang } 31334ee09551764b045fdc02df754157473125edf60Kevin Tang } 31434ee09551764b045fdc02df754157473125edf60Kevin Tang 31534ee09551764b045fdc02df754157473125edf60Kevin Tang virtual bool notifyRsrcStatus(Notification ¬ification); 31634ee09551764b045fdc02df754157473125edf60Kevin Tang 317e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo inline virtual void setIPAddresses(uint32_t &v4, char* v6) 318e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo { v4 = ID; memcpy(v6, mIPv6Addr, sizeof(mIPv6Addr)); } 31934ee09551764b045fdc02df754157473125edf60Kevin Tang 3200d00b9e0690547ad06eef43a5f1c77a31e8885dcDante Russo inline virtual void setIPAddresses(struct sockaddr_storage& addr) 3210d00b9e0690547ad06eef43a5f1c77a31e8885dcDante Russo { addr.ss_family = AF_INET6;/*todo: convert mIPv6Addr into addr */ } 3220d00b9e0690547ad06eef43a5f1c77a31e8885dcDante Russo 32334ee09551764b045fdc02df754157473125edf60Kevin Tang virtual Subscriber* clone() 32434ee09551764b045fdc02df754157473125edf60Kevin Tang { 325e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo return new BITSubscriber(mStateMachine, ID, mIPv6Addr); 32634ee09551764b045fdc02df754157473125edf60Kevin Tang } 32734ee09551764b045fdc02df754157473125edf60Kevin Tang 32834ee09551764b045fdc02df754157473125edf60Kevin Tang virtual bool equals(const Subscriber *s) const; 329e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo inline virtual ~BITSubscriber(){} 33034ee09551764b045fdc02df754157473125edf60Kevin Tang}; 33134ee09551764b045fdc02df754157473125edf60Kevin Tang 33234ee09551764b045fdc02df754157473125edf60Kevin Tang// ATLSubscriber, created with requests from ATL 33334ee09551764b045fdc02df754157473125edf60Kevin Tangstruct ATLSubscriber : public Subscriber { 334e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo const LocEngAdapter* mLocAdapter; 335e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo const bool mBackwardCompatibleMode; 33634ee09551764b045fdc02df754157473125edf60Kevin Tang inline ATLSubscriber(const int id, 33734ee09551764b045fdc02df754157473125edf60Kevin Tang const AgpsStateMachine* stateMachine, 338e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo const LocEngAdapter* adapter, 339e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo const bool compatibleMode) : 340e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo Subscriber(id, stateMachine), mLocAdapter(adapter), 341e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo mBackwardCompatibleMode(compatibleMode){} 34234ee09551764b045fdc02df754157473125edf60Kevin Tang virtual bool notifyRsrcStatus(Notification ¬ification); 34334ee09551764b045fdc02df754157473125edf60Kevin Tang 344e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo inline virtual void setIPAddresses(uint32_t &v4, char* v6) 34534ee09551764b045fdc02df754157473125edf60Kevin Tang { v4 = INADDR_NONE; v6[0] = 0; } 34634ee09551764b045fdc02df754157473125edf60Kevin Tang 3470d00b9e0690547ad06eef43a5f1c77a31e8885dcDante Russo inline virtual void setIPAddresses(struct sockaddr_storage& addr) 348bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo { addr.ss_family = AF_INET6; } 3490d00b9e0690547ad06eef43a5f1c77a31e8885dcDante Russo 35034ee09551764b045fdc02df754157473125edf60Kevin Tang inline virtual Subscriber* clone() 35134ee09551764b045fdc02df754157473125edf60Kevin Tang { 352e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo return new ATLSubscriber(ID, mStateMachine, mLocAdapter, 353e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo mBackwardCompatibleMode); 354e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo } 355e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo inline virtual ~ATLSubscriber(){} 356e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo}; 357e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo 358e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo// WIFISubscriber, created with requests from MSAPM or QuIPC 359e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russostruct WIFISubscriber : public Subscriber { 360e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo char * mSSID; 361e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo char * mPassword; 362e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo loc_if_req_sender_id_e_type senderId; 363e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo bool mIsInactive; 364e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo inline WIFISubscriber(const AgpsStateMachine* stateMachine, 365e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo char * ssid, char * password, loc_if_req_sender_id_e_type sender_id) : 366e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo Subscriber(sender_id, stateMachine), 367e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo mSSID(NULL == ssid ? NULL : new char[SSID_BUF_SIZE]), 368e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo mPassword(NULL == password ? NULL : new char[SSID_BUF_SIZE]), 369e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo senderId(sender_id) 370e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo { 371e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo if (NULL != mSSID) 372e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo strlcpy(mSSID, ssid, SSID_BUF_SIZE); 373e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo if (NULL != mPassword) 374e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo strlcpy(mPassword, password, SSID_BUF_SIZE); 375e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo mIsInactive = false; 376e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo } 377e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo 378e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo virtual bool notifyRsrcStatus(Notification ¬ification); 379e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo 380e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo inline virtual void setIPAddresses(uint32_t &v4, char* v6) {} 381e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo 3820d00b9e0690547ad06eef43a5f1c77a31e8885dcDante Russo inline virtual void setIPAddresses(struct sockaddr_storage& addr) 3830d00b9e0690547ad06eef43a5f1c77a31e8885dcDante Russo { addr.ss_family = AF_INET6; } 3840d00b9e0690547ad06eef43a5f1c77a31e8885dcDante Russo 385e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo inline virtual void setWifiInfo(char* ssid, char* password) 386e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo { 387e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo if (NULL != mSSID) 388e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo strlcpy(ssid, mSSID, SSID_BUF_SIZE); 389e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo else 390e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo ssid[0] = '\0'; 391e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo if (NULL != mPassword) 392e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo strlcpy(password, mPassword, SSID_BUF_SIZE); 393e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo else 394e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo password[0] = '\0'; 395e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo } 396e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo 397e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo inline virtual bool waitForCloseComplete() { return true; } 398e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo 399e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo inline virtual void setInactive() { mIsInactive = true; } 400e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo inline virtual bool isInactive() { return mIsInactive; } 401e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo 402e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo virtual Subscriber* clone() 403e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo { 404e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo return new WIFISubscriber(mStateMachine, mSSID, mPassword, senderId); 40534ee09551764b045fdc02df754157473125edf60Kevin Tang } 406e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo inline virtual ~WIFISubscriber(){} 407e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo}; 408e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo 409e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russostruct DSSubscriber : public Subscriber { 410e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo bool mIsInactive; 411e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo inline DSSubscriber(const AgpsStateMachine *stateMachine, 412e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo const int id) : 413e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo Subscriber(id, stateMachine) 414e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo { 415e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo mIsInactive = false; 416e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo } 417e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo inline virtual void setIPAddresses(uint32_t &v4, char* v6) {} 4180d00b9e0690547ad06eef43a5f1c77a31e8885dcDante Russo inline virtual void setIPAddresses(struct sockaddr_storage& addr) 4190d00b9e0690547ad06eef43a5f1c77a31e8885dcDante Russo { addr.ss_family = AF_INET6; } 420e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo virtual Subscriber* clone() 421e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo {return new DSSubscriber(mStateMachine, ID);} 422e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo virtual bool notifyRsrcStatus(Notification ¬ification); 423e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo inline virtual bool waitForCloseComplete() { return true; } 424e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo virtual void setInactive(); 425e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo inline virtual bool isInactive() 426e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo { return mIsInactive; } 427e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo inline virtual ~DSSubscriber(){} 428e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo inline virtual char *whoami() {return (char*)"DSSubscriber";} 42934ee09551764b045fdc02df754157473125edf60Kevin Tang}; 43034ee09551764b045fdc02df754157473125edf60Kevin Tang 43134ee09551764b045fdc02df754157473125edf60Kevin Tang#endif //__LOC_ENG_AGPS_H__ 432