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.
450 lines
15 KiB
450 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 */
|