You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
449 lines
15 KiB
449 lines
15 KiB
/* Copyright (c) 2012-2017, 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 AGPS_H |
|
#define AGPS_H |
|
|
|
#include <functional> |
|
#include <list> |
|
#include <MsgTask.h> |
|
#include <gps_extended_c.h> |
|
#include <platform_lib_log_util.h> |
|
|
|
/* ATL callback function pointers |
|
* Passed in by Adapter to AgpsManager */ |
|
typedef std::function<void( |
|
int handle, int isSuccess, char* apn, |
|
AGpsBearerType bearerType, AGpsExtType agpsType)> AgpsAtlOpenStatusCb; |
|
|
|
typedef std::function<void(int handle, int isSuccess)> AgpsAtlCloseStatusCb; |
|
|
|
/* DS Client control APIs |
|
* Passed in by Adapter to AgpsManager */ |
|
typedef std::function<int(bool isDueToSSR)> AgpsDSClientInitFn; |
|
typedef std::function<int()> AgpsDSClientOpenAndStartDataCallFn; |
|
typedef std::function<void()> AgpsDSClientStopDataCallFn; |
|
typedef std::function<void()> AgpsDSClientCloseDataCallFn; |
|
typedef std::function<void()> AgpsDSClientReleaseFn; |
|
|
|
/* Post message to adapter's message queue */ |
|
typedef std::function<void(LocMsg* msg)> SendMsgToAdapterMsgQueueFn; |
|
|
|
/* AGPS States */ |
|
typedef enum { |
|
AGPS_STATE_INVALID = 0, |
|
AGPS_STATE_RELEASED, |
|
AGPS_STATE_PENDING, |
|
AGPS_STATE_ACQUIRED, |
|
AGPS_STATE_RELEASING |
|
} AgpsState; |
|
|
|
typedef enum { |
|
AGPS_EVENT_INVALID = 0, |
|
AGPS_EVENT_SUBSCRIBE, |
|
AGPS_EVENT_UNSUBSCRIBE, |
|
AGPS_EVENT_GRANTED, |
|
AGPS_EVENT_RELEASED, |
|
AGPS_EVENT_DENIED |
|
} AgpsEvent; |
|
|
|
/* Notification Types sent to subscribers */ |
|
typedef enum { |
|
AGPS_NOTIFICATION_TYPE_INVALID = 0, |
|
|
|
/* Meant for all subscribers, either active or inactive */ |
|
AGPS_NOTIFICATION_TYPE_FOR_ALL_SUBSCRIBERS, |
|
|
|
/* Meant for only inactive subscribers */ |
|
AGPS_NOTIFICATION_TYPE_FOR_INACTIVE_SUBSCRIBERS, |
|
|
|
/* Meant for only active subscribers */ |
|
AGPS_NOTIFICATION_TYPE_FOR_ACTIVE_SUBSCRIBERS |
|
} AgpsNotificationType; |
|
|
|
/* Framework AGNSS interface |
|
* This interface is defined in IAGnssCallback provided by |
|
* Android Framework. |
|
* Must be kept in sync with that interface. */ |
|
namespace AgpsFrameworkInterface { |
|
|
|
/** AGNSS type **/ |
|
enum AGnssType : uint8_t { |
|
TYPE_SUPL = 1, |
|
TYPE_C2K = 2 |
|
}; |
|
|
|
enum AGnssStatusValue : uint8_t { |
|
/** GNSS requests data connection for AGNSS. */ |
|
REQUEST_AGNSS_DATA_CONN = 1, |
|
/** GNSS releases the AGNSS data connection. */ |
|
RELEASE_AGNSS_DATA_CONN = 2, |
|
/** AGNSS data connection initiated */ |
|
AGNSS_DATA_CONNECTED = 3, |
|
/** AGNSS data connection completed */ |
|
AGNSS_DATA_CONN_DONE = 4, |
|
/** AGNSS data connection failed */ |
|
AGNSS_DATA_CONN_FAILED = 5 |
|
}; |
|
|
|
/* |
|
* Represents the status of AGNSS augmented to support IPv4. |
|
*/ |
|
struct AGnssStatusIpV4 { |
|
AGnssType type; |
|
AGnssStatusValue status; |
|
/* |
|
* 32-bit IPv4 address. |
|
*/ |
|
unsigned int ipV4Addr; |
|
}; |
|
|
|
/* |
|
* Represents the status of AGNSS augmented to support IPv6. |
|
*/ |
|
struct AGnssStatusIpV6 { |
|
AGnssType type; |
|
AGnssStatusValue status; |
|
/* |
|
* 128-bit IPv6 address. |
|
*/ |
|
unsigned char ipV6Addr[16]; |
|
}; |
|
|
|
/* |
|
* Callback with AGNSS(IpV4) status information. |
|
* |
|
* @param status Will be of type AGnssStatusIpV4. |
|
*/ |
|
typedef void (*AgnssStatusIpV4Cb)(AGnssStatusIpV4 status); |
|
|
|
/* |
|
* Callback with AGNSS(IpV6) status information. |
|
* |
|
* @param status Will be of type AGnssStatusIpV6. |
|
*/ |
|
typedef void (*AgnssStatusIpV6Cb)(AGnssStatusIpV6 status); |
|
} |
|
|
|
/* Classes in this header */ |
|
class AgpsSubscriber; |
|
class AgpsManager; |
|
class AgpsStateMachine; |
|
class DSStateMachine; |
|
|
|
|
|
/* SUBSCRIBER |
|
* Each Subscriber instance corresponds to one AGPS request, |
|
* received by the AGPS state machine */ |
|
class AgpsSubscriber { |
|
|
|
public: |
|
int mConnHandle; |
|
|
|
/* Does this subscriber wait for data call close complete, |
|
* before being notified ATL close ? |
|
* While waiting for data call close, subscriber will be in |
|
* inactive state. */ |
|
bool mWaitForCloseComplete; |
|
bool mIsInactive; |
|
|
|
inline AgpsSubscriber( |
|
int connHandle, bool waitForCloseComplete, bool isInactive) : |
|
mConnHandle(connHandle), |
|
mWaitForCloseComplete(waitForCloseComplete), |
|
mIsInactive(isInactive) {} |
|
inline virtual ~AgpsSubscriber() {} |
|
|
|
inline virtual bool equals(const AgpsSubscriber *s) const |
|
{ return (mConnHandle == s->mConnHandle); } |
|
|
|
inline virtual AgpsSubscriber* clone() |
|
{ return new AgpsSubscriber( |
|
mConnHandle, mWaitForCloseComplete, mIsInactive); } |
|
}; |
|
|
|
/* AGPS STATE MACHINE */ |
|
class AgpsStateMachine { |
|
protected: |
|
/* AGPS Manager instance, from where this state machine is created */ |
|
AgpsManager* mAgpsManager; |
|
|
|
/* List of all subscribers for this State Machine. |
|
* Once a subscriber is notified for ATL open/close status, |
|
* it is deleted */ |
|
std::list<AgpsSubscriber*> mSubscriberList; |
|
|
|
/* Current subscriber, whose request this State Machine is |
|
* currently processing */ |
|
AgpsSubscriber* mCurrentSubscriber; |
|
|
|
/* Current state for this state machine */ |
|
AgpsState mState; |
|
|
|
private: |
|
/* AGPS Type for this state machine |
|
LOC_AGPS_TYPE_ANY 0 |
|
LOC_AGPS_TYPE_SUPL 1 |
|
LOC_AGPS_TYPE_WWAN_ANY 3 |
|
LOC_AGPS_TYPE_SUPL_ES 5 */ |
|
AGpsExtType mAgpsType; |
|
|
|
/* APN and IP Type info for AGPS Call */ |
|
char* mAPN; |
|
unsigned int mAPNLen; |
|
AGpsBearerType mBearer; |
|
|
|
public: |
|
/* CONSTRUCTOR */ |
|
AgpsStateMachine(AgpsManager* agpsManager, AGpsExtType agpsType): |
|
mAgpsManager(agpsManager), mSubscriberList(), |
|
mCurrentSubscriber(NULL), mState(AGPS_STATE_RELEASED), |
|
mAgpsType(agpsType), mAPN(NULL), mAPNLen(0), |
|
mBearer(AGPS_APN_BEARER_INVALID) {}; |
|
|
|
virtual ~AgpsStateMachine() { if(NULL != mAPN) delete[] mAPN; }; |
|
|
|
/* Getter/Setter methods */ |
|
void setAPN(char* apn, unsigned int len); |
|
inline char* getAPN() const { return (char*)mAPN; } |
|
inline void setBearer(AGpsBearerType bearer) { mBearer = bearer; } |
|
inline AGpsBearerType getBearer() const { return mBearer; } |
|
inline AGpsExtType getType() const { return mAgpsType; } |
|
inline void setCurrentSubscriber(AgpsSubscriber* subscriber) |
|
{ mCurrentSubscriber = subscriber; } |
|
|
|
/* Fetch subscriber with specified handle */ |
|
AgpsSubscriber* getSubscriber(int connHandle); |
|
|
|
/* Fetch first active or inactive subscriber in list |
|
* isInactive = true : fetch first inactive subscriber |
|
* isInactive = false : fetch first active subscriber */ |
|
AgpsSubscriber* getFirstSubscriber(bool isInactive); |
|
|
|
/* Process LOC AGPS Event being passed in |
|
* onRsrcEvent */ |
|
virtual void processAgpsEvent(AgpsEvent event); |
|
|
|
/* Drop all subscribers, in case of Modem SSR */ |
|
void dropAllSubscribers(); |
|
|
|
protected: |
|
/* Remove the specified subscriber from list if present. |
|
* Also delete the subscriber instance. */ |
|
void deleteSubscriber(AgpsSubscriber* subscriber); |
|
|
|
private: |
|
/* Send call setup request to framework |
|
* sendRsrcRequest(LOC_GPS_REQUEST_AGPS_DATA_CONN) |
|
* sendRsrcRequest(LOC_GPS_RELEASE_AGPS_DATA_CONN) */ |
|
virtual int requestOrReleaseDataConn(bool request); |
|
|
|
/* Individual event processing methods */ |
|
void processAgpsEventSubscribe(); |
|
void processAgpsEventUnsubscribe(); |
|
void processAgpsEventGranted(); |
|
void processAgpsEventReleased(); |
|
void processAgpsEventDenied(); |
|
|
|
/* Clone the passed in subscriber and add to the subscriber list |
|
* if not already present */ |
|
void addSubscriber(AgpsSubscriber* subscriber); |
|
|
|
/* Notify subscribers about AGPS events */ |
|
void notifyAllSubscribers( |
|
AgpsEvent event, bool deleteSubscriberPostNotify, |
|
AgpsNotificationType notificationType); |
|
virtual void notifyEventToSubscriber( |
|
AgpsEvent event, AgpsSubscriber* subscriber, |
|
bool deleteSubscriberPostNotify); |
|
|
|
/* Do we have any subscribers in active state */ |
|
bool anyActiveSubscribers(); |
|
|
|
/* Transition state */ |
|
void transitionState(AgpsState newState); |
|
}; |
|
|
|
/* DS STATE MACHINE */ |
|
class DSStateMachine : public AgpsStateMachine { |
|
|
|
private: |
|
static const int MAX_START_DATA_CALL_RETRIES; |
|
static const int DATA_CALL_RETRY_DELAY_MSEC; |
|
|
|
int mRetries; |
|
|
|
public: |
|
/* CONSTRUCTOR */ |
|
DSStateMachine(AgpsManager* agpsManager): |
|
AgpsStateMachine(agpsManager, LOC_AGPS_TYPE_SUPL_ES), mRetries(0) {} |
|
|
|
/* Overridden method |
|
* DS SM needs to handle one event differently */ |
|
void processAgpsEvent(AgpsEvent event); |
|
|
|
/* Retry callback, used in case call failure */ |
|
void retryCallback(); |
|
|
|
private: |
|
/* Overridden method, different functionality for DS SM |
|
* Send call setup request to framework |
|
* sendRsrcRequest(LOC_GPS_REQUEST_AGPS_DATA_CONN) |
|
* sendRsrcRequest(LOC_GPS_RELEASE_AGPS_DATA_CONN) */ |
|
int requestOrReleaseDataConn(bool request); |
|
|
|
/* Overridden method, different functionality for DS SM */ |
|
void notifyEventToSubscriber( |
|
AgpsEvent event, AgpsSubscriber* subscriber, |
|
bool deleteSubscriberPostNotify); |
|
}; |
|
|
|
/* LOC AGPS MANAGER */ |
|
class AgpsManager { |
|
|
|
friend class AgpsStateMachine; |
|
friend class DSStateMachine; |
|
|
|
public: |
|
/* CONSTRUCTOR */ |
|
AgpsManager(): |
|
mFrameworkStatusV4Cb(NULL), |
|
mAtlOpenStatusCb(), mAtlCloseStatusCb(), |
|
mDSClientInitFn(), mDSClientOpenAndStartDataCallFn(), |
|
mDSClientStopDataCallFn(), mDSClientCloseDataCallFn(), mDSClientReleaseFn(), |
|
mSendMsgToAdapterQueueFn(), |
|
mAgnssNif(NULL), mInternetNif(NULL), mDsNif(NULL) {} |
|
|
|
/* Register callbacks */ |
|
void registerCallbacks( |
|
AgpsFrameworkInterface::AgnssStatusIpV4Cb |
|
frameworkStatusV4Cb, |
|
|
|
AgpsAtlOpenStatusCb atlOpenStatusCb, |
|
AgpsAtlCloseStatusCb atlCloseStatusCb, |
|
|
|
AgpsDSClientInitFn dsClientInitFn, |
|
AgpsDSClientOpenAndStartDataCallFn dsClientOpenAndStartDataCallFn, |
|
AgpsDSClientStopDataCallFn dsClientStopDataCallFn, |
|
AgpsDSClientCloseDataCallFn dsClientCloseDataCallFn, |
|
AgpsDSClientReleaseFn dsClientReleaseFn, |
|
|
|
SendMsgToAdapterMsgQueueFn sendMsgToAdapterQueueFn ){ |
|
|
|
mFrameworkStatusV4Cb = frameworkStatusV4Cb; |
|
|
|
mAtlOpenStatusCb = atlOpenStatusCb; |
|
mAtlCloseStatusCb = atlCloseStatusCb; |
|
|
|
mDSClientInitFn = dsClientInitFn; |
|
mDSClientOpenAndStartDataCallFn = dsClientOpenAndStartDataCallFn; |
|
mDSClientStopDataCallFn = dsClientStopDataCallFn; |
|
mDSClientCloseDataCallFn = dsClientCloseDataCallFn; |
|
mDSClientReleaseFn = dsClientReleaseFn; |
|
|
|
mSendMsgToAdapterQueueFn = sendMsgToAdapterQueueFn; |
|
} |
|
|
|
/* Create all AGPS state machines */ |
|
void createAgpsStateMachines(); |
|
|
|
/* Process incoming ATL requests */ |
|
void requestATL(int connHandle, AGpsExtType agpsType); |
|
void releaseATL(int connHandle); |
|
|
|
/* Process incoming DS Client data call events */ |
|
void reportDataCallOpened(); |
|
void reportDataCallClosed(); |
|
|
|
/* Process incoming framework data call events */ |
|
void reportAtlOpenSuccess( |
|
AGpsExtType agpsType, char* apnName, int apnLen, |
|
LocApnIpType ipType); |
|
void reportAtlOpenFailed(AGpsExtType agpsType); |
|
void reportAtlClosed(AGpsExtType agpsType); |
|
|
|
/* Handle Modem SSR */ |
|
void handleModemSSR(); |
|
|
|
protected: |
|
AgpsFrameworkInterface::AgnssStatusIpV4Cb mFrameworkStatusV4Cb; |
|
|
|
AgpsAtlOpenStatusCb mAtlOpenStatusCb; |
|
AgpsAtlCloseStatusCb mAtlCloseStatusCb; |
|
|
|
AgpsDSClientInitFn mDSClientInitFn; |
|
AgpsDSClientOpenAndStartDataCallFn mDSClientOpenAndStartDataCallFn; |
|
AgpsDSClientStopDataCallFn mDSClientStopDataCallFn; |
|
AgpsDSClientCloseDataCallFn mDSClientCloseDataCallFn; |
|
AgpsDSClientReleaseFn mDSClientReleaseFn; |
|
|
|
SendMsgToAdapterMsgQueueFn mSendMsgToAdapterQueueFn; |
|
|
|
AgpsStateMachine* mAgnssNif; |
|
AgpsStateMachine* mInternetNif; |
|
AgpsStateMachine* mDsNif; |
|
|
|
private: |
|
/* Fetch state machine for handling request ATL call */ |
|
AgpsStateMachine* getAgpsStateMachine(AGpsExtType agpsType); |
|
}; |
|
|
|
/* Request SUPL/INTERNET/SUPL_ES ATL |
|
* This LocMsg is defined in this header since it has to be used from more |
|
* than one place, other Agps LocMsg are restricted to GnssAdapter and |
|
* declared inline */ |
|
struct AgpsMsgRequestATL: public LocMsg { |
|
|
|
AgpsManager* mAgpsManager; |
|
int mConnHandle; |
|
AGpsExtType mAgpsType; |
|
|
|
inline AgpsMsgRequestATL(AgpsManager* agpsManager, int connHandle, |
|
AGpsExtType agpsType) : |
|
LocMsg(), mAgpsManager(agpsManager), mConnHandle(connHandle), mAgpsType( |
|
agpsType) { |
|
|
|
LOC_LOGV("AgpsMsgRequestATL"); |
|
} |
|
|
|
inline virtual void proc() const { |
|
|
|
LOC_LOGV("AgpsMsgRequestATL::proc()"); |
|
mAgpsManager->requestATL(mConnHandle, mAgpsType); |
|
} |
|
}; |
|
|
|
namespace AgpsUtils { |
|
|
|
AGpsBearerType ipTypeToBearerType(LocApnIpType ipType); |
|
LocApnIpType bearerTypeToIpType(AGpsBearerType bearerType); |
|
|
|
} |
|
|
|
#endif /* AGPS_H */
|
|
|