/* 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 */