summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSaurabh Srivastava <ssrivast@codeaurora.org>2017-02-03 00:46:48 +0530
committerGerrit - the friendly Code Review server <code-review@localhost>2017-02-28 16:59:38 -0800
commit5fecc1979b38724fb54d824ddadc61ba35475743 (patch)
treed9273f6964b8ebbfa0d34358302959f2c98e72d6
parent52b413eb442e184a22d508f98af5e7f30e6952a5 (diff)
downloadgps-5fecc1979b38724fb54d824ddadc61ba35475743.tar.gz
Adding ATL call flow to new Loc API interface
Re-designed the ATL call flow, to fit along with updated Location API. Change-Id: If22e672d1c233c55b6b52107be7169b3036d9a3e CRs-fixed: 1112712
-rw-r--r--android/AGnss.cpp65
-rw-r--r--android/AGnss.h22
-rw-r--r--gnss/Agps.cpp963
-rw-r--r--gnss/Agps.h446
-rw-r--r--gnss/Android.mk3
-rw-r--r--gnss/GnssAdapter.cpp335
-rw-r--r--gnss/GnssAdapter.h20
-rw-r--r--gnss/location_gnss.cpp37
-rw-r--r--location/location_interface.h4
9 files changed, 1879 insertions, 16 deletions
diff --git a/android/AGnss.cpp b/android/AGnss.cpp
index 3b40e60..c497ed4 100644
--- a/android/AGnss.cpp
+++ b/android/AGnss.cpp
@@ -23,6 +23,7 @@
#include <log_util.h>
#include "Gnss.h"
#include "AGnss.h"
+#include <gps_extended_c.h>
namespace android {
namespace hardware {
@@ -30,9 +31,73 @@ namespace gnss {
namespace V1_0 {
namespace implementation {
+sp<IAGnssCallback> AGnss::sAGnssCbIface = nullptr;
+
AGnss::AGnss(Gnss* gnss) : mGnss(gnss) {
}
+void AGnss::agnssStatusIpV4Cb(IAGnssCallback::AGnssStatusIpV4 status){
+
+ sAGnssCbIface->agnssStatusIpV4Cb(status);
+}
+
+Return<void> AGnss::setCallback(const sp<IAGnssCallback>& callback) {
+
+ if(mGnss == nullptr || mGnss->getGnssInterface() == nullptr){
+ LOC_LOGE("Null GNSS interface");
+ return Void();
+ }
+
+ // Save the interface
+ sAGnssCbIface = callback;
+
+ mGnss->getGnssInterface()->agpsInit((void*)agnssStatusIpV4Cb);
+ return Void();
+}
+
+Return<bool> AGnss::dataConnClosed() {
+
+ if(mGnss == nullptr || mGnss->getGnssInterface() == nullptr){
+ LOC_LOGE("Null GNSS interface");
+ return false;
+ }
+
+ mGnss->getGnssInterface()->agpsDataConnClosed(LOC_AGPS_TYPE_SUPL);
+ return true;
+}
+
+Return<bool> AGnss::dataConnFailed() {
+
+ if(mGnss == nullptr || mGnss->getGnssInterface() == nullptr){
+ LOC_LOGE("Null GNSS interface");
+ return false;
+ }
+
+ mGnss->getGnssInterface()->agpsDataConnFailed(LOC_AGPS_TYPE_SUPL);
+ return true;
+}
+
+Return<bool> AGnss::dataConnOpen(const hidl_string& apn,
+ IAGnss::ApnIpType apnIpType) {
+
+ if(mGnss == nullptr || mGnss->getGnssInterface() == nullptr){
+ LOC_LOGE("Null GNSS interface");
+ return false;
+ }
+
+ /* Validate */
+ if(apn.empty()){
+ LOC_LOGE("Invalid APN");
+ return false;
+ }
+
+ LOC_LOGD("dataConnOpen APN name = [%s]", apn.c_str());
+
+ mGnss->getGnssInterface()->agpsDataConnOpen(
+ LOC_AGPS_TYPE_SUPL, apn.c_str(), apn.size(), (int)apnIpType);
+ return true;
+}
+
Return<bool> AGnss::setServer(IAGnssCallback::AGnssType type,
const hidl_string& hostname,
int32_t port) {
diff --git a/android/AGnss.h b/android/AGnss.h
index 54775c1..f4216b0 100644
--- a/android/AGnss.h
+++ b/android/AGnss.h
@@ -40,35 +40,31 @@ using ::android::sp;
struct Gnss;
struct AGnss : public IAGnss {
+
AGnss(Gnss* gnss);
~AGnss() = default;
/*
* Methods from ::android::hardware::gnss::V1_0::IAGnss interface follow.
* These declarations were generated from IAGnss.hal.
*/
- inline Return<void> setCallback(const sp<IAGnssCallback>& /*callback*/) override {
- return Void();
- }
+ Return<void> setCallback(const sp<IAGnssCallback>& callback) override;
- inline Return<bool> dataConnClosed() override {
- return false;
- }
+ Return<bool> dataConnClosed() override;
- inline Return<bool> dataConnFailed() override {
- return false;
- }
+ Return<bool> dataConnFailed() override;
- inline Return<bool> dataConnOpen(const hidl_string& /*apn*/,
- IAGnss::ApnIpType /*apnIpType*/) override {
- return false;
- }
+ Return<bool> dataConnOpen(const hidl_string& apn,
+ IAGnss::ApnIpType apnIpType) override;
Return<bool> setServer(IAGnssCallback::AGnssType type,
const hidl_string& hostname, int32_t port) override;
+ /* Data call setup callback passed down to GNSS HAL implementation */
+ static void agnssStatusIpV4Cb(IAGnssCallback::AGnssStatusIpV4 status);
private:
Gnss* mGnss = nullptr;
+ static sp<IAGnssCallback> sAGnssCbIface;
};
} // namespace implementation
diff --git a/gnss/Agps.cpp b/gnss/Agps.cpp
new file mode 100644
index 0000000..aacd9da
--- /dev/null
+++ b/gnss/Agps.cpp
@@ -0,0 +1,963 @@
+/* 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.
+ *
+ */
+
+#define LOG_TAG "LocSvc_Agps"
+
+#include <Agps.h>
+#include <platform_lib_includes.h>
+#include <ContextBase.h>
+#include <loc_timer.h>
+
+/* --------------------------------------------------------------------
+ * AGPS State Machine Methods
+ * -------------------------------------------------------------------*/
+void AgpsStateMachine::processAgpsEvent(AgpsEvent event){
+
+ LOC_LOGD("processAgpsEvent(): SM %p, Event %d, State %d",
+ this, event, mState);
+
+ switch (event){
+
+ case AGPS_EVENT_SUBSCRIBE:
+ processAgpsEventSubscribe();
+ break;
+
+ case AGPS_EVENT_UNSUBSCRIBE:
+ processAgpsEventUnsubscribe();
+ break;
+
+ case AGPS_EVENT_GRANTED:
+ processAgpsEventGranted();
+ break;
+
+ case AGPS_EVENT_RELEASED:
+ processAgpsEventReleased();
+ break;
+
+ case AGPS_EVENT_DENIED:
+ processAgpsEventDenied();
+ break;
+
+ default:
+ LOC_LOGE("Invalid Loc Agps Event");
+ }
+}
+
+void AgpsStateMachine::processAgpsEventSubscribe(){
+
+ switch (mState){
+
+ case AGPS_STATE_RELEASED:
+ /* Add subscriber to list
+ * No notifications until we get RSRC_GRANTED */
+ addSubscriber(mCurrentSubscriber);
+
+ /* Send data request
+ * The if condition below is added so that if the data call setup
+ * fails for DS State Machine, we want to retry in released state.
+ * for Agps State Machine, sendRsrcRequest() will always return
+ * success. */
+ if(requestOrReleaseDataConn(true) == 0){
+ // If data request successful, move to pending state
+ transitionState(AGPS_STATE_PENDING);
+ }
+ break;
+
+ case AGPS_STATE_PENDING:
+ /* Already requested for data connection,
+ * do nothing until we get RSRC_GRANTED event;
+ * Just add this subscriber to the list, for notifications */
+ addSubscriber(mCurrentSubscriber);
+ break;
+
+ case AGPS_STATE_ACQUIRED:
+ /* We already have the data connection setup,
+ * Notify current subscriber with GRANTED event,
+ * And add it to the subscriber list for further notifications. */
+ notifyEventToSubscriber(AGPS_EVENT_GRANTED, mCurrentSubscriber, false);
+ addSubscriber(mCurrentSubscriber);
+ break;
+
+ case AGPS_STATE_RELEASING:
+ addSubscriber(mCurrentSubscriber);
+ break;
+
+ default:
+ LOC_LOGE("Invalid state: %d", mState);
+ }
+}
+
+void AgpsStateMachine::processAgpsEventUnsubscribe(){
+
+ switch (mState){
+
+ case AGPS_STATE_RELEASED:
+ notifyEventToSubscriber(
+ AGPS_EVENT_UNSUBSCRIBE, mCurrentSubscriber, false);
+ break;
+
+ case AGPS_STATE_PENDING:
+ case AGPS_STATE_ACQUIRED:
+ /* If the subscriber wishes to wait for connection close,
+ * before being removed from list, move to inactive state
+ * and notify */
+ if(mCurrentSubscriber->mWaitForCloseComplete){
+ mCurrentSubscriber->mIsInactive = true;
+ notifyEventToSubscriber(
+ AGPS_EVENT_UNSUBSCRIBE, mCurrentSubscriber, false);
+ }
+ else{
+ /* Notify only current subscriber and then delete it from
+ * subscriberList */
+ notifyEventToSubscriber(
+ AGPS_EVENT_UNSUBSCRIBE, mCurrentSubscriber, true);
+ }
+
+ /* If no subscribers in list, release data connection */
+ if(mSubscriberList.empty()){
+ transitionState(AGPS_STATE_RELEASED);
+ requestOrReleaseDataConn(false);
+ }
+ /* Some subscribers in list, but all inactive;
+ * Release data connection */
+ else if(!anyActiveSubscribers()){
+ transitionState(AGPS_STATE_RELEASING);
+ requestOrReleaseDataConn(false);
+ }
+ break;
+
+ case AGPS_STATE_RELEASING:
+ /* If the subscriber wishes to wait for connection close,
+ * before being removed from list, move to inactive state
+ * and notify */
+ if(mCurrentSubscriber->mWaitForCloseComplete){
+ mCurrentSubscriber->mIsInactive = true;
+ notifyEventToSubscriber(
+ AGPS_EVENT_UNSUBSCRIBE, mCurrentSubscriber, false);
+ }
+ else{
+ /* Notify only current subscriber and then delete it from
+ * subscriberList */
+ notifyEventToSubscriber(
+ AGPS_EVENT_UNSUBSCRIBE, mCurrentSubscriber, true);
+ }
+
+ /* If no subscribers in list, just move the state.
+ * Request for releasing data connection should already have been
+ * sent */
+ if(mSubscriberList.empty()){
+ transitionState(AGPS_STATE_RELEASED);
+ }
+ break;
+
+ default:
+ LOC_LOGE("Invalid state: %d", mState);
+ }
+}
+
+void AgpsStateMachine::processAgpsEventGranted(){
+
+ switch (mState){
+
+ case AGPS_STATE_RELEASED:
+ case AGPS_STATE_ACQUIRED:
+ case AGPS_STATE_RELEASING:
+ LOC_LOGE("Unexpected event GRANTED in state %d", mState);
+ break;
+
+ case AGPS_STATE_PENDING:
+ // Move to acquired state
+ transitionState(AGPS_STATE_ACQUIRED);
+ notifyAllSubscribers(
+ AGPS_EVENT_GRANTED, false,
+ AGPS_NOTIFICATION_TYPE_FOR_ACTIVE_SUBSCRIBERS);
+ break;
+
+ default:
+ LOC_LOGE("Invalid state: %d", mState);
+ }
+}
+
+void AgpsStateMachine::processAgpsEventReleased(){
+
+ switch (mState){
+
+ case AGPS_STATE_RELEASED:
+ LOC_LOGE("Unexpected event RELEASED in state %d", mState);
+ break;
+
+ case AGPS_STATE_ACQUIRED:
+ /* Force release received */
+ LOC_LOGW("Force RELEASED event in ACQUIRED state");
+ transitionState(AGPS_STATE_RELEASED);
+ notifyAllSubscribers(
+ AGPS_EVENT_RELEASED, true,
+ AGPS_NOTIFICATION_TYPE_FOR_ALL_SUBSCRIBERS);
+ break;
+
+ case AGPS_STATE_RELEASING:
+ /* Notify all inactive subscribers about the event */
+ notifyAllSubscribers(
+ AGPS_EVENT_RELEASED, true,
+ AGPS_NOTIFICATION_TYPE_FOR_INACTIVE_SUBSCRIBERS);
+
+ /* If we have active subscribers now, they must be waiting for
+ * data conn setup */
+ if(anyActiveSubscribers()){
+ transitionState(AGPS_STATE_PENDING);
+ requestOrReleaseDataConn(true);
+ }
+ /* No active subscribers, move to released state */
+ else{
+ transitionState(AGPS_STATE_RELEASED);
+ }
+ break;
+
+ case AGPS_STATE_PENDING:
+ /* NOOP */
+ break;
+
+ default:
+ LOC_LOGE("Invalid state: %d", mState);
+ }
+}
+
+void AgpsStateMachine::processAgpsEventDenied(){
+
+ switch (mState){
+
+ case AGPS_STATE_RELEASED:
+ LOC_LOGE("Unexpected event DENIED in state %d", mState);
+ break;
+
+ case AGPS_STATE_ACQUIRED:
+ /* NOOP */
+ break;
+
+ case AGPS_STATE_RELEASING:
+ /* Notify all inactive subscribers about the event */
+ notifyAllSubscribers(
+ AGPS_EVENT_RELEASED, true,
+ AGPS_NOTIFICATION_TYPE_FOR_INACTIVE_SUBSCRIBERS);
+
+ /* If we have active subscribers now, they must be waiting for
+ * data conn setup */
+ if(anyActiveSubscribers()){
+ transitionState(AGPS_STATE_PENDING);
+ requestOrReleaseDataConn(true);
+ }
+ /* No active subscribers, move to released state */
+ else{
+ transitionState(AGPS_STATE_RELEASED);
+ }
+ break;
+
+ case AGPS_STATE_PENDING:
+ transitionState(AGPS_STATE_RELEASED);
+ notifyAllSubscribers(
+ AGPS_EVENT_DENIED, true,
+ AGPS_NOTIFICATION_TYPE_FOR_ALL_SUBSCRIBERS);
+ break;
+
+ default:
+ LOC_LOGE("Invalid state: %d", mState);
+ }
+}
+
+/* Request or Release data connection
+ * bool request :
+ * true = Request data connection
+ * false = Release data connection */
+int AgpsStateMachine::requestOrReleaseDataConn(bool request){
+
+ AgpsFrameworkInterface::AGnssStatusIpV4 nifRequest;
+ memset(&nifRequest, 0, sizeof(nifRequest));
+
+ nifRequest.type = (AgpsFrameworkInterface::AGnssType)mAgpsType;
+
+ if(request){
+ LOC_LOGD("AGPS Data Conn Request");
+ nifRequest.status = (AgpsFrameworkInterface::AGnssStatusValue)
+ LOC_GPS_REQUEST_AGPS_DATA_CONN;
+ }
+ else{
+ LOC_LOGD("AGPS Data Conn Release");
+ nifRequest.status = (AgpsFrameworkInterface::AGnssStatusValue)
+ LOC_GPS_RELEASE_AGPS_DATA_CONN;
+ }
+
+ mAgpsManager->mFrameworkStatusV4Cb(nifRequest);
+ return 0;
+}
+
+void AgpsStateMachine::notifyAllSubscribers(
+ AgpsEvent event, bool deleteSubscriberPostNotify,
+ AgpsNotificationType notificationType){
+
+ LOC_LOGD("notifyAllSubscribers(): "
+ "SM %p, Event %d Delete %d Notification Type %d",
+ this, event, deleteSubscriberPostNotify, notificationType);
+
+ std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin();
+ while ( it != mSubscriberList.end() ){
+
+ AgpsSubscriber* subscriber = *it;
+
+ if(notificationType == AGPS_NOTIFICATION_TYPE_FOR_ALL_SUBSCRIBERS ||
+ (notificationType == AGPS_NOTIFICATION_TYPE_FOR_INACTIVE_SUBSCRIBERS &&
+ subscriber->mIsInactive) ||
+ (notificationType == AGPS_NOTIFICATION_TYPE_FOR_ACTIVE_SUBSCRIBERS &&
+ !subscriber->mIsInactive)) {
+
+ /* Deleting via this call would require another traversal
+ * through subscriber list, inefficient; hence pass in false*/
+ notifyEventToSubscriber(event, subscriber, false);
+
+ if(deleteSubscriberPostNotify){
+ it = mSubscriberList.erase(it);
+ delete subscriber;
+ } else{
+ it++;
+ }
+ } else{
+ it++;
+ }
+ }
+}
+
+void AgpsStateMachine::notifyEventToSubscriber(
+ AgpsEvent event, AgpsSubscriber* subscriberToNotify,
+ bool deleteSubscriberPostNotify) {
+
+ LOC_LOGD("notifyEventToSubscriber(): "
+ "SM %p, Event %d Subscriber %p Delete %d",
+ this, event, subscriberToNotify, deleteSubscriberPostNotify);
+
+ switch (event){
+
+ case AGPS_EVENT_GRANTED:
+ mAgpsManager->mAtlOpenStatusCb(
+ subscriberToNotify->mConnHandle, 1, getAPN(),
+ getBearer(), mAgpsType);
+ break;
+
+ case AGPS_EVENT_DENIED:
+ mAgpsManager->mAtlOpenStatusCb(
+ subscriberToNotify->mConnHandle, 0, getAPN(),
+ getBearer(), mAgpsType);
+ break;
+
+ case AGPS_EVENT_UNSUBSCRIBE:
+ case AGPS_EVENT_RELEASED:
+ mAgpsManager->mAtlCloseStatusCb(subscriberToNotify->mConnHandle, 1);
+ break;
+
+ default:
+ LOC_LOGE("Invalid event %d", event);
+ }
+
+ /* Search this subscriber in list and delete */
+ if (deleteSubscriberPostNotify) {
+ deleteSubscriber(subscriberToNotify);
+ }
+}
+
+void AgpsStateMachine::transitionState(AgpsState newState){
+
+ LOC_LOGD("transitionState(): SM %p, old %d, new %d",
+ this, mState, newState);
+
+ mState = newState;
+
+ // notify state transitions to all subscribers ?
+}
+
+void AgpsStateMachine::addSubscriber(AgpsSubscriber* subscriberToAdd){
+
+ LOC_LOGD("addSubscriber(): SM %p, Subscriber %p",
+ this, subscriberToAdd);
+
+ // Check if subscriber is already present in the current list
+ // If not, then add
+ std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin();
+ for(; it != mSubscriberList.end(); it++){
+ AgpsSubscriber* subscriber = *it;
+ if(subscriber->equals(subscriberToAdd)){
+ LOC_LOGE("Subscriber already in list");
+ return;
+ }
+ }
+
+ AgpsSubscriber* cloned = subscriberToAdd->clone();
+ LOC_LOGD("addSubscriber(): cloned subscriber: %p", cloned);
+ mSubscriberList.push_back(cloned);
+}
+
+void AgpsStateMachine::deleteSubscriber(AgpsSubscriber* subscriberToDelete){
+
+ LOC_LOGD("deleteSubscriber(): SM %p, Subscriber %p",
+ this, subscriberToDelete);
+
+ std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin();
+ while ( it != mSubscriberList.end() ) {
+
+ AgpsSubscriber* subscriber = *it;
+ if(subscriber && subscriber->equals(subscriberToDelete)){
+
+ it = mSubscriberList.erase(it);
+ delete subscriber;
+ }else{
+ it++;
+ }
+ }
+}
+
+bool AgpsStateMachine::anyActiveSubscribers(){
+
+ std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin();
+ for(; it != mSubscriberList.end(); it++){
+ AgpsSubscriber* subscriber = *it;
+ if(!subscriber->mIsInactive){
+ return true;
+ }
+ }
+ return false;
+}
+
+void AgpsStateMachine::setAPN(char* apn, unsigned int len){
+
+ if (NULL != mAPN) {
+ delete mAPN;
+ }
+
+ if(apn == NULL || len <= 0){
+ LOC_LOGD("Invalid apn len (%d) or null apn", len);
+ mAPN = NULL;
+ mAPNLen = 0;
+ }
+
+ if (NULL != apn) {
+ mAPN = new char[len+1];
+ memcpy(mAPN, apn, len);
+ mAPN[len] = '\0';
+ mAPNLen = len;
+ }
+}
+
+AgpsSubscriber* AgpsStateMachine::getSubscriber(int connHandle){
+
+ /* Go over the subscriber list */
+ std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin();
+ for(; it != mSubscriberList.end(); it++){
+ AgpsSubscriber* subscriber = *it;
+ if(subscriber->mConnHandle == connHandle){
+ return subscriber;
+ }
+ }
+
+ /* Not found, return NULL */
+ return NULL;
+}
+
+AgpsSubscriber* AgpsStateMachine::getFirstSubscriber(bool isInactive){
+
+ /* Go over the subscriber list */
+ std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin();
+ for(; it != mSubscriberList.end(); it++){
+ AgpsSubscriber* subscriber = *it;
+ if(subscriber->mIsInactive == isInactive){
+ return subscriber;
+ }
+ }
+
+ /* Not found, return NULL */
+ return NULL;
+}
+
+void AgpsStateMachine::dropAllSubscribers(){
+
+ LOC_LOGD("dropAllSubscribers(): SM %p", this);
+
+ /* Go over the subscriber list */
+ std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin();
+ while ( it != mSubscriberList.end() ){
+ AgpsSubscriber* subscriber = *it;
+ it = mSubscriberList.erase(it);
+ delete subscriber;
+ }
+}
+
+/* --------------------------------------------------------------------
+ * DS State Machine Methods
+ * -------------------------------------------------------------------*/
+const int DSStateMachine::MAX_START_DATA_CALL_RETRIES = 4;
+const int DSStateMachine::DATA_CALL_RETRY_DELAY_MSEC = 500;
+
+/* Overridden method
+ * DS SM needs to handle one scenario differently */
+void DSStateMachine::processAgpsEvent(AgpsEvent event){
+
+ LOC_LOGD("DSStateMachine::processAgpsEvent() %d", event);
+
+ /* DS Client call setup APIs don't return failure/closure separately.
+ * Hence we receive RELEASED event in both cases.
+ * If we are in pending, we should consider RELEASED as DENIED */
+ if(event == AGPS_EVENT_RELEASED && mState == AGPS_STATE_PENDING){
+
+ LOC_LOGD("Translating RELEASED to DENIED event");
+ event = AGPS_EVENT_DENIED;
+ }
+
+ /* Redirect process to base class */
+ AgpsStateMachine::processAgpsEvent(event);
+}
+
+/* Timer Callback
+ * For the retry timer started in case of DS Client call setup failure */
+void delay_callback(void *callbackData, int result)
+{
+ LOC_LOGD("delay_callback(): cbData %p", callbackData);
+
+ (void)result;
+
+ if(callbackData == NULL) {
+ LOC_LOGE("delay_callback(): NULL argument received !");
+ return;
+ }
+ DSStateMachine* dsStateMachine = (DSStateMachine *)callbackData;
+ dsStateMachine->retryCallback();
+}
+
+/* Invoked from Timer Callback
+ * For the retry timer started in case of DS Client call setup failure */
+void DSStateMachine :: retryCallback()
+{
+ LOC_LOGD("DSStateMachine::retryCallback()");
+
+ /* Request SUPL ES
+ * There must be at least one active subscriber in list */
+ AgpsSubscriber* subscriber = getFirstSubscriber(false);
+ if(subscriber == NULL) {
+
+ LOC_LOGE("No active subscriber for DS Client call setup");
+ return;
+ }
+
+ /* Send message to retry */
+ mAgpsManager->mSendMsgToAdapterQueueFn(
+ new AgpsMsgRequestATL(
+ mAgpsManager, subscriber->mConnHandle,
+ LOC_AGPS_TYPE_SUPL_ES));
+}
+
+/* Overridden method
+ * Request or Release data connection
+ * bool request :
+ * true = Request data connection
+ * false = Release data connection */
+int DSStateMachine::requestOrReleaseDataConn(bool request){
+
+ LOC_LOGD("DSStateMachine::requestOrReleaseDataConn(): "
+ "request %d", request);
+
+ /* Release data connection required ? */
+ if(!request && mAgpsManager->mDSClientStopDataCallFn){
+
+ mAgpsManager->mDSClientStopDataCallFn();
+ LOC_LOGD("DS Client release data call request sent !");
+ return 0;
+ }
+
+ /* Setup data connection request
+ * There must be at least one active subscriber in list */
+ AgpsSubscriber* subscriber = getFirstSubscriber(false);
+ if(subscriber == NULL) {
+
+ LOC_LOGE("No active subscriber for DS Client call setup");
+ return -1;
+ }
+
+ /* DS Client Fn registered ? */
+ if(!mAgpsManager->mDSClientOpenAndStartDataCallFn){
+
+ LOC_LOGE("DS Client start fn not registered, fallback to SUPL ATL");
+ notifyEventToSubscriber(AGPS_EVENT_DENIED, subscriber, false);
+ return -1;
+ }
+
+ /* Setup the call */
+ int ret = mAgpsManager->mDSClientOpenAndStartDataCallFn();
+
+ /* Check if data call start failed */
+ switch (ret) {
+
+ case LOC_API_ADAPTER_ERR_ENGINE_BUSY:
+ LOC_LOGE("DS Client open call failed, err: %d", ret);
+ mRetries++;
+ if(mRetries > MAX_START_DATA_CALL_RETRIES) {
+
+ LOC_LOGE("DS Client call retries exhausted, "
+ "falling back to normal SUPL ATL");
+ notifyEventToSubscriber(AGPS_EVENT_DENIED, subscriber, false);
+ }
+ /* Retry DS Client call setup after some delay */
+ else if(loc_timer_start(
+ DATA_CALL_RETRY_DELAY_MSEC, delay_callback, this)) {
+ LOC_LOGE("Error: Could not start delay thread\n");
+ return -1;
+ }
+ break;
+
+ case LOC_API_ADAPTER_ERR_UNSUPPORTED:
+ LOC_LOGE("No emergency profile found. Fall back to normal SUPL ATL");
+ notifyEventToSubscriber(AGPS_EVENT_DENIED, subscriber, false);
+ break;
+
+ case LOC_API_ADAPTER_ERR_SUCCESS:
+ LOC_LOGD("Request to start data call sent");
+ break;
+
+ default:
+ LOC_LOGE("Unrecognized return value: %d", ret);
+ }
+
+ return ret;
+}
+
+void DSStateMachine::notifyEventToSubscriber(
+ AgpsEvent event, AgpsSubscriber* subscriberToNotify,
+ bool deleteSubscriberPostNotify) {
+
+ LOC_LOGD("DSStateMachine::notifyEventToSubscriber");
+
+ switch (event){
+
+ case AGPS_EVENT_GRANTED:
+ mAgpsManager->mAtlOpenStatusCb(
+ subscriberToNotify->mConnHandle, 1, NULL,
+ AGPS_APN_BEARER_INVALID, LOC_AGPS_TYPE_SUPL_ES);
+ break;
+
+ case AGPS_EVENT_DENIED:
+ /* Now try with regular SUPL
+ * We need to send request via message queue */
+ mRetries = 0;
+ mAgpsManager->mSendMsgToAdapterQueueFn(
+ new AgpsMsgRequestATL(
+ mAgpsManager, subscriberToNotify->mConnHandle,
+ LOC_AGPS_TYPE_SUPL));
+ break;
+
+ case AGPS_EVENT_UNSUBSCRIBE:
+ mAgpsManager->mAtlCloseStatusCb(subscriberToNotify->mConnHandle, 1);
+ break;
+
+ case AGPS_EVENT_RELEASED:
+ mAgpsManager->mDSClientCloseDataCallFn();
+ break;
+
+ default:
+ LOC_LOGE("Invalid event %d", event);
+ }
+
+ /* Search this subscriber in list and delete */
+ if (deleteSubscriberPostNotify) {
+ deleteSubscriber(subscriberToNotify);
+ }
+}
+
+/* --------------------------------------------------------------------
+ * Loc AGPS Manager Methods
+ * -------------------------------------------------------------------*/
+
+/* CREATE AGPS STATE MACHINES
+ * Must be invoked in Msg Handler context */
+void AgpsManager::createAgpsStateMachines() {
+
+ LOC_LOGD("AgpsManager::createAgpsStateMachines");
+
+ bool agpsCapable =
+ ((loc_core::ContextBase::mGps_conf.CAPABILITIES & LOC_GPS_CAPABILITY_MSA) ||
+ (loc_core::ContextBase::mGps_conf.CAPABILITIES & LOC_GPS_CAPABILITY_MSB));
+
+ if (NULL == mInternetNif) {
+ mInternetNif = new AgpsStateMachine(this, LOC_AGPS_TYPE_WWAN_ANY);
+ LOC_LOGD("Internet NIF: %p", mInternetNif);
+ }
+ if (agpsCapable) {
+ if (NULL == mAgnssNif) {
+ mAgnssNif = new AgpsStateMachine(this, LOC_AGPS_TYPE_SUPL);
+ LOC_LOGD("AGNSS NIF: %p", mAgnssNif);
+ }
+ if (NULL == mDsNif &&
+ loc_core::ContextBase::mGps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL){
+
+ if(!mDSClientInitFn){
+
+ LOC_LOGE("DS Client Init Fn not registered !");
+ return;
+ }
+ if(mDSClientInitFn(false) != 0){
+
+ LOC_LOGE("Failed to init data service client");
+ return;
+ }
+ mDsNif = new DSStateMachine(this);
+ LOC_LOGD("DS NIF: %p", mDsNif);
+ }
+ }
+}
+
+AgpsStateMachine* AgpsManager::getAgpsStateMachine(AGpsExtType agpsType) {
+
+ LOC_LOGD("AgpsManager::getAgpsStateMachine(): agpsType %d", agpsType);
+
+ switch (agpsType) {
+
+ case LOC_AGPS_TYPE_INVALID:
+ case LOC_AGPS_TYPE_SUPL:
+ if(mAgnssNif == NULL){
+ LOC_LOGE("NULL AGNSS NIF !");
+ }
+ return mAgnssNif;
+
+ case LOC_AGPS_TYPE_SUPL_ES:
+ if (loc_core::ContextBase::mGps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL) {
+ if (mDsNif == NULL) {
+ createAgpsStateMachines();
+ }
+ return mDsNif;
+ } else {
+ return mAgnssNif;
+ }
+
+ default:
+ return mInternetNif;
+ }
+
+ LOC_LOGE("No SM found !");
+ return NULL;
+}
+
+void AgpsManager::requestATL(int connHandle, AGpsExtType agpsType){
+
+ LOC_LOGD("AgpsManager::requestATL(): connHandle %d, agpsType %d",
+ connHandle, agpsType);
+
+ AgpsStateMachine* sm = getAgpsStateMachine(agpsType);
+
+ if(sm == NULL){
+
+ LOC_LOGE("No AGPS State Machine for agpsType: %d", agpsType);
+ mAtlOpenStatusCb(
+ connHandle, 0, NULL, AGPS_APN_BEARER_INVALID, agpsType);
+ return;
+ }
+
+ /* Invoke AGPS SM processing */
+ AgpsSubscriber subscriber(connHandle);
+ sm->setCurrentSubscriber(&subscriber);
+
+ /* If DS State Machine, wait for close complete */
+ if(agpsType == LOC_AGPS_TYPE_SUPL_ES){
+ subscriber.mWaitForCloseComplete = true;
+ }
+
+ /* Send subscriber event */
+ sm->processAgpsEvent(AGPS_EVENT_SUBSCRIBE);
+}
+
+void AgpsManager::releaseATL(int connHandle){
+
+ LOC_LOGD("AgpsManager::releaseATL(): connHandle %d", connHandle);
+
+ /* First find the subscriber with specified handle.
+ * We need to search in all state machines. */
+ AgpsStateMachine* sm = NULL;
+ AgpsSubscriber* subscriber = NULL;
+
+ if (mAgnssNif &&
+ (subscriber = mAgnssNif->getSubscriber(connHandle)) != NULL) {
+ sm = mAgnssNif;
+ }
+ else if (mInternetNif &&
+ (subscriber = mInternetNif->getSubscriber(connHandle)) != NULL) {
+ sm = mInternetNif;
+ }
+ else if (mDsNif &&
+ (subscriber = mDsNif->getSubscriber(connHandle)) != NULL) {
+ sm = mDsNif;
+ }
+
+ if(sm == NULL){
+ LOC_LOGE("Subscriber with connHandle %d not found in any SM",
+ connHandle);
+ mAtlCloseStatusCb(connHandle, 0);
+ return;
+ }
+
+ /* Now send unsubscribe event */
+ sm->setCurrentSubscriber(subscriber);
+ sm->processAgpsEvent(AGPS_EVENT_UNSUBSCRIBE);
+}
+
+void AgpsManager::reportDataCallOpened(){
+
+ LOC_LOGD("AgpsManager::reportDataCallOpened");
+
+ if (mDsNif) {
+ mDsNif->processAgpsEvent(AGPS_EVENT_GRANTED);
+ }
+}
+
+void AgpsManager::reportDataCallClosed(){
+
+ LOC_LOGD("AgpsManager::reportDataCallClosed");
+
+ if (mDsNif) {
+ mDsNif->processAgpsEvent(AGPS_EVENT_RELEASED);
+ }
+}
+
+void AgpsManager::reportAtlOpenSuccess(
+ AGpsExtType agpsType, char* apnName, int apnLen,
+ LocApnIpType ipType){
+
+ LOC_LOGD("AgpsManager::reportAtlOpenSuccess(): "
+ "AgpsType %d, APN [%s], Len %d, IPType %d",
+ agpsType, apnName, apnLen, ipType);
+
+ /* Find the state machine instance */
+ AgpsStateMachine* sm = getAgpsStateMachine(agpsType);
+
+ /* Convert LocApnIpType sent by framework to AGpsBearerType */
+ AGpsBearerType bearerType;
+ switch (ipType) {
+ case LOC_APN_IP_IPV4:
+ bearerType = AGPS_APN_BEARER_IPV4;
+ break;
+ case LOC_APN_IP_IPV6:
+ bearerType = AGPS_APN_BEARER_IPV6;
+ break;
+ case LOC_APN_IP_IPV4V6:
+ bearerType = AGPS_APN_BEARER_IPV4V6;
+ break;
+ default:
+ bearerType = AGPS_APN_BEARER_IPV4;
+ break;
+ }
+
+ /* Set bearer and apn info in state machine instance */
+ sm->setBearer(bearerType);
+ sm->setAPN(apnName, apnLen);
+
+ /* Send GRANTED event to state machine */
+ sm->processAgpsEvent(AGPS_EVENT_GRANTED);
+}
+
+void AgpsManager::reportAtlOpenFailed(AGpsExtType agpsType){
+
+ LOC_LOGD("AgpsManager::reportAtlOpenFailed(): AgpsType %d", agpsType);
+
+ /* Fetch SM and send DENIED event */
+ AgpsStateMachine* sm = getAgpsStateMachine(agpsType);
+ sm->processAgpsEvent(AGPS_EVENT_DENIED);
+}
+
+void AgpsManager::reportAtlClosed(AGpsExtType agpsType){
+
+ LOC_LOGD("AgpsManager::reportAtlClosed(): AgpsType %d", agpsType);
+
+ /* Fetch SM and send RELEASED event */
+ AgpsStateMachine* sm = getAgpsStateMachine(agpsType);
+ sm->processAgpsEvent(AGPS_EVENT_RELEASED);
+}
+
+void AgpsManager::handleModemSSR(){
+
+ LOC_LOGD("AgpsManager::handleModemSSR");
+
+ /* Drop subscribers from all state machines */
+ if (mAgnssNif){
+ mAgnssNif->dropAllSubscribers();
+ }
+ if (mInternetNif){
+ mInternetNif->dropAllSubscribers();
+ }
+ if(mDsNif){
+ mDsNif->dropAllSubscribers();
+ }
+
+ // reinitialize DS client in SSR mode
+ if(loc_core::ContextBase::mGps_conf.
+ USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL){
+
+ mDSClientStopDataCallFn();
+ mDSClientCloseDataCallFn();
+ mDSClientReleaseFn();
+
+ mDSClientInitFn(true);
+ }
+}
+
+AGpsBearerType AgpsUtils::ipTypeToBearerType(LocApnIpType ipType) {
+
+ switch (ipType) {
+
+ case LOC_APN_IP_IPV4:
+ return AGPS_APN_BEARER_IPV4;
+
+ case LOC_APN_IP_IPV6:
+ return AGPS_APN_BEARER_IPV6;
+
+ case LOC_APN_IP_IPV4V6:
+ return AGPS_APN_BEARER_IPV4V6;
+
+ default:
+ return AGPS_APN_BEARER_IPV4;
+ }
+}
+
+LocApnIpType AgpsUtils::bearerTypeToIpType(AGpsBearerType bearerType){
+
+ switch (bearerType) {
+
+ case AGPS_APN_BEARER_IPV4:
+ return LOC_APN_IP_IPV4;
+
+ case AGPS_APN_BEARER_IPV6:
+ return LOC_APN_IP_IPV6;
+
+ case AGPS_APN_BEARER_IPV4V6:
+ return LOC_APN_IP_IPV4V6;
+
+ default:
+ return LOC_APN_IP_IPV4;
+ }
+}
diff --git a/gnss/Agps.h b/gnss/Agps.h
new file mode 100644
index 0000000..1e95a42
--- /dev/null
+++ b/gnss/Agps.h
@@ -0,0 +1,446 @@
+/* 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) :
+ mConnHandle(connHandle), mWaitForCloseComplete(false),
+ mIsInactive(false) {}
+ inline virtual ~AgpsSubscriber() {}
+
+ inline virtual bool equals(const AgpsSubscriber *s) const
+ { return (mConnHandle == s->mConnHandle); }
+
+ inline virtual AgpsSubscriber* clone()
+ { return new AgpsSubscriber(mConnHandle); }
+};
+
+/* 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 */
diff --git a/gnss/Android.mk b/gnss/Android.mk
index 16d796c..1f0a549 100644
--- a/gnss/Android.mk
+++ b/gnss/Android.mk
@@ -20,7 +20,8 @@ LOCAL_SHARED_LIBRARIES := \
LOCAL_SRC_FILES += \
location_gnss.cpp \
- GnssAdapter.cpp
+ GnssAdapter.cpp \
+ Agps.cpp
LOCAL_CFLAGS += \
-fno-short-enums \
diff --git a/gnss/GnssAdapter.cpp b/gnss/GnssAdapter.cpp
index 1ddb41d..3a6ae55 100644
--- a/gnss/GnssAdapter.cpp
+++ b/gnss/GnssAdapter.cpp
@@ -39,6 +39,7 @@
#include <GnssAdapter.h>
#include <string>
#include <loc_log.h>
+#include <Agps.h>
using namespace loc_core;
@@ -55,7 +56,8 @@ GnssAdapter::GnssAdapter() :
mGnssSvIdUsedInPosAvail(false),
mControlCallbacks(),
mPowerVoteId(0),
- mNiData()
+ mNiData(),
+ mAgpsManager()
{
LOC_LOGD("%s]: Constructor %p", __func__, this);
mUlpPositionMode.mode = LOC_POSITION_MODE_INVALID;
@@ -2878,3 +2880,334 @@ GnssAdapter::generateNmeaGGA(const UlpLocation& ulpLocation,
length = nmeaPutChecksum(sentence, size);
reportNmeaEvent(sentence, length);
}
+
+/* INIT LOC AGPS MANAGER */
+void GnssAdapter::initAgpsCommand(void* statusV4Cb){
+
+ LOC_LOGI("GnssAdapter::initAgpsCommand");
+
+ /* Set ATL open/close callbacks */
+ AgpsAtlOpenStatusCb atlOpenStatusCb =
+ [this](int handle, int isSuccess, char* apn,
+ AGpsBearerType bearerType, AGpsExtType agpsType) {
+
+ mLocApi->atlOpenStatus(
+ handle, isSuccess, apn, bearerType, agpsType);
+ };
+ AgpsAtlCloseStatusCb atlCloseStatusCb =
+ [this](int handle, int isSuccess) {
+
+ mLocApi->atlCloseStatus(handle, isSuccess);
+ };
+
+ /* Register DS Client APIs */
+ AgpsDSClientInitFn dsClientInitFn =
+ [this](bool isDueToSSR) {
+
+ return mLocApi->initDataServiceClient(isDueToSSR);
+ };
+
+ AgpsDSClientOpenAndStartDataCallFn dsClientOpenAndStartDataCallFn =
+ [this] {
+
+ return mLocApi->openAndStartDataCall();
+ };
+
+ AgpsDSClientStopDataCallFn dsClientStopDataCallFn =
+ [this] {
+
+ mLocApi->stopDataCall();
+ };
+
+ AgpsDSClientCloseDataCallFn dsClientCloseDataCallFn =
+ [this] {
+
+ mLocApi->closeDataCall();
+ };
+
+ AgpsDSClientReleaseFn dsClientReleaseFn =
+ [this] {
+
+ mLocApi->releaseDataServiceClient();
+ };
+
+ /* Send Msg function */
+ SendMsgToAdapterMsgQueueFn sendMsgFn =
+ [this](LocMsg* msg) {
+
+ sendMsg(msg);
+ };
+
+ /* Message to initialize AGPS module */
+ struct AgpsMsgInit: public LocMsg {
+
+ AgpsManager* mAgpsManager;
+
+ AgpsFrameworkInterface::AgnssStatusIpV4Cb mFrameworkStatusV4Cb;
+
+ AgpsAtlOpenStatusCb mAtlOpenStatusCb;
+ AgpsAtlCloseStatusCb mAtlCloseStatusCb;
+
+ AgpsDSClientInitFn mDSClientInitFn;
+ AgpsDSClientOpenAndStartDataCallFn mDSClientOpenAndStartDataCallFn;
+ AgpsDSClientStopDataCallFn mDSClientStopDataCallFn;
+ AgpsDSClientCloseDataCallFn mDSClientCloseDataCallFn;
+ AgpsDSClientReleaseFn mDSClientReleaseFn;
+
+ SendMsgToAdapterMsgQueueFn mSendMsgFn;
+
+ inline AgpsMsgInit(AgpsManager* agpsManager,
+ AgpsFrameworkInterface::AgnssStatusIpV4Cb frameworkStatusV4Cb,
+ AgpsAtlOpenStatusCb atlOpenStatusCb,
+ AgpsAtlCloseStatusCb atlCloseStatusCb,
+ AgpsDSClientInitFn dsClientInitFn,
+ AgpsDSClientOpenAndStartDataCallFn dsClientOpenAndStartDataCallFn,
+ AgpsDSClientStopDataCallFn dsClientStopDataCallFn,
+ AgpsDSClientCloseDataCallFn dsClientCloseDataCallFn,
+ AgpsDSClientReleaseFn dsClientReleaseFn,
+ SendMsgToAdapterMsgQueueFn sendMsgFn) :
+ LocMsg(), mAgpsManager(agpsManager), mFrameworkStatusV4Cb(
+ frameworkStatusV4Cb), mAtlOpenStatusCb(atlOpenStatusCb), mAtlCloseStatusCb(
+ atlCloseStatusCb), mDSClientInitFn(dsClientInitFn), mDSClientOpenAndStartDataCallFn(
+ dsClientOpenAndStartDataCallFn), mDSClientStopDataCallFn(
+ dsClientStopDataCallFn), mDSClientCloseDataCallFn(
+ dsClientCloseDataCallFn), mDSClientReleaseFn(
+ dsClientReleaseFn), mSendMsgFn(sendMsgFn) {
+
+ LOC_LOGV("AgpsMsgInit");
+ }
+
+ inline virtual void proc() const {
+
+ LOC_LOGV("AgpsMsgInit::proc()");
+
+ mAgpsManager->registerCallbacks(mFrameworkStatusV4Cb, mAtlOpenStatusCb,
+ mAtlCloseStatusCb, mDSClientInitFn,
+ mDSClientOpenAndStartDataCallFn, mDSClientStopDataCallFn,
+ mDSClientCloseDataCallFn, mDSClientReleaseFn, mSendMsgFn);
+
+ mAgpsManager->createAgpsStateMachines();
+ }
+ };
+
+ /* Send message to initialize AGPS Manager */
+ sendMsg(new AgpsMsgInit(
+ &mAgpsManager,
+ (AgpsFrameworkInterface::AgnssStatusIpV4Cb)statusV4Cb,
+ atlOpenStatusCb, atlCloseStatusCb,
+ dsClientInitFn, dsClientOpenAndStartDataCallFn,
+ dsClientStopDataCallFn, dsClientCloseDataCallFn,
+ dsClientReleaseFn,
+ sendMsgFn));
+}
+
+/* GnssAdapter::requestATL
+ * Method triggered in QMI thread as part of handling below message:
+ * eQMI_LOC_SERVER_REQUEST_OPEN_V02
+ * Triggers the AGPS state machine to setup AGPS call for below WWAN types:
+ * eQMI_LOC_WWAN_TYPE_INTERNET_V02
+ * eQMI_LOC_WWAN_TYPE_AGNSS_V02 */
+bool GnssAdapter::requestATL(int connHandle, LocAGpsType agpsType){
+
+ LOC_LOGI("GnssAdapter::requestATL");
+
+ sendMsg( new AgpsMsgRequestATL(
+ &mAgpsManager, connHandle, (AGpsExtType)agpsType));
+
+ return true;
+}
+
+/* GnssAdapter::requestSuplES
+ * Method triggered in QMI thread as part of handling below message:
+ * eQMI_LOC_SERVER_REQUEST_OPEN_V02
+ * Triggers the AGPS state machine to setup AGPS call for below WWAN types:
+ * eQMI_LOC_WWAN_TYPE_AGNSS_EMERGENCY_V02 */
+bool GnssAdapter::requestSuplES(int connHandle){
+
+ LOC_LOGI("GnssAdapter::requestSuplES");
+
+ sendMsg( new AgpsMsgRequestATL(
+ &mAgpsManager, connHandle, LOC_AGPS_TYPE_SUPL_ES));
+
+ return true;
+}
+
+/* GnssAdapter::releaseATL
+ * Method triggered in QMI thread as part of handling below message:
+ * eQMI_LOC_SERVER_REQUEST_CLOSE_V02
+ * Triggers teardown of an existing AGPS call */
+bool GnssAdapter::releaseATL(int connHandle){
+
+ LOC_LOGI("GnssAdapter::releaseATL");
+
+ /* Release SUPL/INTERNET/SUPL_ES ATL */
+ struct AgpsMsgReleaseATL: public LocMsg {
+
+ AgpsManager* mAgpsManager;
+ int mConnHandle;
+
+ inline AgpsMsgReleaseATL(AgpsManager* agpsManager, int connHandle) :
+ LocMsg(), mAgpsManager(agpsManager), mConnHandle(connHandle) {
+
+ LOC_LOGV("AgpsMsgReleaseATL");
+ }
+
+ inline virtual void proc() const {
+
+ LOC_LOGV("AgpsMsgReleaseATL::proc()");
+ mAgpsManager->releaseATL(mConnHandle);
+ }
+ };
+
+ sendMsg( new AgpsMsgReleaseATL(&mAgpsManager, connHandle));
+
+ return true;
+}
+
+/* GnssAdapter::reportDataCallOpened
+ * DS Client data call opened successfully.
+ * Send message to AGPS Manager to handle. */
+bool GnssAdapter::reportDataCallOpened(){
+
+ LOC_LOGI("GnssAdapter::reportDataCallOpened");
+
+ struct AgpsMsgSuplEsOpened: public LocMsg {
+
+ AgpsManager* mAgpsManager;
+
+ inline AgpsMsgSuplEsOpened(AgpsManager* agpsManager) :
+ LocMsg(), mAgpsManager(agpsManager) {
+
+ LOC_LOGV("AgpsMsgSuplEsOpened");
+ }
+
+ inline virtual void proc() const {
+
+ LOC_LOGV("AgpsMsgSuplEsOpened::proc()");
+ mAgpsManager->reportDataCallOpened();
+ }
+ };
+
+ sendMsg( new AgpsMsgSuplEsOpened(&mAgpsManager));
+
+ return true;
+}
+
+/* GnssAdapter::reportDataCallClosed
+ * DS Client data call closed.
+ * Send message to AGPS Manager to handle. */
+bool GnssAdapter::reportDataCallClosed(){
+
+ LOC_LOGI("GnssAdapter::reportDataCallClosed");
+
+ struct AgpsMsgSuplEsClosed: public LocMsg {
+
+ AgpsManager* mAgpsManager;
+
+ inline AgpsMsgSuplEsClosed(AgpsManager* agpsManager) :
+ LocMsg(), mAgpsManager(agpsManager) {
+
+ LOC_LOGV("AgpsMsgSuplEsClosed");
+ }
+
+ inline virtual void proc() const {
+
+ LOC_LOGV("AgpsMsgSuplEsClosed::proc()");
+ mAgpsManager->reportDataCallClosed();
+ }
+ };
+
+ sendMsg( new AgpsMsgSuplEsClosed(&mAgpsManager));
+
+ return true;
+}
+
+void GnssAdapter::dataConnOpenCommand(
+ AGpsExtType agpsType,
+ const char* apnName, int apnLen, LocApnIpType ipType){
+
+ LOC_LOGI("GnssAdapter::frameworkDataConnOpen");
+
+ struct AgpsMsgAtlOpenSuccess: public LocMsg {
+
+ AgpsManager* mAgpsManager;
+ AGpsExtType mAgpsType;
+ char* mApnName;
+ int mApnLen;
+ LocApnIpType mIpType;
+
+ inline AgpsMsgAtlOpenSuccess(AgpsManager* agpsManager, AGpsExtType agpsType,
+ const char* apnName, int apnLen, LocApnIpType ipType) :
+ LocMsg(), mAgpsManager(agpsManager), mAgpsType(agpsType), mApnName(
+ new char[apnLen + 1]), mApnLen(apnLen), mIpType(ipType) {
+
+ LOC_LOGV("AgpsMsgAtlOpenSuccess");
+ memcpy(mApnName, apnName, apnLen);
+ mApnName[apnLen] = 0;
+ }
+
+ inline ~AgpsMsgAtlOpenSuccess() {
+ delete[] mApnName;
+ }
+
+ inline virtual void proc() const {
+
+ LOC_LOGV("AgpsMsgAtlOpenSuccess::proc()");
+ mAgpsManager->reportAtlOpenSuccess(mAgpsType, mApnName, mApnLen,
+ mIpType);
+ }
+ };
+
+ sendMsg( new AgpsMsgAtlOpenSuccess(
+ &mAgpsManager, (AGpsExtType)agpsType, apnName, apnLen, ipType));
+}
+
+void GnssAdapter::dataConnClosedCommand(AGpsExtType agpsType){
+
+ LOC_LOGI("GnssAdapter::frameworkDataConnClosed");
+
+ struct AgpsMsgAtlClosed: public LocMsg {
+
+ AgpsManager* mAgpsManager;
+ AGpsExtType mAgpsType;
+
+ inline AgpsMsgAtlClosed(AgpsManager* agpsManager, AGpsExtType agpsType) :
+ LocMsg(), mAgpsManager(agpsManager), mAgpsType(agpsType) {
+
+ LOC_LOGV("AgpsMsgAtlClosed");
+ }
+
+ inline virtual void proc() const {
+
+ LOC_LOGV("AgpsMsgAtlClosed::proc()");
+ mAgpsManager->reportAtlClosed(mAgpsType);
+ }
+ };
+
+ sendMsg( new AgpsMsgAtlClosed(&mAgpsManager, (AGpsExtType)agpsType));
+}
+
+void GnssAdapter::dataConnFailedCommand(AGpsExtType agpsType){
+
+ LOC_LOGI("GnssAdapter::frameworkDataConnFailed");
+
+ struct AgpsMsgAtlOpenFailed: public LocMsg {
+
+ AgpsManager* mAgpsManager;
+ AGpsExtType mAgpsType;
+
+ inline AgpsMsgAtlOpenFailed(AgpsManager* agpsManager, AGpsExtType agpsType) :
+ LocMsg(), mAgpsManager(agpsManager), mAgpsType(agpsType) {
+
+ LOC_LOGV("AgpsMsgAtlOpenFailed");
+ }
+
+ inline virtual void proc() const {
+
+ LOC_LOGV("AgpsMsgAtlOpenFailed::proc()");
+ mAgpsManager->reportAtlOpenFailed(mAgpsType);
+ }
+ };
+
+ sendMsg( new AgpsMsgAtlOpenFailed(&mAgpsManager, (AGpsExtType)agpsType));
+}
diff --git a/gnss/GnssAdapter.h b/gnss/GnssAdapter.h
index 5bd2a12..f5a5300 100644
--- a/gnss/GnssAdapter.h
+++ b/gnss/GnssAdapter.h
@@ -33,6 +33,7 @@
#include <LocDualContext.h>
#include <UlpProxyBase.h>
#include <LocationAPI.h>
+#include <Agps.h>
#define MAX_URL_LEN 256
#define NMEA_SENTENCE_MAX_LENGTH 200
@@ -95,6 +96,10 @@ class GnssAdapter : public LocAdapterBase {
/* ==== NI ============================================================================= */
NiData mNiData;
+ /* ==== AGPS ========================================================*/
+ // This must be initialized via initAgps()
+ AgpsManager mAgpsManager;
+
/*==== CONVERSION ===================================================================*/
static void convertOptions(LocPosMode& out, const LocationOptions& options);
static void convertLocation(Location& out, const LocGpsLocation& locGpsLocation,
@@ -177,6 +182,14 @@ public:
void setConfigCommand();
uint32_t* gnssUpdateConfigCommand(GnssConfig config);
uint32_t gnssDeleteAidingDataCommand(GnssAidingData& data);
+
+ void initAgpsCommand(void* statusV4Cb);
+ void dataConnOpenCommand(
+ AGpsExtType agpsType,
+ const char* apnName, int apnLen, LocApnIpType ipType);
+ void dataConnClosedCommand(AGpsExtType agpsType);
+ void dataConnFailedCommand(AGpsExtType agpsType);
+
/* ======== RESPONSES ================================================================== */
void reportResponse(LocationError err, uint32_t sessionId);
void reportResponse(size_t count, LocationError* errs, uint32_t* ids);
@@ -201,6 +214,13 @@ public:
virtual void reportGnssMeasurementDataEvent(const GnssMeasurementsNotification& measurementsNotify);
virtual void reportSvMeasurementEvent(GnssSvMeasurementSet &svMeasurementSet);
virtual void reportSvPolynomialEvent(GnssSvPolynomial &svPolynomial);
+
+ virtual bool requestATL(int connHandle, LocAGpsType agps_type);
+ virtual bool releaseATL(int connHandle);
+ virtual bool requestSuplES(int connHandle);
+ virtual bool reportDataCallOpened();
+ virtual bool reportDataCallClosed();
+
/* ======== UTILITIES ================================================================= */
void reportPosition(const UlpLocation &ulpLocation,
const GpsLocationExtended &locationExtended,
diff --git a/gnss/location_gnss.cpp b/gnss/location_gnss.cpp
index 242e72e..0995f4b 100644
--- a/gnss/location_gnss.cpp
+++ b/gnss/location_gnss.cpp
@@ -54,6 +54,11 @@ static uint32_t* gnssUpdateConfig(GnssConfig config);
static void injectLocation(double latitude, double longitude, float accuracy);
static void injectTime(int64_t time, int64_t timeReference, int32_t uncertainty);
+static void agpsInit(void* statusV4Cb);
+static void agpsDataConnOpen(AGpsExtType agpsType, const char* apnName, int apnLen, int ipType);
+static void agpsDataConnClosed(AGpsExtType agpsType);
+static void agpsDataConnFailed(AGpsExtType agpsType);
+
static const GnssInterface gGnssInterface = {
sizeof(GnssInterface),
initialize,
@@ -71,7 +76,11 @@ static const GnssInterface gGnssInterface = {
gnssUpdateConfig,
gnssDeleteAidingData,
injectLocation,
- injectTime
+ injectTime,
+ agpsInit,
+ agpsDataConnOpen,
+ agpsDataConnClosed,
+ agpsDataConnFailed
};
#ifndef DEBUG_X86
@@ -204,3 +213,29 @@ static void injectTime(int64_t time, int64_t timeReference, int32_t uncertainty)
}
}
+static void agpsInit(void* statusV4Cb) {
+
+ if (NULL != gGnssAdapter) {
+ gGnssAdapter->initAgpsCommand(statusV4Cb);
+ }
+}
+static void agpsDataConnOpen(
+ AGpsExtType agpsType, const char* apnName, int apnLen, int ipType) {
+
+ if (NULL != gGnssAdapter) {
+ gGnssAdapter->dataConnOpenCommand(
+ agpsType, apnName, apnLen, ipType);
+ }
+}
+static void agpsDataConnClosed(AGpsExtType agpsType) {
+
+ if (NULL != gGnssAdapter) {
+ gGnssAdapter->dataConnClosedCommand(agpsType);
+ }
+}
+static void agpsDataConnFailed(AGpsExtType agpsType) {
+
+ if (NULL != gGnssAdapter) {
+ gGnssAdapter->dataConnFailedCommand(agpsType);
+ }
+}
diff --git a/location/location_interface.h b/location/location_interface.h
index b726931..b084b65 100644
--- a/location/location_interface.h
+++ b/location/location_interface.h
@@ -49,6 +49,10 @@ struct GnssInterface {
uint32_t (*gnssDeleteAidingData)(GnssAidingData& data);
void (*injectLocation)(double latitude, double longitude, float accuracy);
void (*injectTime)(int64_t time, int64_t timeReference, int32_t uncertainty);
+ void (*agpsInit)(void* statusV4Cb);
+ void (*agpsDataConnOpen)(short agpsType, const char* apnName, int apnLen, int ipType);
+ void (*agpsDataConnClosed)(short agpsType);
+ void (*agpsDataConnFailed)(short agpsType);
};
struct FlpInterface {