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 &notification) = 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 &notification);
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 &notification);
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 &notification);
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 &notification);
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 &notification);
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