diff options
author | Giulio Cervera <giulio.cervera@cyanogenmod.org> | 2014-04-26 16:01:41 +0200 |
---|---|---|
committer | Giulio Cervera <giulio.cervera@cyanogenmod.org> | 2014-04-27 02:10:43 +0200 |
commit | 604472bce94efef6fdeae8cc795507007c4325b3 (patch) | |
tree | 943d9b6467758b3ee51cd3a5a710e50d61aab0eb /gps/libloc_api_50001/loc_eng_agps.h |
Initial Shinano import
based on rhine-common 7e2a33e
Diffstat (limited to 'gps/libloc_api_50001/loc_eng_agps.h')
-rw-r--r-- | gps/libloc_api_50001/loc_eng_agps.h | 419 |
1 files changed, 419 insertions, 0 deletions
diff --git a/gps/libloc_api_50001/loc_eng_agps.h b/gps/libloc_api_50001/loc_eng_agps.h new file mode 100644 index 0000000..055d955 --- /dev/null +++ b/gps/libloc_api_50001/loc_eng_agps.h @@ -0,0 +1,419 @@ +/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation, nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef __LOC_ENG_AGPS_H__ +#define __LOC_ENG_AGPS_H__ + +#include <stdbool.h> +#include <ctype.h> +#include <string.h> +#include <arpa/inet.h> +#include <hardware/gps.h> +#include <gps_extended.h> +#include <loc_core_log.h> +#include <linked_list.h> +#include <loc_timer.h> +#include <LocEngAdapter.h> + +// forward declaration +class AgpsStateMachine; +class Subscriber; + +// NIF resource events +typedef enum { + RSRC_SUBSCRIBE, + RSRC_UNSUBSCRIBE, + RSRC_GRANTED, + RSRC_RELEASED, + RSRC_DENIED, + RSRC_STATUS_MAX +} AgpsRsrcStatus; + +typedef enum { + servicerTypeNoCbParam, + servicerTypeAgps, + servicerTypeExt +}servicerType; + +//DS Callback struct +typedef struct { + LocEngAdapter *mAdapter; + AGpsStatusValue action; +}dsCbData; + +// information bundle for subscribers +struct Notification { + // goes to every subscriber + static const int BROADCAST_ALL; + // goes to every ACTIVE subscriber + static const int BROADCAST_ACTIVE; + // goes to every INACTIVE subscriber + static const int BROADCAST_INACTIVE; + + // go to a specific subscriber + const Subscriber* rcver; + // broadcast + const int groupID; + // the new resource status event + const AgpsRsrcStatus rsrcStatus; + // should the subscriber be deleted after the notification + const bool postNotifyDelete; + + // convenient constructor + inline Notification(const int broadcast, + const AgpsRsrcStatus status, + const bool deleteAfterwards) : + rcver(NULL), groupID(broadcast), rsrcStatus(status), + postNotifyDelete(deleteAfterwards) {} + + // convenient constructor + inline Notification(const Subscriber* subscriber, + const AgpsRsrcStatus status, + const bool deleteAfterwards) : + rcver(subscriber), groupID(-1), rsrcStatus(status), + postNotifyDelete(deleteAfterwards) {} + + // convenient constructor + inline Notification(const int broadcast) : + rcver(NULL), groupID(broadcast), rsrcStatus(RSRC_STATUS_MAX), + postNotifyDelete(false) {} + + // convenient constructor + inline Notification(const Subscriber* subscriber) : + rcver(subscriber), groupID(-1), rsrcStatus(RSRC_STATUS_MAX), + postNotifyDelete(false) {} +}; + +class AgpsState { + // allows AgpsStateMachine to access private data + // no class members are public. We don't want + // anyone but state machine to use state. + friend class AgpsStateMachine; + friend class DSStateMachine; + // state transitions are done here. + // Each state implements its own transitions (of course). + inline virtual AgpsState* onRsrcEvent(AgpsRsrcStatus event, void* data) = 0; + +protected: + // handle back to state machine + const AgpsStateMachine* mStateMachine; + // each state has pointers to all 3 states + // one of which is to itself. + AgpsState* mReleasedState; + AgpsState* mAcquiredState; + AgpsState* mPendingState; + AgpsState* mReleasingState; + + inline AgpsState(const AgpsStateMachine *stateMachine) : + mStateMachine(stateMachine), + mReleasedState(NULL), + mAcquiredState(NULL), + mPendingState(NULL), + mReleasingState(NULL) {} + virtual ~AgpsState() {} + +public: + // for logging purpose + inline virtual char* whoami() = 0; +}; + +class Servicer { + void (*callback)(void); +public: + static Servicer* getServicer(servicerType type, void *cb_func); + virtual int requestRsrc(void *cb_data); + Servicer() {} + Servicer(void *cb_func) + { callback = (void(*)(void))(cb_func); } + virtual ~Servicer(){} + inline virtual char *whoami() {return (char*)"Servicer";} +}; + +class ExtServicer : public Servicer { + int (*callbackExt)(void *cb_data); +public: + int requestRsrc(void *cb_data); + ExtServicer() {} + ExtServicer(void *cb_func) + { callbackExt = (int(*)(void *))(cb_func); } + virtual ~ExtServicer(){} + inline virtual char *whoami() {return (char*)"ExtServicer";} +}; + +class AGpsServicer : public Servicer { + void (*callbackAGps)(AGpsStatus* status); +public: + int requestRsrc(void *cb_data); + AGpsServicer() {} + AGpsServicer(void *cb_func) + { callbackAGps = (void(*)(AGpsStatus *))(cb_func); } + virtual ~AGpsServicer(){} + inline virtual char *whoami() {return (char*)"AGpsServicer";} +}; + +class AgpsStateMachine { +protected: + // a linked list of subscribers. + void* mSubscribers; + //handle to whoever provides the service + Servicer *mServicer; + // allows AgpsState to access private data + // each state is really internal data to the + // state machine, so it should be able to + // access anything within the state machine. + friend class AgpsState; + // pointer to the current state. + AgpsState* mStatePtr; +private: + // NIF type: AGNSS or INTERNET. + const AGpsExtType mType; + // apn to the NIF. Each state machine tracks + // resource state of a particular NIF. For each + // NIF, there is also an active APN. + char* mAPN; + // for convenience, we don't do strlen each time. + unsigned int mAPNLen; + // bear + AGpsBearerType mBearer; + // ipv4 address for routing + bool mEnforceSingleSubscriber; + +public: + AgpsStateMachine(servicerType servType, void *cb_func, + AGpsExtType type, bool enforceSingleSubscriber); + virtual ~AgpsStateMachine(); + + // self explanatory methods below + void setAPN(const char* apn, unsigned int len); + inline const char* getAPN() const { return (const char*)mAPN; } + inline void setBearer(AGpsBearerType bearer) { mBearer = bearer; } + inline AGpsBearerType getBearer() const { return mBearer; } + inline AGpsExtType getType() const { return (AGpsExtType)mType; } + + // someone, a ATL client or BIT, is asking for NIF + void subscribeRsrc(Subscriber *subscriber); + + // someone, a ATL client or BIT, is done with NIF + bool unsubscribeRsrc(Subscriber *subscriber); + + // add a subscriber in the linked list, if not already there. + void addSubscriber(Subscriber* subscriber) const; + + virtual void onRsrcEvent(AgpsRsrcStatus event); + + // put the data together and send the FW + virtual int sendRsrcRequest(AGpsStatusValue action) const; + + //if list is empty, linked_list_empty returns 1 + //else if list is not empty, returns 0 + //so hasSubscribers() returns 1 if list is not empty + //and returns 0 if list is empty + inline bool hasSubscribers() const + { return !linked_list_empty(mSubscribers); } + + bool hasActiveSubscribers() const; + + inline void dropAllSubscribers() const + { linked_list_flush(mSubscribers); } + + // private. Only a state gets to call this. + void notifySubscribers(Notification& notification) const; + +}; + +class DSStateMachine : public AgpsStateMachine { + static const unsigned char MAX_START_DATA_CALL_RETRIES; + static const unsigned int DATA_CALL_RETRY_DELAY_MSEC; + LocEngAdapter* mLocAdapter; + unsigned char mRetries; +public: + DSStateMachine(servicerType type, + void *cb_func, + LocEngAdapter* adapterHandle); + int sendRsrcRequest(AGpsStatusValue action) const; + void onRsrcEvent(AgpsRsrcStatus event); + void retryCallback(); + void informStatus(AgpsRsrcStatus status, int ID) const; + inline void incRetries() {mRetries++;} + inline virtual char *whoami() {return (char*)"DSStateMachine";} +}; + +// each subscriber is a AGPS client. In the case of ATL, there could be +// multiple clients from modem. In the case of BIT, there is only one +// cilent from BIT daemon. +struct Subscriber { + const uint32_t ID; + const AgpsStateMachine* mStateMachine; + inline Subscriber(const int id, + const AgpsStateMachine* stateMachine) : + ID(id), mStateMachine(stateMachine) {} + inline virtual ~Subscriber() {} + + virtual void setIPAddresses(uint32_t &v4, char* v6) = 0; + inline virtual void setWifiInfo(char* ssid, char* password) + { ssid[0] = 0; password[0] = 0; } + + inline virtual bool equals(const Subscriber *s) const + { return ID == s->ID; } + + // notifies a subscriber a new NIF resource status, usually + // either GRANTE, DENIED, or RELEASED + virtual bool notifyRsrcStatus(Notification ¬ification) = 0; + + virtual bool waitForCloseComplete() { return false; } + virtual void setInactive() {} + virtual bool isInactive() { return false; } + + virtual Subscriber* clone() = 0; + // checks if this notification is for me, i.e. + // either has my id, or has a broadcast id. + bool forMe(Notification ¬ification); +}; + +// BITSubscriber, created with requests from BIT daemon +struct BITSubscriber : public Subscriber { + char mIPv6Addr[16]; + + inline BITSubscriber(const AgpsStateMachine* stateMachine, + unsigned int ipv4, char* ipv6) : + Subscriber(ipv4, stateMachine) + { + if (NULL == ipv6) { + mIPv6Addr[0] = 0; + } else { + memcpy(mIPv6Addr, ipv6, sizeof(mIPv6Addr)); + } + } + + virtual bool notifyRsrcStatus(Notification ¬ification); + + inline virtual void setIPAddresses(uint32_t &v4, char* v6) + { v4 = ID; memcpy(v6, mIPv6Addr, sizeof(mIPv6Addr)); } + + virtual Subscriber* clone() + { + return new BITSubscriber(mStateMachine, ID, mIPv6Addr); + } + + virtual bool equals(const Subscriber *s) const; + inline virtual ~BITSubscriber(){} +}; + +// ATLSubscriber, created with requests from ATL +struct ATLSubscriber : public Subscriber { + const LocEngAdapter* mLocAdapter; + const bool mBackwardCompatibleMode; + inline ATLSubscriber(const int id, + const AgpsStateMachine* stateMachine, + const LocEngAdapter* adapter, + const bool compatibleMode) : + Subscriber(id, stateMachine), mLocAdapter(adapter), + mBackwardCompatibleMode(compatibleMode){} + virtual bool notifyRsrcStatus(Notification ¬ification); + + inline virtual void setIPAddresses(uint32_t &v4, char* v6) + { v4 = INADDR_NONE; v6[0] = 0; } + + inline virtual Subscriber* clone() + { + return new ATLSubscriber(ID, mStateMachine, mLocAdapter, + mBackwardCompatibleMode); + } + inline virtual ~ATLSubscriber(){} +}; + +// WIFISubscriber, created with requests from MSAPM or QuIPC +struct WIFISubscriber : public Subscriber { + char * mSSID; + char * mPassword; + loc_if_req_sender_id_e_type senderId; + bool mIsInactive; + inline WIFISubscriber(const AgpsStateMachine* stateMachine, + char * ssid, char * password, loc_if_req_sender_id_e_type sender_id) : + Subscriber(sender_id, stateMachine), + mSSID(NULL == ssid ? NULL : new char[SSID_BUF_SIZE]), + mPassword(NULL == password ? NULL : new char[SSID_BUF_SIZE]), + senderId(sender_id) + { + if (NULL != mSSID) + strlcpy(mSSID, ssid, SSID_BUF_SIZE); + if (NULL != mPassword) + strlcpy(mPassword, password, SSID_BUF_SIZE); + mIsInactive = false; + } + + virtual bool notifyRsrcStatus(Notification ¬ification); + + inline virtual void setIPAddresses(uint32_t &v4, char* v6) {} + + inline virtual void setWifiInfo(char* ssid, char* password) + { + if (NULL != mSSID) + strlcpy(ssid, mSSID, SSID_BUF_SIZE); + else + ssid[0] = '\0'; + if (NULL != mPassword) + strlcpy(password, mPassword, SSID_BUF_SIZE); + else + password[0] = '\0'; + } + + inline virtual bool waitForCloseComplete() { return true; } + + inline virtual void setInactive() { mIsInactive = true; } + inline virtual bool isInactive() { return mIsInactive; } + + virtual Subscriber* clone() + { + return new WIFISubscriber(mStateMachine, mSSID, mPassword, senderId); + } + inline virtual ~WIFISubscriber(){} +}; + +struct DSSubscriber : public Subscriber { + bool mIsInactive; + inline DSSubscriber(const AgpsStateMachine *stateMachine, + const int id) : + Subscriber(id, stateMachine) + { + mIsInactive = false; + } + inline virtual void setIPAddresses(uint32_t &v4, char* v6) {} + virtual Subscriber* clone() + {return new DSSubscriber(mStateMachine, ID);} + virtual bool notifyRsrcStatus(Notification ¬ification); + inline virtual bool waitForCloseComplete() { return true; } + virtual void setInactive(); + inline virtual bool isInactive() + { return mIsInactive; } + inline virtual ~DSSubscriber(){} + inline virtual char *whoami() {return (char*)"DSSubscriber";} +}; + +#endif //__LOC_ENG_AGPS_H__ |