summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Peng <robinpeng@google.com>2019-05-02 14:59:06 +0800
committerRobin Peng <robinpeng@google.com>2019-05-02 15:03:31 +0800
commit46d54eed524a863536da3390830b74be03f79282 (patch)
tree16974137e59c2831a45947e11bad87d79fd60cd2
parentc28ceeeaf9d5085b36146e6930d23aa1c0d34d17 (diff)
parentbd25bb0ea834034debd4935d31647ba226e7ffd7 (diff)
downloadgps-46d54eed524a863536da3390830b74be03f79282.tar.gz
Merge remote-tracking branch 'goog/qcom/release/LA.UM.8.1.R1.09.00.00.529.037' into qt-dev
Bug: 131580615 Change-Id: Iaf60110b0da8b16bba6f135ebc962804bd2e33d8
-rw-r--r--android/1.0/Android.mk5
-rw-r--r--android/1.0/Gnss.cpp10
-rw-r--r--android/1.0/Gnss.h4
-rw-r--r--android/1.0/location_api/GnssAPIClient.cpp8
-rw-r--r--android/1.0/service.cpp51
-rw-r--r--android/1.1/Android.mk5
-rw-r--r--android/1.1/Gnss.cpp18
-rw-r--r--android/1.1/Gnss.h6
-rw-r--r--android/1.1/location_api/GnssAPIClient.cpp8
-rw-r--r--android/1.1/location_api/MeasurementAPIClient.cpp12
-rw-r--r--android/1.1/service.cpp51
-rw-r--r--android/2.0/AGnss.cpp209
-rw-r--r--android/2.0/AGnss.h77
-rw-r--r--android/2.0/AGnssRil.cpp133
-rw-r--r--android/2.0/AGnssRil.h84
-rw-r--r--android/2.0/Android.mk102
-rw-r--r--android/2.0/Gnss.cpp538
-rw-r--r--android/2.0/Gnss.h185
-rw-r--r--android/2.0/GnssBatching.cpp130
-rw-r--r--android/2.0/GnssBatching.h80
-rw-r--r--android/2.0/GnssConfiguration.cpp304
-rw-r--r--android/2.0/GnssConfiguration.h80
-rw-r--r--android/2.0/GnssDebug.cpp177
-rw-r--r--android/2.0/GnssDebug.h63
-rw-r--r--android/2.0/GnssGeofencing.cpp141
-rw-r--r--android/2.0/GnssGeofencing.h91
-rw-r--r--android/2.0/GnssMeasurement.cpp165
-rw-r--r--android/2.0/GnssMeasurement.h86
-rw-r--r--android/2.0/GnssNi.cpp85
-rw-r--r--android/2.0/GnssNi.h75
-rw-r--r--android/2.0/android.hardware.gnss@2.0-service-qti.rc (renamed from android/dummy/android.hardware.gnss@1.0-service-qti.rc)2
-rw-r--r--android/2.0/location_api/BatchingAPIClient.cpp196
-rw-r--r--android/2.0/location_api/BatchingAPIClient.h74
-rw-r--r--android/2.0/location_api/GeofenceAPIClient.cpp275
-rw-r--r--android/2.0/location_api/GeofenceAPIClient.h76
-rw-r--r--android/2.0/location_api/GnssAPIClient.cpp565
-rw-r--r--android/2.0/location_api/GnssAPIClient.h108
-rw-r--r--android/2.0/location_api/LocationUtil.cpp206
-rw-r--r--android/2.0/location_api/LocationUtil.h55
-rw-r--r--android/2.0/location_api/MeasurementAPIClient.cpp424
-rw-r--r--android/2.0/location_api/MeasurementAPIClient.h89
-rw-r--r--android/2.0/service.cpp84
-rw-r--r--android/Android.mk6
-rw-r--r--android/dummy/Android.mk17
-rw-r--r--android/dummy/android.hardware.gnss@2.0-service-qti.rc4
-rw-r--r--android/measurement_corrections/1.0/MeasurementCorrections.cpp70
-rw-r--r--android/measurement_corrections/1.0/MeasurementCorrections.h76
-rw-r--r--android/visibility_control/1.0/GnssVisibilityControl.cpp145
-rw-r--r--android/visibility_control/1.0/GnssVisibilityControl.h88
-rw-r--r--batching/Android.mk37
-rw-r--r--batching/BatchingAdapter.cpp1050
-rw-r--r--batching/BatchingAdapter.h152
-rw-r--r--batching/Makefile.am45
-rw-r--r--batching/configure.ac78
-rw-r--r--batching/location-batching.pc.in10
-rw-r--r--batching/location_batching.cpp134
-rw-r--r--build/target_specific_features.mk43
-rw-r--r--core/Android.mk2
-rw-r--r--core/ContextBase.cpp2
-rw-r--r--core/ContextBase.h2
-rw-r--r--core/EngineHubProxyBase.h11
-rw-r--r--core/LocAdapterBase.cpp227
-rw-r--r--core/LocAdapterBase.h70
-rw-r--r--core/LocAdapterProxyBase.h4
-rw-r--r--core/LocApiBase.cpp201
-rw-r--r--core/LocApiBase.h176
-rw-r--r--core/LocContext.cpp98
-rw-r--r--core/LocContext.h (renamed from core/LocDualContext.h)32
-rw-r--r--core/LocDualContext.cpp150
-rw-r--r--core/Makefile.am4
-rw-r--r--core/SystemStatus.cpp8
-rw-r--r--core/SystemStatus.h21
-rw-r--r--core/data-items/DataItemConcreteTypesBase.h19
-rw-r--r--etc/Android.mk13
-rw-r--r--etc/flp.conf60
-rw-r--r--etc/gps.conf5
-rw-r--r--geofence/Android.mk36
-rw-r--r--geofence/GeofenceAdapter.cpp867
-rw-r--r--geofence/GeofenceAdapter.h136
-rw-r--r--geofence/Makefile.am50
-rw-r--r--geofence/configure.ac72
-rw-r--r--geofence/location-geofence.pc.in10
-rw-r--r--geofence/location_geofence.cpp145
-rw-r--r--gnss/Agps.cpp7
-rw-r--r--gnss/GnssAdapter.cpp1327
-rw-r--r--gnss/GnssAdapter.h106
-rw-r--r--gnss/XtraSystemStatusObserver.cpp28
-rw-r--r--gnss/XtraSystemStatusObserver.h13
-rw-r--r--gnss/location_gnss.cpp37
-rw-r--r--gps_vendor_board.mk3
-rw-r--r--gps_vendor_product.mk4
-rw-r--r--location/LocationAPI.cpp214
-rw-r--r--location/LocationAPI.h2
-rw-r--r--location/LocationAPIClientBase.h2
-rw-r--r--location/LocationDataTypes.h163
-rw-r--r--location/location_interface.h14
-rw-r--r--pla/oe/loc_pla.h17
-rw-r--r--utils/Android.mk1
-rw-r--r--utils/LocIpc.h8
-rw-r--r--utils/LocSharedLock.h20
-rw-r--r--utils/LocThread.cpp4
-rw-r--r--utils/Makefile.am2
-rw-r--r--utils/MsgTask.cpp2
-rw-r--r--utils/configure.ac18
-rw-r--r--utils/gps_extended_c.h321
-rw-r--r--utils/linked_list.h2
-rw-r--r--utils/loc_cfg.cpp74
-rw-r--r--utils/loc_misc_utils.cpp31
-rw-r--r--utils/loc_misc_utils.h28
-rw-r--r--utils/loc_nmea.cpp227
-rw-r--r--utils/log_util.h9
-rw-r--r--utils/msg_q.c45
-rw-r--r--utils/msg_q.h23
113 files changed, 10838 insertions, 1427 deletions
diff --git a/android/1.0/Android.mk b/android/1.0/Android.mk
index 434b432..122ff8d 100644
--- a/android/1.0/Android.mk
+++ b/android/1.0/Android.mk
@@ -81,4 +81,9 @@ LOCAL_SHARED_LIBRARIES += \
android.hardware.gnss@1.0 \
LOCAL_CFLAGS += $(GNSS_CFLAGS)
+
+ifneq ($(LOC_HIDL_VERSION),)
+LOCAL_CFLAGS += -DLOC_HIDL_VERSION='"$(LOC_HIDL_VERSION)"'
+endif
+
include $(BUILD_EXECUTABLE)
diff --git a/android/1.0/Gnss.cpp b/android/1.0/Gnss.cpp
index 6e34f1e..93b320b 100644
--- a/android/1.0/Gnss.cpp
+++ b/android/1.0/Gnss.cpp
@@ -27,7 +27,7 @@
#include "Gnss.h"
#include <LocationUtil.h>
-typedef void* (getLocationInterface)();
+typedef const GnssInterface* (getLocationInterface)();
namespace android {
namespace hardware {
@@ -84,7 +84,7 @@ GnssAPIClient* Gnss::getApi() {
return mApi;
}
-GnssInterface* Gnss::getGnssInterface() {
+const GnssInterface* Gnss::getGnssInterface() {
static bool getGnssInterfaceFailed = false;
if (nullptr == mGnssInterface && !getGnssInterfaceFailed) {
LOC_LOGD("%s]: loading libgnss.so::getGnssInterface ...", __func__);
@@ -105,7 +105,7 @@ GnssInterface* Gnss::getGnssInterface() {
if (NULL == getter) {
getGnssInterfaceFailed = true;
} else {
- mGnssInterface = (GnssInterface*)(*getter)();
+ mGnssInterface = (const GnssInterface*)(*getter)();
}
}
return mGnssInterface;
@@ -238,7 +238,7 @@ Return<bool> Gnss::injectLocation(double latitudeDegrees,
double longitudeDegrees,
float accuracyMeters) {
ENTRY_LOG_CALLFLOW();
- GnssInterface* gnssInterface = getGnssInterface();
+ const GnssInterface* gnssInterface = getGnssInterface();
if (nullptr != gnssInterface) {
gnssInterface->injectLocation(latitudeDegrees, longitudeDegrees, accuracyMeters);
return true;
@@ -250,7 +250,7 @@ Return<bool> Gnss::injectLocation(double latitudeDegrees,
Return<bool> Gnss::injectTime(int64_t timeMs, int64_t timeReferenceMs,
int32_t uncertaintyMs) {
ENTRY_LOG_CALLFLOW();
- GnssInterface* gnssInterface = getGnssInterface();
+ const GnssInterface* gnssInterface = getGnssInterface();
if (nullptr != gnssInterface) {
gnssInterface->injectTime(timeMs, timeReferenceMs, uncertaintyMs);
return true;
diff --git a/android/1.0/Gnss.h b/android/1.0/Gnss.h
index c23b337..900a510 100644
--- a/android/1.0/Gnss.h
+++ b/android/1.0/Gnss.h
@@ -99,7 +99,7 @@ struct Gnss : public IGnss {
GnssAPIClient* getApi();
Return<bool> setGnssNiCb(const sp<IGnssNiCallback>& niCb);
Return<bool> updateConfiguration(GnssConfig& gnssConfig);
- GnssInterface* getGnssInterface();
+ const GnssInterface* getGnssInterface();
// Callback for ODCPI request
void odcpiRequestCb(const OdcpiRequestInfo& request);
@@ -129,7 +129,7 @@ struct Gnss : public IGnss {
sp<V1_0::IGnssCallback> mGnssCbIface = nullptr;
sp<V1_0::IGnssNiCallback> mGnssNiCbIface = nullptr;
GnssConfig mPendingConfig;
- GnssInterface* mGnssInterface = nullptr;
+ const GnssInterface* mGnssInterface = nullptr;
};
extern "C" IGnss* HIDL_FETCH_IGnss(const char* name);
diff --git a/android/1.0/location_api/GnssAPIClient.cpp b/android/1.0/location_api/GnssAPIClient.cpp
index d04939e..a36d2b4 100644
--- a/android/1.0/location_api/GnssAPIClient.cpp
+++ b/android/1.0/location_api/GnssAPIClient.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019, 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
@@ -36,7 +36,7 @@
#include "LocationUtil.h"
#include "GnssAPIClient.h"
-#include <LocDualContext.h>
+#include <LocContext.h>
namespace android {
namespace hardware {
@@ -110,9 +110,9 @@ void GnssAPIClient::gnssUpdateCallbacks(const sp<IGnssCallback>& gpsCb,
locationCallbacks.gnssNiCb = nullptr;
loc_core::ContextBase* context =
- loc_core::LocDualContext::getLocFgContext(
+ loc_core::LocContext::getLocContext(
NULL, NULL,
- loc_core::LocDualContext::mLocationHalName, false);
+ loc_core::LocContext::mLocationHalName, false);
if (mGnssNiCbIface != nullptr && !context->hasAgpsExtendedCapabilities()) {
LOC_LOGD("Registering NI CB");
locationCallbacks.gnssNiCb = [this](uint32_t id, GnssNiNotification gnssNiNotification) {
diff --git a/android/1.0/service.cpp b/android/1.0/service.cpp
index ee61a10..04bb8ab 100644
--- a/android/1.0/service.cpp
+++ b/android/1.0/service.cpp
@@ -22,22 +22,63 @@
#include <android/hardware/gnss/1.0/IGnss.h>
#include <hidl/LegacySupport.h>
-
#include "loc_cfg.h"
+#include "loc_misc_utils.h"
+
extern "C" {
#include "vndfwk-detect.h"
}
+#ifdef ARCH_ARM_32
+#define DEFAULT_HW_BINDER_MEM_SIZE 65536
+#endif
+
using android::hardware::gnss::V1_0::IGnss;
-using android::hardware::defaultPassthroughServiceImplementation;
+
+using android::hardware::configureRpcThreadpool;
+using android::hardware::registerPassthroughServiceImplementation;
+using android::hardware::joinRpcThreadpool;
+
+using android::status_t;
+using android::OK;
+
+typedef int vendorEnhancedServiceMain(int /* argc */, char* /* argv */ []);
int main() {
+
+ ALOGI("%s", __FUNCTION__);
+
bool vendorEnhanced = isRunningWithVendorEnhancedFramework();
setVendorEnhanced(vendorEnhanced);
- if (!vendorEnhanced) {
- return defaultPassthroughServiceImplementation<IGnss>();
+#ifdef ARCH_ARM_32
+ android::hardware::ProcessState::initWithMmapSize((size_t)(DEFAULT_HW_BINDER_MEM_SIZE));
+#endif
+ configureRpcThreadpool(1, true);
+ status_t status;
+
+ status = registerPassthroughServiceImplementation<IGnss>();
+ if (status == OK) {
+ if (vendorEnhanced) {
+ #ifdef LOC_HIDL_VERSION
+ #define VENDOR_ENHANCED_LIB "vendor.qti.gnss@" LOC_HIDL_VERSION "-service.so"
+
+ void* libHandle = NULL;
+ vendorEnhancedServiceMain* vendorEnhancedMainMethod = (vendorEnhancedServiceMain*)
+ dlGetSymFromLib(libHandle, VENDOR_ENHANCED_LIB, "main");
+ if (NULL != vendorEnhancedMainMethod) {
+ (*vendorEnhancedMainMethod)(0, NULL);
+ }
+ #else
+ ALOGE("LOC_HIDL_VERSION not defined.");
+ #endif
+ }
+
+ joinRpcThreadpool();
+
} else {
- return -1;
+ ALOGE("Error while registering IGnss 1.0 service: %d", status);
}
+
+ return 0;
}
diff --git a/android/1.1/Android.mk b/android/1.1/Android.mk
index 33e5b0d..5c97f40 100644
--- a/android/1.1/Android.mk
+++ b/android/1.1/Android.mk
@@ -83,4 +83,9 @@ LOCAL_SHARED_LIBRARIES += \
android.hardware.gnss@1.1 \
LOCAL_CFLAGS += $(GNSS_CFLAGS)
+
+ifneq ($(LOC_HIDL_VERSION),)
+LOCAL_CFLAGS += -DLOC_HIDL_VERSION='"$(LOC_HIDL_VERSION)"'
+endif
+
include $(BUILD_EXECUTABLE)
diff --git a/android/1.1/Gnss.cpp b/android/1.1/Gnss.cpp
index fca72e6..8d5d8a8 100644
--- a/android/1.1/Gnss.cpp
+++ b/android/1.1/Gnss.cpp
@@ -27,7 +27,7 @@
#include "Gnss.h"
#include <LocationUtil.h>
-typedef void* (getLocationInterface)();
+typedef const GnssInterface* (getLocationInterface)();
#define IMAGES_INFO_FILE "/sys/devices/soc0/images"
#define DELIMITER ";"
@@ -124,7 +124,7 @@ GnssAPIClient* Gnss::getApi() {
return mApi;
}
-GnssInterface* Gnss::getGnssInterface() {
+const GnssInterface* Gnss::getGnssInterface() {
static bool getGnssInterfaceFailed = false;
if (nullptr == mGnssInterface && !getGnssInterfaceFailed) {
LOC_LOGD("%s]: loading libgnss.so::getGnssInterface ...", __func__);
@@ -145,7 +145,7 @@ GnssInterface* Gnss::getGnssInterface() {
if (NULL == getter) {
getGnssInterfaceFailed = true;
} else {
- mGnssInterface = (GnssInterface*)(*getter)();
+ mGnssInterface = (const GnssInterface*)(*getter)();
}
}
return mGnssInterface;
@@ -278,7 +278,7 @@ Return<bool> Gnss::injectLocation(double latitudeDegrees,
double longitudeDegrees,
float accuracyMeters) {
ENTRY_LOG_CALLFLOW();
- GnssInterface* gnssInterface = getGnssInterface();
+ const GnssInterface* gnssInterface = getGnssInterface();
if (nullptr != gnssInterface) {
gnssInterface->injectLocation(latitudeDegrees, longitudeDegrees, accuracyMeters);
return true;
@@ -290,7 +290,7 @@ Return<bool> Gnss::injectLocation(double latitudeDegrees,
Return<bool> Gnss::injectTime(int64_t timeMs, int64_t timeReferenceMs,
int32_t uncertaintyMs) {
ENTRY_LOG_CALLFLOW();
- GnssInterface* gnssInterface = getGnssInterface();
+ const GnssInterface* gnssInterface = getGnssInterface();
if (nullptr != gnssInterface) {
gnssInterface->injectTime(timeMs, timeReferenceMs, uncertaintyMs);
return true;
@@ -375,7 +375,7 @@ Return<bool> Gnss::setCallback_1_1(const sp<V1_1::IGnssCallback>& callback) {
ENTRY_LOG_CALLFLOW();
callback->gnssNameCb(getVersionString());
mGnssCbIface_1_1 = callback;
- GnssInterface* gnssInterface = getGnssInterface();
+ const GnssInterface* gnssInterface = getGnssInterface();
if (nullptr != gnssInterface) {
OdcpiRequestCallback cb = [this](const OdcpiRequestInfo& odcpiRequest) {
odcpiRequestCb(odcpiRequest);
@@ -419,7 +419,7 @@ Return<sp<V1_1::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration_1_1() {
Return<bool> Gnss::injectBestLocation(const GnssLocation& gnssLocation) {
ENTRY_LOG_CALLFLOW();
- GnssInterface* gnssInterface = getGnssInterface();
+ const GnssInterface* gnssInterface = getGnssInterface();
if (nullptr != gnssInterface) {
Location location = {};
convertGnssLocation(gnssLocation, location);
@@ -446,9 +446,9 @@ void Gnss::odcpiRequestCb(const OdcpiRequestInfo& request) {
}
}
-IGnss* HIDL_FETCH_IGnss(const char* hal) {
+V1_0::IGnss* HIDL_FETCH_IGnss(const char* hal) {
ENTRY_LOG_CALLFLOW();
- IGnss* iface = nullptr;
+ V1_0::IGnss* iface = nullptr;
iface = new Gnss();
if (iface == nullptr) {
LOC_LOGE("%s]: failed to get %s", __FUNCTION__, hal);
diff --git a/android/1.1/Gnss.h b/android/1.1/Gnss.h
index 4c0c8b0..15645eb 100644
--- a/android/1.1/Gnss.h
+++ b/android/1.1/Gnss.h
@@ -109,7 +109,7 @@ struct Gnss : public IGnss {
GnssAPIClient* getApi();
Return<bool> setGnssNiCb(const sp<IGnssNiCallback>& niCb);
Return<bool> updateConfiguration(GnssConfig& gnssConfig);
- GnssInterface* getGnssInterface();
+ const GnssInterface* getGnssInterface();
// Callback for ODCPI request
void odcpiRequestCb(const OdcpiRequestInfo& request);
@@ -140,10 +140,10 @@ struct Gnss : public IGnss {
sp<V1_1::IGnssCallback> mGnssCbIface_1_1 = nullptr;
sp<V1_0::IGnssNiCallback> mGnssNiCbIface = nullptr;
GnssConfig mPendingConfig;
- GnssInterface* mGnssInterface = nullptr;
+ const GnssInterface* mGnssInterface = nullptr;
};
-extern "C" IGnss* HIDL_FETCH_IGnss(const char* name);
+extern "C" V1_0::IGnss* HIDL_FETCH_IGnss(const char* name);
} // namespace implementation
} // namespace V1_1
diff --git a/android/1.1/location_api/GnssAPIClient.cpp b/android/1.1/location_api/GnssAPIClient.cpp
index fcef459..89877e5 100644
--- a/android/1.1/location_api/GnssAPIClient.cpp
+++ b/android/1.1/location_api/GnssAPIClient.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019, 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
@@ -36,7 +36,7 @@
#include "LocationUtil.h"
#include "GnssAPIClient.h"
-#include <LocDualContext.h>
+#include <LocContext.h>
namespace android {
namespace hardware {
@@ -110,9 +110,9 @@ void GnssAPIClient::gnssUpdateCallbacks(const sp<IGnssCallback>& gpsCb,
locationCallbacks.gnssNiCb = nullptr;
loc_core::ContextBase* context =
- loc_core::LocDualContext::getLocFgContext(
+ loc_core::LocContext::getLocContext(
NULL, NULL,
- loc_core::LocDualContext::mLocationHalName, false);
+ loc_core::LocContext::mLocationHalName, false);
if (mGnssNiCbIface != nullptr && !context->hasAgpsExtendedCapabilities()) {
LOC_LOGD("Registering NI CB");
locationCallbacks.gnssNiCb = [this](uint32_t id, GnssNiNotification gnssNiNotification) {
diff --git a/android/1.1/location_api/MeasurementAPIClient.cpp b/android/1.1/location_api/MeasurementAPIClient.cpp
index 7017e52..6f25067 100644
--- a/android/1.1/location_api/MeasurementAPIClient.cpp
+++ b/android/1.1/location_api/MeasurementAPIClient.cpp
@@ -309,6 +309,18 @@ static void convertGnssData_1_1(GnssMeasurementsNotification& in,
out.measurements.resize(in.count);
for (size_t i = 0; i < in.count; i++) {
convertGnssMeasurement(in.measurements[i], out.measurements[i].v1_0);
+ if (in.measurements[i].adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_VALID_BIT)
+ out.measurements[i].accumulatedDeltaRangeState |=
+ IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_VALID;
+ if (in.measurements[i].adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_RESET_BIT)
+ out.measurements[i].accumulatedDeltaRangeState |=
+ IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_RESET;
+ if (in.measurements[i].adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_CYCLE_SLIP_BIT)
+ out.measurements[i].accumulatedDeltaRangeState |=
+ IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_CYCLE_SLIP;
+ if (in.measurements[i].adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_HALF_CYCLE_RESOLVED_BIT)
+ out.measurements[i].accumulatedDeltaRangeState |=
+ IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_HALF_CYCLE_RESOLVED;
}
convertGnssClock(in.clock, out.clock);
}
diff --git a/android/1.1/service.cpp b/android/1.1/service.cpp
index c1bc6b0..bf7ad07 100644
--- a/android/1.1/service.cpp
+++ b/android/1.1/service.cpp
@@ -22,22 +22,63 @@
#include <android/hardware/gnss/1.1/IGnss.h>
#include <hidl/LegacySupport.h>
-
#include "loc_cfg.h"
+#include "loc_misc_utils.h"
+
extern "C" {
#include "vndfwk-detect.h"
}
+#ifdef ARCH_ARM_32
+#define DEFAULT_HW_BINDER_MEM_SIZE 65536
+#endif
+
using android::hardware::gnss::V1_1::IGnss;
-using android::hardware::defaultPassthroughServiceImplementation;
+
+using android::hardware::configureRpcThreadpool;
+using android::hardware::registerPassthroughServiceImplementation;
+using android::hardware::joinRpcThreadpool;
+
+using android::status_t;
+using android::OK;
+
+typedef int vendorEnhancedServiceMain(int /* argc */, char* /* argv */ []);
int main() {
+
+ ALOGI("%s", __FUNCTION__);
+
bool vendorEnhanced = isRunningWithVendorEnhancedFramework();
setVendorEnhanced(vendorEnhanced);
- if (!vendorEnhanced) {
- return defaultPassthroughServiceImplementation<IGnss>();
+#ifdef ARCH_ARM_32
+ android::hardware::ProcessState::initWithMmapSize((size_t)(DEFAULT_HW_BINDER_MEM_SIZE));
+#endif
+ configureRpcThreadpool(1, true);
+ status_t status;
+
+ status = registerPassthroughServiceImplementation<IGnss>();
+ if (status == OK) {
+ if (vendorEnhanced) {
+ #ifdef LOC_HIDL_VERSION
+ #define VENDOR_ENHANCED_LIB "vendor.qti.gnss@" LOC_HIDL_VERSION "-service.so"
+
+ void* libHandle = NULL;
+ vendorEnhancedServiceMain* vendorEnhancedMainMethod = (vendorEnhancedServiceMain*)
+ dlGetSymFromLib(libHandle, VENDOR_ENHANCED_LIB, "main");
+ if (NULL != vendorEnhancedMainMethod) {
+ (*vendorEnhancedMainMethod)(0, NULL);
+ }
+ #else
+ ALOGE("LOC_HIDL_VERSION not defined.");
+ #endif
+ }
+
+ joinRpcThreadpool();
+
} else {
- return -1;
+ ALOGE("Error while registering IGnss 1.1 service: %d", status);
}
+
+ return 0;
}
diff --git a/android/2.0/AGnss.cpp b/android/2.0/AGnss.cpp
new file mode 100644
index 0000000..7bd015e
--- /dev/null
+++ b/android/2.0/AGnss.cpp
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "LocSvc_AGnssInterface"
+
+#include <log_util.h>
+#include "Gnss.h"
+#include "AGnss.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+static AGnss* spAGnss = nullptr;
+
+AGnss::AGnss(Gnss* gnss) : mGnss(gnss) {
+ spAGnss = this;
+}
+
+AGnss::~AGnss() {
+ spAGnss = nullptr;
+}
+
+void AGnss::agnssStatusIpV4Cb(AGnssExtStatusIpV4 status) {
+ if (nullptr != spAGnss) {
+ spAGnss->statusCb(status.type, status.status);
+ }
+}
+
+void AGnss::statusCb(AGpsExtType type, LocAGpsStatusValue status) {
+
+ V2_0::IAGnssCallback::AGnssType aType;
+ IAGnssCallback::AGnssStatusValue aStatus;
+
+ switch (type) {
+ case LOC_AGPS_TYPE_SUPL:
+ aType = IAGnssCallback::AGnssType::SUPL;
+ break;
+ case LOC_AGPS_TYPE_SUPL_ES:
+ aType = IAGnssCallback::AGnssType::SUPL_EIMS;
+ break;
+ default:
+ LOC_LOGE("invalid type: %d", type);
+ return;
+ }
+
+ switch (status) {
+ case LOC_GPS_REQUEST_AGPS_DATA_CONN:
+ aStatus = IAGnssCallback::AGnssStatusValue::REQUEST_AGNSS_DATA_CONN;
+ break;
+ case LOC_GPS_RELEASE_AGPS_DATA_CONN:
+ aStatus = IAGnssCallback::AGnssStatusValue::RELEASE_AGNSS_DATA_CONN;
+ break;
+ case LOC_GPS_AGPS_DATA_CONNECTED:
+ aStatus = IAGnssCallback::AGnssStatusValue::AGNSS_DATA_CONNECTED;
+ break;
+ case LOC_GPS_AGPS_DATA_CONN_DONE:
+ aStatus = IAGnssCallback::AGnssStatusValue::AGNSS_DATA_CONN_DONE;
+ break;
+ case LOC_GPS_AGPS_DATA_CONN_FAILED:
+ aStatus = IAGnssCallback::AGnssStatusValue::AGNSS_DATA_CONN_FAILED;
+ break;
+ default:
+ LOC_LOGE("invalid status: %d", status);
+ return;
+ }
+
+ if (mAGnssCbIface != nullptr) {
+ auto r = mAGnssCbIface->agnssStatusCb(aType, aStatus);
+ if (!r.isOk()) {
+ LOC_LOGw("Error invoking AGNSS status cb %s", r.description().c_str());
+ }
+ }
+ else {
+ LOC_LOGw("setCallback has not been called yet");
+ }
+}
+
+Return<void> AGnss::setCallback(const sp<V2_0::IAGnssCallback>& callback) {
+
+ if(mGnss == nullptr || mGnss->getGnssInterface() == nullptr){
+ LOC_LOGE("Null GNSS interface");
+ return Void();
+ }
+
+ // Save the interface
+ mAGnssCbIface = callback;
+
+ AgpsCbInfo cbInfo = {};
+ cbInfo.statusV4Cb = (void*)agnssStatusIpV4Cb;
+ cbInfo.cbPriority = AGPS_CB_PRIORITY_HIGH;
+
+ mGnss->getGnssInterface()->agpsInit(cbInfo);
+ 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(uint64_t /*networkHandle*/, const hidl_string& apn,
+ V2_0::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());
+
+ AGpsBearerType bearerType;
+ switch (apnIpType) {
+ case IAGnss::ApnIpType::IPV4:
+ bearerType = AGPS_APN_BEARER_IPV4;
+ break;
+ case IAGnss::ApnIpType::IPV6:
+ bearerType = AGPS_APN_BEARER_IPV6;
+ break;
+ case IAGnss::ApnIpType::IPV4V6:
+ bearerType = AGPS_APN_BEARER_IPV4V6;
+ break;
+ default:
+ bearerType = AGPS_APN_BEARER_IPV4;
+ break;
+ }
+
+ mGnss->getGnssInterface()->agpsDataConnOpen(
+ LOC_AGPS_TYPE_SUPL, apn.c_str(), apn.size(), (int)bearerType);
+ return true;
+}
+
+Return<bool> AGnss::setServer(V2_0::IAGnssCallback::AGnssType type,
+ const hidl_string& hostname,
+ int32_t port) {
+ if (mGnss == nullptr) {
+ LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
+ return false;
+ }
+
+ GnssConfig config;
+ memset(&config, 0, sizeof(GnssConfig));
+ config.size = sizeof(GnssConfig);
+ config.flags = GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT;
+ config.assistanceServer.size = sizeof(GnssConfigSetAssistanceServer);
+ if (type == IAGnssCallback::AGnssType::SUPL) {
+ config.assistanceServer.type = GNSS_ASSISTANCE_TYPE_SUPL;
+ } else if (type == IAGnssCallback::AGnssType::C2K) {
+ config.assistanceServer.type = GNSS_ASSISTANCE_TYPE_C2K;
+ } else if (type == IAGnssCallback::AGnssType::SUPL_EIMS) {
+ config.assistanceServer.type = GNSS_ASSISTANCE_TYPE_SUPL_EIMS;
+ } else if (type == IAGnssCallback::AGnssType::SUPL_IMS) {
+ config.assistanceServer.type = GNSS_ASSISTANCE_TYPE_SUPL_IMS;
+ } else {
+ LOC_LOGE("%s]: invalid AGnssType: %d", __FUNCTION__, static_cast<uint8_t>(type));
+ return false;
+ }
+ config.assistanceServer.hostName = strdup(hostname.c_str());
+ config.assistanceServer.port = port;
+ return mGnss->updateConfiguration(config);
+}
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/android/2.0/AGnss.h b/android/2.0/AGnss.h
new file mode 100644
index 0000000..c442327
--- /dev/null
+++ b/android/2.0/AGnss.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GNSS_V2_0_AGNSS_H
+#define ANDROID_HARDWARE_GNSS_V2_0_AGNSS_H
+
+#include <android/hardware/gnss/2.0/IAGnss.h>
+#include <hidl/Status.h>
+#include <gps_extended_c.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+struct Gnss;
+struct AGnss : public V2_0::IAGnss {
+
+ AGnss(Gnss* gnss);
+ ~AGnss();
+ /*
+ * Methods from ::android::hardware::gnss::V2_0::IAGnss interface follow.
+ * These declarations were generated from IAGnss.hal.
+ */
+ Return<void> setCallback(const sp<V2_0::IAGnssCallback>& callback) override;
+
+ Return<bool> dataConnClosed() override;
+
+ Return<bool> dataConnFailed() override;
+
+ Return<bool> dataConnOpen(uint64_t networkHandle, const hidl_string& apn,
+ V2_0::IAGnss::ApnIpType apnIpType) override;
+
+ Return<bool> setServer(V2_0::IAGnssCallback::AGnssType type,
+ const hidl_string& hostname, int32_t port) override;
+
+ void statusCb(AGpsExtType type, LocAGpsStatusValue status);
+
+ /* Data call setup callback passed down to GNSS HAL implementation */
+ static void agnssStatusIpV4Cb(AGnssExtStatusIpV4 status);
+
+ private:
+ Gnss* mGnss = nullptr;
+ sp<IAGnssCallback> mAGnssCbIface = nullptr;
+};
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V2_0_AGNSS_H
diff --git a/android/2.0/AGnssRil.cpp b/android/2.0/AGnssRil.cpp
new file mode 100644
index 0000000..9de8b7d
--- /dev/null
+++ b/android/2.0/AGnssRil.cpp
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "LocSvc__AGnssRilInterface"
+
+#include <log_util.h>
+#include <dlfcn.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sstream>
+#include <string>
+#include "Gnss.h"
+#include "AGnssRil.h"
+#include <DataItemConcreteTypesBase.h>
+
+typedef void* (getLocationInterface)();
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+
+AGnssRil::AGnssRil(Gnss* gnss) : mGnss(gnss) {
+ ENTRY_LOG_CALLFLOW();
+}
+
+AGnssRil::~AGnssRil() {
+ ENTRY_LOG_CALLFLOW();
+}
+
+Return<bool> AGnssRil::updateNetworkState(bool connected, NetworkType type, bool /*roaming*/) {
+ ENTRY_LOG_CALLFLOW();
+ // Extra NetworkTypes not available in IAgnssRil enums
+ const int NetworkType_BLUETOOTH = 7;
+ const int NetworkType_ETHERNET = 9;
+ const int NetworkType_PROXY = 16;
+
+ // for XTRA
+ if (nullptr != mGnss && ( nullptr != mGnss->getGnssInterface() )) {
+ int8_t typeout = loc_core::NetworkInfoDataItemBase::TYPE_UNKNOWN;
+ switch(type)
+ {
+ case IAGnssRil::NetworkType::MOBILE:
+ typeout = loc_core::NetworkInfoDataItemBase::TYPE_MOBILE;
+ break;
+ case IAGnssRil::NetworkType::WIFI:
+ typeout = loc_core::NetworkInfoDataItemBase::TYPE_WIFI;
+ break;
+ case IAGnssRil::NetworkType::MMS:
+ typeout = loc_core::NetworkInfoDataItemBase::TYPE_MMS;
+ break;
+ case IAGnssRil::NetworkType::SUPL:
+ typeout = loc_core::NetworkInfoDataItemBase::TYPE_SUPL;
+ break;
+ case IAGnssRil::NetworkType::DUN:
+ typeout = loc_core::NetworkInfoDataItemBase::TYPE_DUN;
+ break;
+ case IAGnssRil::NetworkType::HIPRI:
+ typeout = loc_core::NetworkInfoDataItemBase::TYPE_HIPRI;
+ break;
+ case IAGnssRil::NetworkType::WIMAX:
+ typeout = loc_core::NetworkInfoDataItemBase::TYPE_WIMAX;
+ break;
+ default:
+ {
+ int networkType = (int) type;
+ // Handling network types not available in IAgnssRil
+ switch(networkType)
+ {
+ case NetworkType_BLUETOOTH:
+ typeout = loc_core::NetworkInfoDataItemBase::TYPE_BLUETOOTH;
+ break;
+ case NetworkType_ETHERNET:
+ typeout = loc_core::NetworkInfoDataItemBase::TYPE_ETHERNET;
+ break;
+ case NetworkType_PROXY:
+ typeout = loc_core::NetworkInfoDataItemBase::TYPE_PROXY;
+ break;
+ default:
+ typeout = loc_core::NetworkInfoDataItemBase::TYPE_UNKNOWN;
+ }
+ }
+ break;
+ }
+ mGnss->getGnssInterface()->updateConnectionStatus(connected, false, typeout, 0);
+ }
+ return true;
+}
+Return<bool> AGnssRil::updateNetworkState_2_0(const V2_0::IAGnssRil::NetworkAttributes& attributes) {
+ ENTRY_LOG_CALLFLOW();
+
+ if (nullptr != mGnss && (nullptr != mGnss->getGnssInterface())) {
+ int8_t typeout = loc_core::NetworkInfoDataItemBase::TYPE_UNKNOWN;
+ bool roaming = false;
+ if (attributes.capabilities & IAGnssRil::NetworkCapability::NOT_METERED) {
+ typeout = loc_core::NetworkInfoDataItemBase::TYPE_WIFI;
+ } else {
+ typeout = loc_core::NetworkInfoDataItemBase::TYPE_MOBILE;
+ }
+ if (attributes.capabilities & IAGnssRil::NetworkCapability::NOT_ROAMING) {
+ roaming = false;
+ }
+ mGnss->getGnssInterface()->updateConnectionStatus(attributes.isConnected,
+ typeout, roaming, (NetworkHandle) attributes.networkHandle);
+ }
+ return true;
+}
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/android/2.0/AGnssRil.h b/android/2.0/AGnssRil.h
new file mode 100644
index 0000000..a04d8aa
--- /dev/null
+++ b/android/2.0/AGnssRil.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GNSS_V2_0_AGNSSRIL_H_
+#define ANDROID_HARDWARE_GNSS_V2_0_AGNSSRIL_H_
+
+#include <android/hardware/gnss/2.0/IAGnssRil.h>
+#include <hidl/Status.h>
+#include <location_interface.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+struct Gnss;
+/*
+ * Extended interface for AGNSS RIL support. An Assisted GNSS Radio Interface Layer interface
+ * allows the GNSS chipset to request radio interface layer information from Android platform.
+ * Examples of such information are reference location, unique subscriber ID, phone number string
+ * and network availability changes. Also contains wrapper methods to allow methods from
+ * IAGnssiRilCallback interface to be passed into the conventional implementation of the GNSS HAL.
+ */
+struct AGnssRil : public V2_0::IAGnssRil {
+ AGnssRil(Gnss* gnss);
+ ~AGnssRil();
+
+ /*
+ * Methods from ::android::hardware::gnss::V1_0::IAGnssRil follow.
+ * These declarations were generated from IAGnssRil.hal.
+ */
+ Return<void> setCallback(const sp<V1_0::IAGnssRilCallback>& /*callback*/) override {
+ return Void();
+ }
+ Return<void> setRefLocation(const V1_0::IAGnssRil::AGnssRefLocation& /*agnssReflocation*/) override {
+ return Void();
+ }
+ Return<bool> setSetId(V1_0::IAGnssRil::SetIDType /*type*/, const hidl_string& /*setid*/) override {
+ return false;
+ }
+ Return<bool> updateNetworkAvailability(bool /*available*/,
+ const hidl_string& /*apn*/) override {
+ return false;
+ }
+ Return<bool> updateNetworkState(bool connected, V1_0::IAGnssRil::NetworkType type, bool roaming) override;
+
+ // Methods from ::android::hardware::gnss::V2_0::IAGnssRil follow
+ Return<bool> updateNetworkState_2_0(const V2_0::IAGnssRil::NetworkAttributes& attributes) override;
+
+ private:
+ Gnss* mGnss = nullptr;
+};
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V2_0_AGNSSRIL_H_
diff --git a/android/2.0/Android.mk b/android/2.0/Android.mk
new file mode 100644
index 0000000..2000bb8
--- /dev/null
+++ b/android/2.0/Android.mk
@@ -0,0 +1,102 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.gnss@2.0-impl-qti
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_SRC_FILES := \
+ AGnss.cpp \
+ Gnss.cpp \
+ AGnssRil.cpp \
+ GnssMeasurement.cpp \
+ GnssConfiguration.cpp \
+ GnssBatching.cpp \
+ GnssGeofencing.cpp \
+ GnssNi.cpp \
+ GnssDebug.cpp \
+ ../measurement_corrections/1.0/MeasurementCorrections.cpp \
+ ../visibility_control/1.0/GnssVisibilityControl.cpp
+
+LOCAL_SRC_FILES += \
+ location_api/GnssAPIClient.cpp \
+ location_api/MeasurementAPIClient.cpp \
+ location_api/GeofenceAPIClient.cpp \
+ location_api/BatchingAPIClient.cpp \
+ location_api/LocationUtil.cpp \
+
+ifeq ($(GNSS_HIDL_LEGACY_MEASURMENTS),true)
+LOCAL_CFLAGS += \
+ -DGNSS_HIDL_LEGACY_MEASURMENTS
+endif
+
+LOCAL_C_INCLUDES:= \
+ $(LOCAL_PATH)/location_api \
+ $(LOCAL_PATH)/../measurement_corrections/1.0 \
+ $(LOCAL_PATH)/../visibility_control/1.0
+LOCAL_HEADER_LIBRARIES := \
+ libgps.utils_headers \
+ libloc_core_headers \
+ libloc_pla_headers \
+ liblocation_api_headers
+
+LOCAL_SHARED_LIBRARIES := \
+ liblog \
+ libhidlbase \
+ libhidltransport \
+ libhwbinder \
+ libcutils \
+ libutils \
+ android.hardware.gnss@1.0 \
+ android.hardware.gnss@1.1 \
+ android.hardware.gnss@2.0 \
+ android.hardware.gnss.measurement_corrections@1.0 \
+ android.hardware.gnss.visibility_control@1.0
+
+LOCAL_SHARED_LIBRARIES += \
+ libloc_core \
+ libgps.utils \
+ libdl \
+ liblocation_api \
+
+LOCAL_CFLAGS += $(GNSS_CFLAGS)
+include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.gnss@2.0-service-qti
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_INIT_RC := android.hardware.gnss@2.0-service-qti.rc
+LOCAL_SRC_FILES := \
+ service.cpp \
+
+LOCAL_HEADER_LIBRARIES := \
+ libgps.utils_headers \
+ libloc_core_headers \
+ libloc_pla_headers \
+ liblocation_api_headers
+
+
+LOCAL_SHARED_LIBRARIES := \
+ liblog \
+ libcutils \
+ libdl \
+ libbase \
+ libutils \
+ libgps.utils \
+ libqti_vndfwk_detect \
+
+LOCAL_SHARED_LIBRARIES += \
+ libhwbinder \
+ libhidlbase \
+ libhidltransport \
+ android.hardware.gnss@1.0 \
+ android.hardware.gnss@1.1 \
+ android.hardware.gnss@2.0 \
+
+LOCAL_CFLAGS += $(GNSS_CFLAGS)
+
+ifneq ($(LOC_HIDL_VERSION),)
+LOCAL_CFLAGS += -DLOC_HIDL_VERSION='"$(LOC_HIDL_VERSION)"'
+endif
+
+include $(BUILD_EXECUTABLE)
diff --git a/android/2.0/Gnss.cpp b/android/2.0/Gnss.cpp
new file mode 100644
index 0000000..1021938
--- /dev/null
+++ b/android/2.0/Gnss.cpp
@@ -0,0 +1,538 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "LocSvc_GnssInterface"
+
+#include <fstream>
+#include <log_util.h>
+#include <dlfcn.h>
+#include <cutils/properties.h>
+#include "Gnss.h"
+#include "LocationUtil.h"
+
+typedef const GnssInterface* (getLocationInterface)();
+
+#define IMAGES_INFO_FILE "/sys/devices/soc0/images"
+#define DELIMITER ";"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::visibility_control::V1_0::implementation::GnssVisibilityControl;
+
+static std::string getVersionString() {
+ static std::string version;
+ if (!version.empty())
+ return version;
+
+ char value[PROPERTY_VALUE_MAX] = {0};
+ property_get("ro.hardware", value, "unknown");
+ version.append(value).append(DELIMITER);
+
+ std::ifstream in(IMAGES_INFO_FILE);
+ std::string s;
+ while(getline(in, s)) {
+ std::size_t found = s.find("CRM:");
+ if (std::string::npos == found) {
+ continue;
+ }
+
+ // skip over space characters after "CRM:"
+ const char* substr = s.c_str();
+ found += 4;
+ while (0 != substr[found] && isspace(substr[found])) {
+ found++;
+ }
+ if (s.find("11:") != found) {
+ continue;
+ }
+ s.erase(0, found + 3);
+
+ found = s.find_first_of("\r\n");
+ if (std::string::npos != found) {
+ s.erase(s.begin() + found, s.end());
+ }
+ version.append(s).append(DELIMITER);
+ }
+ return version;
+}
+
+void Gnss::GnssDeathRecipient::serviceDied(uint64_t cookie, const wp<IBase>& who) {
+ LOC_LOGE("%s] service died. cookie: %llu, who: %p",
+ __FUNCTION__, static_cast<unsigned long long>(cookie), &who);
+ if (mGnss != nullptr) {
+ mGnss->stop();
+ mGnss->cleanup();
+ }
+}
+
+Gnss::Gnss() {
+ ENTRY_LOG_CALLFLOW();
+ // clear pending GnssConfig
+ memset(&mPendingConfig, 0, sizeof(GnssConfig));
+ mGnssDeathRecipient = new GnssDeathRecipient(this);
+}
+
+Gnss::~Gnss() {
+ ENTRY_LOG_CALLFLOW();
+ if (mApi != nullptr) {
+ delete mApi;
+ mApi = nullptr;
+ }
+}
+
+GnssAPIClient* Gnss::getApi() {
+ if (mApi == nullptr && (mGnssCbIface != nullptr || mGnssNiCbIface != nullptr)) {
+ mApi = new GnssAPIClient(mGnssCbIface, mGnssNiCbIface);
+ if (mApi == nullptr) {
+ LOC_LOGE("%s] faild to create GnssAPIClient", __FUNCTION__);
+ return mApi;
+ }
+
+ if (mPendingConfig.size == sizeof(GnssConfig)) {
+ // we have pending GnssConfig
+ mApi->gnssConfigurationUpdate(mPendingConfig);
+ // clear size to invalid mPendingConfig
+ mPendingConfig.size = 0;
+ if (mPendingConfig.assistanceServer.hostName != nullptr) {
+ free((void*)mPendingConfig.assistanceServer.hostName);
+ }
+ }
+ }
+ if (mApi == nullptr) {
+ LOC_LOGW("%s] GnssAPIClient is not ready", __FUNCTION__);
+ }
+ return mApi;
+}
+
+const GnssInterface* Gnss::getGnssInterface() {
+ static bool getGnssInterfaceFailed = false;
+ if (nullptr == mGnssInterface && !getGnssInterfaceFailed) {
+ LOC_LOGD("%s]: loading libgnss.so::getGnssInterface ...", __func__);
+ getLocationInterface* getter = NULL;
+ const char *error = NULL;
+ dlerror();
+ void *handle = dlopen("libgnss.so", RTLD_NOW);
+ if (NULL == handle || (error = dlerror()) != NULL) {
+ LOC_LOGW("dlopen for libgnss.so failed, error = %s", error);
+ } else {
+ getter = (getLocationInterface*)dlsym(handle, "getGnssInterface");
+ if ((error = dlerror()) != NULL) {
+ LOC_LOGW("dlsym for libgnss.so::getGnssInterface failed, error = %s", error);
+ getter = NULL;
+ }
+ }
+
+ if (NULL == getter) {
+ getGnssInterfaceFailed = true;
+ } else {
+ mGnssInterface = (const GnssInterface*)(*getter)();
+ }
+ }
+ return mGnssInterface;
+}
+
+Return<bool> Gnss::setCallback(const sp<V1_0::IGnssCallback>& callback) {
+ ENTRY_LOG_CALLFLOW();
+ if (mGnssCbIface != nullptr) {
+ mGnssCbIface->unlinkToDeath(mGnssDeathRecipient);
+ }
+ mGnssCbIface = callback;
+ if (mGnssCbIface != nullptr) {
+ mGnssCbIface->linkToDeath(mGnssDeathRecipient, 0 /*cookie*/);
+ }
+
+ GnssAPIClient* api = getApi();
+ if (api != nullptr) {
+ api->gnssUpdateCallbacks(mGnssCbIface, mGnssNiCbIface);
+ api->gnssEnable(LOCATION_TECHNOLOGY_TYPE_GNSS);
+ api->requestCapabilities();
+ }
+ return true;
+}
+
+Return<bool> Gnss::setGnssNiCb(const sp<IGnssNiCallback>& callback) {
+ ENTRY_LOG_CALLFLOW();
+ mGnssNiCbIface = callback;
+ GnssAPIClient* api = getApi();
+ if (api != nullptr) {
+ api->gnssUpdateCallbacks(mGnssCbIface, mGnssNiCbIface);
+ }
+ return true;
+}
+
+Return<bool> Gnss::updateConfiguration(GnssConfig& gnssConfig) {
+ ENTRY_LOG_CALLFLOW();
+ GnssAPIClient* api = getApi();
+ if (api) {
+ api->gnssConfigurationUpdate(gnssConfig);
+ } else if (gnssConfig.flags != 0) {
+ // api is not ready yet, update mPendingConfig with gnssConfig
+ mPendingConfig.size = sizeof(GnssConfig);
+
+ if (gnssConfig.flags & GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT) {
+ mPendingConfig.flags |= GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT;
+ mPendingConfig.gpsLock = gnssConfig.gpsLock;
+ }
+ if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT) {
+ mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT;
+ mPendingConfig.suplVersion = gnssConfig.suplVersion;
+ }
+ if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT) {
+ mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT;
+ mPendingConfig.assistanceServer.size = sizeof(GnssConfigSetAssistanceServer);
+ mPendingConfig.assistanceServer.type = gnssConfig.assistanceServer.type;
+ if (mPendingConfig.assistanceServer.hostName != nullptr) {
+ free((void*)mPendingConfig.assistanceServer.hostName);
+ mPendingConfig.assistanceServer.hostName =
+ strdup(gnssConfig.assistanceServer.hostName);
+ }
+ mPendingConfig.assistanceServer.port = gnssConfig.assistanceServer.port;
+ }
+ if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT) {
+ mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT;
+ mPendingConfig.lppProfile = gnssConfig.lppProfile;
+ }
+ if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT) {
+ mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT;
+ mPendingConfig.lppeControlPlaneMask = gnssConfig.lppeControlPlaneMask;
+ }
+ if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT) {
+ mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT;
+ mPendingConfig.lppeUserPlaneMask = gnssConfig.lppeUserPlaneMask;
+ }
+ if (gnssConfig.flags & GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT) {
+ mPendingConfig.flags |= GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT;
+ mPendingConfig.aGlonassPositionProtocolMask = gnssConfig.aGlonassPositionProtocolMask;
+ }
+ if (gnssConfig.flags & GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT) {
+ mPendingConfig.flags |= GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT;
+ mPendingConfig.emergencyPdnForEmergencySupl = gnssConfig.emergencyPdnForEmergencySupl;
+ }
+ if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT) {
+ mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT;
+ mPendingConfig.suplEmergencyServices = gnssConfig.suplEmergencyServices;
+ }
+ if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_MODE_BIT) {
+ mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_MODE_BIT;
+ mPendingConfig.suplModeMask = gnssConfig.suplModeMask;
+ }
+ if (gnssConfig.flags & GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT) {
+ mPendingConfig.flags |= GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT;
+ mPendingConfig.blacklistedSvIds = gnssConfig.blacklistedSvIds;
+ }
+ if (gnssConfig.flags & GNSS_CONFIG_FLAGS_EMERGENCY_EXTENSION_SECONDS_BIT) {
+ mPendingConfig.flags |= GNSS_CONFIG_FLAGS_EMERGENCY_EXTENSION_SECONDS_BIT;
+ mPendingConfig.emergencyExtensionSeconds = gnssConfig.emergencyExtensionSeconds;
+ }
+ }
+ return true;
+}
+
+Return<bool> Gnss::start() {
+ ENTRY_LOG_CALLFLOW();
+ bool retVal = false;
+ GnssAPIClient* api = getApi();
+ if (api) {
+ retVal = api->gnssStart();
+ }
+ return retVal;
+}
+
+Return<bool> Gnss::stop() {
+ ENTRY_LOG_CALLFLOW();
+ bool retVal = false;
+ GnssAPIClient* api = getApi();
+ if (api) {
+ retVal = api->gnssStop();
+ }
+ return retVal;
+}
+
+Return<void> Gnss::cleanup() {
+ ENTRY_LOG_CALLFLOW();
+
+ if (mApi != nullptr) {
+ mApi->gnssDisable();
+ }
+
+ return Void();
+}
+
+Return<bool> Gnss::injectLocation(double latitudeDegrees,
+ double longitudeDegrees,
+ float accuracyMeters) {
+ ENTRY_LOG_CALLFLOW();
+ const GnssInterface* gnssInterface = getGnssInterface();
+ if (nullptr != gnssInterface) {
+ gnssInterface->injectLocation(latitudeDegrees, longitudeDegrees, accuracyMeters);
+ return true;
+ } else {
+ return false;
+ }
+}
+
+Return<bool> Gnss::injectTime(int64_t timeMs, int64_t timeReferenceMs,
+ int32_t uncertaintyMs) {
+ ENTRY_LOG_CALLFLOW();
+ const GnssInterface* gnssInterface = getGnssInterface();
+ if (nullptr != gnssInterface) {
+ gnssInterface->injectTime(timeMs, timeReferenceMs, uncertaintyMs);
+ return true;
+ } else {
+ return false;
+ }
+}
+
+Return<void> Gnss::deleteAidingData(V1_0::IGnss::GnssAidingData aidingDataFlags) {
+ ENTRY_LOG_CALLFLOW();
+ GnssAPIClient* api = getApi();
+ if (api) {
+ api->gnssDeleteAidingData(aidingDataFlags);
+ }
+ return Void();
+}
+
+Return<bool> Gnss::setPositionMode(V1_0::IGnss::GnssPositionMode mode,
+ V1_0::IGnss::GnssPositionRecurrence recurrence,
+ uint32_t minIntervalMs,
+ uint32_t preferredAccuracyMeters,
+ uint32_t preferredTimeMs) {
+ ENTRY_LOG_CALLFLOW();
+ bool retVal = false;
+ GnssAPIClient* api = getApi();
+ if (api) {
+ retVal = api->gnssSetPositionMode(mode, recurrence, minIntervalMs,
+ preferredAccuracyMeters, preferredTimeMs);
+ }
+ return retVal;
+}
+
+Return<sp<V1_0::IAGnss>> Gnss::getExtensionAGnss() {
+ ENTRY_LOG_CALLFLOW();
+ //mAGnssIface = new ::android::hardware::gnss::V1_1::implementation::AGnss(this); //need V1_1 AGnss
+ //return mAGnssIface;
+ return nullptr;
+}
+
+Return<sp<V1_0::IGnssNi>> Gnss::getExtensionGnssNi() {
+ ENTRY_LOG_CALLFLOW();
+ mGnssNi = new GnssNi(this);
+ return mGnssNi;
+}
+
+Return<sp<V1_0::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement() {
+ ENTRY_LOG_CALLFLOW();
+ if (mGnssMeasurement == nullptr)
+ mGnssMeasurement = new GnssMeasurement();
+ return mGnssMeasurement;
+}
+
+Return<sp<V1_0::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration() {
+ ENTRY_LOG_CALLFLOW();
+ mGnssConfig = new GnssConfiguration(this);
+ return mGnssConfig;
+}
+
+Return<sp<V1_0::IGnssGeofencing>> Gnss::getExtensionGnssGeofencing() {
+ ENTRY_LOG_CALLFLOW();
+ mGnssGeofencingIface = new GnssGeofencing();
+ return mGnssGeofencingIface;
+}
+
+Return<sp<V1_0::IGnssBatching>> Gnss::getExtensionGnssBatching() {
+ ENTRY_LOG_CALLFLOW();
+ mGnssBatching = new GnssBatching();
+ return mGnssBatching;
+}
+
+Return<sp<V1_0::IGnssDebug>> Gnss::getExtensionGnssDebug() {
+ ENTRY_LOG_CALLFLOW();
+ mGnssDebug = new GnssDebug(this);
+ return mGnssDebug;
+}
+
+Return<sp<V1_0::IAGnssRil>> Gnss::getExtensionAGnssRil() {
+ ENTRY_LOG_CALLFLOW();
+ mGnssRil = new AGnssRil(this);
+ return mGnssRil;
+}
+
+// Methods from ::android::hardware::gnss::V1_1::IGnss follow.
+Return<bool> Gnss::setCallback_1_1(const sp<V1_1::IGnssCallback>& callback) {
+ ENTRY_LOG_CALLFLOW();
+ callback->gnssNameCb(getVersionString());
+ mGnssCbIface_1_1 = callback;
+ const GnssInterface* gnssInterface = getGnssInterface();
+ if (nullptr != gnssInterface) {
+ OdcpiRequestCallback cb = [this](const OdcpiRequestInfo& odcpiRequest) {
+ odcpiRequestCb(odcpiRequest);
+ };
+ gnssInterface->odcpiInit(cb);
+ }
+ return setCallback(callback);
+}
+
+Return<bool> Gnss::setPositionMode_1_1(V1_0::IGnss::GnssPositionMode mode,
+ V1_0::IGnss::GnssPositionRecurrence recurrence,
+ uint32_t minIntervalMs,
+ uint32_t preferredAccuracyMeters,
+ uint32_t preferredTimeMs,
+ bool lowPowerMode) {
+ ENTRY_LOG_CALLFLOW();
+ bool retVal = false;
+ GnssAPIClient* api = getApi();
+ if (api) {
+ GnssPowerMode powerMode = lowPowerMode?
+ GNSS_POWER_MODE_M4 : GNSS_POWER_MODE_M2;
+ retVal = api->gnssSetPositionMode(mode, recurrence, minIntervalMs,
+ preferredAccuracyMeters, preferredTimeMs, powerMode, minIntervalMs);
+ }
+ return retVal;
+}
+
+Return<sp<V1_1::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement_1_1() {
+ ENTRY_LOG_CALLFLOW();
+#ifdef GNSS_HIDL_LEGACY_MEASURMENTS
+ return nullptr;
+#else
+ if (mGnssMeasurement == nullptr)
+ mGnssMeasurement = new GnssMeasurement();
+ return mGnssMeasurement;
+#endif
+}
+
+Return<sp<V1_1::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration_1_1() {
+ ENTRY_LOG_CALLFLOW();
+ if (mGnssConfig == nullptr)
+ mGnssConfig = new GnssConfiguration(this);
+ return mGnssConfig;
+}
+
+Return<bool> Gnss::injectBestLocation(const GnssLocation& gnssLocation) {
+ ENTRY_LOG_CALLFLOW();
+ const GnssInterface* gnssInterface = getGnssInterface();
+ if (nullptr != gnssInterface) {
+ Location location = {};
+ convertGnssLocation(gnssLocation, location);
+ gnssInterface->odcpiInject(location);
+ }
+ return true;
+}
+
+void Gnss::odcpiRequestCb(const OdcpiRequestInfo& request) {
+ ENTRY_LOG_CALLFLOW();
+ if (mGnssCbIface_1_1 != nullptr) {
+ // For emergency mode, request DBH (Device based hybrid) location
+ // Mark Independent from GNSS flag to false.
+ if (ODCPI_REQUEST_TYPE_START == request.type) {
+ auto r = mGnssCbIface_1_1->gnssRequestLocationCb(!request.isEmergencyMode);
+ if (!r.isOk()) {
+ LOC_LOGe("Error invoking gnssRequestLocationCb %s", r.description().c_str());
+ }
+ } else {
+ LOC_LOGv("Unsupported ODCPI request type: %d", request.type);
+ }
+ } else {
+ LOC_LOGe("ODCPI request not supported.");
+ }
+}
+
+// Methods from ::android::hardware::gnss::V2_0::IGnss follow.
+Return<bool> Gnss::setCallback_2_0(const sp<V2_0::IGnssCallback>& callback) {
+ ENTRY_LOG_CALLFLOW();
+ return setCallback_1_1(callback);
+}
+Return<sp<V2_0::IAGnss>> Gnss::getExtensionAGnss_2_0() {
+ ENTRY_LOG_CALLFLOW();
+ mAGnssIface_2_0 = new AGnss(this);
+ return mAGnssIface_2_0;
+}
+Return<sp<V2_0::IAGnssRil>> Gnss::getExtensionAGnssRil_2_0() {
+ mGnssRil = new AGnssRil(this);
+ return mGnssRil;
+}
+
+Return<sp<V2_0::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration_2_0() {
+ ENTRY_LOG_CALLFLOW();
+ mGnssConfig = new GnssConfiguration(this);
+ return mGnssConfig;
+}
+Return<sp<V2_0::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement_2_0() {
+ ENTRY_LOG_CALLFLOW();
+#ifdef GNSS_HIDL_LEGACY_MEASURMENTS
+ return nullptr;
+#else
+ if (mGnssMeasurement == nullptr)
+ mGnssMeasurement = new GnssMeasurement();
+ return mGnssMeasurement;
+#endif
+}
+Return<sp<::android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrections>>
+ Gnss::getExtensionMeasurementCorrections() {
+ if (mGnssMeasCorr == nullptr) {
+ mGnssMeasCorr = new MeasurementCorrections();
+ }
+ return mGnssMeasCorr;
+}
+Return<sp<::android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControl>>
+ Gnss::getExtensionVisibilityControl() {
+ ENTRY_LOG_CALLFLOW();
+ if (mVisibCtrl == nullptr) {
+ mVisibCtrl = new GnssVisibilityControl(this);
+ }
+ return mVisibCtrl;
+}
+
+Return<bool> Gnss::injectBestLocation_2_0(
+ const ::android::hardware::gnss::V2_0::GnssLocation& location) {
+ ENTRY_LOG_CALLFLOW();
+ /* TBD */
+ return false;
+}
+
+Return<sp<V2_0::IGnssBatching>> Gnss::getExtensionGnssBatching_2_0() {
+ ENTRY_LOG_CALLFLOW();
+ return nullptr;
+}
+
+Return<sp<V2_0::IGnssDebug>> Gnss::getExtensionGnssDebug_2_0() {
+ ENTRY_LOG_CALLFLOW();
+ return nullptr;
+}
+
+V1_0::IGnss* HIDL_FETCH_IGnss(const char* hal) {
+ ENTRY_LOG_CALLFLOW();
+ V1_0::IGnss* iface = nullptr;
+ iface = new Gnss();
+ if (iface == nullptr) {
+ LOC_LOGE("%s]: failed to get %s", __FUNCTION__, hal);
+ }
+ return iface;
+}
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/android/2.0/Gnss.h b/android/2.0/Gnss.h
new file mode 100644
index 0000000..df62901
--- /dev/null
+++ b/android/2.0/Gnss.h
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GNSS_V2_0_GNSS_H
+#define ANDROID_HARDWARE_GNSS_V2_0_GNSS_H
+
+#include <AGnss.h>
+#include <AGnssRil.h>
+#include <GnssConfiguration.h>
+#include <GnssMeasurement.h>
+#include <GnssBatching.h>
+#include <GnssGeofencing.h>
+#include <GnssNi.h>
+#include <GnssDebug.h>
+
+#include <android/hardware/gnss/2.0/IGnss.h>
+#include <MeasurementCorrections.h>
+#include <GnssVisibilityControl.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+#include "GnssAPIClient.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+using ::android::hardware::gnss::V1_0::GnssLocation;
+using ::android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrections;
+using ::android::hardware::gnss::measurement_corrections::V1_0::implementation::MeasurementCorrections;
+using ::android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControl;
+
+struct Gnss : public IGnss {
+ Gnss();
+ ~Gnss();
+
+ /*
+ * Methods from ::android::hardware::gnss::V1_0::IGnss follow.
+ * These declarations were generated from Gnss.hal.
+ */
+ Return<bool> setCallback(const sp<V1_0::IGnssCallback>& callback) override;
+ Return<bool> start() override;
+ Return<bool> stop() override;
+ Return<void> cleanup() override;
+ Return<bool> injectLocation(double latitudeDegrees,
+ double longitudeDegrees,
+ float accuracyMeters) override;
+ Return<bool> injectTime(int64_t timeMs,
+ int64_t timeReferenceMs,
+ int32_t uncertaintyMs) override;
+ Return<void> deleteAidingData(V1_0::IGnss::GnssAidingData aidingDataFlags) override;
+ Return<bool> setPositionMode(V1_0::IGnss::GnssPositionMode mode,
+ V1_0::IGnss::GnssPositionRecurrence recurrence,
+ uint32_t minIntervalMs,
+ uint32_t preferredAccuracyMeters,
+ uint32_t preferredTimeMs) override;
+ Return<sp<V1_0::IAGnss>> getExtensionAGnss() override;
+ Return<sp<V1_0::IGnssNi>> getExtensionGnssNi() override;
+ Return<sp<V1_0::IGnssMeasurement>> getExtensionGnssMeasurement() override;
+ Return<sp<V1_0::IGnssConfiguration>> getExtensionGnssConfiguration() override;
+ Return<sp<V1_0::IGnssGeofencing>> getExtensionGnssGeofencing() override;
+ Return<sp<V1_0::IGnssBatching>> getExtensionGnssBatching() override;
+
+ Return<sp<V1_0::IAGnssRil>> getExtensionAGnssRil() override;
+
+ inline Return<sp<V1_0::IGnssNavigationMessage>> getExtensionGnssNavigationMessage() override {
+ return nullptr;
+ }
+
+ inline Return<sp<V1_0::IGnssXtra>> getExtensionXtra() override {
+ return nullptr;
+ }
+
+ Return<sp<V1_0::IGnssDebug>> getExtensionGnssDebug() override;
+
+ // Methods from ::android::hardware::gnss::V1_1::IGnss follow.
+ Return<bool> setCallback_1_1(const sp<V1_1::IGnssCallback>& callback) override;
+ Return<bool> setPositionMode_1_1(V1_0::IGnss::GnssPositionMode mode,
+ V1_0::IGnss::GnssPositionRecurrence recurrence,
+ uint32_t minIntervalMs, uint32_t preferredAccuracyMeters,
+ uint32_t preferredTimeMs, bool lowPowerMode) override;
+ Return<sp<V1_1::IGnssMeasurement>> getExtensionGnssMeasurement_1_1() override;
+ Return<sp<V1_1::IGnssConfiguration>> getExtensionGnssConfiguration_1_1() override;
+ Return<bool> injectBestLocation(const GnssLocation& location) override;
+
+ // Methods from ::android::hardware::gnss::V2_0::IGnss follow.
+ Return<bool> setCallback_2_0(const sp<V2_0::IGnssCallback>& callback) override;
+ Return<sp<V2_0::IAGnss>> getExtensionAGnss_2_0() override;
+ Return<sp<V2_0::IAGnssRil>> getExtensionAGnssRil_2_0() override;
+
+ Return<sp<V2_0::IGnssConfiguration>> getExtensionGnssConfiguration_2_0() override;
+ Return<sp<::android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrections>>
+ getExtensionMeasurementCorrections() override;
+ Return<sp<V2_0::IGnssMeasurement>> getExtensionGnssMeasurement_2_0() override;
+
+ Return<bool> injectBestLocation_2_0(const ::android::hardware::gnss::V2_0::GnssLocation& location) override;
+
+ Return<sp<V2_0::IGnssBatching>> getExtensionGnssBatching_2_0() override;
+ Return<sp<V2_0::IGnssDebug>> getExtensionGnssDebug_2_0() override;
+
+
+ /**
+ * This method returns the IGnssVisibilityControl interface.
+ *
+ * @return visibilityControlIface Handle to the IGnssVisibilityControl interface.
+ */
+ Return<sp<::android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControl>>
+ getExtensionVisibilityControl() override;
+
+
+ // These methods are not part of the IGnss base class.
+ GnssAPIClient* getApi();
+ Return<bool> setGnssNiCb(const sp<IGnssNiCallback>& niCb);
+ Return<bool> updateConfiguration(GnssConfig& gnssConfig);
+ const GnssInterface* getGnssInterface();
+
+ // Callback for ODCPI request
+ void odcpiRequestCb(const OdcpiRequestInfo& request);
+ private:
+ struct GnssDeathRecipient : hidl_death_recipient {
+ GnssDeathRecipient(sp<Gnss> gnss) : mGnss(gnss) {
+ }
+ ~GnssDeathRecipient() = default;
+ virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override;
+ sp<Gnss> mGnss;
+ };
+
+ private:
+ sp<GnssDeathRecipient> mGnssDeathRecipient = nullptr;
+
+ sp<V1_0::IGnssNi> mGnssNi = nullptr;
+ sp<V1_0::IGnssGeofencing> mGnssGeofencingIface = nullptr;
+ sp<V1_0::IGnssBatching> mGnssBatching = nullptr;
+ sp<V1_0::IGnssDebug> mGnssDebug = nullptr;
+ sp<V1_0::IAGnss> mAGnssIface = nullptr;
+ sp<V1_0::IGnssCallback> mGnssCbIface = nullptr;
+ sp<V1_0::IGnssNiCallback> mGnssNiCbIface = nullptr;
+ sp<V1_1::IGnssCallback> mGnssCbIface_1_1 = nullptr;
+ sp<V2_0::IAGnss> mAGnssIface_2_0 = nullptr;
+ sp<V2_0::IAGnssRil> mGnssRil = nullptr;
+ sp<V2_0::IGnssMeasurement> mGnssMeasurement = nullptr;
+ sp<V2_0::IGnssConfiguration> mGnssConfig = nullptr;
+ sp<IMeasurementCorrections> mGnssMeasCorr = nullptr;
+ sp<IGnssVisibilityControl> mVisibCtrl = nullptr;
+
+ GnssAPIClient* mApi = nullptr;
+ GnssConfig mPendingConfig;
+ const GnssInterface* mGnssInterface = nullptr;
+};
+
+extern "C" V1_0::IGnss* HIDL_FETCH_IGnss(const char* name);
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V2_0_GNSS_H
diff --git a/android/2.0/GnssBatching.cpp b/android/2.0/GnssBatching.cpp
new file mode 100644
index 0000000..cf215ea
--- /dev/null
+++ b/android/2.0/GnssBatching.cpp
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "LocSvc_GnssBatchingInterface"
+
+#include <log_util.h>
+#include <BatchingAPIClient.h>
+#include "GnssBatching.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+void GnssBatching::GnssBatchingDeathRecipient::serviceDied(
+ uint64_t cookie, const wp<IBase>& who) {
+ LOC_LOGE("%s] service died. cookie: %llu, who: %p",
+ __FUNCTION__, static_cast<unsigned long long>(cookie), &who);
+ if (mGnssBatching != nullptr) {
+ mGnssBatching->stop();
+ mGnssBatching->cleanup();
+ }
+}
+
+GnssBatching::GnssBatching() : mApi(nullptr) {
+ mGnssBatchingDeathRecipient = new GnssBatchingDeathRecipient(this);
+}
+
+GnssBatching::~GnssBatching() {
+ if (mApi != nullptr) {
+ delete mApi;
+ mApi = nullptr;
+ }
+}
+
+
+// Methods from ::android::hardware::gnss::V1_0::IGnssBatching follow.
+Return<bool> GnssBatching::init(const sp<IGnssBatchingCallback>& callback) {
+ if (mApi != nullptr) {
+ LOC_LOGD("%s]: mApi is NOT nullptr, delete it first", __FUNCTION__);
+ delete mApi;
+ mApi = nullptr;
+ }
+
+ mApi = new BatchingAPIClient(callback);
+ if (mApi == nullptr) {
+ LOC_LOGE("%s]: failed to create mApi", __FUNCTION__);
+ return false;
+ }
+
+ if (mGnssBatchingCbIface != nullptr) {
+ mGnssBatchingCbIface->unlinkToDeath(mGnssBatchingDeathRecipient);
+ }
+ mGnssBatchingCbIface = callback;
+ if (mGnssBatchingCbIface != nullptr) {
+ mGnssBatchingCbIface->linkToDeath(mGnssBatchingDeathRecipient, 0 /*cookie*/);
+ }
+
+ return true;
+}
+
+Return<uint16_t> GnssBatching::getBatchSize() {
+ uint16_t ret = 0;
+ if (mApi == nullptr) {
+ LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+ } else {
+ ret = mApi->getBatchSize();
+ }
+ return ret;
+}
+
+Return<bool> GnssBatching::start(const IGnssBatching::Options& options) {
+ bool ret = false;
+ if (mApi == nullptr) {
+ LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+ } else {
+ ret = mApi->startSession(options);
+ }
+ return ret;
+}
+
+Return<void> GnssBatching::flush() {
+ if (mApi == nullptr) {
+ LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+ } else {
+ mApi->flushBatchedLocations();
+ }
+ return Void();
+}
+
+Return<bool> GnssBatching::stop() {
+ bool ret = false;
+ if (mApi == nullptr) {
+ LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+ } else {
+ ret = mApi->stopSession();
+ }
+ return ret;
+}
+
+Return<void> GnssBatching::cleanup() {
+ if (mGnssBatchingCbIface != nullptr) {
+ mGnssBatchingCbIface->unlinkToDeath(mGnssBatchingDeathRecipient);
+ }
+ return Void();
+}
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/android/2.0/GnssBatching.h b/android/2.0/GnssBatching.h
new file mode 100644
index 0000000..f7dc65b
--- /dev/null
+++ b/android/2.0/GnssBatching.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GNSS_V2_0_GNSSBATCHING_H
+#define ANDROID_HARDWARE_GNSS_V2_0_GNSSBATCHING_H
+
+#include <android/hardware/gnss/1.0/IGnssBatching.h>
+#include <hidl/Status.h>
+
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IGnssBatching;
+using ::android::hardware::gnss::V1_0::IGnssBatchingCallback;
+using ::android::hidl::base::V1_0::IBase;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+class BatchingAPIClient;
+struct GnssBatching : public IGnssBatching {
+ GnssBatching();
+ ~GnssBatching();
+
+ // Methods from ::android::hardware::gnss::V1_0::IGnssBatching follow.
+ Return<bool> init(const sp<IGnssBatchingCallback>& callback) override;
+ Return<uint16_t> getBatchSize() override;
+ Return<bool> start(const IGnssBatching::Options& options ) override;
+ Return<void> flush() override;
+ Return<bool> stop() override;
+ Return<void> cleanup() override;
+
+ private:
+ struct GnssBatchingDeathRecipient : hidl_death_recipient {
+ GnssBatchingDeathRecipient(sp<GnssBatching> gnssBatching) :
+ mGnssBatching(gnssBatching) {
+ }
+ ~GnssBatchingDeathRecipient() = default;
+ virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override;
+ sp<GnssBatching> mGnssBatching;
+ };
+
+ private:
+ sp<GnssBatchingDeathRecipient> mGnssBatchingDeathRecipient = nullptr;
+ sp<IGnssBatchingCallback> mGnssBatchingCbIface = nullptr;
+ BatchingAPIClient* mApi = nullptr;
+};
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V2_0_GNSSBATCHING_H
diff --git a/android/2.0/GnssConfiguration.cpp b/android/2.0/GnssConfiguration.cpp
new file mode 100644
index 0000000..eb98be1
--- /dev/null
+++ b/android/2.0/GnssConfiguration.cpp
@@ -0,0 +1,304 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "LocSvc_GnssConfigurationInterface"
+
+#include <log_util.h>
+#include "Gnss.h"
+#include "GnssConfiguration.h"
+#include <android/hardware/gnss/1.0/types.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::GnssConstellationType;
+
+GnssConfiguration::GnssConfiguration(Gnss* gnss) : mGnss(gnss) {
+}
+
+// Methods from ::android::hardware::gps::V1_0::IGnssConfiguration follow.
+Return<bool> GnssConfiguration::setSuplEs(bool enabled) {
+ if (mGnss == nullptr) {
+ LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
+ return false;
+ }
+
+ GnssConfig config;
+ memset(&config, 0, sizeof(GnssConfig));
+ config.size = sizeof(GnssConfig);
+ config.flags = GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT;
+ config.suplEmergencyServices = (enabled ?
+ GNSS_CONFIG_SUPL_EMERGENCY_SERVICES_YES :
+ GNSS_CONFIG_SUPL_EMERGENCY_SERVICES_NO);
+
+ return mGnss->updateConfiguration(config);
+}
+
+Return<bool> GnssConfiguration::setSuplVersion(uint32_t version) {
+ if (mGnss == nullptr) {
+ LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
+ return false;
+ }
+
+ GnssConfig config;
+ memset(&config, 0, sizeof(GnssConfig));
+ config.size = sizeof(GnssConfig);
+ config.flags = GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT;
+ switch (version) {
+ case 0x00020002:
+ config.suplVersion = GNSS_CONFIG_SUPL_VERSION_2_0_2;
+ break;
+ case 0x00020000:
+ config.suplVersion = GNSS_CONFIG_SUPL_VERSION_2_0_0;
+ break;
+ case 0x00010000:
+ config.suplVersion = GNSS_CONFIG_SUPL_VERSION_1_0_0;
+ break;
+ default:
+ LOC_LOGE("%s]: invalid version: 0x%x.", __FUNCTION__, version);
+ return false;
+ break;
+ }
+
+ return mGnss->updateConfiguration(config);
+}
+
+Return<bool> GnssConfiguration::setSuplMode(uint8_t mode) {
+ if (mGnss == nullptr) {
+ LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
+ return false;
+ }
+
+ GnssConfig config;
+ memset(&config, 0, sizeof(GnssConfig));
+ config.size = sizeof(GnssConfig);
+ config.flags = GNSS_CONFIG_FLAGS_SUPL_MODE_BIT;
+ switch (mode) {
+ case 0:
+ config.suplModeMask = 0; // STANDALONE ONLY
+ break;
+ case 1:
+ config.suplModeMask = GNSS_CONFIG_SUPL_MODE_MSB_BIT;
+ break;
+ case 2:
+ config.suplModeMask = GNSS_CONFIG_SUPL_MODE_MSA_BIT;
+ break;
+ case 3:
+ config.suplModeMask = GNSS_CONFIG_SUPL_MODE_MSB_BIT | GNSS_CONFIG_SUPL_MODE_MSA_BIT;
+ break;
+ default:
+ LOC_LOGE("%s]: invalid mode: %d.", __FUNCTION__, mode);
+ return false;
+ break;
+ }
+
+ return mGnss->updateConfiguration(config);
+}
+
+Return<bool> GnssConfiguration::setLppProfile(uint8_t lppProfile) {
+ if (mGnss == nullptr) {
+ LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
+ return false;
+ }
+
+ GnssConfig config;
+ memset(&config, 0, sizeof(GnssConfig));
+ config.size = sizeof(GnssConfig);
+ config.flags = GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT;
+ switch (lppProfile) {
+ case 0:
+ config.lppProfile = GNSS_CONFIG_LPP_PROFILE_RRLP_ON_LTE;
+ break;
+ case 1:
+ config.lppProfile = GNSS_CONFIG_LPP_PROFILE_USER_PLANE;
+ break;
+ case 2:
+ config.lppProfile = GNSS_CONFIG_LPP_PROFILE_CONTROL_PLANE;
+ break;
+ case 3:
+ config.lppProfile = GNSS_CONFIG_LPP_PROFILE_USER_PLANE_AND_CONTROL_PLANE;
+ break;
+ default:
+ LOC_LOGE("%s]: invalid lppProfile: %d.", __FUNCTION__, lppProfile);
+ return false;
+ break;
+ }
+
+ return mGnss->updateConfiguration(config);
+}
+
+Return<bool> GnssConfiguration::setGlonassPositioningProtocol(uint8_t protocol) {
+ if (mGnss == nullptr) {
+ LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
+ return false;
+ }
+
+ GnssConfig config;
+ memset(&config, 0, sizeof(GnssConfig));
+ config.size = sizeof(GnssConfig);
+
+ config.flags = GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT;
+ if (protocol & (1<<0)) {
+ config.aGlonassPositionProtocolMask |= GNSS_CONFIG_RRC_CONTROL_PLANE_BIT;
+ }
+ if (protocol & (1<<1)) {
+ config.aGlonassPositionProtocolMask |= GNSS_CONFIG_RRLP_USER_PLANE_BIT;
+ }
+ if (protocol & (1<<2)) {
+ config.aGlonassPositionProtocolMask |= GNSS_CONFIG_LLP_USER_PLANE_BIT;
+ }
+ if (protocol & (1<<3)) {
+ config.aGlonassPositionProtocolMask |= GNSS_CONFIG_LLP_CONTROL_PLANE_BIT;
+ }
+
+ return mGnss->updateConfiguration(config);
+}
+
+Return<bool> GnssConfiguration::setGpsLock(uint8_t lock) {
+ /* we no longer set GPS lock here, there is
+ visibility control for this */
+ return true;
+}
+
+Return<bool> GnssConfiguration::setEmergencySuplPdn(bool enabled) {
+ if (mGnss == nullptr) {
+ LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
+ return false;
+ }
+
+ GnssConfig config;
+ memset(&config, 0, sizeof(GnssConfig));
+ config.size = sizeof(GnssConfig);
+ config.flags = GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT;
+ config.emergencyPdnForEmergencySupl = (enabled ?
+ GNSS_CONFIG_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_YES :
+ GNSS_CONFIG_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_NO);
+
+ return mGnss->updateConfiguration(config);
+}
+
+// Methods from ::android::hardware::gnss::V1_1::IGnssConfiguration follow.
+Return<bool> GnssConfiguration::setBlacklist(
+ const hidl_vec<GnssConfiguration::BlacklistedSource>& blacklist) {
+
+ ENTRY_LOG_CALLFLOW();
+ if (nullptr == mGnss) {
+ LOC_LOGe("mGnss is null");
+ return false;
+ }
+
+ // blValid is true if blacklist is empty, i.e. clearing the BL;
+ // if blacklist is not empty, blValid is initialied to false, and later
+ // updated in the for loop to become true only if there is at least
+ // one {constellation, svid} in the list that is valid.
+ bool blValid = (0 == blacklist.size());
+ GnssConfig config;
+ memset(&config, 0, sizeof(GnssConfig));
+ config.size = sizeof(GnssConfig);
+ config.flags = GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT;
+ config.blacklistedSvIds.clear();
+
+ GnssSvIdSource source = {};
+ for (int idx = 0; idx < (int)blacklist.size(); idx++) {
+ // Set blValid true if any one source is valid
+ blValid = setBlacklistedSource(source, blacklist[idx]) || blValid;
+ config.blacklistedSvIds.push_back(source);
+ }
+
+ // Update configuration only if blValid is true
+ // i.e. only if atleast one source is valid for blacklisting
+ return (blValid && mGnss->updateConfiguration(config));
+}
+
+bool GnssConfiguration::setBlacklistedSource(
+ GnssSvIdSource& copyToSource,
+ const GnssConfiguration::BlacklistedSource& copyFromSource) {
+
+ bool retVal = true;
+ uint16_t svIdOffset = 0;
+ copyToSource.size = sizeof(GnssSvIdSource);
+ copyToSource.svId = copyFromSource.svid;
+
+ switch(copyFromSource.constellation) {
+ case GnssConstellationType::GPS:
+ copyToSource.constellation = GNSS_SV_TYPE_GPS;
+ LOC_LOGe("GPS SVs can't be blacklisted.");
+ retVal = false;
+ break;
+ case GnssConstellationType::SBAS:
+ copyToSource.constellation = GNSS_SV_TYPE_SBAS;
+ LOC_LOGe("SBAS SVs can't be blacklisted.");
+ retVal = false;
+ break;
+ case GnssConstellationType::GLONASS:
+ copyToSource.constellation = GNSS_SV_TYPE_GLONASS;
+ svIdOffset = GNSS_SV_CONFIG_GLO_INITIAL_SV_ID - 1;
+ break;
+ case GnssConstellationType::QZSS:
+ copyToSource.constellation = GNSS_SV_TYPE_QZSS;
+ svIdOffset = 0;
+ break;
+ case GnssConstellationType::BEIDOU:
+ copyToSource.constellation = GNSS_SV_TYPE_BEIDOU;
+ svIdOffset = GNSS_SV_CONFIG_BDS_INITIAL_SV_ID - 1;
+ break;
+ case GnssConstellationType::GALILEO:
+ copyToSource.constellation = GNSS_SV_TYPE_GALILEO;
+ svIdOffset = GNSS_SV_CONFIG_GAL_INITIAL_SV_ID - 1;
+ break;
+ default:
+ copyToSource.constellation = GNSS_SV_TYPE_UNKNOWN;
+ LOC_LOGe("Invalid constellation %d", copyFromSource.constellation);
+ retVal = false;
+ break;
+ }
+
+ if (copyToSource.svId > 0 && svIdOffset > 0) {
+ copyToSource.svId += svIdOffset;
+ }
+
+ return retVal;
+}
+
+// Methods from ::android::hardware::gnss::V2_0::IGnssConfiguration follow.
+Return<bool> GnssConfiguration::setEsExtensionSec(uint32_t emergencyExtensionSeconds) {
+ ENTRY_LOG_CALLFLOW();
+ if (mGnss == nullptr) {
+ LOC_LOGe("mGnss is nullptr");
+ return false;
+ }
+
+ GnssConfig config;
+ memset(&config, 0, sizeof(GnssConfig));
+ config.size = sizeof(GnssConfig);
+ config.flags = GNSS_CONFIG_FLAGS_EMERGENCY_EXTENSION_SECONDS_BIT;
+ config.emergencyExtensionSeconds = emergencyExtensionSeconds;
+
+ return mGnss->updateConfiguration(config);
+}
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/android/2.0/GnssConfiguration.h b/android/2.0/GnssConfiguration.h
new file mode 100644
index 0000000..202a9fd
--- /dev/null
+++ b/android/2.0/GnssConfiguration.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+
+ /* Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef ANDROID_HARDWARE_GNSS_V2_0_GNSSCONFIGURATION_H
+#define ANDROID_HARDWARE_GNSS_V2_0_GNSSCONFIGURATION_H
+
+#include <android/hardware/gnss/2.0/IGnssConfiguration.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+/*
+ * Interface for passing GNSS configuration info from platform to HAL.
+ */
+struct Gnss;
+struct GnssConfiguration : public V2_0::IGnssConfiguration {
+ GnssConfiguration(Gnss* gnss);
+ ~GnssConfiguration() = default;
+
+ /*
+ * Methods from ::android::hardware::gnss::V1_0::IGnssConfiguration follow.
+ * These declarations were generated from IGnssConfiguration.hal.
+ */
+ Return<bool> setSuplVersion(uint32_t version) override;
+ Return<bool> setSuplMode(uint8_t mode) override;
+ Return<bool> setSuplEs(bool enabled) override;
+ Return<bool> setLppProfile(uint8_t lppProfile) override;
+ Return<bool> setGlonassPositioningProtocol(uint8_t protocol) override;
+ Return<bool> setEmergencySuplPdn(bool enable) override;
+ Return<bool> setGpsLock(uint8_t lock) override;
+
+ // Methods from ::android::hardware::gnss::V1_1::IGnssConfiguration follow.
+ Return<bool> setBlacklist(
+ const hidl_vec<GnssConfiguration::BlacklistedSource>& blacklist) override;
+
+ // Methods from ::android::hardware::gnss::V2_0::IGnssConfiguration follow.
+ Return<bool> setEsExtensionSec(uint32_t emergencyExtensionSeconds) override;
+
+ private:
+ Gnss* mGnss = nullptr;
+ bool setBlacklistedSource(
+ GnssSvIdSource& copyToSource,
+ const GnssConfiguration::BlacklistedSource& copyFromSource);
+};
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V2_0_GNSSCONFIGURATION_H
diff --git a/android/2.0/GnssDebug.cpp b/android/2.0/GnssDebug.cpp
new file mode 100644
index 0000000..582acc9
--- /dev/null
+++ b/android/2.0/GnssDebug.cpp
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "LocSvc_GnssDebugInterface"
+
+#include <log/log.h>
+#include <log_util.h>
+#include "Gnss.h"
+#include "GnssDebug.h"
+#include "LocationUtil.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::hidl_vec;
+
+#define GNSS_DEBUG_UNKNOWN_HORIZONTAL_ACCURACY_METERS (20000000)
+#define GNSS_DEBUG_UNKNOWN_VERTICAL_ACCURACY_METERS (20000)
+#define GNSS_DEBUG_UNKNOWN_SPEED_ACCURACY_PER_SEC (500)
+#define GNSS_DEBUG_UNKNOWN_BEARING_ACCURACY_DEG (180)
+
+#define GNSS_DEBUG_UNKNOWN_UTC_TIME (1483228800000LL) // 1/1/2017 00:00 GMT
+#define GNSS_DEBUG_UNKNOWN_UTC_TIME_UNC (1.57783680E17) // 5 years in ns
+#define GNSS_DEBUG_UNKNOWN_FREQ_UNC_NS_PER_SEC (2.0e5) // ppm
+
+GnssDebug::GnssDebug(Gnss* gnss) : mGnss(gnss)
+{
+}
+
+/*
+ * This methods requests position, time and satellite ephemeris debug information
+ * from the HAL.
+ *
+ * @return void
+*/
+Return<void> GnssDebug::getDebugData(getDebugData_cb _hidl_cb)
+{
+ LOC_LOGD("%s]: ", __func__);
+
+ DebugData data = { };
+
+ if((nullptr == mGnss) || (nullptr == mGnss->getGnssInterface())){
+ LOC_LOGE("GnssDebug - Null GNSS interface");
+ _hidl_cb(data);
+ return Void();
+ }
+
+ // get debug report snapshot via hal interface
+ GnssDebugReport reports = { };
+ mGnss->getGnssInterface()->getDebugReport(reports);
+
+ // location block
+ if (reports.mLocation.mValid) {
+ data.position.valid = true;
+ data.position.latitudeDegrees = reports.mLocation.mLocation.latitude;
+ data.position.longitudeDegrees = reports.mLocation.mLocation.longitude;
+ data.position.altitudeMeters = reports.mLocation.mLocation.altitude;
+
+ data.position.speedMetersPerSec =
+ (double)(reports.mLocation.mLocation.speed);
+ data.position.bearingDegrees =
+ (double)(reports.mLocation.mLocation.bearing);
+ data.position.horizontalAccuracyMeters =
+ (double)(reports.mLocation.mLocation.accuracy);
+ data.position.verticalAccuracyMeters =
+ reports.mLocation.verticalAccuracyMeters;
+ data.position.speedAccuracyMetersPerSecond =
+ reports.mLocation.speedAccuracyMetersPerSecond;
+ data.position.bearingAccuracyDegrees =
+ reports.mLocation.bearingAccuracyDegrees;
+
+ timeval tv_now, tv_report;
+ tv_report.tv_sec = reports.mLocation.mUtcReported.tv_sec;
+ tv_report.tv_usec = reports.mLocation.mUtcReported.tv_nsec / 1000ULL;
+ gettimeofday(&tv_now, NULL);
+ data.position.ageSeconds =
+ (tv_now.tv_sec - tv_report.tv_sec) +
+ (float)((tv_now.tv_usec - tv_report.tv_usec)) / 1000000;
+ }
+ else {
+ data.position.valid = false;
+ }
+
+ if (data.position.horizontalAccuracyMeters <= 0 ||
+ data.position.horizontalAccuracyMeters > GNSS_DEBUG_UNKNOWN_HORIZONTAL_ACCURACY_METERS) {
+ data.position.horizontalAccuracyMeters = GNSS_DEBUG_UNKNOWN_HORIZONTAL_ACCURACY_METERS;
+ }
+ if (data.position.verticalAccuracyMeters <= 0 ||
+ data.position.verticalAccuracyMeters > GNSS_DEBUG_UNKNOWN_VERTICAL_ACCURACY_METERS) {
+ data.position.verticalAccuracyMeters = GNSS_DEBUG_UNKNOWN_VERTICAL_ACCURACY_METERS;
+ }
+ if (data.position.speedAccuracyMetersPerSecond <= 0 ||
+ data.position.speedAccuracyMetersPerSecond > GNSS_DEBUG_UNKNOWN_SPEED_ACCURACY_PER_SEC) {
+ data.position.speedAccuracyMetersPerSecond = GNSS_DEBUG_UNKNOWN_SPEED_ACCURACY_PER_SEC;
+ }
+ if (data.position.bearingAccuracyDegrees <= 0 ||
+ data.position.bearingAccuracyDegrees > GNSS_DEBUG_UNKNOWN_BEARING_ACCURACY_DEG) {
+ data.position.bearingAccuracyDegrees = GNSS_DEBUG_UNKNOWN_BEARING_ACCURACY_DEG;
+ }
+
+ // time block
+ if (reports.mTime.mValid) {
+ data.time.timeEstimate = reports.mTime.timeEstimate;
+ data.time.timeUncertaintyNs = reports.mTime.timeUncertaintyNs;
+ data.time.frequencyUncertaintyNsPerSec =
+ reports.mTime.frequencyUncertaintyNsPerSec;
+ }
+
+ if (data.time.timeEstimate < GNSS_DEBUG_UNKNOWN_UTC_TIME) {
+ data.time.timeEstimate = GNSS_DEBUG_UNKNOWN_UTC_TIME;
+ }
+ if (data.time.timeUncertaintyNs <= 0 ||
+ data.time.timeUncertaintyNs > (float)GNSS_DEBUG_UNKNOWN_UTC_TIME_UNC) {
+ data.time.timeUncertaintyNs = (float)GNSS_DEBUG_UNKNOWN_UTC_TIME_UNC;
+ }
+ if (data.time.frequencyUncertaintyNsPerSec <= 0 ||
+ data.time.frequencyUncertaintyNsPerSec > (float)GNSS_DEBUG_UNKNOWN_FREQ_UNC_NS_PER_SEC) {
+ data.time.frequencyUncertaintyNsPerSec = (float)GNSS_DEBUG_UNKNOWN_FREQ_UNC_NS_PER_SEC;
+ }
+
+ // satellite data block
+ SatelliteData s = { };
+ std::vector<SatelliteData> s_array = { };
+
+ for (uint32_t i=0; i<reports.mSatelliteInfo.size(); i++) {
+ memset(&s, 0, sizeof(s));
+ s.svid = reports.mSatelliteInfo[i].svid;
+ convertGnssConstellationType(
+ reports.mSatelliteInfo[i].constellation, s.constellation);
+ convertGnssEphemerisType(
+ reports.mSatelliteInfo[i].mEphemerisType, s.ephemerisType);
+ convertGnssEphemerisSource(
+ reports.mSatelliteInfo[i].mEphemerisSource, s.ephemerisSource);
+ convertGnssEphemerisHealth(
+ reports.mSatelliteInfo[i].mEphemerisHealth, s.ephemerisHealth);
+
+ s.ephemerisAgeSeconds =
+ reports.mSatelliteInfo[i].ephemerisAgeSeconds;
+ s.serverPredictionIsAvailable =
+ reports.mSatelliteInfo[i].serverPredictionIsAvailable;
+ s.serverPredictionAgeSeconds =
+ reports.mSatelliteInfo[i].serverPredictionAgeSeconds;
+
+ s_array.push_back(s);
+ }
+ data.satelliteDataArray = s_array;
+
+ // callback HIDL with collected debug data
+ _hidl_cb(data);
+ return Void();
+}
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/android/2.0/GnssDebug.h b/android/2.0/GnssDebug.h
new file mode 100644
index 0000000..8d4fde3
--- /dev/null
+++ b/android/2.0/GnssDebug.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GNSS_V2_0_GNSSDEBUG_H
+#define ANDROID_HARDWARE_GNSS_V2_0_GNSSDEBUG_H
+
+
+#include <android/hardware/gnss/1.0/IGnssDebug.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IGnssDebug;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+/* Interface for GNSS Debug support. */
+struct Gnss;
+struct GnssDebug : public IGnssDebug {
+ GnssDebug(Gnss* gnss);
+ ~GnssDebug() {};
+
+ /*
+ * Methods from ::android::hardware::gnss::V1_0::IGnssDebug follow.
+ * These declarations were generated from IGnssDebug.hal.
+ */
+ Return<void> getDebugData(getDebugData_cb _hidl_cb) override;
+
+private:
+ Gnss* mGnss = nullptr;
+};
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V2_0_GNSSDEBUG_H
diff --git a/android/2.0/GnssGeofencing.cpp b/android/2.0/GnssGeofencing.cpp
new file mode 100644
index 0000000..b72d835
--- /dev/null
+++ b/android/2.0/GnssGeofencing.cpp
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "GnssHal_GnssGeofencing"
+
+#include <log_util.h>
+#include <GeofenceAPIClient.h>
+#include "GnssGeofencing.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+void GnssGeofencing::GnssGeofencingDeathRecipient::serviceDied(
+ uint64_t cookie, const wp<IBase>& who) {
+ LOC_LOGE("%s] service died. cookie: %llu, who: %p",
+ __FUNCTION__, static_cast<unsigned long long>(cookie), &who);
+ if (mGnssGeofencing != nullptr) {
+ mGnssGeofencing->removeAllGeofences();
+ }
+}
+
+GnssGeofencing::GnssGeofencing() : mApi(nullptr) {
+ mGnssGeofencingDeathRecipient = new GnssGeofencingDeathRecipient(this);
+}
+
+GnssGeofencing::~GnssGeofencing() {
+ if (mApi != nullptr) {
+ delete mApi;
+ mApi = nullptr;
+ }
+}
+
+// Methods from ::android::hardware::gnss::V1_0::IGnssGeofencing follow.
+Return<void> GnssGeofencing::setCallback(const sp<IGnssGeofenceCallback>& callback) {
+ if (mApi != nullptr) {
+ LOC_LOGd("mApi is NOT nullptr");
+ return Void();
+ }
+
+ mApi = new GeofenceAPIClient(callback);
+ if (mApi == nullptr) {
+ LOC_LOGE("%s]: failed to create mApi", __FUNCTION__);
+ }
+
+ if (mGnssGeofencingCbIface != nullptr) {
+ mGnssGeofencingCbIface->unlinkToDeath(mGnssGeofencingDeathRecipient);
+ }
+ mGnssGeofencingCbIface = callback;
+ if (mGnssGeofencingCbIface != nullptr) {
+ mGnssGeofencingCbIface->linkToDeath(mGnssGeofencingDeathRecipient, 0 /*cookie*/);
+ }
+
+ return Void();
+}
+
+Return<void> GnssGeofencing::addGeofence(
+ int32_t geofenceId,
+ double latitudeDegrees,
+ double longitudeDegrees,
+ double radiusMeters,
+ IGnssGeofenceCallback::GeofenceTransition lastTransition,
+ int32_t monitorTransitions,
+ uint32_t notificationResponsivenessMs,
+ uint32_t unknownTimerMs) {
+ if (mApi == nullptr) {
+ LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+ } else {
+ mApi->geofenceAdd(
+ geofenceId,
+ latitudeDegrees,
+ longitudeDegrees,
+ radiusMeters,
+ static_cast<int32_t>(lastTransition),
+ monitorTransitions,
+ notificationResponsivenessMs,
+ unknownTimerMs);
+ }
+ return Void();
+}
+
+Return<void> GnssGeofencing::pauseGeofence(int32_t geofenceId) {
+ if (mApi == nullptr) {
+ LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+ } else {
+ mApi->geofencePause(geofenceId);
+ }
+ return Void();
+}
+
+Return<void> GnssGeofencing::resumeGeofence(int32_t geofenceId, int32_t monitorTransitions) {
+ if (mApi == nullptr) {
+ LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+ } else {
+ mApi->geofenceResume(geofenceId, monitorTransitions);
+ }
+ return Void();
+}
+
+Return<void> GnssGeofencing::removeGeofence(int32_t geofenceId) {
+ if (mApi == nullptr) {
+ LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+ } else {
+ mApi->geofenceRemove(geofenceId);
+ }
+ return Void();
+}
+
+Return<void> GnssGeofencing::removeAllGeofences() {
+ if (mApi == nullptr) {
+ LOC_LOGD("%s]: mApi is nullptr, do nothing", __FUNCTION__);
+ } else {
+ mApi->geofenceRemoveAll();
+ }
+ return Void();
+}
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/android/2.0/GnssGeofencing.h b/android/2.0/GnssGeofencing.h
new file mode 100644
index 0000000..caa56d0
--- /dev/null
+++ b/android/2.0/GnssGeofencing.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GNSS_V2_0_GNSSGEOFENCING_H
+#define ANDROID_HARDWARE_GNSS_V2_0_GNSSGEOFENCING_H
+
+#include <android/hardware/gnss/1.0/IGnssGeofencing.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IGnssGeofenceCallback;
+using ::android::hardware::gnss::V1_0::IGnssGeofencing;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+class GeofenceAPIClient;
+struct GnssGeofencing : public IGnssGeofencing {
+ GnssGeofencing();
+ ~GnssGeofencing();
+
+ /*
+ * Methods from ::android::hardware::gnss::V1_0::IGnssGeofencing follow.
+ * These declarations were generated from IGnssGeofencing.hal.
+ */
+ Return<void> setCallback(const sp<IGnssGeofenceCallback>& callback) override;
+ Return<void> addGeofence(int32_t geofenceId,
+ double latitudeDegrees,
+ double longitudeDegrees,
+ double radiusMeters,
+ IGnssGeofenceCallback::GeofenceTransition lastTransition,
+ int32_t monitorTransitions,
+ uint32_t notificationResponsivenessMs,
+ uint32_t unknownTimerMs) override;
+
+ Return<void> pauseGeofence(int32_t geofenceId) override;
+ Return<void> resumeGeofence(int32_t geofenceId, int32_t monitorTransitions) override;
+ Return<void> removeGeofence(int32_t geofenceId) override;
+
+ private:
+ // This method is not part of the IGnss base class.
+ // It is called by GnssGeofencingDeathRecipient to remove all geofences added so far.
+ Return<void> removeAllGeofences();
+
+ private:
+ struct GnssGeofencingDeathRecipient : hidl_death_recipient {
+ GnssGeofencingDeathRecipient(sp<GnssGeofencing> gnssGeofencing) :
+ mGnssGeofencing(gnssGeofencing) {
+ }
+ ~GnssGeofencingDeathRecipient() = default;
+ virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override;
+ sp<GnssGeofencing> mGnssGeofencing;
+ };
+
+ private:
+ sp<GnssGeofencingDeathRecipient> mGnssGeofencingDeathRecipient = nullptr;
+ sp<IGnssGeofenceCallback> mGnssGeofencingCbIface = nullptr;
+ GeofenceAPIClient* mApi = nullptr;
+};
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V2_0_GNSSGEOFENCING_H
diff --git a/android/2.0/GnssMeasurement.cpp b/android/2.0/GnssMeasurement.cpp
new file mode 100644
index 0000000..721a48c
--- /dev/null
+++ b/android/2.0/GnssMeasurement.cpp
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "LocSvc_GnssMeasurementInterface"
+
+#include <log_util.h>
+#include "GnssMeasurement.h"
+#include "MeasurementAPIClient.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+void GnssMeasurement::GnssMeasurementDeathRecipient::serviceDied(
+ uint64_t cookie, const wp<IBase>& who) {
+ LOC_LOGE("%s] service died. cookie: %llu, who: %p",
+ __FUNCTION__, static_cast<unsigned long long>(cookie), &who);
+ if (mGnssMeasurement != nullptr) {
+ mGnssMeasurement->close();
+ }
+}
+
+GnssMeasurement::GnssMeasurement() {
+ mGnssMeasurementDeathRecipient = new GnssMeasurementDeathRecipient(this);
+ mApi = new MeasurementAPIClient();
+}
+
+GnssMeasurement::~GnssMeasurement() {
+ if (mApi) {
+ delete mApi;
+ mApi = nullptr;
+ }
+}
+
+// Methods from ::android::hardware::gnss::V1_0::IGnssMeasurement follow.
+Return<GnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback(
+ const sp<V1_0::IGnssMeasurementCallback>& callback) {
+
+ Return<GnssMeasurement::GnssMeasurementStatus> ret =
+ IGnssMeasurement::GnssMeasurementStatus::ERROR_GENERIC;
+ if (mGnssMeasurementCbIface != nullptr) {
+ LOC_LOGE("%s]: GnssMeasurementCallback is already set", __FUNCTION__);
+ return IGnssMeasurement::GnssMeasurementStatus::ERROR_ALREADY_INIT;
+ }
+
+ if (callback == nullptr) {
+ LOC_LOGE("%s]: callback is nullptr", __FUNCTION__);
+ return ret;
+ }
+ if (mApi == nullptr) {
+ LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+ return ret;
+ }
+
+ mGnssMeasurementCbIface = callback;
+ mGnssMeasurementCbIface->linkToDeath(mGnssMeasurementDeathRecipient, 0);
+
+ return mApi->measurementSetCallback(callback);
+}
+
+Return<void> GnssMeasurement::close() {
+ if (mApi == nullptr) {
+ LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+ return Void();
+ }
+
+ if (mGnssMeasurementCbIface != nullptr) {
+ mGnssMeasurementCbIface->unlinkToDeath(mGnssMeasurementDeathRecipient);
+ mGnssMeasurementCbIface = nullptr;
+ }
+ if (mGnssMeasurementCbIface_1_1 != nullptr) {
+ mGnssMeasurementCbIface_1_1->unlinkToDeath(mGnssMeasurementDeathRecipient);
+ mGnssMeasurementCbIface_1_1 = nullptr;
+ }
+ if (mGnssMeasurementCbIface_2_0 != nullptr) {
+ mGnssMeasurementCbIface_2_0->unlinkToDeath(mGnssMeasurementDeathRecipient);
+ mGnssMeasurementCbIface_2_0 = nullptr;
+ }
+ mApi->measurementClose();
+
+ return Void();
+}
+
+// Methods from ::android::hardware::gnss::V1_1::IGnssMeasurement follow.
+Return<GnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback_1_1(
+ const sp<V1_1::IGnssMeasurementCallback>& callback, bool enableFullTracking) {
+
+ Return<GnssMeasurement::GnssMeasurementStatus> ret =
+ IGnssMeasurement::GnssMeasurementStatus::ERROR_GENERIC;
+ if (mGnssMeasurementCbIface_1_1 != nullptr) {
+ LOC_LOGE("%s]: GnssMeasurementCallback is already set", __FUNCTION__);
+ return IGnssMeasurement::GnssMeasurementStatus::ERROR_ALREADY_INIT;
+ }
+
+ if (callback == nullptr) {
+ LOC_LOGE("%s]: callback is nullptr", __FUNCTION__);
+ return ret;
+ }
+ if (nullptr == mApi) {
+ LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+ return ret;
+ }
+
+ mGnssMeasurementCbIface_1_1 = callback;
+ mGnssMeasurementCbIface_1_1->linkToDeath(mGnssMeasurementDeathRecipient, 0);
+
+ GnssPowerMode powerMode = enableFullTracking?
+ GNSS_POWER_MODE_M1 : GNSS_POWER_MODE_M2;
+
+ return mApi->measurementSetCallback_1_1(callback, powerMode);
+}
+// Methods from ::android::hardware::gnss::V2_0::IGnssMeasurement follow.
+Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback_2_0(
+ const sp<V2_0::IGnssMeasurementCallback>& callback,
+ bool enableFullTracking) {
+
+ Return<GnssMeasurement::GnssMeasurementStatus> ret =
+ IGnssMeasurement::GnssMeasurementStatus::ERROR_GENERIC;
+ if (mGnssMeasurementCbIface_2_0 != nullptr) {
+ LOC_LOGE("%s]: GnssMeasurementCallback is already set", __FUNCTION__);
+ return IGnssMeasurement::GnssMeasurementStatus::ERROR_ALREADY_INIT;
+ }
+
+ if (callback == nullptr) {
+ LOC_LOGE("%s]: callback is nullptr", __FUNCTION__);
+ return ret;
+ }
+ if (nullptr == mApi) {
+ LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+ return ret;
+ }
+
+ mGnssMeasurementCbIface_2_0 = callback;
+ mGnssMeasurementCbIface_2_0->linkToDeath(mGnssMeasurementDeathRecipient, 0);
+
+ GnssPowerMode powerMode = enableFullTracking ?
+ GNSS_POWER_MODE_M1 : GNSS_POWER_MODE_M2;
+
+ return mApi->measurementSetCallback_2_0(callback, powerMode);
+}
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/android/2.0/GnssMeasurement.h b/android/2.0/GnssMeasurement.h
new file mode 100644
index 0000000..000b00f
--- /dev/null
+++ b/android/2.0/GnssMeasurement.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GNSS_V2_0_GNSSMEASUREMENT_H
+#define ANDROID_HARDWARE_GNSS_V2_0_GNSSMEASUREMENT_H
+
+#include <android/hardware/gnss/2.0/IGnssMeasurement.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+class MeasurementAPIClient;
+struct GnssMeasurement : public V2_0::IGnssMeasurement {
+ GnssMeasurement();
+ ~GnssMeasurement();
+
+ /*
+ * Methods from ::android::hardware::gnss::V1_0::IGnssMeasurement follow.
+ * These declarations were generated from IGnssMeasurement.hal.
+ */
+ Return<GnssMeasurement::GnssMeasurementStatus> setCallback(
+ const sp<V1_0::IGnssMeasurementCallback>& callback) override;
+ Return<void> close() override;
+
+ // Methods from ::android::hardware::gnss::V1_1::IGnssMeasurement follow.
+ Return<GnssMeasurement::GnssMeasurementStatus> setCallback_1_1(
+ const sp<V1_1::IGnssMeasurementCallback>& callback,
+ bool enableFullTracking) override;
+
+ // Methods from ::android::hardware::gnss::V2_0::IGnssMeasurement follow.
+ Return<GnssMeasurement::GnssMeasurementStatus> setCallback_2_0(
+ const sp<V2_0::IGnssMeasurementCallback>& callback,
+ bool enableFullTracking) override;
+ private:
+ struct GnssMeasurementDeathRecipient : hidl_death_recipient {
+ GnssMeasurementDeathRecipient(sp<GnssMeasurement> gnssMeasurement) :
+ mGnssMeasurement(gnssMeasurement) {
+ }
+ ~GnssMeasurementDeathRecipient() = default;
+ virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override;
+ sp<GnssMeasurement> mGnssMeasurement;
+ };
+
+ private:
+ sp<GnssMeasurementDeathRecipient> mGnssMeasurementDeathRecipient = nullptr;
+ sp<V1_0::IGnssMeasurementCallback> mGnssMeasurementCbIface = nullptr;
+ sp<V1_1::IGnssMeasurementCallback> mGnssMeasurementCbIface_1_1 = nullptr;
+ sp<V2_0::IGnssMeasurementCallback> mGnssMeasurementCbIface_2_0 = nullptr;
+ MeasurementAPIClient* mApi;
+};
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V2_0_GNSSMEASUREMENT_H
diff --git a/android/2.0/GnssNi.cpp b/android/2.0/GnssNi.cpp
new file mode 100644
index 0000000..d65a488
--- /dev/null
+++ b/android/2.0/GnssNi.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "LocSvc_GnssNiInterface"
+
+#include <log_util.h>
+#include "Gnss.h"
+#include "GnssNi.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+void GnssNi::GnssNiDeathRecipient::serviceDied(uint64_t cookie, const wp<IBase>& who) {
+ LOC_LOGE("%s] service died. cookie: %llu, who: %p",
+ __FUNCTION__, static_cast<unsigned long long>(cookie), &who);
+ // we do nothing here
+ // Gnss::GnssDeathRecipient will stop the session
+}
+
+GnssNi::GnssNi(Gnss* gnss) : mGnss(gnss) {
+ mGnssNiDeathRecipient = new GnssNiDeathRecipient(this);
+}
+
+// Methods from ::android::hardware::gnss::V1_0::IGnssNi follow.
+Return<void> GnssNi::setCallback(const sp<IGnssNiCallback>& callback) {
+ if (mGnss == nullptr) {
+ LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
+ return Void();
+ }
+
+ mGnss->setGnssNiCb(callback);
+
+ if (mGnssNiCbIface != nullptr) {
+ mGnssNiCbIface->unlinkToDeath(mGnssNiDeathRecipient);
+ }
+ mGnssNiCbIface = callback;
+ if (mGnssNiCbIface != nullptr) {
+ mGnssNiCbIface->linkToDeath(mGnssNiDeathRecipient, 0 /*cookie*/);
+ }
+
+ return Void();
+}
+
+Return<void> GnssNi::respond(int32_t notifId, IGnssNiCallback::GnssUserResponseType userResponse) {
+ if (mGnss == nullptr) {
+ LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
+ return Void();
+ }
+
+ GnssAPIClient* api = mGnss->getApi();
+ if (api == nullptr) {
+ LOC_LOGE("%s]: api is nullptr", __FUNCTION__);
+ return Void();
+ }
+
+ api->gnssNiRespond(notifId, userResponse);
+
+ return Void();
+}
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/android/2.0/GnssNi.h b/android/2.0/GnssNi.h
new file mode 100644
index 0000000..26e281f
--- /dev/null
+++ b/android/2.0/GnssNi.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GNSS_V2_0_GNSSNI_H
+#define ANDROID_HARDWARE_GNSS_V2_0_GNSSNI_H
+
+#include <android/hardware/gnss/1.0/IGnssNi.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IGnssNi;
+using ::android::hardware::gnss::V1_0::IGnssNiCallback;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+struct Gnss;
+struct GnssNi : public IGnssNi {
+ GnssNi(Gnss* gnss);
+ ~GnssNi() = default;
+
+ /*
+ * Methods from ::android::hardware::gnss::V1_0::IGnssNi follow.
+ * These declarations were generated from IGnssNi.hal.
+ */
+ Return<void> setCallback(const sp<IGnssNiCallback>& callback) override;
+ Return<void> respond(int32_t notifId,
+ IGnssNiCallback::GnssUserResponseType userResponse) override;
+
+ private:
+ struct GnssNiDeathRecipient : hidl_death_recipient {
+ GnssNiDeathRecipient(sp<GnssNi> gnssNi) : mGnssNi(gnssNi) {
+ }
+ ~GnssNiDeathRecipient() = default;
+ virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override;
+ sp<GnssNi> mGnssNi;
+ };
+
+ private:
+ sp<GnssNiDeathRecipient> mGnssNiDeathRecipient = nullptr;
+ sp<IGnssNiCallback> mGnssNiCbIface = nullptr;
+ Gnss* mGnss = nullptr;
+};
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V2_0_GNSSNI_H
diff --git a/android/dummy/android.hardware.gnss@1.0-service-qti.rc b/android/2.0/android.hardware.gnss@2.0-service-qti.rc
index b5da6f9..36ee47c 100644
--- a/android/dummy/android.hardware.gnss@1.0-service-qti.rc
+++ b/android/2.0/android.hardware.gnss@2.0-service-qti.rc
@@ -1,4 +1,4 @@
-service gnss_service /vendor/bin/hw/android.hardware.gnss@1.0-service-qti
+service gnss_service /vendor/bin/hw/android.hardware.gnss@2.0-service-qti
class hal
user gps
group system gps radio
diff --git a/android/2.0/location_api/BatchingAPIClient.cpp b/android/2.0/location_api/BatchingAPIClient.cpp
new file mode 100644
index 0000000..48caee6
--- /dev/null
+++ b/android/2.0/location_api/BatchingAPIClient.cpp
@@ -0,0 +1,196 @@
+/* Copyright (c) 2017-2019, 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_NDEBUG 0
+#define LOG_TAG "LocSvc_BatchingAPIClient"
+
+#include <log_util.h>
+#include <loc_cfg.h>
+
+#include "LocationUtil.h"
+#include "BatchingAPIClient.h"
+
+#include "limits.h"
+
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IGnssBatching;
+using ::android::hardware::gnss::V1_0::IGnssBatchingCallback;
+using ::android::hardware::gnss::V1_0::GnssLocation;
+
+static void convertBatchOption(const IGnssBatching::Options& in, LocationOptions& out,
+ LocationCapabilitiesMask mask);
+
+BatchingAPIClient::BatchingAPIClient(const sp<IGnssBatchingCallback>& callback) :
+ LocationAPIClientBase(),
+ mGnssBatchingCbIface(callback),
+ mDefaultId(UINT_MAX),
+ mLocationCapabilitiesMask(0)
+{
+ LOC_LOGD("%s]: (%p)", __FUNCTION__, &callback);
+
+ LocationCallbacks locationCallbacks;
+ memset(&locationCallbacks, 0, sizeof(LocationCallbacks));
+ locationCallbacks.size = sizeof(LocationCallbacks);
+
+ locationCallbacks.trackingCb = nullptr;
+ locationCallbacks.batchingCb = nullptr;
+ if (mGnssBatchingCbIface != nullptr) {
+ locationCallbacks.batchingCb = [this](size_t count, Location* location,
+ BatchingOptions batchOptions) {
+ onBatchingCb(count, location, batchOptions);
+ };
+ }
+ locationCallbacks.geofenceBreachCb = nullptr;
+ locationCallbacks.geofenceStatusCb = nullptr;
+ locationCallbacks.gnssLocationInfoCb = nullptr;
+ locationCallbacks.gnssNiCb = nullptr;
+ locationCallbacks.gnssSvCb = nullptr;
+ locationCallbacks.gnssNmeaCb = nullptr;
+ locationCallbacks.gnssMeasurementsCb = nullptr;
+
+ locAPISetCallbacks(locationCallbacks);
+}
+
+BatchingAPIClient::~BatchingAPIClient()
+{
+ LOC_LOGD("%s]: ()", __FUNCTION__);
+}
+
+int BatchingAPIClient::getBatchSize()
+{
+ LOC_LOGD("%s]: ()", __FUNCTION__);
+ return locAPIGetBatchSize();
+}
+
+int BatchingAPIClient::startSession(const IGnssBatching::Options& opts)
+{
+ LOC_LOGD("%s]: (%lld %d)", __FUNCTION__,
+ static_cast<long long>(opts.periodNanos), static_cast<uint8_t>(opts.flags));
+ int retVal = -1;
+ LocationOptions options;
+ convertBatchOption(opts, options, mLocationCapabilitiesMask);
+ uint32_t mode = 0;
+ if (opts.flags == static_cast<uint8_t>(IGnssBatching::Flag::WAKEUP_ON_FIFO_FULL)) {
+ mode = SESSION_MODE_ON_FULL;
+ }
+ if (locAPIStartSession(mDefaultId, mode, options) == LOCATION_ERROR_SUCCESS) {
+ retVal = 1;
+ }
+ return retVal;
+}
+
+int BatchingAPIClient::updateSessionOptions(const IGnssBatching::Options& opts)
+{
+ LOC_LOGD("%s]: (%lld %d)", __FUNCTION__,
+ static_cast<long long>(opts.periodNanos), static_cast<uint8_t>(opts.flags));
+ int retVal = -1;
+ LocationOptions options;
+ convertBatchOption(opts, options, mLocationCapabilitiesMask);
+
+ uint32_t mode = 0;
+ if (opts.flags == static_cast<uint8_t>(IGnssBatching::Flag::WAKEUP_ON_FIFO_FULL)) {
+ mode = SESSION_MODE_ON_FULL;
+ }
+ if (locAPIUpdateSessionOptions(mDefaultId, mode, options) == LOCATION_ERROR_SUCCESS) {
+ retVal = 1;
+ }
+ return retVal;
+}
+
+int BatchingAPIClient::stopSession()
+{
+ LOC_LOGD("%s]: ", __FUNCTION__);
+ int retVal = -1;
+ if (locAPIStopSession(mDefaultId) == LOCATION_ERROR_SUCCESS) {
+ retVal = 1;
+ }
+ return retVal;
+}
+
+void BatchingAPIClient::getBatchedLocation(int last_n_locations)
+{
+ LOC_LOGD("%s]: (%d)", __FUNCTION__, last_n_locations);
+ locAPIGetBatchedLocations(mDefaultId, last_n_locations);
+}
+
+void BatchingAPIClient::flushBatchedLocations()
+{
+ LOC_LOGD("%s]: ()", __FUNCTION__);
+ locAPIGetBatchedLocations(mDefaultId, SIZE_MAX);
+}
+
+void BatchingAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)
+{
+ LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask);
+ mLocationCapabilitiesMask = capabilitiesMask;
+}
+
+void BatchingAPIClient::onBatchingCb(size_t count, Location* location,
+ BatchingOptions /*batchOptions*/)
+{
+ LOC_LOGD("%s]: (count: %zu)", __FUNCTION__, count);
+ if (mGnssBatchingCbIface != nullptr && count > 0) {
+ hidl_vec<GnssLocation> locationVec;
+ locationVec.resize(count);
+ for (size_t i = 0; i < count; i++) {
+ convertGnssLocation(location[i], locationVec[i]);
+ }
+ auto r = mGnssBatchingCbIface->gnssLocationBatchCb(locationVec);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssLocationBatchCb description=%s",
+ __func__, r.description().c_str());
+ }
+ }
+}
+
+static void convertBatchOption(const IGnssBatching::Options& in, LocationOptions& out,
+ LocationCapabilitiesMask mask)
+{
+ memset(&out, 0, sizeof(LocationOptions));
+ out.size = sizeof(LocationOptions);
+ out.minInterval = (uint32_t)(in.periodNanos / 1000000L);
+ out.minDistance = 0;
+ out.mode = GNSS_SUPL_MODE_STANDALONE;
+ if (mask & LOCATION_CAPABILITIES_GNSS_MSA_BIT)
+ out.mode = GNSS_SUPL_MODE_MSA;
+ if (mask & LOCATION_CAPABILITIES_GNSS_MSB_BIT)
+ out.mode = GNSS_SUPL_MODE_MSB;
+}
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/android/2.0/location_api/BatchingAPIClient.h b/android/2.0/location_api/BatchingAPIClient.h
new file mode 100644
index 0000000..33a8c2e
--- /dev/null
+++ b/android/2.0/location_api/BatchingAPIClient.h
@@ -0,0 +1,74 @@
+/* Copyright (c) 2017-2019, 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 BATCHING_API_CLINET_H
+#define BATCHING_API_CLINET_H
+
+#include <android/hardware/gnss/1.0/IGnssBatching.h>
+#include <android/hardware/gnss/1.0/IGnssBatchingCallback.h>
+#include <pthread.h>
+
+#include <LocationAPIClientBase.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+class BatchingAPIClient : public LocationAPIClientBase
+{
+public:
+ BatchingAPIClient(const sp<V1_0::IGnssBatchingCallback>& callback);
+ ~BatchingAPIClient();
+ int getBatchSize();
+ int startSession(const V1_0::IGnssBatching::Options& options);
+ int updateSessionOptions(const V1_0::IGnssBatching::Options& options);
+ int stopSession();
+ void getBatchedLocation(int last_n_locations);
+ void flushBatchedLocations();
+
+ inline LocationCapabilitiesMask getCapabilities() { return mLocationCapabilitiesMask; }
+
+ // callbacks
+ void onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask) final;
+ void onBatchingCb(size_t count, Location* location, BatchingOptions batchOptions) final;
+
+private:
+ sp<V1_0::IGnssBatchingCallback> mGnssBatchingCbIface;
+ uint32_t mDefaultId;
+ LocationCapabilitiesMask mLocationCapabilitiesMask;
+};
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+#endif // BATCHING_API_CLINET_H
diff --git a/android/2.0/location_api/GeofenceAPIClient.cpp b/android/2.0/location_api/GeofenceAPIClient.cpp
new file mode 100644
index 0000000..fabf8bb
--- /dev/null
+++ b/android/2.0/location_api/GeofenceAPIClient.cpp
@@ -0,0 +1,275 @@
+/* Copyright (c) 2017-2019, 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_NDEBUG 0
+#define LOG_TAG "LocSvc_GeofenceApiClient"
+
+#include <log_util.h>
+#include <loc_cfg.h>
+
+#include "LocationUtil.h"
+#include "GeofenceAPIClient.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IGnssGeofenceCallback;
+using ::android::hardware::gnss::V1_0::GnssLocation;
+
+GeofenceAPIClient::GeofenceAPIClient(const sp<IGnssGeofenceCallback>& callback) :
+ LocationAPIClientBase(),
+ mGnssGeofencingCbIface(callback)
+{
+ LOC_LOGD("%s]: (%p)", __FUNCTION__, &callback);
+
+ LocationCallbacks locationCallbacks;
+ memset(&locationCallbacks, 0, sizeof(LocationCallbacks));
+ locationCallbacks.size = sizeof(LocationCallbacks);
+
+ locationCallbacks.trackingCb = nullptr;
+ locationCallbacks.batchingCb = nullptr;
+
+ locationCallbacks.geofenceBreachCb = nullptr;
+ if (mGnssGeofencingCbIface != nullptr) {
+ locationCallbacks.geofenceBreachCb =
+ [this](GeofenceBreachNotification geofenceBreachNotification) {
+ onGeofenceBreachCb(geofenceBreachNotification);
+ };
+
+ locationCallbacks.geofenceStatusCb =
+ [this](GeofenceStatusNotification geofenceStatusNotification) {
+ onGeofenceStatusCb(geofenceStatusNotification);
+ };
+ }
+
+ locationCallbacks.gnssLocationInfoCb = nullptr;
+ locationCallbacks.gnssNiCb = nullptr;
+ locationCallbacks.gnssSvCb = nullptr;
+ locationCallbacks.gnssNmeaCb = nullptr;
+ locationCallbacks.gnssMeasurementsCb = nullptr;
+
+ locAPISetCallbacks(locationCallbacks);
+}
+
+void GeofenceAPIClient::geofenceAdd(uint32_t geofence_id, double latitude, double longitude,
+ double radius_meters, int32_t last_transition, int32_t monitor_transitions,
+ uint32_t notification_responsiveness_ms, uint32_t unknown_timer_ms)
+{
+ LOC_LOGD("%s]: (%d %f %f %f %d %d %d %d)", __FUNCTION__,
+ geofence_id, latitude, longitude, radius_meters,
+ last_transition, monitor_transitions, notification_responsiveness_ms, unknown_timer_ms);
+
+ GeofenceOption options;
+ memset(&options, 0, sizeof(GeofenceOption));
+ options.size = sizeof(GeofenceOption);
+ if (monitor_transitions & IGnssGeofenceCallback::GeofenceTransition::ENTERED)
+ options.breachTypeMask |= GEOFENCE_BREACH_ENTER_BIT;
+ if (monitor_transitions & IGnssGeofenceCallback::GeofenceTransition::EXITED)
+ options.breachTypeMask |= GEOFENCE_BREACH_EXIT_BIT;
+ options.responsiveness = notification_responsiveness_ms;
+
+ GeofenceInfo data;
+ data.size = sizeof(GeofenceInfo);
+ data.latitude = latitude;
+ data.longitude = longitude;
+ data.radius = radius_meters;
+
+ LocationError err = (LocationError)locAPIAddGeofences(1, &geofence_id, &options, &data);
+ if (LOCATION_ERROR_SUCCESS != err) {
+ onAddGeofencesCb(1, &err, &geofence_id);
+ }
+}
+
+void GeofenceAPIClient::geofencePause(uint32_t geofence_id)
+{
+ LOC_LOGD("%s]: (%d)", __FUNCTION__, geofence_id);
+ locAPIPauseGeofences(1, &geofence_id);
+}
+
+void GeofenceAPIClient::geofenceResume(uint32_t geofence_id, int32_t monitor_transitions)
+{
+ LOC_LOGD("%s]: (%d %d)", __FUNCTION__, geofence_id, monitor_transitions);
+ GeofenceBreachTypeMask mask = 0;
+ if (monitor_transitions & IGnssGeofenceCallback::GeofenceTransition::ENTERED)
+ mask |= GEOFENCE_BREACH_ENTER_BIT;
+ if (monitor_transitions & IGnssGeofenceCallback::GeofenceTransition::EXITED)
+ mask |= GEOFENCE_BREACH_EXIT_BIT;
+ locAPIResumeGeofences(1, &geofence_id, &mask);
+}
+
+void GeofenceAPIClient::geofenceRemove(uint32_t geofence_id)
+{
+ LOC_LOGD("%s]: (%d)", __FUNCTION__, geofence_id);
+ locAPIRemoveGeofences(1, &geofence_id);
+}
+
+void GeofenceAPIClient::geofenceRemoveAll()
+{
+ LOC_LOGD("%s]", __FUNCTION__);
+ // TODO locAPIRemoveAllGeofences();
+}
+
+// callbacks
+void GeofenceAPIClient::onGeofenceBreachCb(GeofenceBreachNotification geofenceBreachNotification)
+{
+ LOC_LOGD("%s]: (%zu)", __FUNCTION__, geofenceBreachNotification.count);
+ if (mGnssGeofencingCbIface != nullptr) {
+ for (size_t i = 0; i < geofenceBreachNotification.count; i++) {
+ GnssLocation gnssLocation;
+ convertGnssLocation(geofenceBreachNotification.location, gnssLocation);
+
+ IGnssGeofenceCallback::GeofenceTransition transition;
+ if (geofenceBreachNotification.type == GEOFENCE_BREACH_ENTER)
+ transition = IGnssGeofenceCallback::GeofenceTransition::ENTERED;
+ else if (geofenceBreachNotification.type == GEOFENCE_BREACH_EXIT)
+ transition = IGnssGeofenceCallback::GeofenceTransition::EXITED;
+ else {
+ // continue with other breach if transition is
+ // nether GPS_GEOFENCE_ENTERED nor GPS_GEOFENCE_EXITED
+ continue;
+ }
+
+ auto r = mGnssGeofencingCbIface->gnssGeofenceTransitionCb(
+ geofenceBreachNotification.ids[i], gnssLocation, transition,
+ static_cast<V1_0::GnssUtcTime>(geofenceBreachNotification.timestamp));
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssGeofenceTransitionCb description=%s",
+ __func__, r.description().c_str());
+ }
+ }
+ }
+}
+
+void GeofenceAPIClient::onGeofenceStatusCb(GeofenceStatusNotification geofenceStatusNotification)
+{
+ LOC_LOGD("%s]: (%d)", __FUNCTION__, geofenceStatusNotification.available);
+ if (mGnssGeofencingCbIface != nullptr) {
+ IGnssGeofenceCallback::GeofenceAvailability status =
+ IGnssGeofenceCallback::GeofenceAvailability::UNAVAILABLE;
+ if (geofenceStatusNotification.available == GEOFENCE_STATUS_AVAILABILE_YES) {
+ status = IGnssGeofenceCallback::GeofenceAvailability::AVAILABLE;
+ }
+ GnssLocation gnssLocation;
+ memset(&gnssLocation, 0, sizeof(GnssLocation));
+ auto r = mGnssGeofencingCbIface->gnssGeofenceStatusCb(status, gnssLocation);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssGeofenceStatusCb description=%s",
+ __func__, r.description().c_str());
+ }
+ }
+}
+
+void GeofenceAPIClient::onAddGeofencesCb(size_t count, LocationError* errors, uint32_t* ids)
+{
+ LOC_LOGD("%s]: (%zu)", __FUNCTION__, count);
+ if (mGnssGeofencingCbIface != nullptr) {
+ for (size_t i = 0; i < count; i++) {
+ IGnssGeofenceCallback::GeofenceStatus status =
+ IGnssGeofenceCallback::GeofenceStatus::ERROR_GENERIC;
+ if (errors[i] == LOCATION_ERROR_SUCCESS)
+ status = IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS;
+ else if (errors[i] == LOCATION_ERROR_ID_EXISTS)
+ status = IGnssGeofenceCallback::GeofenceStatus::ERROR_ID_EXISTS;
+ auto r = mGnssGeofencingCbIface->gnssGeofenceAddCb(ids[i], status);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssGeofenceAddCb description=%s",
+ __func__, r.description().c_str());
+ }
+ }
+ }
+}
+
+void GeofenceAPIClient::onRemoveGeofencesCb(size_t count, LocationError* errors, uint32_t* ids)
+{
+ LOC_LOGD("%s]: (%zu)", __FUNCTION__, count);
+ if (mGnssGeofencingCbIface != nullptr) {
+ for (size_t i = 0; i < count; i++) {
+ IGnssGeofenceCallback::GeofenceStatus status =
+ IGnssGeofenceCallback::GeofenceStatus::ERROR_GENERIC;
+ if (errors[i] == LOCATION_ERROR_SUCCESS)
+ status = IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS;
+ else if (errors[i] == LOCATION_ERROR_ID_UNKNOWN)
+ status = IGnssGeofenceCallback::GeofenceStatus::ERROR_ID_UNKNOWN;
+ auto r = mGnssGeofencingCbIface->gnssGeofenceRemoveCb(ids[i], status);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssGeofenceRemoveCb description=%s",
+ __func__, r.description().c_str());
+ }
+ }
+ }
+}
+
+void GeofenceAPIClient::onPauseGeofencesCb(size_t count, LocationError* errors, uint32_t* ids)
+{
+ LOC_LOGD("%s]: (%zu)", __FUNCTION__, count);
+ if (mGnssGeofencingCbIface != nullptr) {
+ for (size_t i = 0; i < count; i++) {
+ IGnssGeofenceCallback::GeofenceStatus status =
+ IGnssGeofenceCallback::GeofenceStatus::ERROR_GENERIC;
+ if (errors[i] == LOCATION_ERROR_SUCCESS)
+ status = IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS;
+ else if (errors[i] == LOCATION_ERROR_ID_UNKNOWN)
+ status = IGnssGeofenceCallback::GeofenceStatus::ERROR_ID_UNKNOWN;
+ auto r = mGnssGeofencingCbIface->gnssGeofencePauseCb(ids[i], status);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssGeofencePauseCb description=%s",
+ __func__, r.description().c_str());
+ }
+ }
+ }
+}
+
+void GeofenceAPIClient::onResumeGeofencesCb(size_t count, LocationError* errors, uint32_t* ids)
+{
+ LOC_LOGD("%s]: (%zu)", __FUNCTION__, count);
+ if (mGnssGeofencingCbIface != nullptr) {
+ for (size_t i = 0; i < count; i++) {
+ IGnssGeofenceCallback::GeofenceStatus status =
+ IGnssGeofenceCallback::GeofenceStatus::ERROR_GENERIC;
+ if (errors[i] == LOCATION_ERROR_SUCCESS)
+ status = IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS;
+ else if (errors[i] == LOCATION_ERROR_ID_UNKNOWN)
+ status = IGnssGeofenceCallback::GeofenceStatus::ERROR_ID_UNKNOWN;
+ auto r = mGnssGeofencingCbIface->gnssGeofenceResumeCb(ids[i], status);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssGeofenceResumeCb description=%s",
+ __func__, r.description().c_str());
+ }
+ }
+ }
+}
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/android/2.0/location_api/GeofenceAPIClient.h b/android/2.0/location_api/GeofenceAPIClient.h
new file mode 100644
index 0000000..71049de
--- /dev/null
+++ b/android/2.0/location_api/GeofenceAPIClient.h
@@ -0,0 +1,76 @@
+/* Copyright (c) 2017-2019, 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 GEOFENCE_API_CLINET_H
+#define GEOFENCE_API_CLINET_H
+
+
+#include <android/hardware/gnss/1.0/IGnssGeofenceCallback.h>
+#include <LocationAPIClientBase.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::sp;
+
+class GeofenceAPIClient : public LocationAPIClientBase
+{
+public:
+ GeofenceAPIClient(const sp<V1_0::IGnssGeofenceCallback>& callback);
+ virtual ~GeofenceAPIClient() = default;
+
+ void geofenceAdd(uint32_t geofence_id, double latitude, double longitude,
+ double radius_meters, int32_t last_transition, int32_t monitor_transitions,
+ uint32_t notification_responsiveness_ms, uint32_t unknown_timer_ms);
+ void geofencePause(uint32_t geofence_id);
+ void geofenceResume(uint32_t geofence_id, int32_t monitor_transitions);
+ void geofenceRemove(uint32_t geofence_id);
+ void geofenceRemoveAll();
+
+ // callbacks
+ void onGeofenceBreachCb(GeofenceBreachNotification geofenceBreachNotification) final;
+ void onGeofenceStatusCb(GeofenceStatusNotification geofenceStatusNotification) final;
+ void onAddGeofencesCb(size_t count, LocationError* errors, uint32_t* ids) final;
+ void onRemoveGeofencesCb(size_t count, LocationError* errors, uint32_t* ids) final;
+ void onPauseGeofencesCb(size_t count, LocationError* errors, uint32_t* ids) final;
+ void onResumeGeofencesCb(size_t count, LocationError* errors, uint32_t* ids) final;
+
+private:
+ sp<V1_0::IGnssGeofenceCallback> mGnssGeofencingCbIface;
+};
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+#endif // GEOFENCE_API_CLINET_H
diff --git a/android/2.0/location_api/GnssAPIClient.cpp b/android/2.0/location_api/GnssAPIClient.cpp
new file mode 100644
index 0000000..44ae284
--- /dev/null
+++ b/android/2.0/location_api/GnssAPIClient.cpp
@@ -0,0 +1,565 @@
+/* Copyright (c) 2017-2019, 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_NDEBUG 0
+#define LOG_TAG "LocSvc_GnssAPIClient"
+#define SINGLE_SHOT_MIN_TRACKING_INTERVAL_MSEC (590 * 60 * 60 * 1000) // 590 hours
+
+#include <log_util.h>
+#include <loc_cfg.h>
+
+#include "LocationUtil.h"
+#include "GnssAPIClient.h"
+#include <LocContext.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IGnss;
+using ::android::hardware::gnss::V1_0::IGnssCallback;
+using ::android::hardware::gnss::V1_0::IGnssNiCallback;
+using ::android::hardware::gnss::V1_0::GnssLocation;
+
+static void convertGnssSvStatus(GnssSvNotification& in, IGnssCallback::GnssSvStatus& out);
+
+GnssAPIClient::GnssAPIClient(const sp<IGnssCallback>& gpsCb,
+ const sp<IGnssNiCallback>& niCb) :
+ LocationAPIClientBase(),
+ mGnssCbIface(nullptr),
+ mGnssNiCbIface(nullptr),
+ mControlClient(new LocationAPIControlClient()),
+ mLocationCapabilitiesMask(0),
+ mLocationCapabilitiesCached(false)
+{
+ LOC_LOGD("%s]: (%p %p)", __FUNCTION__, &gpsCb, &niCb);
+
+ // set default LocationOptions.
+ memset(&mTrackingOptions, 0, sizeof(TrackingOptions));
+ mTrackingOptions.size = sizeof(TrackingOptions);
+ mTrackingOptions.minInterval = 1000;
+ mTrackingOptions.minDistance = 0;
+ mTrackingOptions.mode = GNSS_SUPL_MODE_STANDALONE;
+
+ gnssUpdateCallbacks(gpsCb, niCb);
+}
+
+GnssAPIClient::~GnssAPIClient()
+{
+ LOC_LOGD("%s]: ()", __FUNCTION__);
+ if (mControlClient) {
+ delete mControlClient;
+ mControlClient = nullptr;
+ }
+}
+
+// for GpsInterface
+void GnssAPIClient::gnssUpdateCallbacks(const sp<IGnssCallback>& gpsCb,
+ const sp<IGnssNiCallback>& niCb)
+{
+ LOC_LOGD("%s]: (%p %p)", __FUNCTION__, &gpsCb, &niCb);
+
+ mMutex.lock();
+ mGnssCbIface = gpsCb;
+ mGnssNiCbIface = niCb;
+ mMutex.unlock();
+
+ LocationCallbacks locationCallbacks;
+ memset(&locationCallbacks, 0, sizeof(LocationCallbacks));
+ locationCallbacks.size = sizeof(LocationCallbacks);
+
+ locationCallbacks.trackingCb = nullptr;
+ if (mGnssCbIface != nullptr) {
+ locationCallbacks.trackingCb = [this](Location location) {
+ onTrackingCb(location);
+ };
+ }
+
+ locationCallbacks.batchingCb = nullptr;
+ locationCallbacks.geofenceBreachCb = nullptr;
+ locationCallbacks.geofenceStatusCb = nullptr;
+ locationCallbacks.gnssLocationInfoCb = nullptr;
+
+ locationCallbacks.gnssNiCb = nullptr;
+ loc_core::ContextBase* context =
+ loc_core::LocContext::getLocContext(
+ NULL, NULL,
+ loc_core::LocContext::mLocationHalName, false);
+ if (mGnssNiCbIface != nullptr && !context->hasAgpsExtendedCapabilities()) {
+ LOC_LOGD("Registering NI CB");
+ locationCallbacks.gnssNiCb = [this](uint32_t id, GnssNiNotification gnssNiNotification) {
+ onGnssNiCb(id, gnssNiNotification);
+ };
+ }
+
+ locationCallbacks.gnssSvCb = nullptr;
+ if (mGnssCbIface != nullptr) {
+ locationCallbacks.gnssSvCb = [this](GnssSvNotification gnssSvNotification) {
+ onGnssSvCb(gnssSvNotification);
+ };
+ }
+
+ locationCallbacks.gnssNmeaCb = nullptr;
+ if (mGnssCbIface != nullptr) {
+ locationCallbacks.gnssNmeaCb = [this](GnssNmeaNotification gnssNmeaNotification) {
+ onGnssNmeaCb(gnssNmeaNotification);
+ };
+ }
+
+ locationCallbacks.gnssMeasurementsCb = nullptr;
+
+ locAPISetCallbacks(locationCallbacks);
+}
+
+bool GnssAPIClient::gnssStart()
+{
+ LOC_LOGD("%s]: ()", __FUNCTION__);
+ bool retVal = true;
+ locAPIStartTracking(mTrackingOptions);
+ return retVal;
+}
+
+bool GnssAPIClient::gnssStop()
+{
+ LOC_LOGD("%s]: ()", __FUNCTION__);
+ bool retVal = true;
+ locAPIStopTracking();
+ return retVal;
+}
+
+bool GnssAPIClient::gnssSetPositionMode(IGnss::GnssPositionMode mode,
+ IGnss::GnssPositionRecurrence recurrence, uint32_t minIntervalMs,
+ uint32_t preferredAccuracyMeters, uint32_t preferredTimeMs,
+ GnssPowerMode powerMode, uint32_t timeBetweenMeasurement)
+{
+ LOC_LOGD("%s]: (%d %d %d %d %d %d %d)", __FUNCTION__,
+ (int)mode, recurrence, minIntervalMs, preferredAccuracyMeters,
+ preferredTimeMs, (int)powerMode, timeBetweenMeasurement);
+ bool retVal = true;
+ memset(&mTrackingOptions, 0, sizeof(TrackingOptions));
+ mTrackingOptions.size = sizeof(TrackingOptions);
+ mTrackingOptions.minInterval = minIntervalMs;
+ if (IGnss::GnssPositionMode::MS_ASSISTED == mode ||
+ IGnss::GnssPositionRecurrence::RECURRENCE_SINGLE == recurrence) {
+ // We set a very large interval to simulate SINGLE mode. Once we report a fix,
+ // the caller should take the responsibility to stop the session.
+ // For MSA, we always treat it as SINGLE mode.
+ mTrackingOptions.minInterval = SINGLE_SHOT_MIN_TRACKING_INTERVAL_MSEC;
+ }
+ mTrackingOptions.minDistance = preferredAccuracyMeters;
+ if (mode == IGnss::GnssPositionMode::STANDALONE)
+ mTrackingOptions.mode = GNSS_SUPL_MODE_STANDALONE;
+ else if (mode == IGnss::GnssPositionMode::MS_BASED)
+ mTrackingOptions.mode = GNSS_SUPL_MODE_MSB;
+ else if (mode == IGnss::GnssPositionMode::MS_ASSISTED)
+ mTrackingOptions.mode = GNSS_SUPL_MODE_MSA;
+ else {
+ LOC_LOGD("%s]: invalid GnssPositionMode: %d", __FUNCTION__, (int)mode);
+ retVal = false;
+ }
+ if (GNSS_POWER_MODE_INVALID != powerMode) {
+ mTrackingOptions.powerMode = powerMode;
+ mTrackingOptions.tbm = timeBetweenMeasurement;
+ }
+ locAPIUpdateTrackingOptions(mTrackingOptions);
+ return retVal;
+}
+
+// for GpsNiInterface
+void GnssAPIClient::gnssNiRespond(int32_t notifId,
+ IGnssNiCallback::GnssUserResponseType userResponse)
+{
+ LOC_LOGD("%s]: (%d %d)", __FUNCTION__, notifId, static_cast<int>(userResponse));
+ GnssNiResponse data;
+ switch (userResponse) {
+ case IGnssNiCallback::GnssUserResponseType::RESPONSE_ACCEPT:
+ data = GNSS_NI_RESPONSE_ACCEPT;
+ break;
+ case IGnssNiCallback::GnssUserResponseType::RESPONSE_DENY:
+ data = GNSS_NI_RESPONSE_DENY;
+ break;
+ case IGnssNiCallback::GnssUserResponseType::RESPONSE_NORESP:
+ data = GNSS_NI_RESPONSE_NO_RESPONSE;
+ break;
+ default:
+ data = GNSS_NI_RESPONSE_IGNORE;
+ break;
+ }
+
+ locAPIGnssNiResponse(notifId, data);
+}
+
+// these apis using LocationAPIControlClient
+void GnssAPIClient::gnssDeleteAidingData(IGnss::GnssAidingData aidingDataFlags)
+{
+ LOC_LOGD("%s]: (%02hx)", __FUNCTION__, aidingDataFlags);
+ if (mControlClient == nullptr) {
+ return;
+ }
+ GnssAidingData data;
+ memset(&data, 0, sizeof (GnssAidingData));
+ data.sv.svTypeMask = GNSS_AIDING_DATA_SV_TYPE_GPS_BIT |
+ GNSS_AIDING_DATA_SV_TYPE_GLONASS_BIT |
+ GNSS_AIDING_DATA_SV_TYPE_QZSS_BIT |
+ GNSS_AIDING_DATA_SV_TYPE_BEIDOU_BIT |
+ GNSS_AIDING_DATA_SV_TYPE_GALILEO_BIT;
+
+ if (aidingDataFlags == IGnss::GnssAidingData::DELETE_ALL)
+ data.deleteAll = true;
+ else {
+ if (aidingDataFlags & IGnss::GnssAidingData::DELETE_EPHEMERIS)
+ data.sv.svMask |= GNSS_AIDING_DATA_SV_EPHEMERIS_BIT;
+ if (aidingDataFlags & IGnss::GnssAidingData::DELETE_ALMANAC)
+ data.sv.svMask |= GNSS_AIDING_DATA_SV_ALMANAC_BIT;
+ if (aidingDataFlags & IGnss::GnssAidingData::DELETE_POSITION)
+ data.common.mask |= GNSS_AIDING_DATA_COMMON_POSITION_BIT;
+ if (aidingDataFlags & IGnss::GnssAidingData::DELETE_TIME)
+ data.common.mask |= GNSS_AIDING_DATA_COMMON_TIME_BIT;
+ if (aidingDataFlags & IGnss::GnssAidingData::DELETE_IONO)
+ data.sv.svMask |= GNSS_AIDING_DATA_SV_IONOSPHERE_BIT;
+ if (aidingDataFlags & IGnss::GnssAidingData::DELETE_UTC)
+ data.common.mask |= GNSS_AIDING_DATA_COMMON_UTC_BIT;
+ if (aidingDataFlags & IGnss::GnssAidingData::DELETE_HEALTH)
+ data.sv.svMask |= GNSS_AIDING_DATA_SV_HEALTH_BIT;
+ if (aidingDataFlags & IGnss::GnssAidingData::DELETE_SVDIR)
+ data.sv.svMask |= GNSS_AIDING_DATA_SV_DIRECTION_BIT;
+ if (aidingDataFlags & IGnss::GnssAidingData::DELETE_SVSTEER)
+ data.sv.svMask |= GNSS_AIDING_DATA_SV_STEER_BIT;
+ if (aidingDataFlags & IGnss::GnssAidingData::DELETE_SADATA)
+ data.sv.svMask |= GNSS_AIDING_DATA_SV_SA_DATA_BIT;
+ if (aidingDataFlags & IGnss::GnssAidingData::DELETE_RTI)
+ data.common.mask |= GNSS_AIDING_DATA_COMMON_RTI_BIT;
+ if (aidingDataFlags & IGnss::GnssAidingData::DELETE_CELLDB_INFO)
+ data.common.mask |= GNSS_AIDING_DATA_COMMON_CELLDB_BIT;
+ }
+ mControlClient->locAPIGnssDeleteAidingData(data);
+}
+
+void GnssAPIClient::gnssEnable(LocationTechnologyType techType)
+{
+ LOC_LOGD("%s]: (%0d)", __FUNCTION__, techType);
+ if (mControlClient == nullptr) {
+ return;
+ }
+ mControlClient->locAPIEnable(techType);
+}
+
+void GnssAPIClient::gnssDisable()
+{
+ LOC_LOGD("%s]: ()", __FUNCTION__);
+ if (mControlClient == nullptr) {
+ return;
+ }
+ mControlClient->locAPIDisable();
+}
+
+void GnssAPIClient::gnssConfigurationUpdate(const GnssConfig& gnssConfig)
+{
+ LOC_LOGD("%s]: (%02x)", __FUNCTION__, gnssConfig.flags);
+ if (mControlClient == nullptr) {
+ return;
+ }
+ mControlClient->locAPIGnssUpdateConfig(gnssConfig);
+}
+
+void GnssAPIClient::requestCapabilities() {
+ // only send capablities if it's already cached, otherwise the first time LocationAPI
+ // is initialized, capabilities will be sent by LocationAPI
+ if (mLocationCapabilitiesCached) {
+ onCapabilitiesCb(mLocationCapabilitiesMask);
+ }
+}
+
+// callbacks
+void GnssAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)
+{
+ LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask);
+ mLocationCapabilitiesMask = capabilitiesMask;
+ mLocationCapabilitiesCached = true;
+
+ mMutex.lock();
+ auto gnssCbIface(mGnssCbIface);
+ mMutex.unlock();
+
+ if (gnssCbIface != nullptr) {
+ uint32_t data = 0;
+ if ((capabilitiesMask & LOCATION_CAPABILITIES_TIME_BASED_TRACKING_BIT) ||
+ (capabilitiesMask & LOCATION_CAPABILITIES_TIME_BASED_BATCHING_BIT) ||
+ (capabilitiesMask & LOCATION_CAPABILITIES_DISTANCE_BASED_TRACKING_BIT) ||
+ (capabilitiesMask & LOCATION_CAPABILITIES_DISTANCE_BASED_BATCHING_BIT))
+ data |= IGnssCallback::Capabilities::SCHEDULING;
+ if (capabilitiesMask & LOCATION_CAPABILITIES_GEOFENCE_BIT)
+ data |= IGnssCallback::Capabilities::GEOFENCING;
+ if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT)
+ data |= IGnssCallback::Capabilities::MEASUREMENTS;
+ if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MSB_BIT)
+ data |= IGnssCallback::Capabilities::MSB;
+ if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MSA_BIT)
+ data |= IGnssCallback::Capabilities::MSA;
+ auto r = gnssCbIface->gnssSetCapabilitesCb(data);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssSetCapabilitesCb description=%s",
+ __func__, r.description().c_str());
+ }
+ }
+ if (gnssCbIface != nullptr) {
+ IGnssCallback::GnssSystemInfo gnssInfo;
+ if (capabilitiesMask & LOCATION_CAPABILITIES_CONSTELLATION_ENABLEMENT_BIT ||
+ capabilitiesMask & LOCATION_CAPABILITIES_AGPM_BIT) {
+ gnssInfo.yearOfHw = 2018;
+ } else if (capabilitiesMask & LOCATION_CAPABILITIES_DEBUG_NMEA_BIT) {
+ gnssInfo.yearOfHw = 2017;
+ } else if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT) {
+ gnssInfo.yearOfHw = 2016;
+ } else {
+ gnssInfo.yearOfHw = 2015;
+ }
+ LOC_LOGV("%s:%d] set_system_info_cb (%d)", __FUNCTION__, __LINE__, gnssInfo.yearOfHw);
+ auto r = gnssCbIface->gnssSetSystemInfoCb(gnssInfo);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssSetSystemInfoCb description=%s",
+ __func__, r.description().c_str());
+ }
+ }
+}
+
+void GnssAPIClient::onTrackingCb(Location location)
+{
+ LOC_LOGD("%s]: (flags: %02x)", __FUNCTION__, location.flags);
+ mMutex.lock();
+ auto gnssCbIface(mGnssCbIface);
+ mMutex.unlock();
+
+ if (gnssCbIface != nullptr) {
+ GnssLocation gnssLocation;
+ convertGnssLocation(location, gnssLocation);
+ auto r = gnssCbIface->gnssLocationCb(gnssLocation);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssLocationCb description=%s",
+ __func__, r.description().c_str());
+ }
+ }
+}
+
+void GnssAPIClient::onGnssNiCb(uint32_t id, GnssNiNotification gnssNiNotification)
+{
+ LOC_LOGD("%s]: (id: %d)", __FUNCTION__, id);
+ mMutex.lock();
+ auto gnssNiCbIface(mGnssNiCbIface);
+ mMutex.unlock();
+
+ if (gnssNiCbIface == nullptr) {
+ LOC_LOGE("%s]: mGnssNiCbIface is nullptr", __FUNCTION__);
+ return;
+ }
+
+ IGnssNiCallback::GnssNiNotification notificationGnss = {};
+
+ notificationGnss.notificationId = id;
+
+ if (gnssNiNotification.type == GNSS_NI_TYPE_VOICE)
+ notificationGnss.niType = IGnssNiCallback::GnssNiType::VOICE;
+ else if (gnssNiNotification.type == GNSS_NI_TYPE_SUPL)
+ notificationGnss.niType = IGnssNiCallback::GnssNiType::UMTS_SUPL;
+ else if (gnssNiNotification.type == GNSS_NI_TYPE_CONTROL_PLANE)
+ notificationGnss.niType = IGnssNiCallback::GnssNiType::UMTS_CTRL_PLANE;
+ else if (gnssNiNotification.type == GNSS_NI_TYPE_EMERGENCY_SUPL)
+ notificationGnss.niType = IGnssNiCallback::GnssNiType::EMERGENCY_SUPL;
+
+ if (gnssNiNotification.options & GNSS_NI_OPTIONS_NOTIFICATION_BIT)
+ notificationGnss.notifyFlags |= IGnssNiCallback::GnssNiNotifyFlags::NEED_NOTIFY;
+ if (gnssNiNotification.options & GNSS_NI_OPTIONS_VERIFICATION_BIT)
+ notificationGnss.notifyFlags |= IGnssNiCallback::GnssNiNotifyFlags::NEED_VERIFY;
+ if (gnssNiNotification.options & GNSS_NI_OPTIONS_PRIVACY_OVERRIDE_BIT)
+ notificationGnss.notifyFlags |= IGnssNiCallback::GnssNiNotifyFlags::PRIVACY_OVERRIDE;
+
+ notificationGnss.timeoutSec = gnssNiNotification.timeout;
+
+ if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_ACCEPT)
+ notificationGnss.defaultResponse = IGnssNiCallback::GnssUserResponseType::RESPONSE_ACCEPT;
+ else if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_DENY)
+ notificationGnss.defaultResponse = IGnssNiCallback::GnssUserResponseType::RESPONSE_DENY;
+ else if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_NO_RESPONSE ||
+ gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_IGNORE)
+ notificationGnss.defaultResponse = IGnssNiCallback::GnssUserResponseType::RESPONSE_NORESP;
+
+ notificationGnss.requestorId = gnssNiNotification.requestor;
+
+ notificationGnss.notificationMessage = gnssNiNotification.message;
+
+ if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_NONE)
+ notificationGnss.requestorIdEncoding =
+ IGnssNiCallback::GnssNiEncodingType::ENC_NONE;
+ else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_GSM_DEFAULT)
+ notificationGnss.requestorIdEncoding =
+ IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_GSM_DEFAULT;
+ else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_UTF8)
+ notificationGnss.requestorIdEncoding =
+ IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UTF8;
+ else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_UCS2)
+ notificationGnss.requestorIdEncoding =
+ IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UCS2;
+
+ if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_NONE)
+ notificationGnss.notificationIdEncoding =
+ IGnssNiCallback::GnssNiEncodingType::ENC_NONE;
+ else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_GSM_DEFAULT)
+ notificationGnss.notificationIdEncoding =
+ IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_GSM_DEFAULT;
+ else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_UTF8)
+ notificationGnss.notificationIdEncoding =
+ IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UTF8;
+ else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_UCS2)
+ notificationGnss.notificationIdEncoding =
+ IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UCS2;
+
+ gnssNiCbIface->niNotifyCb(notificationGnss);
+}
+
+void GnssAPIClient::onGnssSvCb(GnssSvNotification gnssSvNotification)
+{
+ LOC_LOGD("%s]: (count: %zu)", __FUNCTION__, gnssSvNotification.count);
+ mMutex.lock();
+ auto gnssCbIface(mGnssCbIface);
+ mMutex.unlock();
+
+ if (gnssCbIface != nullptr) {
+ IGnssCallback::GnssSvStatus svStatus;
+ convertGnssSvStatus(gnssSvNotification, svStatus);
+ auto r = gnssCbIface->gnssSvStatusCb(svStatus);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssSvStatusCb description=%s",
+ __func__, r.description().c_str());
+ }
+ }
+}
+
+void GnssAPIClient::onGnssNmeaCb(GnssNmeaNotification gnssNmeaNotification)
+{
+ mMutex.lock();
+ auto gnssCbIface(mGnssCbIface);
+ mMutex.unlock();
+
+ if (gnssCbIface != nullptr) {
+ const std::string s(gnssNmeaNotification.nmea);
+ std::stringstream ss(s);
+ std::string each;
+ while(std::getline(ss, each, '\n')) {
+ each += '\n';
+ android::hardware::hidl_string nmeaString;
+ nmeaString.setToExternal(each.c_str(), each.length());
+ auto r = gnssCbIface->gnssNmeaCb(
+ static_cast<V1_0::GnssUtcTime>(gnssNmeaNotification.timestamp), nmeaString);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssNmeaCb nmea=%s length=%zu description=%s", __func__,
+ gnssNmeaNotification.nmea, gnssNmeaNotification.length,
+ r.description().c_str());
+ }
+ }
+ }
+}
+
+void GnssAPIClient::onStartTrackingCb(LocationError error)
+{
+ LOC_LOGD("%s]: (%d)", __FUNCTION__, error);
+ mMutex.lock();
+ auto gnssCbIface(mGnssCbIface);
+ mMutex.unlock();
+
+ if (error == LOCATION_ERROR_SUCCESS && gnssCbIface != nullptr) {
+ auto r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_ON);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssStatusCb ENGINE_ON description=%s",
+ __func__, r.description().c_str());
+ }
+ r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_BEGIN);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssStatusCb SESSION_BEGIN description=%s",
+ __func__, r.description().c_str());
+ }
+ }
+}
+
+void GnssAPIClient::onStopTrackingCb(LocationError error)
+{
+ LOC_LOGD("%s]: (%d)", __FUNCTION__, error);
+ mMutex.lock();
+ auto gnssCbIface(mGnssCbIface);
+ mMutex.unlock();
+
+ if (error == LOCATION_ERROR_SUCCESS && gnssCbIface != nullptr) {
+ auto r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_END);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssStatusCb SESSION_END description=%s",
+ __func__, r.description().c_str());
+ }
+ r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_OFF);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssStatusCb ENGINE_OFF description=%s",
+ __func__, r.description().c_str());
+ }
+ }
+}
+
+static void convertGnssSvStatus(GnssSvNotification& in, IGnssCallback::GnssSvStatus& out)
+{
+ memset(&out, 0, sizeof(IGnssCallback::GnssSvStatus));
+ out.numSvs = in.count;
+ if (out.numSvs > static_cast<uint32_t>(V1_0::GnssMax::SVS_COUNT)) {
+ LOC_LOGW("%s]: Too many satellites %u. Clamps to %d.",
+ __FUNCTION__, out.numSvs, V1_0::GnssMax::SVS_COUNT);
+ out.numSvs = static_cast<uint32_t>(V1_0::GnssMax::SVS_COUNT);
+ }
+ for (size_t i = 0; i < out.numSvs; i++) {
+ IGnssCallback::GnssSvInfo& info = out.gnssSvList[i];
+ info.svid = in.gnssSvs[i].svId;
+ convertGnssConstellationType(in.gnssSvs[i].type, info.constellation);
+ info.cN0Dbhz = in.gnssSvs[i].cN0Dbhz;
+ info.elevationDegrees = in.gnssSvs[i].elevation;
+ info.azimuthDegrees = in.gnssSvs[i].azimuth;
+ info.carrierFrequencyHz = in.gnssSvs[i].carrierFrequencyHz;
+ info.svFlag = static_cast<uint8_t>(IGnssCallback::GnssSvFlags::NONE);
+ if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_EPHEMER_BIT)
+ info.svFlag |= IGnssCallback::GnssSvFlags::HAS_EPHEMERIS_DATA;
+ if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_ALMANAC_BIT)
+ info.svFlag |= IGnssCallback::GnssSvFlags::HAS_ALMANAC_DATA;
+ if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_USED_IN_FIX_BIT)
+ info.svFlag |= IGnssCallback::GnssSvFlags::USED_IN_FIX;
+ if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_CARRIER_FREQUENCY_BIT)
+ info.svFlag |= IGnssCallback::GnssSvFlags::HAS_CARRIER_FREQUENCY;
+ }
+}
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/android/2.0/location_api/GnssAPIClient.h b/android/2.0/location_api/GnssAPIClient.h
new file mode 100644
index 0000000..a129cee
--- /dev/null
+++ b/android/2.0/location_api/GnssAPIClient.h
@@ -0,0 +1,108 @@
+/* Copyright (c) 2017-2019, 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 GNSS_API_CLINET_H
+#define GNSS_API_CLINET_H
+
+
+#include <mutex>
+#include <android/hardware/gnss/2.0/IGnss.h>
+//#include <android/hardware/gnss/1.1/IGnssCallback.h>
+#include <LocationAPIClientBase.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::sp;
+
+class GnssAPIClient : public LocationAPIClientBase
+{
+public:
+ GnssAPIClient(const sp<V1_0::IGnssCallback>& gpsCb,
+ const sp<V1_0::IGnssNiCallback>& niCb);
+ virtual ~GnssAPIClient();
+ GnssAPIClient(const GnssAPIClient&) = delete;
+ GnssAPIClient& operator=(const GnssAPIClient&) = delete;
+
+ // for GpsInterface
+ void gnssUpdateCallbacks(const sp<V1_0::IGnssCallback>& gpsCb,
+ const sp<V1_0::IGnssNiCallback>& niCb);
+ bool gnssStart();
+ bool gnssStop();
+ bool gnssSetPositionMode(V1_0::IGnss::GnssPositionMode mode,
+ V1_0::IGnss::GnssPositionRecurrence recurrence,
+ uint32_t minIntervalMs,
+ uint32_t preferredAccuracyMeters,
+ uint32_t preferredTimeMs,
+ GnssPowerMode powerMode = GNSS_POWER_MODE_INVALID,
+ uint32_t timeBetweenMeasurement = 0);
+
+ // for GpsNiInterface
+ void gnssNiRespond(int32_t notifId, V1_0::IGnssNiCallback::GnssUserResponseType userResponse);
+
+ // these apis using LocationAPIControlClient
+ void gnssDeleteAidingData(V1_0::IGnss::GnssAidingData aidingDataFlags);
+ void gnssEnable(LocationTechnologyType techType);
+ void gnssDisable();
+ void gnssConfigurationUpdate(const GnssConfig& gnssConfig);
+
+ inline LocationCapabilitiesMask gnssGetCapabilities() const {
+ return mLocationCapabilitiesMask;
+ }
+ void requestCapabilities();
+
+ // callbacks we are interested in
+ void onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask) final;
+ void onTrackingCb(Location location) final;
+ void onGnssNiCb(uint32_t id, GnssNiNotification gnssNiNotification) final;
+ void onGnssSvCb(GnssSvNotification gnssSvNotification) final;
+ void onGnssNmeaCb(GnssNmeaNotification gnssNmeaNotification) final;
+
+ void onStartTrackingCb(LocationError error) final;
+ void onStopTrackingCb(LocationError error) final;
+
+private:
+ sp<V1_0::IGnssCallback> mGnssCbIface;
+ sp<V1_0::IGnssNiCallback> mGnssNiCbIface;
+ std::mutex mMutex;
+ LocationAPIControlClient* mControlClient;
+ LocationCapabilitiesMask mLocationCapabilitiesMask;
+ bool mLocationCapabilitiesCached;
+ TrackingOptions mTrackingOptions;
+};
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+#endif // GNSS_API_CLINET_H
diff --git a/android/2.0/location_api/LocationUtil.cpp b/android/2.0/location_api/LocationUtil.cpp
new file mode 100644
index 0000000..c921154
--- /dev/null
+++ b/android/2.0/location_api/LocationUtil.cpp
@@ -0,0 +1,206 @@
+/* Copyright (c) 2017-2019, 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.
+ *
+ */
+
+#include <LocationUtil.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::GnssLocation;
+using ::android::hardware::gnss::V1_0::GnssConstellationType;
+using ::android::hardware::gnss::V1_0::GnssLocationFlags;
+
+void convertGnssLocation(Location& in, GnssLocation& out)
+{
+ memset(&out, 0, sizeof(GnssLocation));
+ if (in.flags & LOCATION_HAS_LAT_LONG_BIT) {
+ out.gnssLocationFlags |= GnssLocationFlags::HAS_LAT_LONG;
+ out.latitudeDegrees = in.latitude;
+ out.longitudeDegrees = in.longitude;
+ }
+ if (in.flags & LOCATION_HAS_ALTITUDE_BIT) {
+ out.gnssLocationFlags |= GnssLocationFlags::HAS_ALTITUDE;
+ out.altitudeMeters = in.altitude;
+ }
+ if (in.flags & LOCATION_HAS_SPEED_BIT) {
+ out.gnssLocationFlags |= GnssLocationFlags::HAS_SPEED;
+ out.speedMetersPerSec = in.speed;
+ }
+ if (in.flags & LOCATION_HAS_BEARING_BIT) {
+ out.gnssLocationFlags |= GnssLocationFlags::HAS_BEARING;
+ out.bearingDegrees = in.bearing;
+ }
+ if (in.flags & LOCATION_HAS_ACCURACY_BIT) {
+ out.gnssLocationFlags |= GnssLocationFlags::HAS_HORIZONTAL_ACCURACY;
+ out.horizontalAccuracyMeters = in.accuracy;
+ }
+ if (in.flags & LOCATION_HAS_VERTICAL_ACCURACY_BIT) {
+ out.gnssLocationFlags |= GnssLocationFlags::HAS_VERTICAL_ACCURACY;
+ out.verticalAccuracyMeters = in.verticalAccuracy;
+ }
+ if (in.flags & LOCATION_HAS_SPEED_ACCURACY_BIT) {
+ out.gnssLocationFlags |= GnssLocationFlags::HAS_SPEED_ACCURACY;
+ out.speedAccuracyMetersPerSecond = in.speedAccuracy;
+ }
+ if (in.flags & LOCATION_HAS_BEARING_ACCURACY_BIT) {
+ out.gnssLocationFlags |= GnssLocationFlags::HAS_BEARING_ACCURACY;
+ out.bearingAccuracyDegrees = in.bearingAccuracy;
+ }
+
+ out.timestamp = static_cast<V1_0::GnssUtcTime>(in.timestamp);
+}
+
+void convertGnssLocation(const GnssLocation& in, Location& out)
+{
+ memset(&out, 0, sizeof(out));
+ if (in.gnssLocationFlags & GnssLocationFlags::HAS_LAT_LONG) {
+ out.flags |= LOCATION_HAS_LAT_LONG_BIT;
+ out.latitude = in.latitudeDegrees;
+ out.longitude = in.longitudeDegrees;
+ }
+ if (in.gnssLocationFlags & GnssLocationFlags::HAS_ALTITUDE) {
+ out.flags |= LOCATION_HAS_ALTITUDE_BIT;
+ out.altitude = in.altitudeMeters;
+ }
+ if (in.gnssLocationFlags & GnssLocationFlags::HAS_SPEED) {
+ out.flags |= LOCATION_HAS_SPEED_BIT;
+ out.speed = in.speedMetersPerSec;
+ }
+ if (in.gnssLocationFlags & GnssLocationFlags::HAS_BEARING) {
+ out.flags |= LOCATION_HAS_BEARING_BIT;
+ out.bearing = in.bearingDegrees;
+ }
+ if (in.gnssLocationFlags & GnssLocationFlags::HAS_HORIZONTAL_ACCURACY) {
+ out.flags |= LOCATION_HAS_ACCURACY_BIT;
+ out.accuracy = in.horizontalAccuracyMeters;
+ }
+ if (in.gnssLocationFlags & GnssLocationFlags::HAS_VERTICAL_ACCURACY) {
+ out.flags |= LOCATION_HAS_VERTICAL_ACCURACY_BIT;
+ out.verticalAccuracy = in.verticalAccuracyMeters;
+ }
+ if (in.gnssLocationFlags & GnssLocationFlags::HAS_SPEED_ACCURACY) {
+ out.flags |= LOCATION_HAS_SPEED_ACCURACY_BIT;
+ out.speedAccuracy = in.speedAccuracyMetersPerSecond;
+ }
+ if (in.gnssLocationFlags & GnssLocationFlags::HAS_BEARING_ACCURACY) {
+ out.flags |= LOCATION_HAS_BEARING_ACCURACY_BIT;
+ out.bearingAccuracy = in.bearingAccuracyDegrees;
+ }
+
+ out.timestamp = static_cast<uint64_t>(in.timestamp);
+}
+
+void convertGnssConstellationType(GnssSvType& in, GnssConstellationType& out)
+{
+ switch(in) {
+ case GNSS_SV_TYPE_GPS:
+ out = GnssConstellationType::GPS;
+ break;
+ case GNSS_SV_TYPE_SBAS:
+ out = GnssConstellationType::SBAS;
+ break;
+ case GNSS_SV_TYPE_GLONASS:
+ out = GnssConstellationType::GLONASS;
+ break;
+ case GNSS_SV_TYPE_QZSS:
+ out = GnssConstellationType::QZSS;
+ break;
+ case GNSS_SV_TYPE_BEIDOU:
+ out = GnssConstellationType::BEIDOU;
+ break;
+ case GNSS_SV_TYPE_GALILEO:
+ out = GnssConstellationType::GALILEO;
+ break;
+ case GNSS_SV_TYPE_UNKNOWN:
+ default:
+ out = GnssConstellationType::UNKNOWN;
+ break;
+ }
+}
+
+void convertGnssEphemerisType(GnssEphemerisType& in, GnssDebug::SatelliteEphemerisType& out)
+{
+ switch(in) {
+ case GNSS_EPH_TYPE_EPHEMERIS:
+ out = GnssDebug::SatelliteEphemerisType::EPHEMERIS;
+ break;
+ case GNSS_EPH_TYPE_ALMANAC:
+ out = GnssDebug::SatelliteEphemerisType::ALMANAC_ONLY;
+ break;
+ case GNSS_EPH_TYPE_UNKNOWN:
+ default:
+ out = GnssDebug::SatelliteEphemerisType::NOT_AVAILABLE;
+ break;
+ }
+}
+
+void convertGnssEphemerisSource(GnssEphemerisSource& in, GnssDebug::SatelliteEphemerisSource& out)
+{
+ switch(in) {
+ case GNSS_EPH_SOURCE_DEMODULATED:
+ out = GnssDebug::SatelliteEphemerisSource::DEMODULATED;
+ break;
+ case GNSS_EPH_SOURCE_SUPL_PROVIDED:
+ out = GnssDebug::SatelliteEphemerisSource::SUPL_PROVIDED;
+ break;
+ case GNSS_EPH_SOURCE_OTHER_SERVER_PROVIDED:
+ out = GnssDebug::SatelliteEphemerisSource::OTHER_SERVER_PROVIDED;
+ break;
+ case GNSS_EPH_SOURCE_LOCAL:
+ case GNSS_EPH_SOURCE_UNKNOWN:
+ default:
+ out = GnssDebug::SatelliteEphemerisSource::OTHER;
+ break;
+ }
+}
+
+void convertGnssEphemerisHealth(GnssEphemerisHealth& in, GnssDebug::SatelliteEphemerisHealth& out)
+{
+ switch(in) {
+ case GNSS_EPH_HEALTH_GOOD:
+ out = GnssDebug::SatelliteEphemerisHealth::GOOD;
+ break;
+ case GNSS_EPH_HEALTH_BAD:
+ out = GnssDebug::SatelliteEphemerisHealth::BAD;
+ break;
+ case GNSS_EPH_HEALTH_UNKNOWN:
+ default:
+ out = GnssDebug::SatelliteEphemerisHealth::UNKNOWN;
+ break;
+ }
+}
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/android/2.0/location_api/LocationUtil.h b/android/2.0/location_api/LocationUtil.h
new file mode 100644
index 0000000..c6f5ead
--- /dev/null
+++ b/android/2.0/location_api/LocationUtil.h
@@ -0,0 +1,55 @@
+/* Copyright (c) 2017-2019, 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 LOCATION_UTIL_H
+#define LOCATION_UTIL_H
+
+#include <android/hardware/gnss/1.0/types.h>
+#include <LocationAPI.h>
+#include <GnssDebug.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+void convertGnssLocation(Location& in, V1_0::GnssLocation& out);
+void convertGnssLocation(const V1_0::GnssLocation& in, Location& out);
+void convertGnssConstellationType(GnssSvType& in, V1_0::GnssConstellationType& out);
+void convertGnssEphemerisType(GnssEphemerisType& in, GnssDebug::SatelliteEphemerisType& out);
+void convertGnssEphemerisSource(GnssEphemerisSource& in, GnssDebug::SatelliteEphemerisSource& out);
+void convertGnssEphemerisHealth(GnssEphemerisHealth& in, GnssDebug::SatelliteEphemerisHealth& out);
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+#endif // LOCATION_UTIL_H
diff --git a/android/2.0/location_api/MeasurementAPIClient.cpp b/android/2.0/location_api/MeasurementAPIClient.cpp
new file mode 100644
index 0000000..d9cae18
--- /dev/null
+++ b/android/2.0/location_api/MeasurementAPIClient.cpp
@@ -0,0 +1,424 @@
+/* Copyright (c) 2017-2019, 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_NDEBUG 0
+#define LOG_TAG "LocSvc_MeasurementAPIClient"
+
+#include <log_util.h>
+#include <loc_cfg.h>
+
+#include "LocationUtil.h"
+#include "MeasurementAPIClient.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IGnssMeasurement;
+using ::android::hardware::gnss::V2_0::IGnssMeasurementCallback;
+
+static void convertGnssData(GnssMeasurementsNotification& in,
+ V1_0::IGnssMeasurementCallback::GnssData& out);
+static void convertGnssData_1_1(GnssMeasurementsNotification& in,
+ V1_1::IGnssMeasurementCallback::GnssData& out);
+static void convertGnssData_2_0(GnssMeasurementsNotification& in,
+ V2_0::IGnssMeasurementCallback::GnssData& out);
+static void convertGnssMeasurement(GnssMeasurementsData& in,
+ V1_0::IGnssMeasurementCallback::GnssMeasurement& out);
+static void convertGnssClock(GnssMeasurementsClock& in, IGnssMeasurementCallback::GnssClock& out);
+
+MeasurementAPIClient::MeasurementAPIClient() :
+ mGnssMeasurementCbIface(nullptr),
+ mGnssMeasurementCbIface_1_1(nullptr),
+ mGnssMeasurementCbIface_2_0(nullptr),
+ mTracking(false)
+{
+ LOC_LOGD("%s]: ()", __FUNCTION__);
+}
+
+MeasurementAPIClient::~MeasurementAPIClient()
+{
+ LOC_LOGD("%s]: ()", __FUNCTION__);
+}
+
+// for GpsInterface
+Return<IGnssMeasurement::GnssMeasurementStatus>
+MeasurementAPIClient::measurementSetCallback(const sp<V1_0::IGnssMeasurementCallback>& callback)
+{
+ LOC_LOGD("%s]: (%p)", __FUNCTION__, &callback);
+
+ mMutex.lock();
+ mGnssMeasurementCbIface = callback;
+ mMutex.unlock();
+
+ return startTracking();
+}
+
+Return<IGnssMeasurement::GnssMeasurementStatus>
+MeasurementAPIClient::measurementSetCallback_1_1(
+ const sp<V1_1::IGnssMeasurementCallback>& callback,
+ GnssPowerMode powerMode, uint32_t timeBetweenMeasurement)
+{
+ LOC_LOGD("%s]: (%p) (powermode: %d) (tbm: %d)",
+ __FUNCTION__, &callback, (int)powerMode, timeBetweenMeasurement);
+
+ mMutex.lock();
+ mGnssMeasurementCbIface_1_1 = callback;
+ mMutex.unlock();
+
+ return startTracking(powerMode, timeBetweenMeasurement);
+}
+
+Return<IGnssMeasurement::GnssMeasurementStatus>
+MeasurementAPIClient::measurementSetCallback_2_0(
+ const sp<V2_0::IGnssMeasurementCallback>& callback,
+ GnssPowerMode powerMode, uint32_t timeBetweenMeasurement)
+{
+ LOC_LOGD("%s]: (%p) (powermode: %d) (tbm: %d)",
+ __FUNCTION__, &callback, (int)powerMode, timeBetweenMeasurement);
+
+ mMutex.lock();
+ mGnssMeasurementCbIface_2_0 = callback;
+ mMutex.unlock();
+
+ return startTracking(powerMode, timeBetweenMeasurement);
+}
+
+Return<IGnssMeasurement::GnssMeasurementStatus>
+MeasurementAPIClient::startTracking(
+ GnssPowerMode powerMode, uint32_t timeBetweenMeasurement)
+{
+ LocationCallbacks locationCallbacks;
+ memset(&locationCallbacks, 0, sizeof(LocationCallbacks));
+ locationCallbacks.size = sizeof(LocationCallbacks);
+
+ locationCallbacks.trackingCb = nullptr;
+ locationCallbacks.batchingCb = nullptr;
+ locationCallbacks.geofenceBreachCb = nullptr;
+ locationCallbacks.geofenceStatusCb = nullptr;
+ locationCallbacks.gnssLocationInfoCb = nullptr;
+ locationCallbacks.gnssNiCb = nullptr;
+ locationCallbacks.gnssSvCb = nullptr;
+ locationCallbacks.gnssNmeaCb = nullptr;
+
+ locationCallbacks.gnssMeasurementsCb = nullptr;
+ if (mGnssMeasurementCbIface_2_0 != nullptr ||
+ mGnssMeasurementCbIface_1_1 != nullptr ||
+ mGnssMeasurementCbIface != nullptr) {
+ locationCallbacks.gnssMeasurementsCb =
+ [this](GnssMeasurementsNotification gnssMeasurementsNotification) {
+ onGnssMeasurementsCb(gnssMeasurementsNotification);
+ };
+ }
+
+ locAPISetCallbacks(locationCallbacks);
+
+ TrackingOptions options = {};
+ memset(&options, 0, sizeof(TrackingOptions));
+ options.size = sizeof(TrackingOptions);
+ options.minInterval = 1000;
+ options.mode = GNSS_SUPL_MODE_STANDALONE;
+ if (GNSS_POWER_MODE_INVALID != powerMode) {
+ options.powerMode = powerMode;
+ options.tbm = timeBetweenMeasurement;
+ }
+
+ mTracking = true;
+ LOC_LOGD("%s]: start tracking session", __FUNCTION__);
+ locAPIStartTracking(options);
+ return IGnssMeasurement::GnssMeasurementStatus::SUCCESS;
+}
+
+// for GpsMeasurementInterface
+void MeasurementAPIClient::measurementClose() {
+ LOC_LOGD("%s]: ()", __FUNCTION__);
+ mTracking = false;
+ locAPIStopTracking();
+}
+
+// callbacks
+void MeasurementAPIClient::onGnssMeasurementsCb(
+ GnssMeasurementsNotification gnssMeasurementsNotification)
+{
+ LOC_LOGD("%s]: (count: %zu active: %d)",
+ __FUNCTION__, gnssMeasurementsNotification.count, mTracking);
+ if (mTracking) {
+ mMutex.lock();
+ sp<V1_0::IGnssMeasurementCallback> gnssMeasurementCbIface = nullptr;
+ sp<V1_1::IGnssMeasurementCallback> gnssMeasurementCbIface_1_1 = nullptr;
+ sp<V2_0::IGnssMeasurementCallback> gnssMeasurementCbIface_2_0 = nullptr;
+ if (mGnssMeasurementCbIface_2_0 != nullptr) {
+ gnssMeasurementCbIface_2_0 = mGnssMeasurementCbIface_2_0;
+ } else if (mGnssMeasurementCbIface_1_1 != nullptr) {
+ gnssMeasurementCbIface_1_1 = mGnssMeasurementCbIface_1_1;
+ } else if (mGnssMeasurementCbIface != nullptr) {
+ gnssMeasurementCbIface = mGnssMeasurementCbIface;
+ }
+ mMutex.unlock();
+
+ if (gnssMeasurementCbIface_2_0 != nullptr) {
+ V2_0::IGnssMeasurementCallback::GnssData gnssData;
+ convertGnssData_2_0(gnssMeasurementsNotification, gnssData);
+ auto r = gnssMeasurementCbIface_2_0->gnssMeasurementCb_2_0(gnssData);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssMeasurementCb description=%s",
+ __func__, r.description().c_str());
+ }
+ } else if (gnssMeasurementCbIface_1_1 != nullptr) {
+ V1_1::IGnssMeasurementCallback::GnssData gnssData;
+ convertGnssData_1_1(gnssMeasurementsNotification, gnssData);
+ auto r = gnssMeasurementCbIface_1_1->gnssMeasurementCb(gnssData);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssMeasurementCb description=%s",
+ __func__, r.description().c_str());
+ }
+ } else if (gnssMeasurementCbIface != nullptr) {
+ V1_0::IGnssMeasurementCallback::GnssData gnssData;
+ convertGnssData(gnssMeasurementsNotification, gnssData);
+ auto r = gnssMeasurementCbIface->GnssMeasurementCb(gnssData);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from GnssMeasurementCb description=%s",
+ __func__, r.description().c_str());
+ }
+ }
+ }
+}
+
+static void convertGnssMeasurement(GnssMeasurementsData& in,
+ V1_0::IGnssMeasurementCallback::GnssMeasurement& out)
+{
+ memset(&out, 0, sizeof(IGnssMeasurementCallback::GnssMeasurement));
+ if (in.flags & GNSS_MEASUREMENTS_DATA_SIGNAL_TO_NOISE_RATIO_BIT)
+ out.flags |= IGnssMeasurementCallback::GnssMeasurementFlags::HAS_SNR;
+ if (in.flags & GNSS_MEASUREMENTS_DATA_CARRIER_FREQUENCY_BIT)
+ out.flags |= IGnssMeasurementCallback::GnssMeasurementFlags::HAS_CARRIER_FREQUENCY;
+ if (in.flags & GNSS_MEASUREMENTS_DATA_CARRIER_CYCLES_BIT)
+ out.flags |= IGnssMeasurementCallback::GnssMeasurementFlags::HAS_CARRIER_CYCLES;
+ if (in.flags & GNSS_MEASUREMENTS_DATA_CARRIER_PHASE_BIT)
+ out.flags |= IGnssMeasurementCallback::GnssMeasurementFlags::HAS_CARRIER_PHASE;
+ if (in.flags & GNSS_MEASUREMENTS_DATA_CARRIER_PHASE_UNCERTAINTY_BIT)
+ out.flags |= IGnssMeasurementCallback::GnssMeasurementFlags::HAS_CARRIER_PHASE_UNCERTAINTY;
+ if (in.flags & GNSS_MEASUREMENTS_DATA_AUTOMATIC_GAIN_CONTROL_BIT)
+ out.flags |= IGnssMeasurementCallback::GnssMeasurementFlags::HAS_AUTOMATIC_GAIN_CONTROL;
+ out.svid = in.svId;
+ convertGnssConstellationType(in.svType, out.constellation);
+ out.timeOffsetNs = in.timeOffsetNs;
+ if (in.stateMask & GNSS_MEASUREMENTS_STATE_CODE_LOCK_BIT)
+ out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_CODE_LOCK;
+ if (in.stateMask & GNSS_MEASUREMENTS_STATE_BIT_SYNC_BIT)
+ out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_BIT_SYNC;
+ if (in.stateMask & GNSS_MEASUREMENTS_STATE_SUBFRAME_SYNC_BIT)
+ out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_SUBFRAME_SYNC;
+ if (in.stateMask & GNSS_MEASUREMENTS_STATE_TOW_DECODED_BIT)
+ out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_TOW_DECODED;
+ if (in.stateMask & GNSS_MEASUREMENTS_STATE_MSEC_AMBIGUOUS_BIT)
+ out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_MSEC_AMBIGUOUS;
+ if (in.stateMask & GNSS_MEASUREMENTS_STATE_SYMBOL_SYNC_BIT)
+ out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_SYMBOL_SYNC;
+ if (in.stateMask & GNSS_MEASUREMENTS_STATE_GLO_STRING_SYNC_BIT)
+ out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GLO_STRING_SYNC;
+ if (in.stateMask & GNSS_MEASUREMENTS_STATE_GLO_TOD_DECODED_BIT)
+ out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GLO_TOD_DECODED;
+ if (in.stateMask & GNSS_MEASUREMENTS_STATE_BDS_D2_BIT_SYNC_BIT)
+ out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_BDS_D2_BIT_SYNC;
+ if (in.stateMask & GNSS_MEASUREMENTS_STATE_BDS_D2_SUBFRAME_SYNC_BIT)
+ out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_BDS_D2_SUBFRAME_SYNC;
+ if (in.stateMask & GNSS_MEASUREMENTS_STATE_GAL_E1BC_CODE_LOCK_BIT)
+ out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GAL_E1BC_CODE_LOCK;
+ if (in.stateMask & GNSS_MEASUREMENTS_STATE_GAL_E1C_2ND_CODE_LOCK_BIT)
+ out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GAL_E1C_2ND_CODE_LOCK;
+ if (in.stateMask & GNSS_MEASUREMENTS_STATE_GAL_E1B_PAGE_SYNC_BIT)
+ out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GAL_E1B_PAGE_SYNC;
+ if (in.stateMask & GNSS_MEASUREMENTS_STATE_SBAS_SYNC_BIT)
+ out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_SBAS_SYNC;
+ out.receivedSvTimeInNs = in.receivedSvTimeNs;
+ out.receivedSvTimeUncertaintyInNs = in.receivedSvTimeUncertaintyNs;
+ out.cN0DbHz = in.carrierToNoiseDbHz;
+ out.pseudorangeRateMps = in.pseudorangeRateMps;
+ out.pseudorangeRateUncertaintyMps = in.pseudorangeRateUncertaintyMps;
+ if (in.adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_VALID_BIT)
+ out.accumulatedDeltaRangeState |=
+ IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_VALID;
+ if (in.adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_RESET_BIT)
+ out.accumulatedDeltaRangeState |=
+ IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_RESET;
+ if (in.adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_CYCLE_SLIP_BIT)
+ out.accumulatedDeltaRangeState |=
+ IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_CYCLE_SLIP;
+ out.accumulatedDeltaRangeM = in.adrMeters;
+ out.accumulatedDeltaRangeUncertaintyM = in.adrUncertaintyMeters;
+ out.carrierFrequencyHz = in.carrierFrequencyHz;
+ out.carrierCycles = in.carrierCycles;
+ out.carrierPhase = in.carrierPhase;
+ out.carrierPhaseUncertainty = in.carrierPhaseUncertainty;
+ uint8_t indicator =
+ static_cast<uint8_t>(IGnssMeasurementCallback::GnssMultipathIndicator::INDICATOR_UNKNOWN);
+ if (in.multipathIndicator & GNSS_MEASUREMENTS_MULTIPATH_INDICATOR_PRESENT)
+ indicator |= IGnssMeasurementCallback::GnssMultipathIndicator::INDICATOR_PRESENT;
+ if (in.multipathIndicator & GNSS_MEASUREMENTS_MULTIPATH_INDICATOR_NOT_PRESENT)
+ indicator |= IGnssMeasurementCallback::GnssMultipathIndicator::INDICATIOR_NOT_PRESENT;
+ out.multipathIndicator =
+ static_cast<IGnssMeasurementCallback::GnssMultipathIndicator>(indicator);
+ out.snrDb = in.signalToNoiseRatioDb;
+ out.agcLevelDb = in.agcLevelDb;
+}
+
+static void convertGnssClock(GnssMeasurementsClock& in, IGnssMeasurementCallback::GnssClock& out)
+{
+ memset(&out, 0, sizeof(IGnssMeasurementCallback::GnssClock));
+ if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_LEAP_SECOND_BIT)
+ out.gnssClockFlags |= IGnssMeasurementCallback::GnssClockFlags::HAS_LEAP_SECOND;
+ if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_TIME_UNCERTAINTY_BIT)
+ out.gnssClockFlags |= IGnssMeasurementCallback::GnssClockFlags::HAS_TIME_UNCERTAINTY;
+ if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_FULL_BIAS_BIT)
+ out.gnssClockFlags |= IGnssMeasurementCallback::GnssClockFlags::HAS_FULL_BIAS;
+ if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_BIAS_BIT)
+ out.gnssClockFlags |= IGnssMeasurementCallback::GnssClockFlags::HAS_BIAS;
+ if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_BIAS_UNCERTAINTY_BIT)
+ out.gnssClockFlags |= IGnssMeasurementCallback::GnssClockFlags::HAS_BIAS_UNCERTAINTY;
+ if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_DRIFT_BIT)
+ out.gnssClockFlags |= IGnssMeasurementCallback::GnssClockFlags::HAS_DRIFT;
+ if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_DRIFT_UNCERTAINTY_BIT)
+ out.gnssClockFlags |= IGnssMeasurementCallback::GnssClockFlags::HAS_DRIFT_UNCERTAINTY;
+ out.leapSecond = in.leapSecond;
+ out.timeNs = in.timeNs;
+ out.timeUncertaintyNs = in.timeUncertaintyNs;
+ out.fullBiasNs = in.fullBiasNs;
+ out.biasNs = in.biasNs;
+ out.biasUncertaintyNs = in.biasUncertaintyNs;
+ out.driftNsps = in.driftNsps;
+ out.driftUncertaintyNsps = in.driftUncertaintyNsps;
+ out.hwClockDiscontinuityCount = in.hwClockDiscontinuityCount;
+}
+
+static void convertGnssData(GnssMeasurementsNotification& in,
+ V1_0::IGnssMeasurementCallback::GnssData& out)
+{
+ out.measurementCount = in.count;
+ if (out.measurementCount > static_cast<uint32_t>(V1_0::GnssMax::SVS_COUNT)) {
+ LOC_LOGW("%s]: Too many measurement %u. Clamps to %d.",
+ __FUNCTION__, out.measurementCount, V1_0::GnssMax::SVS_COUNT);
+ out.measurementCount = static_cast<uint32_t>(V1_0::GnssMax::SVS_COUNT);
+ }
+ for (size_t i = 0; i < out.measurementCount; i++) {
+ convertGnssMeasurement(in.measurements[i], out.measurements[i]);
+ }
+ convertGnssClock(in.clock, out.clock);
+}
+
+static void convertGnssData_1_1(GnssMeasurementsNotification& in,
+ V1_1::IGnssMeasurementCallback::GnssData& out)
+{
+ out.measurements.resize(in.count);
+ for (size_t i = 0; i < in.count; i++) {
+ convertGnssMeasurement(in.measurements[i], out.measurements[i].v1_0);
+ if (in.measurements[i].adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_VALID_BIT)
+ out.measurements[i].accumulatedDeltaRangeState |=
+ IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_VALID;
+ if (in.measurements[i].adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_RESET_BIT)
+ out.measurements[i].accumulatedDeltaRangeState |=
+ IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_RESET;
+ if (in.measurements[i].adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_CYCLE_SLIP_BIT)
+ out.measurements[i].accumulatedDeltaRangeState |=
+ IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_CYCLE_SLIP;
+ if (in.measurements[i].adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_HALF_CYCLE_RESOLVED_BIT)
+ out.measurements[i].accumulatedDeltaRangeState |=
+ IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_HALF_CYCLE_RESOLVED;
+ }
+ convertGnssClock(in.clock, out.clock);
+}
+
+static void convertGnssData_2_0(GnssMeasurementsNotification& in,
+ V2_0::IGnssMeasurementCallback::GnssData& out)
+{
+ out.measurements.resize(in.count);
+ for (size_t i = 0; i < in.count; i++) {
+ convertGnssMeasurement(in.measurements[i], out.measurements[i].v1_1.v1_0);
+ if (in.measurements[i].adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_VALID_BIT)
+ out.measurements[i].v1_1.accumulatedDeltaRangeState |=
+ IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_VALID;
+ if (in.measurements[i].adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_RESET_BIT)
+ out.measurements[i].v1_1.accumulatedDeltaRangeState |=
+ IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_RESET;
+ if (in.measurements[i].adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_CYCLE_SLIP_BIT)
+ out.measurements[i].v1_1.accumulatedDeltaRangeState |=
+ IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_CYCLE_SLIP;
+ if (in.measurements[i].adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_HALF_CYCLE_RESOLVED_BIT)
+ out.measurements[i].v1_1.accumulatedDeltaRangeState |=
+ IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_HALF_CYCLE_RESOLVED;
+
+// out.measurements[i].codeType =
+// static_cast<IGnssMeasurementCallback::GnssMeasurementCodeType>(in.measurements[i].codeType);
+// out.measurements[i].otherCodeTypeName = in.measurements[i].otherCodeTypeName;
+
+ if (in.measurements[i].stateMask & GNSS_MEASUREMENTS_STATE_CODE_LOCK_BIT)
+ out.measurements[i].state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_CODE_LOCK;
+ if (in.measurements[i].stateMask & GNSS_MEASUREMENTS_STATE_BIT_SYNC_BIT)
+ out.measurements[i].state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_BIT_SYNC;
+ if (in.measurements[i].stateMask & GNSS_MEASUREMENTS_STATE_SUBFRAME_SYNC_BIT)
+ out.measurements[i].state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_SUBFRAME_SYNC;
+ if (in.measurements[i].stateMask & GNSS_MEASUREMENTS_STATE_TOW_DECODED_BIT)
+ out.measurements[i].state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_TOW_DECODED;
+ if (in.measurements[i].stateMask & GNSS_MEASUREMENTS_STATE_MSEC_AMBIGUOUS_BIT)
+ out.measurements[i].state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_MSEC_AMBIGUOUS;
+ if (in.measurements[i].stateMask & GNSS_MEASUREMENTS_STATE_SYMBOL_SYNC_BIT)
+ out.measurements[i].state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_SYMBOL_SYNC;
+ if (in.measurements[i].stateMask & GNSS_MEASUREMENTS_STATE_GLO_STRING_SYNC_BIT)
+ out.measurements[i].state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GLO_STRING_SYNC;
+ if (in.measurements[i].stateMask & GNSS_MEASUREMENTS_STATE_GLO_TOD_DECODED_BIT)
+ out.measurements[i].state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GLO_TOD_DECODED;
+ if (in.measurements[i].stateMask & GNSS_MEASUREMENTS_STATE_BDS_D2_BIT_SYNC_BIT)
+ out.measurements[i].state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_BDS_D2_BIT_SYNC;
+ if (in.measurements[i].stateMask & GNSS_MEASUREMENTS_STATE_BDS_D2_SUBFRAME_SYNC_BIT)
+ out.measurements[i].state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_BDS_D2_SUBFRAME_SYNC;
+ if (in.measurements[i].stateMask & GNSS_MEASUREMENTS_STATE_GAL_E1BC_CODE_LOCK_BIT)
+ out.measurements[i].state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GAL_E1BC_CODE_LOCK;
+ if (in.measurements[i].stateMask & GNSS_MEASUREMENTS_STATE_GAL_E1C_2ND_CODE_LOCK_BIT)
+ out.measurements[i].state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GAL_E1C_2ND_CODE_LOCK;
+ if (in.measurements[i].stateMask & GNSS_MEASUREMENTS_STATE_GAL_E1B_PAGE_SYNC_BIT)
+ out.measurements[i].state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GAL_E1B_PAGE_SYNC;
+ if (in.measurements[i].stateMask & GNSS_MEASUREMENTS_STATE_SBAS_SYNC_BIT)
+ out.measurements[i].state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_SBAS_SYNC;
+ if (in.measurements[i].stateMask & GNSS_MEASUREMENTS_STATE_TOW_KNOWN_BIT)
+ out.measurements[i].state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_TOW_KNOWN;
+ if (in.measurements[i].stateMask & GNSS_MEASUREMENTS_STATE_GLO_TOD_KNOWN_BIT)
+ out.measurements[i].state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GLO_TOD_KNOWN;
+ if (in.measurements[i].stateMask & GNSS_MEASUREMENTS_STATE_2ND_CODE_LOCK_BIT)
+ out.measurements[i].state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_2ND_CODE_LOCK;
+ }
+ convertGnssClock(in.clock, out.clock);
+}
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/android/2.0/location_api/MeasurementAPIClient.h b/android/2.0/location_api/MeasurementAPIClient.h
new file mode 100644
index 0000000..4146a13
--- /dev/null
+++ b/android/2.0/location_api/MeasurementAPIClient.h
@@ -0,0 +1,89 @@
+/* Copyright (c) 2017-2019, 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 MEASUREMENT_API_CLINET_H
+#define MEASUREMENT_API_CLINET_H
+
+#include <mutex>
+#include <android/hardware/gnss/2.0/IGnssMeasurement.h>
+//#include <android/hardware/gnss/1.1/IGnssMeasurementCallback.h>
+#include <LocationAPIClientBase.h>
+#include <hidl/Status.h>
+#include <gps_extended_c.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::sp;
+
+class MeasurementAPIClient : public LocationAPIClientBase
+{
+public:
+ MeasurementAPIClient();
+ virtual ~MeasurementAPIClient();
+ MeasurementAPIClient(const MeasurementAPIClient&) = delete;
+ MeasurementAPIClient& operator=(const MeasurementAPIClient&) = delete;
+
+ // for GpsMeasurementInterface
+ Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> measurementSetCallback(
+ const sp<V1_0::IGnssMeasurementCallback>& callback);
+ Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> measurementSetCallback_1_1(
+ const sp<V1_1::IGnssMeasurementCallback>& callback,
+ GnssPowerMode powerMode = GNSS_POWER_MODE_INVALID,
+ uint32_t timeBetweenMeasurement = GPS_DEFAULT_FIX_INTERVAL_MS);
+ Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> measurementSetCallback_2_0(
+ const sp<V2_0::IGnssMeasurementCallback>& callback,
+ GnssPowerMode powerMode = GNSS_POWER_MODE_INVALID,
+ uint32_t timeBetweenMeasurement = GPS_DEFAULT_FIX_INTERVAL_MS);
+ void measurementClose();
+ Return<IGnssMeasurement::GnssMeasurementStatus> startTracking(
+ GnssPowerMode powerMode = GNSS_POWER_MODE_INVALID,
+ uint32_t timeBetweenMeasurement = GPS_DEFAULT_FIX_INTERVAL_MS);
+
+ // callbacks we are interested in
+ void onGnssMeasurementsCb(GnssMeasurementsNotification gnssMeasurementsNotification) final;
+
+private:
+ std::mutex mMutex;
+ sp<V1_0::IGnssMeasurementCallback> mGnssMeasurementCbIface;
+ sp<V1_1::IGnssMeasurementCallback> mGnssMeasurementCbIface_1_1;
+ sp<V2_0::IGnssMeasurementCallback> mGnssMeasurementCbIface_2_0;
+
+ bool mTracking;
+};
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+#endif // MEASUREMENT_API_CLINET_H
diff --git a/android/2.0/service.cpp b/android/2.0/service.cpp
new file mode 100644
index 0000000..16f0b06
--- /dev/null
+++ b/android/2.0/service.cpp
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "android.hardware.gnss@2.0-service-qti"
+
+#include <android/hardware/gnss/2.0/IGnss.h>
+#include <hidl/LegacySupport.h>
+#include "loc_cfg.h"
+#include "loc_misc_utils.h"
+
+extern "C" {
+#include "vndfwk-detect.h"
+}
+
+#ifdef ARCH_ARM_32
+#define DEFAULT_HW_BINDER_MEM_SIZE 65536
+#endif
+
+using android::hardware::gnss::V2_0::IGnss;
+
+using android::hardware::configureRpcThreadpool;
+using android::hardware::registerPassthroughServiceImplementation;
+using android::hardware::joinRpcThreadpool;
+
+using android::status_t;
+using android::OK;
+
+typedef int vendorEnhancedServiceMain(int /* argc */, char* /* argv */ []);
+
+int main() {
+
+ ALOGI("%s", __FUNCTION__);
+
+ bool vendorEnhanced = isRunningWithVendorEnhancedFramework();
+ setVendorEnhanced(vendorEnhanced);
+
+#ifdef ARCH_ARM_32
+ android::hardware::ProcessState::initWithMmapSize((size_t)(DEFAULT_HW_BINDER_MEM_SIZE));
+#endif
+ configureRpcThreadpool(1, true);
+ status_t status;
+
+ status = registerPassthroughServiceImplementation<IGnss>();
+ if (status == OK) {
+ if (vendorEnhanced) {
+ #ifdef LOC_HIDL_VERSION
+ #define VENDOR_ENHANCED_LIB "vendor.qti.gnss@" LOC_HIDL_VERSION "-service.so"
+
+ void* libHandle = NULL;
+ vendorEnhancedServiceMain* vendorEnhancedMainMethod = (vendorEnhancedServiceMain*)
+ dlGetSymFromLib(libHandle, VENDOR_ENHANCED_LIB, "main");
+ if (NULL != vendorEnhancedMainMethod) {
+ (*vendorEnhancedMainMethod)(0, NULL);
+ }
+ #else
+ ALOGE("LOC_HIDL_VERSION not defined.");
+ #endif
+ }
+
+ joinRpcThreadpool();
+
+ } else {
+ ALOGE("Error while registering IGnss 2.0 service: %d", status);
+ }
+
+ return 0;
+}
diff --git a/android/Android.mk b/android/Android.mk
index bff117e..f117def 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -1,10 +1,14 @@
LOCAL_PATH := $(call my-dir)
ifneq ($(BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE),)
+ifeq ($(GNSS_HIDL_VERSION),2.0)
+include $(LOCAL_PATH)/2.0/Android.mk
+else
ifeq ($(GNSS_HIDL_VERSION),1.1)
include $(LOCAL_PATH)/1.1/Android.mk
else
include $(LOCAL_PATH)/1.0/Android.mk
-endif
+endif #GNSS HIDL 1.1
+endif #GNSS HIDL 2.0
else #QMAA flag set, build dummy android.hardware.gnss@1.0-impl-qti
include $(LOCAL_PATH)/dummy/Android.mk
endif #BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE
diff --git a/android/dummy/Android.mk b/android/dummy/Android.mk
index d438888..05114e1 100644
--- a/android/dummy/Android.mk
+++ b/android/dummy/Android.mk
@@ -1,9 +1,9 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
-#build dummy android.hardware.gnss@1.0-impl-qti
+#build dummy android.hardware.gnss@2.0-impl-qti
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.gnss@1.0-impl-qti
+LOCAL_MODULE := android.hardware.gnss@2.0-impl-qti
LOCAL_VENDOR_MODULE := true
LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_SRC_FILES := GnssDummy.cpp
@@ -20,19 +20,11 @@ LOCAL_SHARED_LIBRARIES := \
LOCAL_CFLAGS += $(GNSS_CFLAGS)
include $(BUILD_SHARED_LIBRARY)
-BUILD_GNSS_HIDL_SERVICE := true
-ifneq ($(BOARD_VENDOR_QCOM_LOC_PDK_FEATURE_SET), true)
-ifneq ($(LW_FEATURE_SET),true)
-#BUILD_GNSS_HIDL_SERVICE := false
-endif # LW_FEATURE_SET
-endif # BOARD_VENDOR_QCOM_LOC_PDK_FEATURE_SET
-
-ifeq ($(BUILD_GNSS_HIDL_SERVICE), true)
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.gnss@1.0-service-qti
+LOCAL_MODULE := android.hardware.gnss@2.0-service-qti
LOCAL_VENDOR_MODULE := true
LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_INIT_RC := android.hardware.gnss@1.0-service-qti.rc
+LOCAL_INIT_RC := android.hardware.gnss@2.0-service-qti.rc
LOCAL_SRC_FILES := \
serviceDummy.cpp \
@@ -60,4 +52,3 @@ LOCAL_SHARED_LIBRARIES += \
LOCAL_CFLAGS += $(GNSS_CFLAGS)
include $(BUILD_EXECUTABLE)
-endif # BUILD_GNSS_HIDL_SERVICE
diff --git a/android/dummy/android.hardware.gnss@2.0-service-qti.rc b/android/dummy/android.hardware.gnss@2.0-service-qti.rc
new file mode 100644
index 0000000..36ee47c
--- /dev/null
+++ b/android/dummy/android.hardware.gnss@2.0-service-qti.rc
@@ -0,0 +1,4 @@
+service gnss_service /vendor/bin/hw/android.hardware.gnss@2.0-service-qti
+ class hal
+ user gps
+ group system gps radio
diff --git a/android/measurement_corrections/1.0/MeasurementCorrections.cpp b/android/measurement_corrections/1.0/MeasurementCorrections.cpp
new file mode 100644
index 0000000..c1a335a
--- /dev/null
+++ b/android/measurement_corrections/1.0/MeasurementCorrections.cpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2019, 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_MeasurementCorrectionsInterface"
+
+#include <log_util.h>
+#include "MeasurementCorrections.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace measurement_corrections {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+using ::android::hardware::gnss::V1_0::GnssLocation;
+
+MeasurementCorrections::MeasurementCorrections() {
+}
+
+MeasurementCorrections::~MeasurementCorrections() {
+}
+
+Return<bool> MeasurementCorrections::setCorrections(const ::android::hardware::gnss::measurement_corrections::V1_0::MeasurementCorrections& corrections) {
+ return true;
+}
+
+Return<bool> MeasurementCorrections::setCallback(const sp<IMeasurementCorrectionsCallback>& callback) {
+ return true;
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace measurement_corrections
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/android/measurement_corrections/1.0/MeasurementCorrections.h b/android/measurement_corrections/1.0/MeasurementCorrections.h
new file mode 100644
index 0000000..ad534dc
--- /dev/null
+++ b/android/measurement_corrections/1.0/MeasurementCorrections.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2019, 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 ANDROID_HARDWARE_GNSS_V1_0_MeasurementCorrections_H
+#define ANDROID_HARDWARE_GNSS_V1_0_MeasurementCorrections_H
+
+#include <android/hardware/gnss/measurement_corrections/1.0/IMeasurementCorrections.h>
+#include <android/hardware/gnss/measurement_corrections/1.0/IMeasurementCorrectionsCallback.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+#include <location_interface.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace measurement_corrections {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+using ::android::hardware::gnss::V1_0::GnssLocation;
+using ::android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrectionsCallback;
+
+struct MeasurementCorrections : public IMeasurementCorrections {
+ MeasurementCorrections();
+ ~MeasurementCorrections();
+
+// Methods from ::android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrections follow.
+Return<bool> setCorrections(const ::android::hardware::gnss::measurement_corrections::V1_0::MeasurementCorrections& corrections) override;
+
+Return<bool> setCallback(const sp<IMeasurementCorrectionsCallback>& callback) override;
+
+};
+
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace measurement_corrections
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V1_0_MeasurementCorrections_H
diff --git a/android/visibility_control/1.0/GnssVisibilityControl.cpp b/android/visibility_control/1.0/GnssVisibilityControl.cpp
new file mode 100644
index 0000000..82e465c
--- /dev/null
+++ b/android/visibility_control/1.0/GnssVisibilityControl.cpp
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2019, 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.
+ */
+
+#include <android/hardware/gnss/visibility_control/1.0/IGnssVisibilityControl.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include "GnssVisibilityControl.h"
+#include <location_interface.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace visibility_control {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+static GnssVisibilityControl* spGnssVisibilityControl = nullptr;
+
+static void convertGnssNfwNotification(GnssNfwNotification& in,
+ IGnssVisibilityControlCallback::NfwNotification& out);
+
+GnssVisibilityControl::GnssVisibilityControl(Gnss* gnss) : mGnss(gnss) {
+ spGnssVisibilityControl = this;
+}
+GnssVisibilityControl::~GnssVisibilityControl() {
+ spGnssVisibilityControl = nullptr;
+}
+
+void GnssVisibilityControl::nfwStatusCb(GnssNfwNotification notification) {
+ if (nullptr != spGnssVisibilityControl) {
+ spGnssVisibilityControl->statusCb(notification);
+ }
+}
+
+static void convertGnssNfwNotification(GnssNfwNotification& in,
+ IGnssVisibilityControlCallback::NfwNotification& out)
+{
+ memset(&out, 0, sizeof(IGnssVisibilityControlCallback::NfwNotification));
+ out.proxyAppPackageName = in.proxyAppPackageName;
+ out.protocolStack = (IGnssVisibilityControlCallback::NfwProtocolStack)in.protocolStack;
+ out.otherProtocolStackName = in.otherProtocolStackName;
+ out.requestor = (IGnssVisibilityControlCallback::NfwRequestor)in.requestor;
+ out.requestorId = in.requestorId;
+ out.responseType = (IGnssVisibilityControlCallback::NfwResponseType)in.responseType;
+ out.inEmergencyMode = in.inEmergencyMode;
+ out.isCachedLocation = in.isCachedLocation;
+}
+
+void GnssVisibilityControl::statusCb(GnssNfwNotification notification) {
+
+ if (mGnssVisibilityControlCbIface != nullptr) {
+ IGnssVisibilityControlCallback::NfwNotification nfwNotification;
+
+ // Convert from one structure to another
+ convertGnssNfwNotification(notification, nfwNotification);
+
+ auto r = mGnssVisibilityControlCbIface->nfwNotifyCb(nfwNotification);
+ if (!r.isOk()) {
+ LOC_LOGw("Error invoking NFW status cb %s", r.description().c_str());
+ }
+ } else {
+ LOC_LOGw("setCallback has not been called yet");
+ }
+}
+
+// Methods from ::android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControl follow.
+Return<bool> GnssVisibilityControl::enableNfwLocationAccess(const hidl_vec<::android::hardware::hidl_string>& proxyApps) {
+
+ if (nullptr == mGnss || nullptr == mGnss->getGnssInterface()) {
+ LOC_LOGe("Null GNSS interface");
+ return false;
+ }
+
+ /* If the vector is empty we need to disable all NFW clients
+ If there is at least one app in the vector we need to enable
+ all NFW clients */
+ if (0 == proxyApps.size()) {
+ mGnss->getGnssInterface()->enableNfwLocationAccess(false);
+ } else {
+ mGnss->getGnssInterface()->enableNfwLocationAccess(true);
+ }
+
+ return true;
+}
+/**
+ * Registers the callback for HAL implementation to use.
+ *
+ * @param callback Handle to IGnssVisibilityControlCallback interface.
+ */
+Return<bool> GnssVisibilityControl::setCallback(const ::android::sp<::android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControlCallback>& callback) {
+
+ if (nullptr == mGnss || nullptr == mGnss->getGnssInterface()) {
+ LOC_LOGe("Null GNSS interface");
+ return false;
+ }
+ mGnssVisibilityControlCbIface = callback;
+
+ NfwCbInfo cbInfo = {};
+ cbInfo.visibilityControlCb = (void*)nfwStatusCb;
+
+ mGnss->getGnssInterface()->nfwInit(cbInfo);
+
+ return true;
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace visibility_control
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/android/visibility_control/1.0/GnssVisibilityControl.h b/android/visibility_control/1.0/GnssVisibilityControl.h
new file mode 100644
index 0000000..4eaea51
--- /dev/null
+++ b/android/visibility_control/1.0/GnssVisibilityControl.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2019, 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 ANDROID_HARDWARE_GNSS_V1_0_GnssVisibilityControl_H
+#define ANDROID_HARDWARE_GNSS_V1_0_GnssVisibilityControl_H
+
+#include <android/hardware/gnss/visibility_control/1.0/IGnssVisibilityControl.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+#include <gps_extended_c.h>
+#include <location_interface.h>
+#include "Gnss.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace visibility_control {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+using ::android::hardware::gnss::V2_0::implementation::Gnss;
+
+struct GnssVisibilityControl : public IGnssVisibilityControl {
+ GnssVisibilityControl(Gnss* gnss);
+ ~GnssVisibilityControl();
+
+ // Methods from ::android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControl follow.
+ Return<bool> enableNfwLocationAccess(const hidl_vec<::android::hardware::hidl_string>& proxyApps) override;
+ /**
+ * Registers the callback for HAL implementation to use.
+ *
+ * @param callback Handle to IGnssVisibilityControlCallback interface.
+ */
+ Return<bool> setCallback(const ::android::sp<::android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControlCallback>& callback) override;
+
+ void statusCb(GnssNfwNotification notification);
+
+ /* Data call setup callback passed down to GNSS HAL implementation */
+ static void nfwStatusCb(GnssNfwNotification notification);
+
+private:
+ Gnss* mGnss = nullptr;
+ sp<IGnssVisibilityControlCallback> mGnssVisibilityControlCbIface = nullptr;
+};
+
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace visibility_control
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V1_0_GnssVisibilityControl_H
diff --git a/batching/Android.mk b/batching/Android.mk
new file mode 100644
index 0000000..b08d155
--- /dev/null
+++ b/batching/Android.mk
@@ -0,0 +1,37 @@
+ifneq ($(BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE),)
+ifneq ($(BUILD_TINY_ANDROID),true)
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libbatching
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SHARED_LIBRARIES := \
+ libutils \
+ libcutils \
+ liblog \
+ libloc_core \
+ libgps.utils \
+ libdl \
+ liblbs_core
+
+LOCAL_SRC_FILES += \
+ location_batching.cpp \
+ BatchingAdapter.cpp
+
+LOCAL_HEADER_LIBRARIES := \
+ libgps.utils_headers \
+ libloc_core_headers \
+ libloc_pla_headers \
+ liblocation_api_headers
+
+LOCAL_PRELINK_MODULE := false
+
+LOCAL_CFLAGS += $(GNSS_CFLAGS)
+include $(BUILD_SHARED_LIBRARY)
+
+endif # not BUILD_TINY_ANDROID
+endif # BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE
diff --git a/batching/BatchingAdapter.cpp b/batching/BatchingAdapter.cpp
new file mode 100644
index 0000000..135f0ed
--- /dev/null
+++ b/batching/BatchingAdapter.cpp
@@ -0,0 +1,1050 @@
+/* Copyright (c) 2017-2019, 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_NDEBUG 0
+#define LOG_TAG "LocSvc_BatchingAdapter"
+
+#include <loc_pla.h>
+#include <log_util.h>
+#include <LocContext.h>
+#include <BatchingAdapter.h>
+
+using namespace loc_core;
+
+BatchingAdapter::BatchingAdapter() :
+ LocAdapterBase(0,
+ LocContext::getLocContext(
+ NULL,
+ NULL,
+ LocContext::mLocationHalName,
+ false)),
+ mOngoingTripDistance(0),
+ mOngoingTripTBFInterval(0),
+ mTripWithOngoingTBFDropped(false),
+ mTripWithOngoingTripDistanceDropped(false),
+ mBatchingTimeout(0),
+ mBatchingAccuracy(1),
+ mBatchSize(0),
+ mTripBatchSize(0)
+{
+ LOC_LOGD("%s]: Constructor", __func__);
+ readConfigCommand();
+ setConfigCommand();
+}
+
+void
+BatchingAdapter::readConfigCommand()
+{
+ LOC_LOGD("%s]: ", __func__);
+
+ struct MsgReadConfig : public LocMsg {
+ BatchingAdapter& mAdapter;
+ inline MsgReadConfig(BatchingAdapter& adapter) :
+ LocMsg(),
+ mAdapter(adapter) {}
+ inline virtual void proc() const {
+ uint32_t batchingTimeout = 0;
+ uint32_t batchingAccuracy = 0;
+ uint32_t batchSize = 0;
+ uint32_t tripBatchSize = 0;
+ static const loc_param_s_type flp_conf_param_table[] =
+ {
+ {"BATCH_SIZE", &batchSize, NULL, 'n'},
+ {"OUTDOOR_TRIP_BATCH_SIZE", &tripBatchSize, NULL, 'n'},
+ {"BATCH_SESSION_TIMEOUT", &batchingTimeout, NULL, 'n'},
+ {"ACCURACY", &batchingAccuracy, NULL, 'n'},
+ };
+ UTIL_READ_CONF(LOC_PATH_FLP_CONF, flp_conf_param_table);
+
+ LOC_LOGD("%s]: batchSize %u tripBatchSize %u batchingAccuracy %u batchingTimeout %u ",
+ __func__, batchSize, tripBatchSize, batchingAccuracy, batchingTimeout);
+
+ mAdapter.setBatchSize(batchSize);
+ mAdapter.setTripBatchSize(tripBatchSize);
+ mAdapter.setBatchingTimeout(batchingTimeout);
+ mAdapter.setBatchingAccuracy(batchingAccuracy);
+ }
+ };
+
+ sendMsg(new MsgReadConfig(*this));
+
+}
+
+void
+BatchingAdapter::setConfigCommand()
+{
+ LOC_LOGD("%s]: ", __func__);
+
+ struct MsgSetConfig : public LocMsg {
+ BatchingAdapter& mAdapter;
+ LocApiBase& mApi;
+ inline MsgSetConfig(BatchingAdapter& adapter,
+ LocApiBase& api) :
+ LocMsg(),
+ mAdapter(adapter),
+ mApi(api) {}
+ inline virtual void proc() const {
+ mApi.setBatchSize(mAdapter.getBatchSize());
+ mApi.setTripBatchSize(mAdapter.getTripBatchSize());
+ }
+ };
+
+ sendMsg(new MsgSetConfig(*this, *mLocApi));
+}
+
+void
+BatchingAdapter::stopClientSessions(LocationAPI* client)
+{
+ LOC_LOGD("%s]: client %p", __func__, client);
+
+ typedef struct pairKeyBatchMode {
+ LocationAPI* client;
+ uint32_t id;
+ BatchingMode batchingMode;
+ inline pairKeyBatchMode(LocationAPI* _client, uint32_t _id, BatchingMode _bMode) :
+ client(_client), id(_id), batchingMode(_bMode) {}
+ } pairKeyBatchMode;
+ std::vector<pairKeyBatchMode> vBatchingClient;
+ for (auto it : mBatchingSessions) {
+ if (client == it.first.client) {
+ vBatchingClient.emplace_back(it.first.client, it.first.id, it.second.batchingMode);
+ }
+ }
+ for (auto keyBatchingMode : vBatchingClient) {
+ if (keyBatchingMode.batchingMode != BATCHING_MODE_TRIP) {
+ stopBatching(keyBatchingMode.client, keyBatchingMode.id);
+ } else {
+ stopTripBatchingMultiplex(keyBatchingMode.client, keyBatchingMode.id);
+ }
+ }
+}
+
+void
+BatchingAdapter::updateClientsEventMask()
+{
+ LOC_API_ADAPTER_EVENT_MASK_T mask = 0;
+ for (auto it=mClientData.begin(); it != mClientData.end(); ++it) {
+ // we don't register LOC_API_ADAPTER_BIT_BATCH_FULL until we
+ // start batching with ROUTINE or TRIP option
+ if (it->second.batchingCb != nullptr) {
+ mask |= LOC_API_ADAPTER_BIT_BATCH_STATUS;
+ }
+ }
+ if (autoReportBatchingSessionsCount() > 0) {
+ mask |= LOC_API_ADAPTER_BIT_BATCH_FULL;
+ }
+ updateEvtMask(mask, LOC_REGISTRATION_MASK_SET);
+}
+
+void
+BatchingAdapter::handleEngineUpEvent()
+{
+ struct MsgSSREvent : public LocMsg {
+ BatchingAdapter& mAdapter;
+ LocApiBase& mApi;
+ inline MsgSSREvent(BatchingAdapter& adapter,
+ LocApiBase& api) :
+ LocMsg(),
+ mAdapter(adapter),
+ mApi(api) {}
+ virtual void proc() const {
+ mAdapter.setEngineCapabilitiesKnown(true);
+ mAdapter.broadcastCapabilities(mAdapter.getCapabilities());
+ mApi.setBatchSize(mAdapter.getBatchSize());
+ mApi.setTripBatchSize(mAdapter.getTripBatchSize());
+ mAdapter.restartSessions();
+ for (auto msg: mAdapter.mPendingMsgs) {
+ mAdapter.sendMsg(msg);
+ }
+ mAdapter.mPendingMsgs.clear();
+ }
+ };
+
+ sendMsg(new MsgSSREvent(*this, *mLocApi));
+}
+
+void
+BatchingAdapter::restartSessions()
+{
+ LOC_LOGD("%s]: ", __func__);
+
+ if (autoReportBatchingSessionsCount() > 0) {
+ updateEvtMask(LOC_API_ADAPTER_BIT_BATCH_FULL,
+ LOC_REGISTRATION_MASK_ENABLED);
+ }
+ for (auto it = mBatchingSessions.begin();
+ it != mBatchingSessions.end(); ++it) {
+ if (it->second.batchingMode != BATCHING_MODE_TRIP) {
+ mLocApi->startBatching(it->first.id, it->second,
+ getBatchingAccuracy(), getBatchingTimeout(),
+ new LocApiResponse(*getContext(),
+ [] (LocationError /*err*/) {}));
+ }
+ }
+
+ if (mTripSessions.size() > 0) {
+ // restart outdoor trip batching session if any.
+ mOngoingTripDistance = 0;
+ mOngoingTripTBFInterval = 0;
+
+ // record the min trip distance and min tbf interval of all ongoing sessions
+ for (auto tripSession : mTripSessions) {
+
+ TripSessionStatus &tripSessStatus = tripSession.second;
+
+ if ((0 == mOngoingTripDistance) ||
+ (mOngoingTripDistance >
+ (tripSessStatus.tripDistance - tripSessStatus.accumulatedDistanceThisTrip))) {
+ mOngoingTripDistance = tripSessStatus.tripDistance -
+ tripSessStatus.accumulatedDistanceThisTrip;
+ }
+
+ if ((0 == mOngoingTripTBFInterval) ||
+ (mOngoingTripTBFInterval > tripSessStatus.tripTBFInterval)) {
+ mOngoingTripTBFInterval = tripSessStatus.tripTBFInterval;
+ }
+
+ // reset the accumulatedDistanceOngoingBatch for each session
+ tripSessStatus.accumulatedDistanceOngoingBatch = 0;
+
+ }
+
+ mLocApi->startOutdoorTripBatching(mOngoingTripDistance, mOngoingTripTBFInterval,
+ getBatchingTimeout(), new LocApiResponse(*getContext(), [this] (LocationError err) {
+ if (LOCATION_ERROR_SUCCESS != err) {
+ mOngoingTripDistance = 0;
+ mOngoingTripTBFInterval = 0;
+ }
+ printTripReport();
+ }));
+ }
+}
+
+bool
+BatchingAdapter::hasBatchingCallback(LocationAPI* client)
+{
+ auto it = mClientData.find(client);
+ return (it != mClientData.end() && it->second.batchingCb);
+}
+
+bool
+BatchingAdapter::isBatchingSession(LocationAPI* client, uint32_t sessionId)
+{
+ LocationSessionKey key(client, sessionId);
+ return (mBatchingSessions.find(key) != mBatchingSessions.end());
+}
+
+bool
+BatchingAdapter::isTripSession(uint32_t sessionId) {
+ return (mTripSessions.find(sessionId) != mTripSessions.end());
+}
+
+void
+BatchingAdapter::saveBatchingSession(LocationAPI* client, uint32_t sessionId,
+ const BatchingOptions& batchingOptions)
+{
+ LocationSessionKey key(client, sessionId);
+ mBatchingSessions[key] = batchingOptions;
+}
+
+void
+BatchingAdapter::eraseBatchingSession(LocationAPI* client, uint32_t sessionId)
+{
+ LocationSessionKey key(client, sessionId);
+ auto it = mBatchingSessions.find(key);
+ if (it != mBatchingSessions.end()) {
+ mBatchingSessions.erase(it);
+ }
+}
+
+void
+BatchingAdapter::reportResponse(LocationAPI* client, LocationError err, uint32_t sessionId)
+{
+ LOC_LOGD("%s]: client %p id %u err %u", __func__, client, sessionId, err);
+
+ auto it = mClientData.find(client);
+ if (it != mClientData.end() &&
+ it->second.responseCb != nullptr) {
+ it->second.responseCb(err, sessionId);
+ } else {
+ LOC_LOGE("%s]: client %p id %u not found in data", __func__, client, sessionId);
+ }
+}
+
+uint32_t
+BatchingAdapter::autoReportBatchingSessionsCount()
+{
+ uint32_t count = 0;
+ for (auto batchingSession: mBatchingSessions) {
+ if (batchingSession.second.batchingMode != BATCHING_MODE_NO_AUTO_REPORT) {
+ count++;
+ }
+ }
+ count += mTripSessions.size();
+ return count;
+}
+
+uint32_t
+BatchingAdapter::startBatchingCommand(
+ LocationAPI* client, BatchingOptions& batchOptions)
+{
+ uint32_t sessionId = generateSessionId();
+ LOC_LOGD("%s]: client %p id %u minInterval %u minDistance %u mode %u Batching Mode %d",
+ __func__, client, sessionId, batchOptions.minInterval, batchOptions.minDistance,
+ batchOptions.mode,batchOptions.batchingMode);
+
+ struct MsgStartBatching : public LocMsg {
+ BatchingAdapter& mAdapter;
+ LocApiBase& mApi;
+ LocationAPI* mClient;
+ uint32_t mSessionId;
+ BatchingOptions mBatchingOptions;
+ inline MsgStartBatching(BatchingAdapter& adapter,
+ LocApiBase& api,
+ LocationAPI* client,
+ uint32_t sessionId,
+ BatchingOptions batchOptions) :
+ LocMsg(),
+ mAdapter(adapter),
+ mApi(api),
+ mClient(client),
+ mSessionId(sessionId),
+ mBatchingOptions(batchOptions) {}
+ inline virtual void proc() const {
+ if (!mAdapter.isEngineCapabilitiesKnown()) {
+ mAdapter.mPendingMsgs.push_back(new MsgStartBatching(*this));
+ return;
+ }
+ LocationError err = LOCATION_ERROR_SUCCESS;
+
+ if (!mAdapter.hasBatchingCallback(mClient)) {
+ err = LOCATION_ERROR_CALLBACK_MISSING;
+ } else if (0 == mBatchingOptions.size) {
+ err = LOCATION_ERROR_INVALID_PARAMETER;
+ } else if (!ContextBase::isMessageSupported(
+ LOC_API_ADAPTER_MESSAGE_DISTANCE_BASE_LOCATION_BATCHING)) {
+ err = LOCATION_ERROR_NOT_SUPPORTED;
+ }
+ if (LOCATION_ERROR_SUCCESS == err) {
+ if (mBatchingOptions.batchingMode == BATCHING_MODE_ROUTINE ||
+ mBatchingOptions.batchingMode == BATCHING_MODE_NO_AUTO_REPORT) {
+ mAdapter.startBatching(mClient, mSessionId, mBatchingOptions);
+ } else if (mBatchingOptions.batchingMode == BATCHING_MODE_TRIP) {
+ mAdapter.startTripBatchingMultiplex(mClient, mSessionId, mBatchingOptions);
+ } else {
+ mAdapter.reportResponse(mClient, LOCATION_ERROR_INVALID_PARAMETER, mSessionId);
+ }
+ }
+ }
+ };
+
+ sendMsg(new MsgStartBatching(*this, *mLocApi, client, sessionId, batchOptions));
+
+ return sessionId;
+}
+
+void
+BatchingAdapter::startBatching(LocationAPI* client, uint32_t sessionId,
+ const BatchingOptions& batchingOptions)
+{
+ if (batchingOptions.batchingMode != BATCHING_MODE_NO_AUTO_REPORT &&
+ 0 == autoReportBatchingSessionsCount()) {
+ // if there is currenty no batching sessions interested in batch full event, then this
+ // new session will need to register for batch full event
+ updateEvtMask(LOC_API_ADAPTER_BIT_BATCH_FULL,
+ LOC_REGISTRATION_MASK_ENABLED);
+ }
+
+ // Assume start will be OK, remove session if not
+ saveBatchingSession(client, sessionId, batchingOptions);
+ mLocApi->startBatching(sessionId, batchingOptions, getBatchingAccuracy(), getBatchingTimeout(),
+ new LocApiResponse(*getContext(),
+ [this, client, sessionId, batchingOptions] (LocationError err) {
+ if (LOCATION_ERROR_SUCCESS != err) {
+ eraseBatchingSession(client, sessionId);
+ }
+
+ if (LOCATION_ERROR_SUCCESS != err &&
+ batchingOptions.batchingMode != BATCHING_MODE_NO_AUTO_REPORT &&
+ 0 == autoReportBatchingSessionsCount()) {
+ // if we fail to start batching and we have already registered batch full event
+ // we need to undo that since no sessions are now interested in batch full event
+ updateEvtMask(LOC_API_ADAPTER_BIT_BATCH_FULL,
+ LOC_REGISTRATION_MASK_DISABLED);
+ }
+
+ reportResponse(client, err, sessionId);
+ }));
+}
+
+void
+BatchingAdapter::updateBatchingOptionsCommand(LocationAPI* client, uint32_t id,
+ BatchingOptions& batchOptions)
+{
+ LOC_LOGD("%s]: client %p id %u minInterval %u minDistance %u mode %u batchMode %u",
+ __func__, client, id, batchOptions.minInterval,
+ batchOptions.minDistance, batchOptions.mode,
+ batchOptions.batchingMode);
+
+ struct MsgUpdateBatching : public LocMsg {
+ BatchingAdapter& mAdapter;
+ LocApiBase& mApi;
+ LocationAPI* mClient;
+ uint32_t mSessionId;
+ BatchingOptions mBatchOptions;
+ inline MsgUpdateBatching(BatchingAdapter& adapter,
+ LocApiBase& api,
+ LocationAPI* client,
+ uint32_t sessionId,
+ BatchingOptions batchOptions) :
+ LocMsg(),
+ mAdapter(adapter),
+ mApi(api),
+ mClient(client),
+ mSessionId(sessionId),
+ mBatchOptions(batchOptions) {}
+ inline virtual void proc() const {
+ if (!mAdapter.isEngineCapabilitiesKnown()) {
+ mAdapter.mPendingMsgs.push_back(new MsgUpdateBatching(*this));
+ return;
+ }
+ LocationError err = LOCATION_ERROR_SUCCESS;
+ if (!mAdapter.isBatchingSession(mClient, mSessionId)) {
+ err = LOCATION_ERROR_ID_UNKNOWN;
+ } else if ((0 == mBatchOptions.size) ||
+ (mBatchOptions.batchingMode > BATCHING_MODE_NO_AUTO_REPORT)) {
+ err = LOCATION_ERROR_INVALID_PARAMETER;
+ }
+ if (LOCATION_ERROR_SUCCESS == err) {
+ if (!mAdapter.isTripSession(mSessionId)) {
+ mAdapter.stopBatching(mClient, mSessionId, true, mBatchOptions);
+ } else {
+ mAdapter.stopTripBatchingMultiplex(mClient, mSessionId, true, mBatchOptions);
+ }
+ }
+ }
+ };
+
+ sendMsg(new MsgUpdateBatching(*this, *mLocApi, client, id, batchOptions));
+}
+
+void
+BatchingAdapter::stopBatchingCommand(LocationAPI* client, uint32_t id)
+{
+ LOC_LOGD("%s]: client %p id %u", __func__, client, id);
+
+ struct MsgStopBatching : public LocMsg {
+ BatchingAdapter& mAdapter;
+ LocApiBase& mApi;
+ LocationAPI* mClient;
+ uint32_t mSessionId;
+ inline MsgStopBatching(BatchingAdapter& adapter,
+ LocApiBase& api,
+ LocationAPI* client,
+ uint32_t sessionId) :
+ LocMsg(),
+ mAdapter(adapter),
+ mApi(api),
+ mClient(client),
+ mSessionId(sessionId) {}
+ inline virtual void proc() const {
+ if (!mAdapter.isEngineCapabilitiesKnown()) {
+ mAdapter.mPendingMsgs.push_back(new MsgStopBatching(*this));
+ return;
+ }
+ LocationError err = LOCATION_ERROR_SUCCESS;
+ if (!mAdapter.isBatchingSession(mClient, mSessionId)) {
+ err = LOCATION_ERROR_ID_UNKNOWN;
+ }
+ if (LOCATION_ERROR_SUCCESS == err) {
+ if (mAdapter.isTripSession(mSessionId)) {
+ mAdapter.stopTripBatchingMultiplex(mClient, mSessionId);
+ } else {
+ mAdapter.stopBatching(mClient, mSessionId);
+ }
+ }
+ }
+ };
+
+ sendMsg(new MsgStopBatching(*this, *mLocApi, client, id));
+}
+
+void
+BatchingAdapter::stopBatching(LocationAPI* client, uint32_t sessionId, bool restartNeeded,
+ const BatchingOptions& batchOptions)
+{
+ LocationSessionKey key(client, sessionId);
+ auto it = mBatchingSessions.find(key);
+ if (it != mBatchingSessions.end()) {
+ auto flpOptions = it->second;
+ // Assume stop will be OK, restore session if not
+ eraseBatchingSession(client, sessionId);
+ mLocApi->stopBatching(sessionId,
+ new LocApiResponse(*getContext(),
+ [this, client, sessionId, flpOptions, restartNeeded, batchOptions]
+ (LocationError err) {
+ if (LOCATION_ERROR_SUCCESS != err) {
+ saveBatchingSession(client, sessionId, batchOptions);
+ } else {
+ // if stopBatching is success, unregister for batch full event if this was the last
+ // batching session that is interested in batch full event
+ if (0 == autoReportBatchingSessionsCount() &&
+ flpOptions.batchingMode != BATCHING_MODE_NO_AUTO_REPORT) {
+ updateEvtMask(LOC_API_ADAPTER_BIT_BATCH_FULL,
+ LOC_REGISTRATION_MASK_DISABLED);
+ }
+
+ if (restartNeeded) {
+ if (batchOptions.batchingMode == BATCHING_MODE_ROUTINE ||
+ batchOptions.batchingMode == BATCHING_MODE_NO_AUTO_REPORT) {
+ startBatching(client, sessionId, batchOptions);
+ } else if (batchOptions.batchingMode == BATCHING_MODE_TRIP) {
+ startTripBatchingMultiplex(client, sessionId, batchOptions);
+ }
+ }
+ }
+ reportResponse(client, err, sessionId);
+ }));
+ }
+}
+
+void
+BatchingAdapter::getBatchedLocationsCommand(LocationAPI* client, uint32_t id, size_t count)
+{
+ LOC_LOGD("%s]: client %p id %u count %zu", __func__, client, id, count);
+
+ struct MsgGetBatchedLocations : public LocMsg {
+ BatchingAdapter& mAdapter;
+ LocApiBase& mApi;
+ LocationAPI* mClient;
+ uint32_t mSessionId;
+ size_t mCount;
+ inline MsgGetBatchedLocations(BatchingAdapter& adapter,
+ LocApiBase& api,
+ LocationAPI* client,
+ uint32_t sessionId,
+ size_t count) :
+ LocMsg(),
+ mAdapter(adapter),
+ mApi(api),
+ mClient(client),
+ mSessionId(sessionId),
+ mCount(count) {}
+ inline virtual void proc() const {
+ if (!mAdapter.isEngineCapabilitiesKnown()) {
+ mAdapter.mPendingMsgs.push_back(new MsgGetBatchedLocations(*this));
+ return;
+ }
+ LocationError err = LOCATION_ERROR_SUCCESS;
+ if (!mAdapter.hasBatchingCallback(mClient)) {
+ err = LOCATION_ERROR_CALLBACK_MISSING;
+ } else if (!mAdapter.isBatchingSession(mClient, mSessionId)) {
+ err = LOCATION_ERROR_ID_UNKNOWN;
+ }
+ if (LOCATION_ERROR_SUCCESS == err) {
+ if (mAdapter.isTripSession(mSessionId)) {
+ mApi.getBatchedTripLocations(mCount, 0,
+ new LocApiResponse(*mAdapter.getContext(),
+ [&mAdapter = mAdapter, mSessionId = mSessionId,
+ mClient = mClient] (LocationError err) {
+ mAdapter.reportResponse(mClient, err, mSessionId);
+ }));
+ } else {
+ mApi.getBatchedLocations(mCount, new LocApiResponse(*mAdapter.getContext(),
+ [&mAdapter = mAdapter, mSessionId = mSessionId,
+ mClient = mClient] (LocationError err) {
+ mAdapter.reportResponse(mClient, err, mSessionId);
+ }));
+ }
+ } else {
+ mAdapter.reportResponse(mClient, err, mSessionId);
+ }
+ }
+ };
+
+ sendMsg(new MsgGetBatchedLocations(*this, *mLocApi, client, id, count));
+}
+
+void
+BatchingAdapter::reportLocationsEvent(const Location* locations, size_t count,
+ BatchingMode batchingMode)
+{
+ LOC_LOGD("%s]: count %zu batchMode %d", __func__, count, batchingMode);
+
+ struct MsgReportLocations : public LocMsg {
+ BatchingAdapter& mAdapter;
+ Location* mLocations;
+ size_t mCount;
+ BatchingMode mBatchingMode;
+ inline MsgReportLocations(BatchingAdapter& adapter,
+ const Location* locations,
+ size_t count,
+ BatchingMode batchingMode) :
+ LocMsg(),
+ mAdapter(adapter),
+ mLocations(new Location[count]),
+ mCount(count),
+ mBatchingMode(batchingMode)
+ {
+ if (nullptr == mLocations) {
+ LOC_LOGE("%s]: new failed to allocate mLocations", __func__);
+ return;
+ }
+ for (size_t i=0; i < mCount; ++i) {
+ mLocations[i] = locations[i];
+ }
+ }
+ inline virtual ~MsgReportLocations() {
+ if (nullptr != mLocations)
+ delete[] mLocations;
+ }
+ inline virtual void proc() const {
+ mAdapter.reportLocations(mLocations, mCount, mBatchingMode);
+ }
+ };
+
+ sendMsg(new MsgReportLocations(*this, locations, count, batchingMode));
+}
+
+void
+BatchingAdapter::reportLocations(Location* locations, size_t count, BatchingMode batchingMode)
+{
+ BatchingOptions batchOptions = {sizeof(BatchingOptions), batchingMode};
+
+ for (auto it=mClientData.begin(); it != mClientData.end(); ++it) {
+ if (nullptr != it->second.batchingCb) {
+ it->second.batchingCb(count, locations, batchOptions);
+ }
+ }
+}
+
+void
+BatchingAdapter::reportCompletedTripsEvent(uint32_t accumulated_distance)
+{
+ struct MsgReportCompletedTrips : public LocMsg {
+ BatchingAdapter& mAdapter;
+ uint32_t mAccumulatedDistance;
+ inline MsgReportCompletedTrips(BatchingAdapter& adapter,
+ uint32_t accumulated_distance) :
+ LocMsg(),
+ mAdapter(adapter),
+ mAccumulatedDistance(accumulated_distance)
+ {
+ }
+ inline virtual ~MsgReportCompletedTrips() {
+ }
+ inline virtual void proc() const {
+
+ // Check if any trips are completed
+ std::list<uint32_t> completedTripsList;
+ completedTripsList.clear();
+
+ for(auto itt = mAdapter.mTripSessions.begin(); itt != mAdapter.mTripSessions.end();)
+ {
+ TripSessionStatus &tripSession = itt->second;
+
+ tripSession.accumulatedDistanceThisTrip =
+ tripSession.accumulatedDistanceOnTripRestart
+ + (mAccumulatedDistance - tripSession.accumulatedDistanceOngoingBatch);
+ if (tripSession.tripDistance <= tripSession.accumulatedDistanceThisTrip) {
+ // trip is completed
+ completedTripsList.push_back(itt->first);
+ itt = mAdapter.mTripSessions.erase(itt);
+
+ if (tripSession.tripTBFInterval == mAdapter.mOngoingTripTBFInterval) {
+ // trip with ongoing TBF interval is completed
+ mAdapter.mTripWithOngoingTBFDropped = true;
+ }
+
+ if (tripSession.tripDistance == mAdapter.mOngoingTripDistance) {
+ // trip with ongoing trip distance is completed
+ mAdapter.mTripWithOngoingTripDistanceDropped = true;
+ }
+ } else {
+ itt++;
+ }
+ }
+
+ if (completedTripsList.size() > 0) {
+ mAdapter.reportBatchStatusChange(BATCHING_STATUS_TRIP_COMPLETED,
+ completedTripsList);
+ mAdapter.restartTripBatching(false, mAccumulatedDistance, 0);
+ } else {
+ mAdapter.printTripReport();
+ }
+ }
+ };
+
+ LOC_LOGD("%s]: Accumulated Distance so far: %u",
+ __func__, accumulated_distance);
+
+ sendMsg(new MsgReportCompletedTrips(*this, accumulated_distance));
+}
+
+void
+BatchingAdapter::reportBatchStatusChange(BatchingStatus batchStatus,
+ std::list<uint32_t> & completedTripsList)
+{
+ BatchingStatusInfo batchStatusInfo =
+ {sizeof(BatchingStatusInfo), batchStatus};
+
+ for (auto it=mClientData.begin(); it != mClientData.end(); ++it) {
+ if (nullptr != it->second.batchingStatusCb) {
+ it->second.batchingStatusCb(batchStatusInfo, completedTripsList);
+ }
+ }
+}
+
+void
+BatchingAdapter::reportBatchStatusChangeEvent(BatchingStatus batchStatus)
+{
+ struct MsgReportBatchStatus : public LocMsg {
+ BatchingAdapter& mAdapter;
+ BatchingStatus mBatchStatus;
+ inline MsgReportBatchStatus(BatchingAdapter& adapter,
+ BatchingStatus batchStatus) :
+ LocMsg(),
+ mAdapter(adapter),
+ mBatchStatus(batchStatus)
+ {
+ }
+ inline virtual ~MsgReportBatchStatus() {
+ }
+ inline virtual void proc() const {
+ std::list<uint32_t> tempList;
+ tempList.clear();
+ mAdapter.reportBatchStatusChange(mBatchStatus, tempList);
+ }
+ };
+
+ sendMsg(new MsgReportBatchStatus(*this, batchStatus));
+}
+
+void
+BatchingAdapter::startTripBatchingMultiplex(LocationAPI* client, uint32_t sessionId,
+ const BatchingOptions& batchingOptions)
+{
+ if (mTripSessions.size() == 0) {
+ // if there is currenty no batching sessions interested in batch full event, then this
+ // new session will need to register for batch full event
+ if (0 == autoReportBatchingSessionsCount()) {
+ updateEvtMask(LOC_API_ADAPTER_BIT_BATCH_FULL,
+ LOC_REGISTRATION_MASK_ENABLED);
+ }
+
+ // Assume start will be OK, remove session if not
+ saveBatchingSession(client, sessionId, batchingOptions);
+
+ mTripSessions[sessionId] = { 0, 0, 0, batchingOptions.minDistance,
+ batchingOptions.minInterval};
+ mLocApi->startOutdoorTripBatching(batchingOptions.minDistance,
+ batchingOptions.minInterval, getBatchingTimeout(), new LocApiResponse(*getContext(),
+ [this, client, sessionId, batchingOptions] (LocationError err) {
+ if (err == LOCATION_ERROR_SUCCESS) {
+ mOngoingTripDistance = batchingOptions.minDistance;
+ mOngoingTripTBFInterval = batchingOptions.minInterval;
+ LOC_LOGD("%s] New Trip started ...", __func__);
+ printTripReport();
+ } else {
+ eraseBatchingSession(client, sessionId);
+ mTripSessions.erase(sessionId);
+ // if we fail to start batching and we have already registered batch full event
+ // we need to undo that since no sessions are now interested in batch full event
+ if (0 == autoReportBatchingSessionsCount()) {
+ updateEvtMask(LOC_API_ADAPTER_BIT_BATCH_FULL,
+ LOC_REGISTRATION_MASK_DISABLED);
+ }
+ }
+ reportResponse(client, err, sessionId);
+ }));
+ } else {
+ // query accumulated distance
+ mLocApi->queryAccumulatedTripDistance(
+ new LocApiResponseData<LocApiBatchData>(*getContext(),
+ [this, batchingOptions, sessionId, client]
+ (LocationError err, LocApiBatchData data) {
+ uint32_t accumulatedDistanceOngoingBatch = 0;
+ uint32_t numOfBatchedPositions = 0;
+ uint32_t ongoingTripDistance = mOngoingTripDistance;
+ uint32_t ongoingTripInterval = mOngoingTripTBFInterval;
+ bool needsRestart = false;
+
+ // check if TBF of new session is lesser than ongoing TBF interval
+ if (ongoingTripInterval > batchingOptions.minInterval) {
+ ongoingTripInterval = batchingOptions.minInterval;
+ needsRestart = true;
+ }
+ accumulatedDistanceOngoingBatch = data.accumulatedDistance;
+ numOfBatchedPositions = data.numOfBatchedPositions;
+ TripSessionStatus newTripSession = { accumulatedDistanceOngoingBatch, 0, 0,
+ batchingOptions.minDistance,
+ batchingOptions.minInterval};
+ if (err != LOCATION_ERROR_SUCCESS) {
+ // unable to query accumulated distance, assume remaining distance in
+ // ongoing batch is mongoingTripDistance.
+ if (batchingOptions.minDistance < ongoingTripDistance) {
+ ongoingTripDistance = batchingOptions.minDistance;
+ needsRestart = true;
+ }
+ } else {
+ // compute the remaining distance
+ uint32_t ongoing_trip_remaining_distance = ongoingTripDistance -
+ accumulatedDistanceOngoingBatch;
+
+ // check if new trip distance is lesser than the ongoing batch remaining distance
+ if (batchingOptions.minDistance < ongoing_trip_remaining_distance) {
+ ongoingTripDistance = batchingOptions.minDistance;
+ needsRestart = true;
+ } else if (needsRestart == true) {
+ // needsRestart is anyways true , may be because of lesser TBF of new session.
+ ongoingTripDistance = ongoing_trip_remaining_distance;
+ }
+ mTripSessions[sessionId] = newTripSession;
+ LOC_LOGD("%s] New Trip started ...", __func__);
+ printTripReport();
+ }
+
+ if (needsRestart) {
+ mOngoingTripDistance = ongoingTripDistance;
+ mOngoingTripTBFInterval = ongoingTripInterval;
+
+ // reset the accumulatedDistanceOngoingBatch for each session,
+ // and record the total accumulated distance so far for the session.
+ for (auto itt = mTripSessions.begin(); itt != mTripSessions.end(); itt++) {
+ TripSessionStatus &tripSessStatus = itt->second;
+ tripSessStatus.accumulatedDistanceOngoingBatch = 0;
+ tripSessStatus.accumulatedDistanceOnTripRestart =
+ tripSessStatus.accumulatedDistanceThisTrip;
+ }
+ mLocApi->reStartOutdoorTripBatching(ongoingTripDistance, ongoingTripInterval,
+ getBatchingTimeout(), new LocApiResponse(*getContext(),
+ [this, client, sessionId] (LocationError err) {
+ if (err != LOCATION_ERROR_SUCCESS) {
+ LOC_LOGE("%s] New Trip restart failed!", __func__);
+ }
+ reportResponse(client, err, sessionId);
+ }));
+ } else {
+ reportResponse(client, LOCATION_ERROR_SUCCESS, sessionId);
+ }
+ }));
+ }
+}
+
+void
+BatchingAdapter::stopTripBatchingMultiplex(LocationAPI* client, uint32_t sessionId,
+ bool restartNeeded, const BatchingOptions& batchOptions)
+{
+ LocationError err = LOCATION_ERROR_SUCCESS;
+
+ if (mTripSessions.size() == 1) {
+ mLocApi->stopOutdoorTripBatching(true, new LocApiResponse(*getContext(),
+ [this, restartNeeded, client, sessionId, batchOptions]
+ (LocationError err) {
+ if (LOCATION_ERROR_SUCCESS == err) {
+ // if stopOutdoorTripBatching is success, unregister for batch full event if this
+ // was the last batching session that is interested in batch full event
+ if (1 == autoReportBatchingSessionsCount()) {
+ updateEvtMask(LOC_API_ADAPTER_BIT_BATCH_FULL,
+ LOC_REGISTRATION_MASK_DISABLED);
+ }
+ }
+ stopTripBatchingMultiplexCommon(err, client, sessionId, restartNeeded, batchOptions);
+ }));
+ return;
+ }
+
+ stopTripBatchingMultiplexCommon(err, client, sessionId, restartNeeded, batchOptions);
+}
+
+void
+BatchingAdapter::stopTripBatchingMultiplexCommon(LocationError err, LocationAPI* client,
+ uint32_t sessionId, bool restartNeeded, const BatchingOptions& batchOptions)
+{
+ auto itt = mTripSessions.find(sessionId);
+ TripSessionStatus tripSess = itt->second;
+ if (tripSess.tripTBFInterval == mOngoingTripTBFInterval) {
+ // trip with ongoing trip interval is stopped
+ mTripWithOngoingTBFDropped = true;
+ }
+
+ if (tripSess.tripDistance == mOngoingTripDistance) {
+ // trip with ongoing trip distance is stopped
+ mTripWithOngoingTripDistanceDropped = true;
+ }
+
+ mTripSessions.erase(sessionId);
+
+ if (mTripSessions.size() == 0) {
+ mOngoingTripDistance = 0;
+ mOngoingTripTBFInterval = 0;
+ } else {
+ restartTripBatching(true);
+ }
+
+ if (restartNeeded) {
+ eraseBatchingSession(client, sessionId);
+ if (batchOptions.batchingMode == BATCHING_MODE_ROUTINE ||
+ batchOptions.batchingMode == BATCHING_MODE_NO_AUTO_REPORT) {
+ startBatching(client, sessionId, batchOptions);
+ } else if (batchOptions.batchingMode == BATCHING_MODE_TRIP) {
+ startTripBatchingMultiplex(client, sessionId, batchOptions);
+ }
+ }
+ reportResponse(client, err, sessionId);
+}
+
+
+void
+BatchingAdapter::restartTripBatching(bool queryAccumulatedDistance, uint32_t accDist,
+ uint32_t numbatchedPos)
+{
+ // does batch need restart with new trip distance / TBF interval
+ uint32_t minRemainingDistance = 0;
+ uint32_t minTBFInterval = 0;
+
+ // if no more trips left, stop the ongoing trip
+ if (mTripSessions.size() == 0) {
+ mLocApi->stopOutdoorTripBatching(true, new LocApiResponse(*getContext(),
+ [] (LocationError /*err*/) {}));
+ mOngoingTripDistance = 0;
+ mOngoingTripTBFInterval = 0;
+ // unregister for batch full event if there are no more
+ // batching session that is interested in batch full event
+ if (0 == autoReportBatchingSessionsCount()) {
+ updateEvtMask(LOC_API_ADAPTER_BIT_BATCH_FULL,
+ LOC_REGISTRATION_MASK_DISABLED);
+ }
+ return;
+ }
+
+ // record the min trip distance and min tbf interval of all ongoing sessions
+ for (auto itt = mTripSessions.begin(); itt != mTripSessions.end(); itt++) {
+
+ TripSessionStatus tripSessStatus = itt->second;
+
+ if ((minRemainingDistance == 0) ||
+ (minRemainingDistance > (tripSessStatus.tripDistance
+ - tripSessStatus.accumulatedDistanceThisTrip))) {
+ minRemainingDistance = tripSessStatus.tripDistance -
+ tripSessStatus.accumulatedDistanceThisTrip;
+ }
+
+ if ((minTBFInterval == 0) ||
+ (minTBFInterval > tripSessStatus.tripTBFInterval)) {
+ minTBFInterval = tripSessStatus.tripTBFInterval;
+ }
+ }
+
+ mLocApi->queryAccumulatedTripDistance(
+ new LocApiResponseData<LocApiBatchData>(*getContext(),
+ [this, queryAccumulatedDistance, minRemainingDistance, minTBFInterval, accDist,
+ numbatchedPos] (LocationError /*err*/, LocApiBatchData data) {
+ bool needsRestart = false;
+
+ uint32_t ongoingTripDistance = mOngoingTripDistance;
+ uint32_t ongoingTripInterval = mOngoingTripTBFInterval;
+ uint32_t accumulatedDistance = accDist;
+ uint32_t numOfBatchedPositions = numbatchedPos;
+
+ if (queryAccumulatedDistance) {
+ accumulatedDistance = data.accumulatedDistance;
+ numOfBatchedPositions = data.numOfBatchedPositions;
+ }
+
+ if ((!mTripWithOngoingTripDistanceDropped) &&
+ (ongoingTripDistance - accumulatedDistance != 0)) {
+ // if ongoing trip is already not completed still,
+ // check the min distance against the remaining distance
+ if (minRemainingDistance <
+ (ongoingTripDistance - accumulatedDistance)) {
+ ongoingTripDistance = minRemainingDistance;
+ needsRestart = true;
+ }
+ } else if (minRemainingDistance != 0) {
+ // else if ongoing trip is already completed / dropped,
+ // use the minRemainingDistance of ongoing sessions
+ ongoingTripDistance = minRemainingDistance;
+ needsRestart = true;
+ }
+
+ if ((minTBFInterval < ongoingTripInterval) ||
+ ((minTBFInterval != ongoingTripInterval) &&
+ (mTripWithOngoingTBFDropped))) {
+ ongoingTripInterval = minTBFInterval;
+ needsRestart = true;
+ }
+
+ if (needsRestart) {
+ mLocApi->reStartOutdoorTripBatching(ongoingTripDistance, ongoingTripInterval,
+ getBatchingTimeout(), new LocApiResponse(*getContext(),
+ [this, accumulatedDistance, ongoingTripDistance, ongoingTripInterval]
+ (LocationError err) {
+
+ if (err == LOCATION_ERROR_SUCCESS) {
+ for(auto itt = mTripSessions.begin(); itt != mTripSessions.end(); itt++) {
+ TripSessionStatus &tripSessStatus = itt->second;
+ tripSessStatus.accumulatedDistanceThisTrip =
+ tripSessStatus.accumulatedDistanceOnTripRestart +
+ (accumulatedDistance -
+ tripSessStatus.accumulatedDistanceOngoingBatch);
+
+ tripSessStatus.accumulatedDistanceOngoingBatch = 0;
+ tripSessStatus.accumulatedDistanceOnTripRestart =
+ tripSessStatus.accumulatedDistanceThisTrip;
+ }
+
+ mOngoingTripDistance = ongoingTripDistance;
+ mOngoingTripTBFInterval = ongoingTripInterval;
+ }
+ }));
+ }
+ }));
+}
+
+void
+BatchingAdapter::printTripReport()
+{
+ IF_LOC_LOGD {
+ LOC_LOGD("Ongoing Trip Distance = %u, Ongoing Trip TBF Interval = %u",
+ mOngoingTripDistance, mOngoingTripTBFInterval);
+
+ for (auto itt = mTripSessions.begin(); itt != mTripSessions.end(); itt++) {
+ TripSessionStatus tripSessStatus = itt->second;
+
+ LOC_LOGD("tripDistance:%u tripTBFInterval:%u"
+ " trip accumulated Distance:%u"
+ " trip accumualted distance ongoing batch:%u"
+ " trip accumulated distance on trip restart %u \r\n",
+ tripSessStatus.tripDistance, tripSessStatus.tripTBFInterval,
+ tripSessStatus.accumulatedDistanceThisTrip,
+ tripSessStatus.accumulatedDistanceOngoingBatch,
+ tripSessStatus.accumulatedDistanceOnTripRestart);
+ }
+ }
+}
diff --git a/batching/BatchingAdapter.h b/batching/BatchingAdapter.h
new file mode 100644
index 0000000..66f7c5f
--- /dev/null
+++ b/batching/BatchingAdapter.h
@@ -0,0 +1,152 @@
+/* Copyright (c) 2017-2019, 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 BATCHING_ADAPTER_H
+#define BATCHING_ADAPTER_H
+
+#include <LocAdapterBase.h>
+#include <LocContext.h>
+#include <LocationAPI.h>
+#include <map>
+
+using namespace loc_core;
+
+class BatchingAdapter : public LocAdapterBase {
+
+ /* ==== BATCHING ======================================================================= */
+ typedef struct {
+ uint32_t accumulatedDistanceOngoingBatch;
+ uint32_t accumulatedDistanceThisTrip;
+ uint32_t accumulatedDistanceOnTripRestart;
+ uint32_t tripDistance;
+ uint32_t tripTBFInterval;
+ } TripSessionStatus;
+ typedef std::map<uint32_t, TripSessionStatus> TripSessionStatusMap;
+ typedef std::map<LocationSessionKey, BatchingOptions> BatchingSessionMap;
+
+ BatchingSessionMap mBatchingSessions;
+ TripSessionStatusMap mTripSessions;
+ uint32_t mOngoingTripDistance;
+ uint32_t mOngoingTripTBFInterval;
+ bool mTripWithOngoingTBFDropped;
+ bool mTripWithOngoingTripDistanceDropped;
+
+ void startTripBatchingMultiplex(LocationAPI* client, uint32_t sessionId,
+ const BatchingOptions& batchingOptions);
+ void stopTripBatchingMultiplex(LocationAPI* client, uint32_t sessionId,
+ bool restartNeeded,
+ const BatchingOptions& batchOptions);
+ inline void stopTripBatchingMultiplex(LocationAPI* client, uint32_t id) {
+ BatchingOptions batchOptions;
+ stopTripBatchingMultiplex(client, id, false, batchOptions);
+ };
+ void stopTripBatchingMultiplexCommon(LocationError err,
+ LocationAPI* client,
+ uint32_t sessionId,
+ bool restartNeeded,
+ const BatchingOptions& batchOptions);
+ void restartTripBatching(bool queryAccumulatedDistance, uint32_t accDist = 0,
+ uint32_t numbatchedPos = 0);
+ void printTripReport();
+
+ /* ==== CONFIGURATION ================================================================== */
+ uint32_t mBatchingTimeout;
+ uint32_t mBatchingAccuracy;
+ size_t mBatchSize;
+ size_t mTripBatchSize;
+
+protected:
+
+ /* ==== CLIENT ========================================================================= */
+ virtual void updateClientsEventMask();
+ virtual void stopClientSessions(LocationAPI* client);
+
+public:
+ BatchingAdapter();
+ virtual ~BatchingAdapter() {}
+
+ /* ==== SSR ============================================================================ */
+ /* ======== EVENTS ====(Called from QMI Thread)========================================= */
+ virtual void handleEngineUpEvent();
+ /* ======== UTILITIES ================================================================== */
+ void restartSessions();
+
+ /* ==== BATCHING ======================================================================= */
+ /* ======== COMMANDS ====(Called from Client Thread)==================================== */
+ uint32_t startBatchingCommand(LocationAPI* client, BatchingOptions &batchOptions);
+ void updateBatchingOptionsCommand(
+ LocationAPI* client, uint32_t id, BatchingOptions& batchOptions);
+ void stopBatchingCommand(LocationAPI* client, uint32_t id);
+ void getBatchedLocationsCommand(LocationAPI* client, uint32_t id, size_t count);
+ /* ======== RESPONSES ================================================================== */
+ void reportResponse(LocationAPI* client, LocationError err, uint32_t sessionId);
+ /* ======== UTILITIES ================================================================== */
+ bool hasBatchingCallback(LocationAPI* client);
+ bool isBatchingSession(LocationAPI* client, uint32_t sessionId);
+ bool isTripSession(uint32_t sessionId);
+ void saveBatchingSession(LocationAPI* client, uint32_t sessionId,
+ const BatchingOptions& batchingOptions);
+ void eraseBatchingSession(LocationAPI* client, uint32_t sessionId);
+ uint32_t autoReportBatchingSessionsCount();
+ void startBatching(LocationAPI* client, uint32_t sessionId,
+ const BatchingOptions& batchingOptions);
+ void stopBatching(LocationAPI* client, uint32_t sessionId, bool restartNeeded,
+ const BatchingOptions& batchOptions);
+ void stopBatching(LocationAPI* client, uint32_t sessionId) {
+ BatchingOptions batchOptions;
+ stopBatching(client, sessionId, false, batchOptions);
+ };
+
+ /* ==== REPORTS ======================================================================== */
+ /* ======== EVENTS ====(Called from QMI Thread)========================================= */
+ void reportLocationsEvent(const Location* locations, size_t count,
+ BatchingMode batchingMode);
+ void reportCompletedTripsEvent(uint32_t accumulatedDistance);
+ void reportBatchStatusChangeEvent(BatchingStatus batchStatus);
+ /* ======== UTILITIES ================================================================== */
+ void reportLocations(Location* locations, size_t count, BatchingMode batchingMode);
+ void reportBatchStatusChange(BatchingStatus batchStatus,
+ std::list<uint32_t> & completedTripsList);
+
+ /* ==== CONFIGURATION ================================================================== */
+ /* ======== COMMANDS ====(Called from Client Thread)==================================== */
+ void readConfigCommand();
+ void setConfigCommand();
+ /* ======== UTILITIES ================================================================== */
+ void setBatchSize(size_t batchSize) { mBatchSize = batchSize; }
+ size_t getBatchSize() { return mBatchSize; }
+ void setTripBatchSize(size_t batchSize) { mTripBatchSize = batchSize; }
+ size_t getTripBatchSize() { return mTripBatchSize; }
+ void setBatchingTimeout(uint32_t batchingTimeout) { mBatchingTimeout = batchingTimeout; }
+ uint32_t getBatchingTimeout() { return mBatchingTimeout; }
+ void setBatchingAccuracy(uint32_t accuracy) { mBatchingAccuracy = accuracy; }
+ uint32_t getBatchingAccuracy() { return mBatchingAccuracy; }
+
+};
+
+#endif /* BATCHING_ADAPTER_H */
diff --git a/batching/Makefile.am b/batching/Makefile.am
new file mode 100644
index 0000000..ef8011e
--- /dev/null
+++ b/batching/Makefile.am
@@ -0,0 +1,45 @@
+AM_CFLAGS = \
+ $(GPSUTILS_CFLAGS) \
+ $(LOCCORE_CFLAGS) \
+ -I./ \
+ -std=c++1y \
+ -D__func__=__PRETTY_FUNCTION__ \
+ -fno-short-enums
+
+ACLOCAL_AMFLAGS = -I m4
+
+requiredlibs = \
+ $(GPSUTILS_LIBS) \
+ $(LOCCORE_LIBS) \
+ -llog
+
+h_sources = \
+ BatchingAdapter.h
+
+libbatching_la_SOURCES = \
+ location_batching.cpp \
+ BatchingAdapter.cpp
+
+if USE_GLIB
+libbatching_la_CFLAGS = -DUSE_GLIB $(AM_CFLAGS) @GLIB_CFLAGS@
+#libbatching_la_LDFLAGS = -lstdc++ -g -Wl,-z,defs -lpthread $(requiredlibs) @GLIB_LIBS@ -shared -avoid-version
+libbatching_la_LDFLAGS = -lstdc++ -g -Wl,-z,defs -lpthread $(requiredlibs) @GLIB_LIBS@ -avoid-version
+libbatching_la_CPPFLAGS = -DUSE_GLIB $(AM_CFLAGS) $(AM_CPPFLAGS) @GLIB_CFLAGS@
+else
+libbatching_la_CFLAGS = $(AM_CFLAGS)
+libbatching_la_LDFLAGS = -Wl,-z,defs -lpthread $(requiredlibs) -shared -version-info 1:0:0
+libbatching_la_CPPFLAGS = $(AM_CFLAGS) $(AM_CPPFLAGS)
+endif
+
+library_include_HEADERS = $(h_sources)
+
+library_includedir = $(pkgincludedir)
+
+#Create and Install libraries
+lib_LTLIBRARIES = libbatching.la
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = location-batching.pc
+sysconf_DATA = $(WORKSPACE)/hardware/qcom/gps/etc/flp.conf
+EXTRA_DIST = $(pkgconfig_DATA)
+
diff --git a/batching/configure.ac b/batching/configure.ac
new file mode 100644
index 0000000..27435c6
--- /dev/null
+++ b/batching/configure.ac
@@ -0,0 +1,78 @@
+# configure.ac -- Autoconf script for gps location-batching
+#
+# Process this file with autoconf to produce a configure script
+
+# Requires autoconf tool later than 2.61
+AC_PREREQ(2.61)
+# Initialize the gps location-batching package version 1.0.0
+AC_INIT([location-batching],1.0.0)
+# Does not strictly follow GNU Coding standards
+AM_INIT_AUTOMAKE([foreign])
+# Disables auto rebuilding of configure, Makefile.ins
+AM_MAINTAINER_MODE
+# Verifies the --srcdir is correct by checking for the path
+AC_CONFIG_SRCDIR([Makefile.am])
+# defines some macros variable to be included by source
+AC_CONFIG_HEADERS([config.h])
+AC_CONFIG_MACRO_DIR([m4])
+
+# Checks for programs.
+AC_PROG_LIBTOOL
+AC_PROG_CXX
+AC_PROG_CC
+AM_PROG_CC_C_O
+AC_PROG_AWK
+AC_PROG_CPP
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+PKG_PROG_PKG_CONFIG
+
+# Checks for libraries.
+PKG_CHECK_MODULES([GPSUTILS], [gps-utils])
+AC_SUBST([GPSUTILS_CFLAGS])
+AC_SUBST([GPSUTILS_LIBS])
+
+PKG_CHECK_MODULES([LOCCORE], [loc-core])
+AC_SUBST([LOCCORE_CFLAGS])
+AC_SUBST([LOCCORE_LIBS])
+
+PKG_CHECK_MODULES([GEOFENCE], [location-geofence])
+AC_SUBST([GEOFENCE_CFLAGS])
+AC_SUBST([GEOFENCE_LIBS])
+
+AC_ARG_WITH([locpla_includes],
+ AC_HELP_STRING([--with-locpla-includes=@<:@dir@:>@],
+ [specify the path to locpla-includes in loc-pla_git.bb]),
+ [locpla_incdir=$withval],
+ with_locpla_includes=no)
+
+if test "x$with_locpla_includes" != "xno"; then
+ AC_SUBST(LOCPLA_CFLAGS, "-I${locpla_incdir}")
+fi
+
+AC_ARG_WITH([glib],
+ AC_HELP_STRING([--with-glib],
+ [enable glib, building HLOS systems which use glib]))
+
+if (test "x${with_glib}" = "xyes"); then
+ AC_DEFINE(ENABLE_USEGLIB, 1, [Define if HLOS systems uses glib])
+ PKG_CHECK_MODULES(GTHREAD, gthread-2.0 >= 2.16, dummy=yes,
+ AC_MSG_ERROR(GThread >= 2.16 is required))
+ PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.16, dummy=yes,
+ AC_MSG_ERROR(GLib >= 2.16 is required))
+ GLIB_CFLAGS="$GLIB_CFLAGS $GTHREAD_CFLAGS"
+ GLIB_LIBS="$GLIB_LIBS $GTHREAD_LIBS"
+
+ AC_SUBST(GLIB_CFLAGS)
+ AC_SUBST(GLIB_LIBS)
+fi
+
+AM_CONDITIONAL(USE_GLIB, test "x${with_glib}" = "xyes")
+
+AC_CONFIG_FILES([ \
+ Makefile \
+ location-batching.pc
+ ])
+
+AC_OUTPUT
diff --git a/batching/location-batching.pc.in b/batching/location-batching.pc.in
new file mode 100644
index 0000000..da1fbf4
--- /dev/null
+++ b/batching/location-batching.pc.in
@@ -0,0 +1,10 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: location-batching
+Description: QTI GPS Batching
+Version: @VERSION
+Libs: -L${libdir} -lbatching
+Cflags: -I${includedir}/location-batching
diff --git a/batching/location_batching.cpp b/batching/location_batching.cpp
new file mode 100644
index 0000000..571da72
--- /dev/null
+++ b/batching/location_batching.cpp
@@ -0,0 +1,134 @@
+/* Copyright (c) 2017-2019, 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.
+ *
+ */
+#include "BatchingAdapter.h"
+#include "location_interface.h"
+
+static BatchingAdapter* gBatchingAdapter = NULL;
+
+static void initialize();
+static void deinitialize();
+
+static void addClient(LocationAPI* client, const LocationCallbacks& callbacks);
+static void removeClient(LocationAPI* client, removeClientCompleteCallback rmClientCb);
+static void requestCapabilities(LocationAPI* client);
+
+static uint32_t startBatching(LocationAPI* client, BatchingOptions&);
+static void stopBatching(LocationAPI* client, uint32_t id);
+static void updateBatchingOptions(LocationAPI* client, uint32_t id, BatchingOptions&);
+static void getBatchedLocations(LocationAPI* client, uint32_t id, size_t count);
+
+static const BatchingInterface gBatchingInterface = {
+ sizeof(BatchingInterface),
+ initialize,
+ deinitialize,
+ addClient,
+ removeClient,
+ requestCapabilities,
+ startBatching,
+ stopBatching,
+ updateBatchingOptions,
+ getBatchedLocations
+};
+
+#ifndef DEBUG_X86
+extern "C" const BatchingInterface* getBatchingInterface()
+#else
+const BatchingInterface* getBatchingInterface()
+#endif // DEBUG_X86
+{
+ return &gBatchingInterface;
+}
+
+static void initialize()
+{
+ if (NULL == gBatchingAdapter) {
+ gBatchingAdapter = new BatchingAdapter();
+ }
+}
+
+static void deinitialize()
+{
+ if (NULL != gBatchingAdapter) {
+ delete gBatchingAdapter;
+ gBatchingAdapter = NULL;
+ }
+}
+
+static void addClient(LocationAPI* client, const LocationCallbacks& callbacks)
+{
+ if (NULL != gBatchingAdapter) {
+ gBatchingAdapter->addClientCommand(client, callbacks);
+ }
+}
+
+static void removeClient(LocationAPI* client, removeClientCompleteCallback rmClientCb)
+{
+ if (NULL != gBatchingAdapter) {
+ gBatchingAdapter->removeClientCommand(client, rmClientCb);
+ }
+}
+
+static void requestCapabilities(LocationAPI* client)
+{
+ if (NULL != gBatchingAdapter) {
+ gBatchingAdapter->requestCapabilitiesCommand(client);
+ }
+}
+
+static uint32_t startBatching(LocationAPI* client, BatchingOptions &batchOptions)
+{
+ if (NULL != gBatchingAdapter) {
+ return gBatchingAdapter->startBatchingCommand(client, batchOptions);
+ } else {
+ return 0;
+ }
+}
+
+static void stopBatching(LocationAPI* client, uint32_t id)
+{
+ if (NULL != gBatchingAdapter) {
+ gBatchingAdapter->stopBatchingCommand(client, id);
+ }
+}
+
+static void updateBatchingOptions(
+ LocationAPI* client, uint32_t id, BatchingOptions& batchOptions)
+{
+ if (NULL != gBatchingAdapter) {
+ gBatchingAdapter->updateBatchingOptionsCommand(client, id, batchOptions);
+ }
+}
+
+static void getBatchedLocations(LocationAPI* client, uint32_t id, size_t count)
+{
+ if (NULL != gBatchingAdapter) {
+ gBatchingAdapter->getBatchedLocationsCommand(client, id, count);
+ }
+}
+
diff --git a/build/target_specific_features.mk b/build/target_specific_features.mk
index 0c0f730..2e74aff 100644
--- a/build/target_specific_features.mk
+++ b/build/target_specific_features.mk
@@ -16,6 +16,8 @@ GNSS_CFLAGS := \
-Wno-error=switch \
-Wno-error=date-time
+LOCAL_SANITIZE := signed-integer-overflow, unsigned-integer-overflow
+
# GPS-HIDL
GNSS_HIDL_1_0_TARGET_LIST := msm8960
GNSS_HIDL_1_0_TARGET_LIST += msm8974
@@ -28,23 +30,38 @@ GNSS_HIDL_1_0_TARGET_LIST += msm8909
GNSS_HIDL_1_0_TARGET_LIST += msm8952
GNSS_HIDL_1_0_TARGET_LIST += msm8992
GNSS_HIDL_1_0_TARGET_LIST += msm8996
-GNSS_HIDL_1_0_TARGET_LIST += msm8937
-GNSS_HIDL_1_0_TARGET_LIST += msm8953
-GNSS_HIDL_1_0_TARGET_LIST += msm8998
-GNSS_HIDL_1_0_TARGET_LIST += apq8098_latv
-GNSS_HIDL_1_0_TARGET_LIST += sdm710
-GNSS_HIDL_1_0_TARGET_LIST += qcs605
-GNSS_HIDL_1_0_TARGET_LIST += sdm845
-GNSS_HIDL_1_0_TARGET_LIST += sdm660
-GNSS_HIDL_1_1_TARGET_LIST := msmnile
-GNSS_HIDL_1_1_TARGET_LIST += $(MSMSTEPPE)
-GNSS_HIDL_1_1_TARGET_LIST += $(TRINKET)
-
+GNSS_HIDL_2_0_TARGET_LIST := msm8937
+GNSS_HIDL_2_0_TARGET_LIST += msm8953
+GNSS_HIDL_2_0_TARGET_LIST += msm8998
+GNSS_HIDL_2_0_TARGET_LIST += apq8098_latv
+GNSS_HIDL_2_0_TARGET_LIST += sdm710
+GNSS_HIDL_2_0_TARGET_LIST += qcs605
+GNSS_HIDL_2_0_TARGET_LIST += sdm845
+GNSS_HIDL_2_0_TARGET_LIST += sdm660
+GNSS_HIDL_2_0_TARGET_LIST += msmnile
+GNSS_HIDL_2_0_TARGET_LIST += $(MSMSTEPPE)
+GNSS_HIDL_2_0_TARGET_LIST += $(TRINKET)
+GNSS_HIDL_2_0_TARGET_LIST += kona
+ifneq (,$(filter $(GNSS_HIDL_2_0_TARGET_LIST),$(TARGET_BOARD_PLATFORM)))
+GNSS_HIDL_VERSION = 2.0
+endif
ifneq (,$(filter $(GNSS_HIDL_1_0_TARGET_LIST),$(TARGET_BOARD_PLATFORM)))
GNSS_HIDL_VERSION = 1.0
endif
-
ifneq (,$(filter $(GNSS_HIDL_1_1_TARGET_LIST),$(TARGET_BOARD_PLATFORM)))
GNSS_HIDL_VERSION = 1.1
endif
+
+GNSS_HIDL_LEGACY_MEASURMENTS_TARGET_LIST := msm8937
+GNSS_HIDL_LEGACY_MEASURMENTS_TARGET_LIST += msm8953
+GNSS_HIDL_LEGACY_MEASURMENTS_TARGET_LIST += msm8998
+GNSS_HIDL_LEGACY_MEASURMENTS_TARGET_LIST += apq8098_latv
+GNSS_HIDL_LEGACY_MEASURMENTS_TARGET_LIST += sdm710
+GNSS_HIDL_LEGACY_MEASURMENTS_TARGET_LIST += qcs605
+GNSS_HIDL_LEGACY_MEASURMENTS_TARGET_LIST += sdm845
+GNSS_HIDL_LEGACY_MEASURMENTS_TARGET_LIST += sdm660
+
+ifneq (,$(filter $(GNSS_HIDL_LEGACY_MEASURMENTS_TARGET_LIST),$(TARGET_BOARD_PLATFORM)))
+GNSS_HIDL_LEGACY_MEASURMENTS = true
+endif
diff --git a/core/Android.mk b/core/Android.mk
index 97614a1..bd955c1 100644
--- a/core/Android.mk
+++ b/core/Android.mk
@@ -21,7 +21,7 @@ LOCAL_SRC_FILES += \
LocApiBase.cpp \
LocAdapterBase.cpp \
ContextBase.cpp \
- LocDualContext.cpp \
+ LocContext.cpp \
loc_core_log.cpp \
data-items/DataItemsFactoryProxy.cpp \
SystemStatusOsObserver.cpp \
diff --git a/core/ContextBase.cpp b/core/ContextBase.cpp
index 3d55e1c..28109bb 100644
--- a/core/ContextBase.cpp
+++ b/core/ContextBase.cpp
@@ -108,7 +108,7 @@ void ContextBase::readConfig()
mGps_conf.INTERMEDIATE_POS = 0;
mGps_conf.ACCURACY_THRES = 0;
mGps_conf.NMEA_PROVIDER = 0;
- mGps_conf.GPS_LOCK = 0x03;
+ mGps_conf.GPS_LOCK = GNSS_CONFIG_GPS_LOCK_MO_AND_NI;
mGps_conf.SUPL_VER = 0x10000;
mGps_conf.SUPL_MODE = 0x1;
mGps_conf.SUPL_ES = 0;
diff --git a/core/ContextBase.h b/core/ContextBase.h
index 8a3d300..9c72835 100644
--- a/core/ContextBase.h
+++ b/core/ContextBase.h
@@ -55,7 +55,7 @@ typedef struct loc_gps_cfg_s
char XTRA_SERVER_3[LOC_MAX_PARAM_STRING];
uint32_t USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL;
uint32_t NMEA_PROVIDER;
- uint32_t GPS_LOCK;
+ GnssConfigGpsLock GPS_LOCK;
uint32_t A_GLONASS_POS_PROTOCOL_SELECT;
uint32_t AGPS_CERT_WRITABLE_MASK;
uint32_t AGPS_CONFIG_INJECT;
diff --git a/core/EngineHubProxyBase.h b/core/EngineHubProxyBase.h
index 34af4d0..4239a50 100644
--- a/core/EngineHubProxyBase.h
+++ b/core/EngineHubProxyBase.h
@@ -90,6 +90,17 @@ public:
(void) systemInfo;
return false;
}
+
+ inline virtual bool gnssReportKlobucharIonoModel(const GnssKlobucharIonoModel& ionoModel) {
+ (void) ionoModel;
+ return false;
+ }
+
+ inline virtual bool gnssReportAdditionalSystemInfo(
+ const GnssAdditionalSystemInfo& additionalSystemInfo) {
+ (void) additionalSystemInfo;
+ return false;
+ }
};
typedef std::function<void(const UlpLocation& ulpLocation,
diff --git a/core/LocAdapterBase.cpp b/core/LocAdapterBase.cpp
index 3f82dd6..6fad918 100644
--- a/core/LocAdapterBase.cpp
+++ b/core/LocAdapterBase.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2014, 2016-2018 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2014, 2016-2019 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
@@ -46,7 +46,8 @@ LocAdapterBase::LocAdapterBase(const LOC_API_ADAPTER_EVENT_MASK_T mask,
LocAdapterProxyBase *adapterProxyBase) :
mIsMaster(isMaster), mEvtMask(mask), mContext(context),
mLocApi(context->getLocApi()), mLocAdapterProxyBase(adapterProxyBase),
- mMsgTask(context->getMsgTask())
+ mMsgTask(context->getMsgTask()),
+ mIsEngineCapabilitiesKnown(ContextBase::sIsEngineCapabilitiesKnown)
{
mLocApi->addAdapter(this);
}
@@ -100,10 +101,6 @@ void LocAdapterBase::
DEFAULT_IMPL()
void LocAdapterBase::
- reportSvMeasurementEvent(GnssSvMeasurementSet &/*svMeasurementSet*/)
-DEFAULT_IMPL()
-
-void LocAdapterBase::
reportSvPolynomialEvent(GnssSvPolynomial &/*svPolynomial*/)
DEFAULT_IMPL()
@@ -161,7 +158,7 @@ bool LocAdapterBase::
DEFAULT_IMPL(false)
void LocAdapterBase::
- reportGnssMeasurementDataEvent(const GnssMeasurementsNotification& /*measurements*/,
+reportGnssMeasurementsEvent(const GnssMeasurements& /*gnssMeasurements*/,
int /*msInWeek*/)
DEFAULT_IMPL()
@@ -191,4 +188,220 @@ DEFAULT_IMPL(false)
bool LocAdapterBase::
reportDeleteAidingDataEvent(GnssAidingData & /*aidingData*/)
DEFAULT_IMPL(false)
+
+bool LocAdapterBase::
+ reportKlobucharIonoModelEvent(GnssKlobucharIonoModel& /*ionoModel*/)
+DEFAULT_IMPL(false)
+
+bool LocAdapterBase::
+ reportGnssAdditionalSystemInfoEvent(GnssAdditionalSystemInfo& /*additionalSystemInfo*/)
+DEFAULT_IMPL(false)
+
+void LocAdapterBase::
+ reportNfwNotificationEvent(GnssNfwNotification& /*notification*/)
+DEFAULT_IMPL()
+
+void
+LocAdapterBase::geofenceBreachEvent(size_t /*count*/, uint32_t* /*hwIds*/, Location& /*location*/,
+ GeofenceBreachType /*breachType*/, uint64_t /*timestamp*/)
+DEFAULT_IMPL()
+
+void
+LocAdapterBase::geofenceStatusEvent(GeofenceStatusAvailable /*available*/)
+DEFAULT_IMPL()
+
+void
+LocAdapterBase::reportLocationsEvent(const Location* /*locations*/, size_t /*count*/,
+ BatchingMode /*batchingMode*/)
+DEFAULT_IMPL()
+
+void
+LocAdapterBase::reportCompletedTripsEvent(uint32_t /*accumulated_distance*/)
+DEFAULT_IMPL()
+
+void
+LocAdapterBase::reportBatchStatusChangeEvent(BatchingStatus /*batchStatus*/)
+DEFAULT_IMPL()
+
+void
+LocAdapterBase::reportPositionEvent(UlpLocation& /*location*/,
+ GpsLocationExtended& /*locationExtended*/,
+ enum loc_sess_status /*status*/,
+ LocPosTechMask /*loc_technology_mask*/)
+DEFAULT_IMPL()
+
+void
+LocAdapterBase::saveClient(LocationAPI* client, const LocationCallbacks& callbacks)
+{
+ mClientData[client] = callbacks;
+ updateClientsEventMask();
+}
+
+void
+LocAdapterBase::eraseClient(LocationAPI* client)
+{
+ auto it = mClientData.find(client);
+ if (it != mClientData.end()) {
+ mClientData.erase(it);
+ }
+ updateClientsEventMask();
+}
+
+LocationCallbacks
+LocAdapterBase::getClientCallbacks(LocationAPI* client)
+{
+ LocationCallbacks callbacks = {};
+ auto it = mClientData.find(client);
+ if (it != mClientData.end()) {
+ callbacks = it->second;
+ }
+ return callbacks;
+}
+
+LocationCapabilitiesMask
+LocAdapterBase::getCapabilities()
+{
+ LocationCapabilitiesMask mask = 0;
+
+ if (isEngineCapabilitiesKnown()) {
+ // time based tracking always supported
+ mask |= LOCATION_CAPABILITIES_TIME_BASED_TRACKING_BIT;
+ if (ContextBase::isMessageSupported(
+ LOC_API_ADAPTER_MESSAGE_DISTANCE_BASE_LOCATION_BATCHING)){
+ mask |= LOCATION_CAPABILITIES_TIME_BASED_BATCHING_BIT |
+ LOCATION_CAPABILITIES_DISTANCE_BASED_BATCHING_BIT;
+ }
+ if (ContextBase::isMessageSupported(LOC_API_ADAPTER_MESSAGE_DISTANCE_BASE_TRACKING)) {
+ mask |= LOCATION_CAPABILITIES_DISTANCE_BASED_TRACKING_BIT;
+ }
+ if (ContextBase::isMessageSupported(LOC_API_ADAPTER_MESSAGE_OUTDOOR_TRIP_BATCHING)) {
+ mask |= LOCATION_CAPABILITIES_OUTDOOR_TRIP_BATCHING_BIT;
+ }
+ // geofence always supported
+ mask |= LOCATION_CAPABILITIES_GEOFENCE_BIT;
+ if (ContextBase::gnssConstellationConfig()) {
+ mask |= LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT;
+ }
+ uint32_t carrierCapabilities = ContextBase::getCarrierCapabilities();
+ if (carrierCapabilities & LOC_GPS_CAPABILITY_MSB) {
+ mask |= LOCATION_CAPABILITIES_GNSS_MSB_BIT;
+ }
+ if (LOC_GPS_CAPABILITY_MSA & carrierCapabilities) {
+ mask |= LOCATION_CAPABILITIES_GNSS_MSA_BIT;
+ }
+ if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_DEBUG_NMEA_V02)) {
+ mask |= LOCATION_CAPABILITIES_DEBUG_NMEA_BIT;
+ }
+ if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_CONSTELLATION_ENABLEMENT_V02)) {
+ mask |= LOCATION_CAPABILITIES_CONSTELLATION_ENABLEMENT_BIT;
+ }
+ if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_AGPM_V02)) {
+ mask |= LOCATION_CAPABILITIES_AGPM_BIT;
+ }
+ } else {
+ LOC_LOGE("%s]: attempt to get capabilities before they are known.", __func__);
+ }
+
+ return mask;
+}
+
+void
+LocAdapterBase::broadcastCapabilities(LocationCapabilitiesMask mask)
+{
+ for (auto clientData : mClientData) {
+ if (nullptr != clientData.second.capabilitiesCb) {
+ clientData.second.capabilitiesCb(mask);
+ }
+ }
+}
+
+void
+LocAdapterBase::updateClientsEventMask()
+DEFAULT_IMPL()
+
+void
+LocAdapterBase::stopClientSessions(LocationAPI* client)
+DEFAULT_IMPL()
+
+void
+LocAdapterBase::addClientCommand(LocationAPI* client, const LocationCallbacks& callbacks)
+{
+ LOC_LOGD("%s]: client %p", __func__, client);
+
+ struct MsgAddClient : public LocMsg {
+ LocAdapterBase& mAdapter;
+ LocationAPI* mClient;
+ const LocationCallbacks mCallbacks;
+ inline MsgAddClient(LocAdapterBase& adapter,
+ LocationAPI* client,
+ const LocationCallbacks& callbacks) :
+ LocMsg(),
+ mAdapter(adapter),
+ mClient(client),
+ mCallbacks(callbacks) {}
+ inline virtual void proc() const {
+ mAdapter.saveClient(mClient, mCallbacks);
+ }
+ };
+
+ sendMsg(new MsgAddClient(*this, client, callbacks));
+}
+
+void
+LocAdapterBase::removeClientCommand(LocationAPI* client,
+ removeClientCompleteCallback rmClientCb)
+{
+ LOC_LOGD("%s]: client %p", __func__, client);
+
+ struct MsgRemoveClient : public LocMsg {
+ LocAdapterBase& mAdapter;
+ LocationAPI* mClient;
+ removeClientCompleteCallback mRmClientCb;
+ inline MsgRemoveClient(LocAdapterBase& adapter,
+ LocationAPI* client,
+ removeClientCompleteCallback rmCb) :
+ LocMsg(),
+ mAdapter(adapter),
+ mClient(client),
+ mRmClientCb(rmCb){}
+ inline virtual void proc() const {
+ mAdapter.stopClientSessions(mClient);
+ mAdapter.eraseClient(mClient);
+ if (nullptr != mRmClientCb) {
+ (mRmClientCb)(mClient);
+ }
+ }
+ };
+
+ sendMsg(new MsgRemoveClient(*this, client, rmClientCb));
+}
+
+void
+LocAdapterBase::requestCapabilitiesCommand(LocationAPI* client)
+{
+ LOC_LOGD("%s]: ", __func__);
+
+ struct MsgRequestCapabilities : public LocMsg {
+ LocAdapterBase& mAdapter;
+ LocationAPI* mClient;
+ inline MsgRequestCapabilities(LocAdapterBase& adapter,
+ LocationAPI* client) :
+ LocMsg(),
+ mAdapter(adapter),
+ mClient(client) {}
+ inline virtual void proc() const {
+ if (!mAdapter.isEngineCapabilitiesKnown()) {
+ mAdapter.mPendingMsgs.push_back(new MsgRequestCapabilities(*this));
+ return;
+ }
+ LocationCallbacks callbacks = mAdapter.getClientCallbacks(mClient);
+ if (callbacks.capabilitiesCb != nullptr) {
+ callbacks.capabilitiesCb(mAdapter.getCapabilities());
+ }
+ }
+ };
+
+ sendMsg(new MsgRequestCapabilities(*this, client));
+}
+
} // namespace loc_core
diff --git a/core/LocAdapterBase.h b/core/LocAdapterBase.h
index e4f7be2..13c8493 100644
--- a/core/LocAdapterBase.h
+++ b/core/LocAdapterBase.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2014, 2016-2018 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2014, 2016-2019 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
@@ -34,6 +34,8 @@
#include <LocationAPI.h>
#include <map>
+#define MIN_TRACKING_INTERVAL (100) // 100 msec
+
typedef struct LocationSessionKey {
LocationAPI* client;
uint32_t id;
@@ -49,8 +51,8 @@ inline bool operator ==(LocationSessionKey const& left, LocationSessionKey const
inline bool operator !=(LocationSessionKey const& left, LocationSessionKey const& right) {
return left.id != right.id || left.client != right.client;
}
-typedef std::map<LocationSessionKey, LocationOptions> LocationSessionMap;
-typedef std::map<LocationSessionKey, TrackingOptions> TrackingOptionsMap;
+
+typedef void (*removeClientCompleteCallback)(LocationAPI* client);
namespace loc_core {
@@ -60,6 +62,8 @@ class LocAdapterBase {
private:
static uint32_t mSessionIdCounter;
const bool mIsMaster;
+ bool mIsEngineCapabilitiesKnown = false;
+
protected:
LOC_API_ADAPTER_EVENT_MASK_T mEvtMask;
ContextBase* mContext;
@@ -69,15 +73,25 @@ protected:
inline LocAdapterBase(const MsgTask* msgTask) :
mIsMaster(false), mEvtMask(0), mContext(NULL), mLocApi(NULL),
mLocAdapterProxyBase(NULL), mMsgTask(msgTask) {}
- LocAdapterBase(const LOC_API_ADAPTER_EVENT_MASK_T mask,
- ContextBase* context, bool isMaster,
- LocAdapterProxyBase *adapterProxyBase = NULL);
+
+ /* ==== CLIENT ========================================================================= */
+ typedef std::map<LocationAPI*, LocationCallbacks> ClientDataMap;
+ ClientDataMap mClientData;
+ std::vector<LocMsg*> mPendingMsgs; // For temporal storage of msgs before Open is completed
+ /* ======== UTILITIES ================================================================== */
+ void saveClient(LocationAPI* client, const LocationCallbacks& callbacks);
+ void eraseClient(LocationAPI* client);
+ LocationCallbacks getClientCallbacks(LocationAPI* client);
+ LocationCapabilitiesMask getCapabilities();
+ void broadcastCapabilities(LocationCapabilitiesMask mask);
+ virtual void updateClientsEventMask();
+ virtual void stopClientSessions(LocationAPI* client);
+
public:
inline virtual ~LocAdapterBase() { mLocApi->removeAdapter(this); }
- inline LocAdapterBase(const LOC_API_ADAPTER_EVENT_MASK_T mask,
- ContextBase* context,
- LocAdapterProxyBase *adapterProxyBase = NULL) :
- LocAdapterBase(mask, context, false, adapterProxyBase) {}
+ LocAdapterBase(const LOC_API_ADAPTER_EVENT_MASK_T mask,
+ ContextBase* context, bool isMaster = false,
+ LocAdapterProxyBase *adapterProxyBase = NULL);
inline LOC_API_ADAPTER_EVENT_MASK_T
checkMask(LOC_API_ADAPTER_EVENT_MASK_T mask) const {
@@ -128,12 +142,11 @@ public:
return mIsMaster;
}
+ inline bool isEngineCapabilitiesKnown() { return mIsEngineCapabilitiesKnown;}
+ inline void setEngineCapabilitiesKnown(bool value) { mIsEngineCapabilitiesKnown = value;}
+
virtual void handleEngineUpEvent();
virtual void handleEngineDownEvent();
- inline virtual void setPositionModeCommand(LocPosMode& posMode) {
-
- (void)posMode;
- }
virtual void reportPositionEvent(const UlpLocation& location,
const GpsLocationExtended& locationExtended,
enum loc_sess_status status,
@@ -145,7 +158,6 @@ public:
bool fromEngineHub=false);
virtual void reportDataEvent(const GnssDataNotification& dataNotify, int msInWeek);
virtual void reportNmeaEvent(const char* nmea, size_t length);
- virtual void reportSvMeasurementEvent(GnssSvMeasurementSet &svMeasurementSet);
virtual void reportSvPolynomialEvent(GnssSvPolynomial &svPolynomial);
virtual void reportSvEphemerisEvent(GnssSvEphemerisReport &svEphemeris);
virtual void reportStatus(LocGpsStatusValue status);
@@ -162,7 +174,7 @@ public:
virtual bool requestNiNotifyEvent(const GnssNiNotification &notify, const void* data);
inline virtual bool isInSession() { return false; }
ContextBase* getContext() const { return mContext; }
- virtual void reportGnssMeasurementDataEvent(const GnssMeasurementsNotification& measurements,
+ virtual void reportGnssMeasurementsEvent(const GnssMeasurements& gnssMeasurements,
int msInWeek);
virtual bool reportWwanZppFix(LocGpsLocation &zppLoc);
virtual bool reportZppBestAvailableFix(LocGpsLocation &zppLoc,
@@ -172,6 +184,32 @@ public:
virtual bool requestOdcpiEvent(OdcpiRequestInfo& request);
virtual bool reportGnssEngEnergyConsumedEvent(uint64_t energyConsumedSinceFirstBoot);
virtual bool reportDeleteAidingDataEvent(GnssAidingData &aidingData);
+ virtual bool reportKlobucharIonoModelEvent(GnssKlobucharIonoModel& ionoModel);
+ virtual bool reportGnssAdditionalSystemInfoEvent(
+ GnssAdditionalSystemInfo& additionalSystemInfo);
+ virtual void reportNfwNotificationEvent(GnssNfwNotification& notification);
+
+ virtual void geofenceBreachEvent(size_t count, uint32_t* hwIds, Location& location,
+ GeofenceBreachType breachType, uint64_t timestamp);
+ virtual void geofenceStatusEvent(GeofenceStatusAvailable available);
+
+ virtual void reportPositionEvent(UlpLocation &location,
+ GpsLocationExtended &locationExtended,
+ enum loc_sess_status status,
+ LocPosTechMask loc_technology_mask);
+
+ virtual void reportLocationsEvent(const Location* locations, size_t count,
+ BatchingMode batchingMode);
+ virtual void reportCompletedTripsEvent(uint32_t accumulated_distance);
+ virtual void reportBatchStatusChangeEvent(BatchingStatus batchStatus);
+
+ /* ==== CLIENT ========================================================================= */
+ /* ======== COMMANDS ====(Called from Client Thread)==================================== */
+ void addClientCommand(LocationAPI* client, const LocationCallbacks& callbacks);
+ void removeClientCommand(LocationAPI* client,
+ removeClientCompleteCallback rmClientCb);
+ void requestCapabilitiesCommand(LocationAPI* client);
+
};
} // namespace loc_core
diff --git a/core/LocAdapterProxyBase.h b/core/LocAdapterProxyBase.h
index b33d7b0..727d424 100644
--- a/core/LocAdapterProxyBase.h
+++ b/core/LocAdapterProxyBase.h
@@ -40,8 +40,8 @@ private:
LocAdapterBase *mLocAdapterBase;
protected:
inline LocAdapterProxyBase(const LOC_API_ADAPTER_EVENT_MASK_T mask,
- ContextBase* context):
- mLocAdapterBase(new LocAdapterBase(mask, context, this)) {
+ ContextBase* context, bool isMaster = false):
+ mLocAdapterBase(new LocAdapterBase(mask, context, isMaster, this)) {
}
inline virtual ~LocAdapterProxyBase() {
delete mLocAdapterBase;
diff --git a/core/LocApiBase.cpp b/core/LocApiBase.cpp
index c2ee411..c172376 100644
--- a/core/LocApiBase.cpp
+++ b/core/LocApiBase.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2014, 2016-2018 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2014, 2016-2019 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
@@ -31,10 +31,11 @@
#include <dlfcn.h>
#include <inttypes.h>
+#include <gps_extended_c.h>
#include <LocApiBase.h>
#include <LocAdapterBase.h>
#include <log_util.h>
-#include <LocDualContext.h>
+#include <LocContext.h>
namespace loc_core {
@@ -95,7 +96,10 @@ struct LocSsrMsg : public LocMsg {
}
inline virtual void proc() const {
mLocApi->close();
- mLocApi->open(mLocApi->getEvtMask());
+ if (LOC_API_ADAPTER_ERR_SUCCESS == mLocApi->open(mLocApi->getEvtMask())) {
+ // Notify adapters that engine up after SSR
+ mLocApi->handleEngineUpEvent();
+ }
}
inline void locallog() const {
LOC_LOGV("LocSsrMsg");
@@ -107,13 +111,17 @@ struct LocSsrMsg : public LocMsg {
struct LocOpenMsg : public LocMsg {
LocApiBase* mLocApi;
- inline LocOpenMsg(LocApiBase* locApi) :
- LocMsg(), mLocApi(locApi)
+ LocAdapterBase* mAdapter;
+ inline LocOpenMsg(LocApiBase* locApi, LocAdapterBase* adapter = nullptr) :
+ LocMsg(), mLocApi(locApi), mAdapter(adapter)
{
locallog();
}
inline virtual void proc() const {
- mLocApi->open(mLocApi->getEvtMask());
+ if (LOC_API_ADAPTER_ERR_SUCCESS == mLocApi->open(mLocApi->getEvtMask()) &&
+ nullptr != mAdapter) {
+ mAdapter->handleEngineUpEvent();
+ }
}
inline void locallog() const {
LOC_LOGv("LocOpen Mask: %" PRIx64 "\n", mLocApi->getEvtMask());
@@ -189,8 +197,8 @@ bool LocApiBase::isInSession()
}
bool LocApiBase::needReport(const UlpLocation& ulpLocation,
- enum loc_sess_status status,
- LocPosTechMask techMask)
+ enum loc_sess_status status,
+ LocPosTechMask techMask)
{
bool reported = false;
@@ -222,7 +230,7 @@ void LocApiBase::addAdapter(LocAdapterBase* adapter)
for (int i = 0; i < MAX_ADAPTERS && mLocAdapters[i] != adapter; i++) {
if (mLocAdapters[i] == NULL) {
mLocAdapters[i] = adapter;
- mMsgTask->sendMsg(new LocOpenMsg(this));
+ mMsgTask->sendMsg(new LocOpenMsg(this, adapter));
break;
}
}
@@ -295,8 +303,6 @@ void LocApiBase::updateNmeaMask(uint32_t mask)
void LocApiBase::handleEngineUpEvent()
{
- LocDualContext::injectFeatureConfig(mContext);
-
// loop through adapters, and deliver to all adapters.
TO_ALL_LOCADAPTERS(mLocAdapters[i]->handleEngineUpEvent());
}
@@ -374,6 +380,23 @@ void LocApiBase::reportDeleteAidingDataEvent(GnssAidingData& aidingData) {
TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->reportDeleteAidingDataEvent(aidingData));
}
+void LocApiBase::reportKlobucharIonoModel(GnssKlobucharIonoModel & ionoModel) {
+ // loop through adapters, and deliver to the first handling adapter.
+ TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->reportKlobucharIonoModelEvent(ionoModel));
+}
+
+void LocApiBase::reportGnssAdditionalSystemInfo(GnssAdditionalSystemInfo& additionalSystemInfo) {
+ // loop through adapters, and deliver to the first handling adapter.
+ TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->reportGnssAdditionalSystemInfoEvent(
+ additionalSystemInfo));
+}
+
+void LocApiBase::sendNfwNotification(GnssNfwNotification& notification)
+{
+ // loop through adapters, and deliver to the first handling adapter.
+ TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportNfwNotificationEvent(notification));
+
+}
void LocApiBase::reportSv(GnssSvNotification& svNotify)
{
@@ -411,14 +434,6 @@ void LocApiBase::reportSv(GnssSvNotification& svNotify)
);
}
-void LocApiBase::reportSvMeasurement(GnssSvMeasurementSet &svMeasurementSet)
-{
- // loop through adapters, and deliver to all adapters.
- TO_ALL_LOCADAPTERS(
- mLocAdapters[i]->reportSvMeasurementEvent(svMeasurementSet)
- );
-}
-
void LocApiBase::reportSvPolynomial(GnssSvPolynomial &svPolynomial)
{
// loop through adapters, and deliver to all adapters.
@@ -511,11 +526,10 @@ void* LocApiBase :: getSibling()
LocApiProxyBase* LocApiBase :: getLocApiProxy()
DEFAULT_IMPL(NULL)
-void LocApiBase::reportGnssMeasurementData(GnssMeasurementsNotification& measurements,
- int msInWeek)
+void LocApiBase::reportGnssMeasurements(GnssMeasurements& gnssMeasurements, int msInWeek)
{
// loop through adapters, and deliver to all adapters.
- TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportGnssMeasurementDataEvent(measurements, msInWeek));
+ TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportGnssMeasurementsEvent(gnssMeasurements, msInWeek));
}
void LocApiBase::reportGnssSvIdConfig(const GnssSvIdConfig& config)
@@ -540,6 +554,41 @@ void LocApiBase::reportGnssSvTypeConfig(const GnssSvTypeConfig& config)
TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportGnssSvTypeConfigEvent(config));
}
+void LocApiBase::geofenceBreach(size_t count, uint32_t* hwIds, Location& location,
+ GeofenceBreachType breachType, uint64_t timestamp)
+{
+ TO_ALL_LOCADAPTERS(mLocAdapters[i]->geofenceBreachEvent(count, hwIds, location, breachType,
+ timestamp));
+}
+
+void LocApiBase::geofenceStatus(GeofenceStatusAvailable available)
+{
+ TO_ALL_LOCADAPTERS(mLocAdapters[i]->geofenceStatusEvent(available));
+}
+
+void LocApiBase::reportDBTPosition(UlpLocation &location, GpsLocationExtended &locationExtended,
+ enum loc_sess_status status, LocPosTechMask loc_technology_mask)
+{
+ TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportPositionEvent(location, locationExtended, status,
+ loc_technology_mask));
+}
+
+void LocApiBase::reportLocations(Location* locations, size_t count, BatchingMode batchingMode)
+{
+ TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportLocationsEvent(locations, count, batchingMode));
+}
+
+void LocApiBase::reportCompletedTrips(uint32_t accumulated_distance)
+{
+ TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportCompletedTripsEvent(accumulated_distance));
+}
+
+void LocApiBase::handleBatchStatusEvent(BatchingStatus batchStatus)
+{
+ TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportBatchStatusChangeEvent(batchStatus));
+}
+
+
enum loc_api_adapter_err LocApiBase::
open(LOC_API_ADAPTER_EVENT_MASK_T /*mask*/)
DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS)
@@ -588,10 +637,6 @@ void LocApiBase::
atlCloseStatus(int /*handle*/, int /*is_succ*/)
DEFAULT_IMPL()
-void LocApiBase::
- setPositionMode(const LocPosMode& /*posMode*/)
-DEFAULT_IMPL()
-
LocationError LocApiBase::
setServerSync(const char* /*url*/, int /*len*/, LocServerType /*type*/)
DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
@@ -667,6 +712,10 @@ DEFAULT_IMPL(0)
GnssConfigLppeUserPlaneMask LocApiBase::convertLppeUp(const uint32_t /*lppeUserPlaneMask*/)
DEFAULT_IMPL(0)
+LocationError LocApiBase::setEmergencyExtensionWindowSync(
+ const uint32_t /*emergencyExtensionSeconds*/)
+DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
+
void LocApiBase::
getWwanZppFix()
DEFAULT_IMPL()
@@ -721,7 +770,103 @@ LocationError LocApiBase::
setPositionAssistedClockEstimatorMode(bool /*enabled*/)
DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
-LocationError LocApiBase::
- getGnssEnergyConsumed()
+LocationError LocApiBase::getGnssEnergyConsumed()
DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
+
+
+void LocApiBase::addGeofence(uint32_t /*clientId*/, const GeofenceOption& /*options*/,
+ const GeofenceInfo& /*info*/,
+ LocApiResponseData<LocApiGeofenceData>* /*adapterResponseData*/)
+DEFAULT_IMPL()
+
+void LocApiBase::removeGeofence(uint32_t /*hwId*/, uint32_t /*clientId*/,
+ LocApiResponse* /*adapterResponse*/)
+DEFAULT_IMPL()
+
+void LocApiBase::pauseGeofence(uint32_t /*hwId*/, uint32_t /*clientId*/,
+ LocApiResponse* /*adapterResponse*/)
+DEFAULT_IMPL()
+
+void LocApiBase::resumeGeofence(uint32_t /*hwId*/, uint32_t /*clientId*/,
+ LocApiResponse* /*adapterResponse*/)
+DEFAULT_IMPL()
+
+void LocApiBase::modifyGeofence(uint32_t /*hwId*/, uint32_t /*clientId*/,
+ const GeofenceOption& /*options*/, LocApiResponse* /*adapterResponse*/)
+DEFAULT_IMPL()
+
+void LocApiBase::startTimeBasedTracking(const TrackingOptions& /*options*/,
+ LocApiResponse* /*adapterResponse*/)
+DEFAULT_IMPL()
+
+void LocApiBase::stopTimeBasedTracking(LocApiResponse* /*adapterResponse*/)
+DEFAULT_IMPL()
+
+void LocApiBase::startDistanceBasedTracking(uint32_t /*sessionId*/,
+ const LocationOptions& /*options*/, LocApiResponse* /*adapterResponse*/)
+DEFAULT_IMPL()
+
+void LocApiBase::stopDistanceBasedTracking(uint32_t /*sessionId*/,
+ LocApiResponse* /*adapterResponse*/)
+DEFAULT_IMPL()
+
+void LocApiBase::startBatching(uint32_t /*sessionId*/, const LocationOptions& /*options*/,
+ uint32_t /*accuracy*/, uint32_t /*timeout*/, LocApiResponse* /*adapterResponse*/)
+DEFAULT_IMPL()
+
+void LocApiBase::stopBatching(uint32_t /*sessionId*/, LocApiResponse* /*adapterResponse*/)
+DEFAULT_IMPL()
+
+LocationError LocApiBase::startOutdoorTripBatchingSync(uint32_t /*tripDistance*/,
+ uint32_t /*tripTbf*/, uint32_t /*timeout*/)
+DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
+
+void LocApiBase::startOutdoorTripBatching(uint32_t /*tripDistance*/, uint32_t /*tripTbf*/,
+ uint32_t /*timeout*/, LocApiResponse* /*adapterResponse*/)
+DEFAULT_IMPL()
+
+void LocApiBase::reStartOutdoorTripBatching(uint32_t /*ongoingTripDistance*/,
+ uint32_t /*ongoingTripInterval*/, uint32_t /*batchingTimeout,*/,
+ LocApiResponse* /*adapterResponse*/)
+DEFAULT_IMPL()
+
+LocationError LocApiBase::stopOutdoorTripBatchingSync(bool /*deallocBatchBuffer*/)
+DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
+
+void LocApiBase::stopOutdoorTripBatching(bool /*deallocBatchBuffer*/,
+ LocApiResponse* /*adapterResponse*/)
+DEFAULT_IMPL()
+
+LocationError LocApiBase::getBatchedLocationsSync(size_t /*count*/)
+DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
+
+void LocApiBase::getBatchedLocations(size_t /*count*/, LocApiResponse* /*adapterResponse*/)
+DEFAULT_IMPL()
+
+LocationError LocApiBase::getBatchedTripLocationsSync(size_t /*count*/,
+ uint32_t /*accumulatedDistance*/)
+DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
+
+void LocApiBase::getBatchedTripLocations(size_t /*count*/, uint32_t /*accumulatedDistance*/,
+ LocApiResponse* /*adapterResponse*/)
+DEFAULT_IMPL()
+
+LocationError LocApiBase::queryAccumulatedTripDistanceSync(uint32_t& /*accumulated_trip_distance*/,
+ uint32_t& /*numOfBatchedPositions*/)
+DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
+
+void LocApiBase::queryAccumulatedTripDistance(
+ LocApiResponseData<LocApiBatchData>* /*adapterResponseData*/)
+DEFAULT_IMPL()
+
+void LocApiBase::setBatchSize(size_t /*size*/)
+DEFAULT_IMPL()
+
+void LocApiBase::setTripBatchSize(size_t /*size*/)
+DEFAULT_IMPL()
+
+void LocApiBase::addToCallQueue(LocApiResponse* /*adapterResponse*/)
+DEFAULT_IMPL()
+
+
} // namespace loc_core
diff --git a/core/LocApiBase.h b/core/LocApiBase.h
index e5dfebf..1c2afaf 100644
--- a/core/LocApiBase.h
+++ b/core/LocApiBase.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2014, 2016-2018 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2014, 2016-2019 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
@@ -40,6 +40,7 @@ namespace loc_core {
class ContextBase;
struct LocApiResponse;
+template <typename> struct LocApiResponseData;
int hexcode(char *hexstring, int string_size,
const char *data, int data_size);
@@ -163,7 +164,6 @@ public:
GnssDataNotification* pDataNotify = nullptr,
int msInWeek = -1);
void reportSv(GnssSvNotification& svNotify);
- void reportSvMeasurement(GnssSvMeasurementSet &svMeasurementSet);
void reportSvPolynomial(GnssSvPolynomial &svPolynomial);
void reportSvEphemeris(GnssSvEphemerisReport &svEphemeris);
void reportStatus(LocGpsStatusValue status);
@@ -178,7 +178,7 @@ public:
void requestATL(int connHandle, LocAGpsType agps_type, LocApnTypeMask apn_type_mask);
void releaseATL(int connHandle);
void requestNiNotify(GnssNiNotification &notify, const void* data);
- void reportGnssMeasurementData(GnssMeasurementsNotification& measurements, int msInWeek);
+ void reportGnssMeasurements(GnssMeasurements& gnssMeasurements, int msInWeek);
void reportWwanZppFix(LocGpsLocation &zppLoc);
void reportZppBestAvailableFix(LocGpsLocation &zppLoc, GpsLocationExtended &location_extended,
LocPosTechMask tech_mask);
@@ -187,102 +187,69 @@ public:
void requestOdcpi(OdcpiRequestInfo& request);
void reportGnssEngEnergyConsumedEvent(uint64_t energyConsumedSinceFirstBoot);
void reportDeleteAidingDataEvent(GnssAidingData& aidingData);
+ void reportKlobucharIonoModel(GnssKlobucharIonoModel& ionoModel);
+ void reportGnssAdditionalSystemInfo(GnssAdditionalSystemInfo& additionalSystemInfo);
+ void sendNfwNotification(GnssNfwNotification& notification);
+
+ void geofenceBreach(size_t count, uint32_t* hwIds, Location& location,
+ GeofenceBreachType breachType, uint64_t timestamp);
+ void geofenceStatus(GeofenceStatusAvailable available);
+ void reportDBTPosition(UlpLocation &location,
+ GpsLocationExtended &locationExtended,
+ enum loc_sess_status status,
+ LocPosTechMask loc_technology_mask);
+ void reportLocations(Location* locations, size_t count, BatchingMode batchingMode);
+ void reportCompletedTrips(uint32_t accumulated_distance);
+ void handleBatchStatusEvent(BatchingStatus batchStatus);
// downward calls
- // All below functions are to be defined by adapter specific modules:
- // RPC, QMI, etc. The default implementation is empty.
-
virtual void* getSibling();
virtual LocApiProxyBase* getLocApiProxy();
virtual void startFix(const LocPosMode& fixCriteria, LocApiResponse* adapterResponse);
- virtual void
- stopFix(LocApiResponse* adapterResponse);
- virtual void
- deleteAidingData(const GnssAidingData& data, LocApiResponse* adapterResponse);
-
- virtual void
- injectPosition(double latitude, double longitude, float accuracy);
-
- virtual void
- injectPosition(const GnssLocationInfoNotification &locationInfo, bool onDemandCpi=false);
-
- virtual void
- injectPosition(const Location& location, bool onDemandCpi);
- virtual void
- setTime(LocGpsUtcTime time, int64_t timeReference, int uncertainty);
-
- // // TODO:: called from izatapipds
- virtual enum loc_api_adapter_err
- setXtraData(char* data, int length);
-
- virtual void
- atlOpenStatus(int handle, int is_succ, char* apn, uint32_t apnLen,
- AGpsBearerType bear, LocAGpsType agpsType,
- LocApnTypeMask mask);
- virtual void
- atlCloseStatus(int handle, int is_succ);
- virtual void
- setPositionMode(const LocPosMode& posMode);
- virtual LocationError
- setServerSync(const char* url, int len, LocServerType type);
- virtual LocationError
- setServerSync(unsigned int ip, int port, LocServerType type);
- virtual void
- informNiResponse(GnssNiResponse userResponse, const void* passThroughData);
+ virtual void stopFix(LocApiResponse* adapterResponse);
+ virtual void deleteAidingData(const GnssAidingData& data, LocApiResponse* adapterResponse);
+ virtual void injectPosition(double latitude, double longitude, float accuracy);
+ virtual void injectPosition(const GnssLocationInfoNotification &locationInfo,
+ bool onDemandCpi=false);
+ virtual void injectPosition(const Location& location, bool onDemandCpi);
+ virtual void setTime(LocGpsUtcTime time, int64_t timeReference, int uncertainty);
+ virtual enum loc_api_adapter_err setXtraData(char* data, int length);
+ virtual void atlOpenStatus(int handle, int is_succ, char* apn, uint32_t apnLen,
+ AGpsBearerType bear, LocAGpsType agpsType, LocApnTypeMask mask);
+ virtual void atlCloseStatus(int handle, int is_succ);
+ virtual LocationError setServerSync(const char* url, int len, LocServerType type);
+ virtual LocationError setServerSync(unsigned int ip, int port, LocServerType type);
+ virtual void informNiResponse(GnssNiResponse userResponse, const void* passThroughData);
virtual LocationError setSUPLVersionSync(GnssConfigSuplVersion version);
- virtual enum loc_api_adapter_err
- setNMEATypesSync(uint32_t typesMask);
+ virtual enum loc_api_adapter_err setNMEATypesSync(uint32_t typesMask);
virtual LocationError setLPPConfigSync(GnssConfigLppProfile profile);
- virtual enum loc_api_adapter_err
- setSensorPropertiesSync(bool gyroBiasVarianceRandomWalk_valid,
- float gyroBiasVarianceRandomWalk,
- bool accelBiasVarianceRandomWalk_valid,
- float accelBiasVarianceRandomWalk,
- bool angleBiasVarianceRandomWalk_valid,
- float angleBiasVarianceRandomWalk,
- bool rateBiasVarianceRandomWalk_valid,
- float rateBiasVarianceRandomWalk,
- bool velocityBiasVarianceRandomWalk_valid,
- float velocityBiasVarianceRandomWalk);
- virtual enum loc_api_adapter_err
- setSensorPerfControlConfigSync(int controlMode,
- int accelSamplesPerBatch,
- int accelBatchesPerSec,
- int gyroSamplesPerBatch,
- int gyroBatchesPerSec,
- int accelSamplesPerBatchHigh,
- int accelBatchesPerSecHigh,
- int gyroSamplesPerBatchHigh,
- int gyroBatchesPerSecHigh,
- int algorithmConfig);
+ virtual enum loc_api_adapter_err setSensorPropertiesSync(
+ bool gyroBiasVarianceRandomWalk_valid, float gyroBiasVarianceRandomWalk,
+ bool accelBiasVarianceRandomWalk_valid, float accelBiasVarianceRandomWalk,
+ bool angleBiasVarianceRandomWalk_valid, float angleBiasVarianceRandomWalk,
+ bool rateBiasVarianceRandomWalk_valid, float rateBiasVarianceRandomWalk,
+ bool velocityBiasVarianceRandomWalk_valid, float velocityBiasVarianceRandomWalk);
+ virtual enum loc_api_adapter_err setSensorPerfControlConfigSync(int controlMode,
+ int accelSamplesPerBatch, int accelBatchesPerSec, int gyroSamplesPerBatch,
+ int gyroBatchesPerSec, int accelSamplesPerBatchHigh, int accelBatchesPerSecHigh,
+ int gyroSamplesPerBatchHigh, int gyroBatchesPerSecHigh, int algorithmConfig);
virtual LocationError
- setAGLONASSProtocolSync(GnssConfigAGlonassPositionProtocolMask aGlonassProtocol);
+ setAGLONASSProtocolSync(GnssConfigAGlonassPositionProtocolMask aGlonassProtocol);
virtual LocationError setLPPeProtocolCpSync(GnssConfigLppeControlPlaneMask lppeCP);
virtual LocationError setLPPeProtocolUpSync(GnssConfigLppeUserPlaneMask lppeUP);
virtual GnssConfigSuplVersion convertSuplVersion(const uint32_t suplVersion);
virtual GnssConfigLppProfile convertLppProfile(const uint32_t lppProfile);
virtual GnssConfigLppeControlPlaneMask convertLppeCp(const uint32_t lppeControlPlaneMask);
virtual GnssConfigLppeUserPlaneMask convertLppeUp(const uint32_t lppeUserPlaneMask);
+ virtual LocationError setEmergencyExtensionWindowSync(const uint32_t emergencyExtensionSeconds);
virtual void getWwanZppFix();
virtual void getBestAvailableZppFix();
- virtual void installAGpsCert(const LocDerEncodedCertificate* pData,
- size_t length,
- uint32_t slotBitMask);
- inline virtual void setInSession(bool inSession) {
-
- (void)inSession;
- }
-
-
- void updateEvtMask();
- void updateNmeaMask(uint32_t mask);
-
+ virtual void installAGpsCert(const LocDerEncodedCertificate* pData, size_t length,
+ uint32_t slotBitMask);
virtual LocationError setGpsLockSync(GnssConfigGpsLock lock);
virtual void requestForAidingData(GnssAidingDataSvMask svDataMask);
-
virtual LocationError setXtraVersionCheckSync(uint32_t check);
-
/* Requests for SV/Constellation Control */
virtual LocationError setBlacklistSvSync(const GnssSvIdConfig& config);
virtual void setBlacklistSv(const GnssSvIdConfig& config);
@@ -290,12 +257,55 @@ public:
virtual void setConstellationControl(const GnssSvTypeConfig& config);
virtual void getConstellationControl();
virtual void resetConstellationControl();
-
- virtual LocationError setConstrainedTuncMode(bool enabled,
- float tuncConstraint,
- uint32_t energyBudget);
+ virtual LocationError setConstrainedTuncMode(bool enabled, float tuncConstraint,
+ uint32_t energyBudget);
virtual LocationError setPositionAssistedClockEstimatorMode(bool enabled);
virtual LocationError getGnssEnergyConsumed();
+
+ virtual void addGeofence(uint32_t clientId, const GeofenceOption& options,
+ const GeofenceInfo& info, LocApiResponseData<LocApiGeofenceData>* adapterResponseData);
+ virtual void removeGeofence(uint32_t hwId, uint32_t clientId, LocApiResponse* adapterResponse);
+ virtual void pauseGeofence(uint32_t hwId, uint32_t clientId, LocApiResponse* adapterResponse);
+ virtual void resumeGeofence(uint32_t hwId, uint32_t clientId, LocApiResponse* adapterResponse);
+ virtual void modifyGeofence(uint32_t hwId, uint32_t clientId, const GeofenceOption& options,
+ LocApiResponse* adapterResponse);
+
+ virtual void startTimeBasedTracking(const TrackingOptions& options,
+ LocApiResponse* adapterResponse);
+ virtual void stopTimeBasedTracking(LocApiResponse* adapterResponse);
+ virtual void startDistanceBasedTracking(uint32_t sessionId, const LocationOptions& options,
+ LocApiResponse* adapterResponse);
+ virtual void stopDistanceBasedTracking(uint32_t sessionId,
+ LocApiResponse* adapterResponse = nullptr);
+ virtual void startBatching(uint32_t sessionId, const LocationOptions& options,
+ uint32_t accuracy, uint32_t timeout, LocApiResponse* adapterResponse);
+ virtual void stopBatching(uint32_t sessionId, LocApiResponse* adapterResponse);
+ virtual LocationError startOutdoorTripBatchingSync(uint32_t tripDistance,
+ uint32_t tripTbf, uint32_t timeout);
+ virtual void startOutdoorTripBatching(uint32_t tripDistance,
+ uint32_t tripTbf, uint32_t timeout, LocApiResponse* adapterResponse);
+ virtual void reStartOutdoorTripBatching(uint32_t ongoingTripDistance,
+ uint32_t ongoingTripInterval, uint32_t batchingTimeout,
+ LocApiResponse* adapterResponse);
+ virtual LocationError stopOutdoorTripBatchingSync(bool deallocBatchBuffer = true);
+ virtual void stopOutdoorTripBatching(bool deallocBatchBuffer = true,
+ LocApiResponse* adapterResponse = nullptr);
+ virtual LocationError getBatchedLocationsSync(size_t count);
+ virtual void getBatchedLocations(size_t count, LocApiResponse* adapterResponse);
+ virtual LocationError getBatchedTripLocationsSync(size_t count, uint32_t accumulatedDistance);
+ virtual void getBatchedTripLocations(size_t count, uint32_t accumulatedDistance,
+ LocApiResponse* adapterResponse);
+ virtual LocationError queryAccumulatedTripDistanceSync(uint32_t &accumulated_trip_distance,
+ uint32_t &numOfBatchedPositions);
+ virtual void queryAccumulatedTripDistance(
+ LocApiResponseData<LocApiBatchData>* adapterResponseData);
+ virtual void setBatchSize(size_t size);
+ virtual void setTripBatchSize(size_t size);
+ virtual void addToCallQueue(LocApiResponse* adapterResponse);
+
+ void updateEvtMask();
+ void updateNmeaMask(uint32_t mask);
+
};
typedef LocApiBase* (getLocApi_t)(LOC_API_ADAPTER_EVENT_MASK_T exMask,
diff --git a/core/LocContext.cpp b/core/LocContext.cpp
new file mode 100644
index 0000000..18d3f2d
--- /dev/null
+++ b/core/LocContext.cpp
@@ -0,0 +1,98 @@
+/* Copyright (c) 2011-2014, 2016-2019 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_NDEBUG 0
+#define LOG_TAG "LocSvc_Ctx"
+
+#include <cutils/sched_policy.h>
+#include <unistd.h>
+#include <LocContext.h>
+#include <msg_q.h>
+#include <log_util.h>
+#include <loc_log.h>
+
+namespace loc_core {
+
+const MsgTask* LocContext::mMsgTask = NULL;
+ContextBase* LocContext::mContext = NULL;
+// the name must be shorter than 15 chars
+const char* LocContext::mLocationHalName = "Loc_hal_worker";
+#ifndef USE_GLIB
+const char* LocContext::mLBSLibName = "liblbs_core.so";
+#else
+const char* LocContext::mLBSLibName = "liblbs_core.so.1";
+#endif
+
+pthread_mutex_t LocContext::mGetLocContextMutex = PTHREAD_MUTEX_INITIALIZER;
+
+const MsgTask* LocContext::getMsgTask(LocThread::tCreate tCreator,
+ const char* name, bool joinable)
+{
+ if (NULL == mMsgTask) {
+ mMsgTask = new MsgTask(tCreator, name, joinable);
+ }
+ return mMsgTask;
+}
+
+inline
+const MsgTask* LocContext::getMsgTask(const char* name, bool joinable) {
+ return getMsgTask((LocThread::tCreate)NULL, name, joinable);
+}
+
+ContextBase* LocContext::getLocContext(LocThread::tCreate tCreator,
+ LocMsg* firstMsg, const char* name, bool joinable)
+{
+ pthread_mutex_lock(&LocContext::mGetLocContextMutex);
+ LOC_LOGD("%s:%d]: querying ContextBase with tCreator", __func__, __LINE__);
+ if (NULL == mContext) {
+ LOC_LOGD("%s:%d]: creating msgTask with tCreator", __func__, __LINE__);
+ const MsgTask* msgTask = getMsgTask(tCreator, name, joinable);
+ mContext = new LocContext(msgTask);
+ }
+ pthread_mutex_unlock(&LocContext::mGetLocContextMutex);
+
+ if (firstMsg) {
+ mContext->sendMsg(firstMsg);
+ }
+
+ return mContext;
+}
+
+void LocContext :: injectFeatureConfig(ContextBase *curContext)
+{
+ LOC_LOGD("%s:%d]: Calling LBSProxy (%p) to inject feature config",
+ __func__, __LINE__, ((LocContext *)curContext)->mLBSProxy);
+ ((LocContext *)curContext)->mLBSProxy->injectFeatureConfig(curContext);
+}
+
+LocContext::LocContext(const MsgTask* msgTask) :
+ ContextBase(msgTask, 0, mLBSLibName)
+{
+}
+
+}
diff --git a/core/LocDualContext.h b/core/LocContext.h
index 3b3ce2c..fb7d009 100644
--- a/core/LocDualContext.h
+++ b/core/LocContext.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2014, 2017 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2014, 2017-2019 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
@@ -26,8 +26,8 @@
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
-#ifndef __LOC_ENG_CONTEXT__
-#define __LOC_ENG_CONTEXT__
+#ifndef __LOC_CONTEXT__
+#define __LOC_CONTEXT__
#include <stdbool.h>
#include <ctype.h>
@@ -36,36 +36,26 @@
namespace loc_core {
-class LocDualContext : public ContextBase {
+class LocContext : public ContextBase {
static const MsgTask* mMsgTask;
- static ContextBase* mFgContext;
- static ContextBase* mBgContext;
- static ContextBase* mInjectContext;
+ static ContextBase* mContext;
static const MsgTask* getMsgTask(LocThread::tCreate tCreator,
const char* name, bool joinable = true);
static const MsgTask* getMsgTask(const char* name, bool joinable = true);
static pthread_mutex_t mGetLocContextMutex;
protected:
- LocDualContext(const MsgTask* msgTask,
- LOC_API_ADAPTER_EVENT_MASK_T exMask);
- inline virtual ~LocDualContext() {}
+ LocContext(const MsgTask* msgTask);
+ inline virtual ~LocContext() {}
public:
static const char* mLBSLibName;
- static const LOC_API_ADAPTER_EVENT_MASK_T mFgExclMask;
- static const LOC_API_ADAPTER_EVENT_MASK_T mBgExclMask;
static const char* mLocationHalName;
- static ContextBase* getLocFgContext(LocThread::tCreate tCreator, LocMsg* firstMsg,
+ static ContextBase* getLocContext(LocThread::tCreate tCreator, LocMsg* firstMsg,
const char* name, bool joinable = true);
- inline static ContextBase* getLocFgContext(const char* name, bool joinable = true) {
- return getLocFgContext(NULL, NULL, name, joinable);
- }
- static ContextBase* getLocBgContext(LocThread::tCreate tCreator, LocMsg* firstMsg,
- const char* name, bool joinable = true);
- inline static ContextBase* getLocBgContext(const char* name, bool joinable = true) {
- return getLocBgContext(NULL, NULL, name, joinable);
+ inline static ContextBase* getLocContext(const char* name, bool joinable = true) {
+ return getLocContext(NULL, NULL, name, joinable);
}
static void injectFeatureConfig(ContextBase *context);
@@ -73,4 +63,4 @@ public:
}
-#endif //__LOC_ENG_CONTEXT__
+#endif //__LOC_CONTEXT__
diff --git a/core/LocDualContext.cpp b/core/LocDualContext.cpp
deleted file mode 100644
index 180d9dc..0000000
--- a/core/LocDualContext.cpp
+++ /dev/null
@@ -1,150 +0,0 @@
-/* Copyright (c) 2011-2014, 2016-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_NDEBUG 0
-#define LOG_TAG "LocSvc_DualCtx"
-
-#include <cutils/sched_policy.h>
-#include <unistd.h>
-#include <LocDualContext.h>
-#include <msg_q.h>
-#include <log_util.h>
-#include <loc_log.h>
-
-namespace loc_core {
-
-// nothing exclude for foreground
-const LOC_API_ADAPTER_EVENT_MASK_T
-LocDualContext::mFgExclMask = 0;
-// excluded events for background clients
-const LOC_API_ADAPTER_EVENT_MASK_T
-LocDualContext::mBgExclMask =
- (LOC_API_ADAPTER_BIT_SATELLITE_REPORT |
- LOC_API_ADAPTER_BIT_NMEA_1HZ_REPORT |
- LOC_API_ADAPTER_BIT_NMEA_POSITION_REPORT |
- LOC_API_ADAPTER_BIT_IOCTL_REPORT |
- LOC_API_ADAPTER_BIT_STATUS_REPORT |
- LOC_API_ADAPTER_BIT_GEOFENCE_GEN_ALERT |
- LOC_API_ADAPTER_BIT_GNSS_MEASUREMENT);
-
-const MsgTask* LocDualContext::mMsgTask = NULL;
-ContextBase* LocDualContext::mFgContext = NULL;
-ContextBase* LocDualContext::mBgContext = NULL;
-ContextBase* LocDualContext::mInjectContext = NULL;
-// the name must be shorter than 15 chars
-const char* LocDualContext::mLocationHalName = "Loc_hal_worker";
-#ifndef USE_GLIB
-const char* LocDualContext::mLBSLibName = "liblbs_core.so";
-#else
-const char* LocDualContext::mLBSLibName = "liblbs_core.so.1";
-#endif
-
-pthread_mutex_t LocDualContext::mGetLocContextMutex = PTHREAD_MUTEX_INITIALIZER;
-
-const MsgTask* LocDualContext::getMsgTask(LocThread::tCreate tCreator,
- const char* name, bool joinable)
-{
- if (NULL == mMsgTask) {
- mMsgTask = new MsgTask(tCreator, name, joinable);
- }
- return mMsgTask;
-}
-
-inline
-const MsgTask* LocDualContext::getMsgTask(const char* name, bool joinable) {
- return getMsgTask((LocThread::tCreate)NULL, name, joinable);
-}
-
-ContextBase* LocDualContext::getLocFgContext(LocThread::tCreate tCreator,
- LocMsg* firstMsg, const char* name, bool joinable)
-{
- pthread_mutex_lock(&LocDualContext::mGetLocContextMutex);
- LOC_LOGD("%s:%d]: querying ContextBase with tCreator", __func__, __LINE__);
- if (NULL == mFgContext) {
- LOC_LOGD("%s:%d]: creating msgTask with tCreator", __func__, __LINE__);
- const MsgTask* msgTask = getMsgTask(tCreator, name, joinable);
- mFgContext = new LocDualContext(msgTask,
- mFgExclMask);
- }
- if(NULL == mInjectContext) {
- LOC_LOGD("%s:%d]: mInjectContext is FgContext", __func__, __LINE__);
- mInjectContext = mFgContext;
- injectFeatureConfig(mInjectContext);
- }
- pthread_mutex_unlock(&LocDualContext::mGetLocContextMutex);
-
- if (firstMsg) {
- mFgContext->sendMsg(firstMsg);
- }
-
- return mFgContext;
-}
-
-ContextBase* LocDualContext::getLocBgContext(LocThread::tCreate tCreator,
- LocMsg* firstMsg, const char* name, bool joinable)
-{
- pthread_mutex_lock(&LocDualContext::mGetLocContextMutex);
- LOC_LOGD("%s:%d]: querying ContextBase with tCreator", __func__, __LINE__);
- if (NULL == mBgContext) {
- LOC_LOGD("%s:%d]: creating msgTask with tCreator", __func__, __LINE__);
- const MsgTask* msgTask = getMsgTask(tCreator, name, joinable);
- mBgContext = new LocDualContext(msgTask,
- mBgExclMask);
- }
- if(NULL == mInjectContext) {
- LOC_LOGD("%s:%d]: mInjectContext is BgContext", __func__, __LINE__);
- mInjectContext = mBgContext;
- injectFeatureConfig(mInjectContext);
- }
- pthread_mutex_unlock(&LocDualContext::mGetLocContextMutex);
-
- if (firstMsg) {
- mBgContext->sendMsg(firstMsg);
- }
-
- return mBgContext;
-}
-
-void LocDualContext :: injectFeatureConfig(ContextBase *curContext)
-{
- LOC_LOGD("%s:%d]: Enter", __func__, __LINE__);
- if(curContext == mInjectContext) {
- LOC_LOGD("%s:%d]: Calling LBSProxy (%p) to inject feature config",
- __func__, __LINE__, ((LocDualContext *)mInjectContext)->mLBSProxy);
- ((LocDualContext *)mInjectContext)->mLBSProxy->injectFeatureConfig(curContext);
- }
- LOC_LOGD("%s:%d]: Exit", __func__, __LINE__);
-}
-
-LocDualContext::LocDualContext(const MsgTask* msgTask,
- LOC_API_ADAPTER_EVENT_MASK_T exMask) :
- ContextBase(msgTask, exMask, mLBSLibName)
-{
-}
-
-}
diff --git a/core/Makefile.am b/core/Makefile.am
index 53059e4..ffd9357 100644
--- a/core/Makefile.am
+++ b/core/Makefile.am
@@ -15,7 +15,7 @@ libloc_core_la_h_sources = \
LocApiBase.h \
LocAdapterBase.h \
ContextBase.h \
- LocDualContext.h \
+ LocContext.h \
LBSProxyBase.h \
loc_core_log.h \
LocAdapterProxyBase.h \
@@ -34,7 +34,7 @@ libloc_core_la_c_sources = \
LocApiBase.cpp \
LocAdapterBase.cpp \
ContextBase.cpp \
- LocDualContext.cpp \
+ LocContext.cpp \
loc_core_log.cpp \
data-items/DataItemsFactoryProxy.cpp \
SystemStatusOsObserver.cpp \
diff --git a/core/SystemStatus.cpp b/core/SystemStatus.cpp
index f4316ca..6ef4993 100644
--- a/core/SystemStatus.cpp
+++ b/core/SystemStatus.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017, 2019, 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
@@ -1682,10 +1682,12 @@ bool SystemStatus::setDefaultGnssEngineStates(void)
@return true when successfully done
******************************************************************************/
-bool SystemStatus::eventConnectionStatus(bool connected, int8_t type)
+bool SystemStatus::eventConnectionStatus(bool connected, int8_t type,
+ bool roaming, NetworkHandle networkHandle)
{
// send networkinof dataitem to systemstatus observer clients
- SystemStatusNetworkInfo s(type, "", "", connected);
+ SystemStatusNetworkInfo s(type, "", "", connected, roaming,
+ (uint64_t) networkHandle);
mSysStatusObsvr.notify({&s});
return true;
diff --git a/core/SystemStatus.h b/core/SystemStatus.h
index 9422322..73a220a 100644
--- a/core/SystemStatus.h
+++ b/core/SystemStatus.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019, 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
@@ -32,6 +32,8 @@
#include <stdint.h>
#include <sys/time.h>
#include <vector>
+#include <algorithm>
+#include <iterator>
#include <loc_pla.h>
#include <log_util.h>
#include <MsgTask.h>
@@ -467,7 +469,8 @@ public:
std::string typeName="",
string subTypeName="",
bool connected=false,
- bool roaming=false) :
+ bool roaming=false,
+ uint64_t networkHandle=NETWORK_HANDLE_UNKNOWN) :
NetworkInfoDataItemBase(
(NetworkType)type,
type,
@@ -475,7 +478,8 @@ public:
subTypeName,
connected && (!roaming),
connected,
- roaming),
+ roaming,
+ networkHandle),
mSrcObjPtr(nullptr) {}
inline SystemStatusNetworkInfo(const NetworkInfoDataItemBase& itemBase) :
NetworkInfoDataItemBase(itemBase),
@@ -487,16 +491,24 @@ public:
}
inline virtual SystemStatusItemBase& collate(SystemStatusItemBase& curInfo) {
uint64_t allTypes = (static_cast<SystemStatusNetworkInfo&>(curInfo)).mAllTypes;
+ uint64_t networkHandle =
+ (static_cast<SystemStatusNetworkInfo&>(curInfo)).mNetworkHandle;
+ int32_t type = (static_cast<SystemStatusNetworkInfo&>(curInfo)).mType;
if (mConnected) {
mAllTypes |= allTypes;
+ mAllNetworkHandles[type] = networkHandle;
} else if (0 != mAllTypes) {
mAllTypes = (allTypes & (~mAllTypes));
+ mAllNetworkHandles[type] = NETWORK_HANDLE_UNKNOWN;
} // else (mConnected == false && mAllTypes == 0)
// we keep mAllTypes as 0, which means no more connections.
if (nullptr != mSrcObjPtr) {
// this is critical, changing mAllTypes of the original obj
mSrcObjPtr->mAllTypes = mAllTypes;
+ memcpy(mSrcObjPtr->mAllNetworkHandles,
+ mAllNetworkHandles,
+ sizeof(mSrcObjPtr->mAllNetworkHandles));
}
return *this;
}
@@ -830,7 +842,8 @@ public:
bool setNmeaString(const char *data, uint32_t len);
bool getReport(SystemStatusReports& reports, bool isLatestonly = false) const;
bool setDefaultGnssEngineStates(void);
- bool eventConnectionStatus(bool connected, int8_t type);
+ bool eventConnectionStatus(bool connected, int8_t type,
+ bool roaming, NetworkHandle networkHandle);
};
} // namespace loc_core
diff --git a/core/data-items/DataItemConcreteTypesBase.h b/core/data-items/DataItemConcreteTypesBase.h
index 44be5f9..552d46a 100644
--- a/core/data-items/DataItemConcreteTypesBase.h
+++ b/core/data-items/DataItemConcreteTypesBase.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2017, 2019, 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
@@ -34,6 +34,7 @@
#include <cstring>
#include <DataItemId.h>
#include <IDataItemCore.h>
+#include <gps_extended_c.h>
#define MAC_ADDRESS_LENGTH 6
// MAC address length in bytes
@@ -222,7 +223,7 @@ protected:
class NetworkInfoDataItemBase : public IDataItemCore {
public:
enum NetworkType {
- TYPE_MOBILE,
+ TYPE_MOBILE = 0,
TYPE_WIFI,
TYPE_ETHERNET,
TYPE_BLUETOOTH,
@@ -236,7 +237,7 @@ public:
};
NetworkInfoDataItemBase(
NetworkType initialType, int32_t type, string typeName, string subTypeName,
- bool available, bool connected, bool roaming ):
+ bool available, bool connected, bool roaming, uint64_t networkHandle ):
mAllTypes(typeToAllTypes(initialType)),
mType(type),
mTypeName(typeName),
@@ -244,7 +245,12 @@ public:
mAvailable(available),
mConnected(connected),
mRoaming(roaming),
- mId(NETWORKINFO_DATA_ITEM_ID) {}
+ mNetworkHandle(networkHandle),
+ mId(NETWORKINFO_DATA_ITEM_ID) {
+ memset (&mAllNetworkHandles, NETWORK_HANDLE_UNKNOWN,
+ sizeof (mAllNetworkHandles));
+ mAllNetworkHandles[type] = networkHandle;
+ }
virtual ~NetworkInfoDataItemBase() {}
inline virtual DataItemId getId() { return mId; }
virtual void stringify(string& /*valueStr*/) {}
@@ -253,6 +259,9 @@ public:
return (NetworkType)mType;
}
inline uint64_t getAllTypes() { return mAllTypes; }
+ inline uint64_t getNetworkHandle(NetworkType type) {
+ return mAllNetworkHandles[type];
+ }
// Data members
uint64_t mAllTypes;
int32_t mType;
@@ -261,6 +270,8 @@ public:
bool mAvailable;
bool mConnected;
bool mRoaming;
+ uint64_t mAllNetworkHandles[TYPE_UNKNOWN + 1];
+ uint64_t mNetworkHandle;
protected:
DataItemId mId;
inline uint64_t typeToAllTypes(NetworkType type) {
diff --git a/etc/Android.mk b/etc/Android.mk
index db59eed..32a0e9c 100644
--- a/etc/Android.mk
+++ b/etc/Android.mk
@@ -1,13 +1,22 @@
ifneq ($(BOARD_VENDOR_QCOM_LOC_PDK_FEATURE_SET),true)
LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
+include $(CLEAR_VARS)
LOCAL_MODULE := gps.conf
+LOCAL_VENDOR_MODULE := true
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/etc/
LOCAL_SRC_FILES := gps.conf
+LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_ETC)
+include $(BUILD_PREBUILT)
+include $(CLEAR_VARS)
+LOCAL_MODULE := flp.conf
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_SRC_FILES := flp.conf
+LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_ETC)
include $(BUILD_PREBUILT)
endif
diff --git a/etc/flp.conf b/etc/flp.conf
new file mode 100644
index 0000000..65d54d3
--- /dev/null
+++ b/etc/flp.conf
@@ -0,0 +1,60 @@
+###################################
+##### FLP settings #####
+###################################
+
+###################################
+# FLP BATCH SIZE
+###################################
+# The number of batched locations
+# requested to modem. The desired number
+# defined below may not be satisfied, as
+# the modem can only return the number
+# of batched locations that can be allocated,
+# which is limited by memory. The default
+# batch size defined as 20 as below.
+BATCH_SIZE=20
+
+###################################
+# FLP OUTDOOR TRIP BATCH SIZE
+###################################
+# The number of batched locations
+# requested to modem for outdoor
+# trip batching. The desired number
+# defined below may not be satisfied, as
+# the modem can only return the number
+# of batched locations that can be allocated,
+# which is limited by memory. The default
+# trip batch size defined as 600 as below.
+OUTDOOR_TRIP_BATCH_SIZE=600
+
+###################################
+# FLP BATCHING SESSION TIMEOUT
+###################################
+# Duration with which batch session timeout
+# happens in milliseconds. If not specified
+# or set to zero, batching session timeout
+# defaults to 20 seconds by the modem.
+# BATCH_SESSION_TIMEOUT=20000
+
+###################################
+# FLP BATCHING ACCURACY
+###################################
+# Set to one of the defined values below
+# to define the accuracy of batching.
+# If not specified, accuracy defaults
+# to LOW.
+# FLP BATCHING ACCURACY values:
+# Low accuracy = 0
+# Medium accuracy = 1
+# High accuracy = 2
+ACCURACY=1
+
+####################################
+# By default if network fixes are not sensor assisted
+# these fixes must be dropped. This parameter adds an exception
+# for targets where there is no PDR and we still want to
+# report out network fixes
+# 0: MUST NOT ALLOW NETWORK FIXES
+# 1: ALLOW NETWORK FIXES
+####################################
+ALLOW_NETWORK_FIXES = 0
diff --git a/etc/gps.conf b/etc/gps.conf
index e5be385..82a7b3c 100644
--- a/etc/gps.conf
+++ b/etc/gps.conf
@@ -54,9 +54,8 @@ SUPL_VER=0x10000
# MSB = 0x02
# MSA = 0x04
# ON_DEMAND_TIME = 0x10
-# GEOFENCE = 0x20
-# default = ON_DEMAND_TIME | MSA | MSB | SCHEDULING | GEOFENCE
-CAPABILITIES=0x37
+# default = ON_DEMAND_TIME | MSA | MSB | SCHEDULING
+CAPABILITIES=0x17
# Accuracy threshold for intermediate positions
# less accurate positions are ignored, 0 for passing all positions
diff --git a/geofence/Android.mk b/geofence/Android.mk
new file mode 100644
index 0000000..6e9e870
--- /dev/null
+++ b/geofence/Android.mk
@@ -0,0 +1,36 @@
+ifneq ($(BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE),)
+ifneq ($(BUILD_TINY_ANDROID),true)
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libgeofencing
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES:= \
+ GeofenceAdapter.cpp \
+ location_geofence.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+ libutils \
+ libcutils \
+ libgps.utils \
+ liblog \
+ libloc_core \
+ liblbs_core
+
+LOCAL_HEADER_LIBRARIES := \
+ libgps.utils_headers \
+ libloc_core_headers \
+ libloc_pla_headers \
+ liblocation_api_headers
+
+LOCAL_PRELINK_MODULE := false
+LOCAL_CFLAGS += $(GNSS_CFLAGS)
+include $(BUILD_SHARED_LIBRARY)
+
+endif # not BUILD_TINY_ANDROID
+endif # BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE
+
diff --git a/geofence/GeofenceAdapter.cpp b/geofence/GeofenceAdapter.cpp
new file mode 100644
index 0000000..b8746fb
--- /dev/null
+++ b/geofence/GeofenceAdapter.cpp
@@ -0,0 +1,867 @@
+/* Copyright (c) 2013-2019, 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_GeofenceAdapter"
+
+#include <GeofenceAdapter.h>
+#include "loc_log.h"
+#include <log_util.h>
+#include <string>
+
+using namespace loc_core;
+
+GeofenceAdapter::GeofenceAdapter() :
+ LocAdapterBase(0,
+ LocContext::getLocContext(
+ NULL,
+ NULL,
+ LocContext::mLocationHalName,
+ false),
+ true /*isMaster*/)
+{
+ LOC_LOGD("%s]: Constructor", __func__);
+}
+
+void
+GeofenceAdapter::stopClientSessions(LocationAPI* client)
+{
+ LOC_LOGD("%s]: client %p", __func__, client);
+
+
+ for (auto it = mGeofenceIds.begin(); it != mGeofenceIds.end();) {
+ uint32_t hwId = it->second;
+ GeofenceKey key(it->first);
+ if (client == key.client) {
+ it = mGeofenceIds.erase(it);
+ mLocApi->removeGeofence(hwId, key.id,
+ new LocApiResponse(*getContext(),
+ [this, hwId] (LocationError err) {
+ if (LOCATION_ERROR_SUCCESS == err) {
+ auto it2 = mGeofences.find(hwId);
+ if (it2 != mGeofences.end()) {
+ mGeofences.erase(it2);
+ } else {
+ LOC_LOGE("%s]:geofence item to erase not found. hwId %u", __func__, hwId);
+ }
+ }
+ }));
+ continue;
+ }
+ ++it; // increment only when not erasing an iterator
+ }
+
+}
+
+void
+GeofenceAdapter::updateClientsEventMask()
+{
+ LOC_API_ADAPTER_EVENT_MASK_T mask = 0;
+ for (auto it=mClientData.begin(); it != mClientData.end(); ++it) {
+ if (it->second.geofenceBreachCb != nullptr) {
+ mask |= LOC_API_ADAPTER_BIT_BATCHED_GENFENCE_BREACH_REPORT;
+ mask |= LOC_API_ADAPTER_BIT_REPORT_GENFENCE_DWELL;
+ }
+ if (it->second.geofenceStatusCb != nullptr) {
+ mask |= LOC_API_ADAPTER_BIT_GEOFENCE_GEN_ALERT;
+ }
+ }
+ updateEvtMask(mask, LOC_REGISTRATION_MASK_SET);
+}
+
+LocationError
+GeofenceAdapter::getHwIdFromClient(LocationAPI* client, uint32_t clientId, uint32_t& hwId)
+{
+ GeofenceKey key(client, clientId);
+ auto it = mGeofenceIds.find(key);
+ if (it != mGeofenceIds.end()) {
+ hwId = it->second;
+ return LOCATION_ERROR_SUCCESS;
+ }
+ return LOCATION_ERROR_ID_UNKNOWN;
+}
+
+LocationError
+GeofenceAdapter::getGeofenceKeyFromHwId(uint32_t hwId, GeofenceKey& key)
+{
+ auto it = mGeofences.find(hwId);
+ if (it != mGeofences.end()) {
+ key = it->second.key;
+ return LOCATION_ERROR_SUCCESS;
+ }
+ return LOCATION_ERROR_ID_UNKNOWN;
+}
+
+void
+GeofenceAdapter::handleEngineUpEvent()
+{
+ struct MsgSSREvent : public LocMsg {
+ GeofenceAdapter& mAdapter;
+ inline MsgSSREvent(GeofenceAdapter& adapter) :
+ LocMsg(),
+ mAdapter(adapter) {}
+ virtual void proc() const {
+ mAdapter.setEngineCapabilitiesKnown(true);
+ mAdapter.broadcastCapabilities(mAdapter.getCapabilities());
+ mAdapter.restartGeofences();
+ for (auto msg: mAdapter.mPendingMsgs) {
+ mAdapter.sendMsg(msg);
+ }
+ mAdapter.mPendingMsgs.clear();
+ }
+ };
+
+ sendMsg(new MsgSSREvent(*this));
+}
+
+void
+GeofenceAdapter::restartGeofences()
+{
+ if (mGeofences.empty()) {
+ return;
+ }
+
+ GeofencesMap oldGeofences(mGeofences);
+ mGeofences.clear();
+ mGeofenceIds.clear();
+
+ for (auto it = oldGeofences.begin(); it != oldGeofences.end(); it++) {
+ GeofenceObject object = it->second;
+ GeofenceOption options = {sizeof(GeofenceOption),
+ object.breachMask,
+ object.responsiveness,
+ object.dwellTime};
+ GeofenceInfo info = {sizeof(GeofenceInfo),
+ object.latitude,
+ object.longitude,
+ object.radius};
+ mLocApi->addGeofence(object.key.id,
+ options,
+ info,
+ new LocApiResponseData<LocApiGeofenceData>(*getContext(),
+ [this, object, options, info] (LocationError err, LocApiGeofenceData data) {
+ if (LOCATION_ERROR_SUCCESS == err) {
+ if (true == object.paused) {
+ mLocApi->pauseGeofence(data.hwId, object.key.id,
+ new LocApiResponse(*getContext(), [] (LocationError err ) {}));
+ }
+ saveGeofenceItem(object.key.client, object.key.id, data.hwId, options, info);
+ }
+ }));
+ }
+}
+
+void
+GeofenceAdapter::reportResponse(LocationAPI* client, size_t count, LocationError* errs,
+ uint32_t* ids)
+{
+ IF_LOC_LOGD {
+ std::string idsString = "[";
+ std::string errsString = "[";
+ if (NULL != ids && NULL != errs) {
+ for (size_t i=0; i < count; ++i) {
+ idsString += std::to_string(ids[i]) + " ";
+ errsString += std::to_string(errs[i]) + " ";
+ }
+ }
+ idsString += "]";
+ errsString += "]";
+
+ LOC_LOGD("%s]: client %p ids %s errs %s",
+ __func__, client, idsString.c_str(), errsString.c_str());
+ }
+
+ auto it = mClientData.find(client);
+ if (it != mClientData.end() && it->second.collectiveResponseCb != nullptr) {
+ it->second.collectiveResponseCb(count, errs, ids);
+ } else {
+ LOC_LOGE("%s]: client %p response not found in info", __func__, client);
+ }
+}
+
+uint32_t*
+GeofenceAdapter::addGeofencesCommand(LocationAPI* client, size_t count, GeofenceOption* options,
+ GeofenceInfo* infos)
+{
+ LOC_LOGD("%s]: client %p count %zu", __func__, client, count);
+
+ struct MsgAddGeofences : public LocMsg {
+ GeofenceAdapter& mAdapter;
+ LocApiBase& mApi;
+ LocationAPI* mClient;
+ size_t mCount;
+ uint32_t* mIds;
+ GeofenceOption* mOptions;
+ GeofenceInfo* mInfos;
+ inline MsgAddGeofences(GeofenceAdapter& adapter,
+ LocApiBase& api,
+ LocationAPI* client,
+ size_t count,
+ uint32_t* ids,
+ GeofenceOption* options,
+ GeofenceInfo* infos) :
+ LocMsg(),
+ mAdapter(adapter),
+ mApi(api),
+ mClient(client),
+ mCount(count),
+ mIds(ids),
+ mOptions(options),
+ mInfos(infos) {}
+ inline virtual void proc() const {
+ LocationError* errs = new LocationError[mCount];
+ if (nullptr == errs) {
+ LOC_LOGE("%s]: new failed to allocate errs", __func__);
+ return;
+ }
+ for (size_t i=0; i < mCount; ++i) {
+ if (NULL == mIds || NULL == mOptions || NULL == mInfos) {
+ errs[i] = LOCATION_ERROR_INVALID_PARAMETER;
+ } else {
+ mApi.addGeofence(mIds[i],
+ mOptions[i],
+ mInfos[i],
+ new LocApiResponseData<LocApiGeofenceData>(*mAdapter.getContext(),
+ [&mAdapter = mAdapter, mOptions = mOptions, mClient = mClient,
+ mCount = mCount, mIds = mIds, mInfos = mInfos, errs, i]
+ (LocationError err, LocApiGeofenceData data) {
+ if (LOCATION_ERROR_SUCCESS == err) {
+ mAdapter.saveGeofenceItem(mClient,
+ mIds[i],
+ data.hwId,
+ mOptions[i],
+ mInfos[i]);
+ }
+ errs[i] = err;
+
+ // Send aggregated response on last item and cleanup
+ if (i == mCount-1) {
+ mAdapter.reportResponse(mClient, mCount, errs, mIds);
+ delete[] errs;
+ delete[] mIds;
+ delete[] mOptions;
+ delete[] mInfos;
+ }
+ }));
+ }
+ }
+ }
+ };
+
+ if (0 == count) {
+ return NULL;
+ }
+ uint32_t* ids = new uint32_t[count];
+ if (nullptr == ids) {
+ LOC_LOGE("%s]: new failed to allocate ids", __func__);
+ return NULL;
+ }
+ if (NULL != ids) {
+ for (size_t i=0; i < count; ++i) {
+ ids[i] = generateSessionId();
+ }
+ }
+ GeofenceOption* optionsCopy;
+ if (options == NULL) {
+ optionsCopy = NULL;
+ } else {
+ optionsCopy = new GeofenceOption[count];
+ if (nullptr == optionsCopy) {
+ LOC_LOGE("%s]: new failed to allocate optionsCopy", __func__);
+ return NULL;
+ }
+ COPY_IF_NOT_NULL(optionsCopy, options, count);
+ }
+ GeofenceInfo* infosCopy;
+ if (infos == NULL) {
+ infosCopy = NULL;
+ } else {
+ infosCopy = new GeofenceInfo[count];
+ if (nullptr == infosCopy) {
+ LOC_LOGE("%s]: new failed to allocate infosCopy", __func__);
+ return NULL;
+ }
+ COPY_IF_NOT_NULL(infosCopy, infos, count);
+ }
+
+ sendMsg(new MsgAddGeofences(*this, *mLocApi, client, count, ids, optionsCopy, infosCopy));
+ return ids;
+}
+
+void
+GeofenceAdapter::removeGeofencesCommand(LocationAPI* client, size_t count, uint32_t* ids)
+{
+ LOC_LOGD("%s]: client %p count %zu", __func__, client, count);
+
+ struct MsgRemoveGeofences : public LocMsg {
+ GeofenceAdapter& mAdapter;
+ LocApiBase& mApi;
+ LocationAPI* mClient;
+ size_t mCount;
+ uint32_t* mIds;
+ inline MsgRemoveGeofences(GeofenceAdapter& adapter,
+ LocApiBase& api,
+ LocationAPI* client,
+ size_t count,
+ uint32_t* ids) :
+ LocMsg(),
+ mAdapter(adapter),
+ mApi(api),
+ mClient(client),
+ mCount(count),
+ mIds(ids) {}
+ inline virtual void proc() const {
+ LocationError* errs = new LocationError[mCount];
+ if (nullptr == errs) {
+ LOC_LOGE("%s]: new failed to allocate errs", __func__);
+ return;
+ }
+ for (size_t i=0; i < mCount; ++i) {
+ mApi.addToCallQueue(new LocApiResponse(*mAdapter.getContext(),
+ [&mAdapter = mAdapter, mCount = mCount, mClient = mClient, mIds = mIds,
+ &mApi = mApi, errs, i] (LocationError err ) {
+ uint32_t hwId = 0;
+ errs[i] = mAdapter.getHwIdFromClient(mClient, mIds[i], hwId);
+ if (LOCATION_ERROR_SUCCESS == errs[i]) {
+ mApi.removeGeofence(hwId, mIds[i],
+ new LocApiResponse(*mAdapter.getContext(),
+ [&mAdapter = mAdapter, mCount = mCount, mClient = mClient, mIds = mIds,
+ hwId, errs, i] (LocationError err ) {
+ if (LOCATION_ERROR_SUCCESS == err) {
+ mAdapter.removeGeofenceItem(hwId);
+ }
+ errs[i] = err;
+
+ // Send aggregated response on last item and cleanup
+ if (i == mCount-1) {
+ mAdapter.reportResponse(mClient, mCount, errs, mIds);
+ delete[] errs;
+ delete[] mIds;
+ }
+ }));
+ } else {
+ // Send aggregated response on last item and cleanup
+ if (i == mCount-1) {
+ mAdapter.reportResponse(mClient, mCount, errs, mIds);
+ delete[] errs;
+ delete[] mIds;
+ }
+ }
+ }));
+ }
+ }
+ };
+
+ if (0 == count) {
+ return;
+ }
+ uint32_t* idsCopy = new uint32_t[count];
+ if (nullptr == idsCopy) {
+ LOC_LOGE("%s]: new failed to allocate idsCopy", __func__);
+ return;
+ }
+ COPY_IF_NOT_NULL(idsCopy, ids, count);
+ sendMsg(new MsgRemoveGeofences(*this, *mLocApi, client, count, idsCopy));
+}
+
+void
+GeofenceAdapter::pauseGeofencesCommand(LocationAPI* client, size_t count, uint32_t* ids)
+{
+ LOC_LOGD("%s]: client %p count %zu", __func__, client, count);
+
+ struct MsgPauseGeofences : public LocMsg {
+ GeofenceAdapter& mAdapter;
+ LocApiBase& mApi;
+ LocationAPI* mClient;
+ size_t mCount;
+ uint32_t* mIds;
+ inline MsgPauseGeofences(GeofenceAdapter& adapter,
+ LocApiBase& api,
+ LocationAPI* client,
+ size_t count,
+ uint32_t* ids) :
+ LocMsg(),
+ mAdapter(adapter),
+ mApi(api),
+ mClient(client),
+ mCount(count),
+ mIds(ids) {}
+ inline virtual void proc() const {
+ LocationError* errs = new LocationError[mCount];
+ if (nullptr == errs) {
+ LOC_LOGE("%s]: new failed to allocate errs", __func__);
+ return;
+ }
+ for (size_t i=0; i < mCount; ++i) {
+ mApi.addToCallQueue(new LocApiResponse(*mAdapter.getContext(),
+ [&mAdapter = mAdapter, mCount = mCount, mClient = mClient, mIds = mIds,
+ &mApi = mApi, errs, i] (LocationError err ) {
+ uint32_t hwId = 0;
+ errs[i] = mAdapter.getHwIdFromClient(mClient, mIds[i], hwId);
+ if (LOCATION_ERROR_SUCCESS == errs[i]) {
+ mApi.pauseGeofence(hwId, mIds[i], new LocApiResponse(*mAdapter.getContext(),
+ [&mAdapter = mAdapter, mCount = mCount, mClient = mClient, mIds = mIds,
+ hwId, errs, i] (LocationError err ) {
+ if (LOCATION_ERROR_SUCCESS == err) {
+ mAdapter.pauseGeofenceItem(hwId);
+ }
+ errs[i] = err;
+
+ // Send aggregated response on last item and cleanup
+ if (i == mCount-1) {
+ mAdapter.reportResponse(mClient, mCount, errs, mIds);
+ delete[] errs;
+ delete[] mIds;
+ }
+ }));
+ } else {
+ // Send aggregated response on last item and cleanup
+ if (i == mCount-1) {
+ mAdapter.reportResponse(mClient, mCount, errs, mIds);
+ delete[] errs;
+ delete[] mIds;
+ }
+ }
+ }));
+ }
+ }
+ };
+
+ if (0 == count) {
+ return;
+ }
+ uint32_t* idsCopy = new uint32_t[count];
+ if (nullptr == idsCopy) {
+ LOC_LOGE("%s]: new failed to allocate idsCopy", __func__);
+ return;
+ }
+ COPY_IF_NOT_NULL(idsCopy, ids, count);
+ sendMsg(new MsgPauseGeofences(*this, *mLocApi, client, count, idsCopy));
+}
+
+void
+GeofenceAdapter::resumeGeofencesCommand(LocationAPI* client, size_t count, uint32_t* ids)
+{
+ LOC_LOGD("%s]: client %p count %zu", __func__, client, count);
+
+ struct MsgResumeGeofences : public LocMsg {
+ GeofenceAdapter& mAdapter;
+ LocApiBase& mApi;
+ LocationAPI* mClient;
+ size_t mCount;
+ uint32_t* mIds;
+ inline MsgResumeGeofences(GeofenceAdapter& adapter,
+ LocApiBase& api,
+ LocationAPI* client,
+ size_t count,
+ uint32_t* ids) :
+ LocMsg(),
+ mAdapter(adapter),
+ mApi(api),
+ mClient(client),
+ mCount(count),
+ mIds(ids) {}
+ inline virtual void proc() const {
+ LocationError* errs = new LocationError[mCount];
+ if (nullptr == errs) {
+ LOC_LOGE("%s]: new failed to allocate errs", __func__);
+ return;
+ }
+ for (size_t i=0; i < mCount; ++i) {
+ mApi.addToCallQueue(new LocApiResponse(*mAdapter.getContext(),
+ [&mAdapter = mAdapter, mCount = mCount, mClient = mClient, mIds = mIds,
+ &mApi = mApi, errs, i] (LocationError err ) {
+ uint32_t hwId = 0;
+ errs[i] = mAdapter.getHwIdFromClient(mClient, mIds[i], hwId);
+ if (LOCATION_ERROR_SUCCESS == errs[i]) {
+ mApi.resumeGeofence(hwId, mIds[i],
+ new LocApiResponse(*mAdapter.getContext(),
+ [&mAdapter = mAdapter, mCount = mCount, mClient = mClient, hwId,
+ errs, mIds = mIds, i] (LocationError err ) {
+ if (LOCATION_ERROR_SUCCESS == err) {
+ errs[i] = err;
+
+ mAdapter.resumeGeofenceItem(hwId);
+ // Send aggregated response on last item and cleanup
+ if (i == mCount-1) {
+ mAdapter.reportResponse(mClient, mCount, errs, mIds);
+ delete[] errs;
+ delete[] mIds;
+ }
+ }
+ }));
+ } else {
+ // Send aggregated response on last item and cleanup
+ if (i == mCount-1) {
+ mAdapter.reportResponse(mClient, mCount, errs, mIds);
+ delete[] errs;
+ delete[] mIds;
+ }
+ }
+ }));
+ }
+ }
+ };
+
+ if (0 == count) {
+ return;
+ }
+ uint32_t* idsCopy = new uint32_t[count];
+ if (nullptr == idsCopy) {
+ LOC_LOGE("%s]: new failed to allocate idsCopy", __func__);
+ return;
+ }
+ COPY_IF_NOT_NULL(idsCopy, ids, count);
+ sendMsg(new MsgResumeGeofences(*this, *mLocApi, client, count, idsCopy));
+}
+
+void
+GeofenceAdapter::modifyGeofencesCommand(LocationAPI* client, size_t count, uint32_t* ids,
+ GeofenceOption* options)
+{
+ LOC_LOGD("%s]: client %p count %zu", __func__, client, count);
+
+ struct MsgModifyGeofences : public LocMsg {
+ GeofenceAdapter& mAdapter;
+ LocApiBase& mApi;
+ LocationAPI* mClient;
+ size_t mCount;
+ uint32_t* mIds;
+ GeofenceOption* mOptions;
+ inline MsgModifyGeofences(GeofenceAdapter& adapter,
+ LocApiBase& api,
+ LocationAPI* client,
+ size_t count,
+ uint32_t* ids,
+ GeofenceOption* options) :
+ LocMsg(),
+ mAdapter(adapter),
+ mApi(api),
+ mClient(client),
+ mCount(count),
+ mIds(ids),
+ mOptions(options) {}
+ inline virtual void proc() const {
+ LocationError* errs = new LocationError[mCount];
+ if (nullptr == errs) {
+ LOC_LOGE("%s]: new failed to allocate errs", __func__);
+ return;
+ }
+ for (size_t i=0; i < mCount; ++i) {
+ if (NULL == mIds || NULL == mOptions) {
+ errs[i] = LOCATION_ERROR_INVALID_PARAMETER;
+ } else {
+ mApi.addToCallQueue(new LocApiResponse(*mAdapter.getContext(),
+ [&mAdapter = mAdapter, mCount = mCount, mClient = mClient, mIds = mIds,
+ &mApi = mApi, mOptions = mOptions, errs, i] (LocationError err ) {
+ uint32_t hwId = 0;
+ errs[i] = mAdapter.getHwIdFromClient(mClient, mIds[i], hwId);
+ if (LOCATION_ERROR_SUCCESS == errs[i]) {
+ mApi.modifyGeofence(hwId, mIds[i], mOptions[i],
+ new LocApiResponse(*mAdapter.getContext(),
+ [&mAdapter = mAdapter, mCount = mCount, mClient = mClient,
+ mIds = mIds, mOptions = mOptions, hwId, errs, i]
+ (LocationError err ) {
+ if (LOCATION_ERROR_SUCCESS == err) {
+ errs[i] = err;
+
+ mAdapter.modifyGeofenceItem(hwId, mOptions[i]);
+ }
+ // Send aggregated response on last item and cleanup
+ if (i == mCount-1) {
+ mAdapter.reportResponse(mClient, mCount, errs, mIds);
+ delete[] errs;
+ delete[] mIds;
+ delete[] mOptions;
+ }
+ }));
+ } else {
+ // Send aggregated response on last item and cleanup
+ if (i == mCount-1) {
+ mAdapter.reportResponse(mClient, mCount, errs, mIds);
+ delete[] errs;
+ delete[] mIds;
+ delete[] mOptions;
+ }
+ }
+ }));
+ }
+ }
+ }
+ };
+
+ if (0 == count) {
+ return;
+ }
+ uint32_t* idsCopy = new uint32_t[count];
+ if (nullptr == idsCopy) {
+ LOC_LOGE("%s]: new failed to allocate idsCopy", __func__);
+ return;
+ }
+ COPY_IF_NOT_NULL(idsCopy, ids, count);
+ GeofenceOption* optionsCopy;
+ if (options == NULL) {
+ optionsCopy = NULL;
+ } else {
+ optionsCopy = new GeofenceOption[count];
+ if (nullptr == optionsCopy) {
+ LOC_LOGE("%s]: new failed to allocate optionsCopy", __func__);
+ return;
+ }
+ COPY_IF_NOT_NULL(optionsCopy, options, count);
+ }
+
+ sendMsg(new MsgModifyGeofences(*this, *mLocApi, client, count, idsCopy, optionsCopy));
+}
+
+void
+GeofenceAdapter::saveGeofenceItem(LocationAPI* client, uint32_t clientId, uint32_t hwId,
+ const GeofenceOption& options, const GeofenceInfo& info)
+{
+ LOC_LOGD("%s]: hwId %u client %p clientId %u", __func__, hwId, client, clientId);
+ GeofenceKey key(client, clientId);
+ GeofenceObject object = {key,
+ options.breachTypeMask,
+ options.responsiveness,
+ options.dwellTime,
+ info.latitude,
+ info.longitude,
+ info.radius,
+ false};
+ mGeofences[hwId] = object;
+ mGeofenceIds[key] = hwId;
+ dump();
+}
+
+void
+GeofenceAdapter::removeGeofenceItem(uint32_t hwId)
+{
+ GeofenceKey key;
+ LocationError err = getGeofenceKeyFromHwId(hwId, key);
+ if (LOCATION_ERROR_SUCCESS != err) {
+ LOC_LOGE("%s]: can not find the key for hwId %u", __func__, hwId);
+ } else {
+ auto it1 = mGeofenceIds.find(key);
+ if (it1 != mGeofenceIds.end()) {
+ mGeofenceIds.erase(it1);
+
+ auto it2 = mGeofences.find(hwId);
+ if (it2 != mGeofences.end()) {
+ mGeofences.erase(it2);
+ dump();
+ } else {
+ LOC_LOGE("%s]:geofence item to erase not found. hwId %u", __func__, hwId);
+ }
+ } else {
+ LOC_LOGE("%s]: geofence item to erase not found. hwId %u", __func__, hwId);
+ }
+ }
+}
+
+void
+GeofenceAdapter::pauseGeofenceItem(uint32_t hwId)
+{
+ auto it = mGeofences.find(hwId);
+ if (it != mGeofences.end()) {
+ it->second.paused = true;
+ dump();
+ } else {
+ LOC_LOGE("%s]: geofence item to pause not found. hwId %u", __func__, hwId);
+ }
+}
+
+void
+GeofenceAdapter::resumeGeofenceItem(uint32_t hwId)
+{
+ auto it = mGeofences.find(hwId);
+ if (it != mGeofences.end()) {
+ it->second.paused = false;
+ dump();
+ } else {
+ LOC_LOGE("%s]: geofence item to resume not found. hwId %u", __func__, hwId);
+ }
+}
+
+void
+GeofenceAdapter::modifyGeofenceItem(uint32_t hwId, const GeofenceOption& options)
+{
+ auto it = mGeofences.find(hwId);
+ if (it != mGeofences.end()) {
+ it->second.breachMask = options.breachTypeMask;
+ it->second.responsiveness = options.responsiveness;
+ it->second.dwellTime = options.dwellTime;
+ dump();
+ } else {
+ LOC_LOGE("%s]: geofence item to modify not found. hwId %u", __func__, hwId);
+ }
+}
+
+
+void
+GeofenceAdapter::geofenceBreachEvent(size_t count, uint32_t* hwIds, Location& location,
+ GeofenceBreachType breachType, uint64_t timestamp)
+{
+
+ IF_LOC_LOGD {
+ std::string idsString = "[";
+ if (NULL != hwIds) {
+ for (size_t i=0; i < count; ++i) {
+ idsString += std::to_string(hwIds[i]) + " ";
+ }
+ }
+ idsString += "]";
+ LOC_LOGD("%s]: breachType %u count %zu ids %s",
+ __func__, breachType, count, idsString.c_str());
+ }
+
+ if (0 == count || NULL == hwIds)
+ return;
+
+ struct MsgGeofenceBreach : public LocMsg {
+ GeofenceAdapter& mAdapter;
+ size_t mCount;
+ uint32_t* mHwIds;
+ Location mLocation;
+ GeofenceBreachType mBreachType;
+ uint64_t mTimestamp;
+ inline MsgGeofenceBreach(GeofenceAdapter& adapter,
+ size_t count,
+ uint32_t* hwIds,
+ Location& location,
+ GeofenceBreachType breachType,
+ uint64_t timestamp) :
+ LocMsg(),
+ mAdapter(adapter),
+ mCount(count),
+ mHwIds(new uint32_t[count]),
+ mLocation(location),
+ mBreachType(breachType),
+ mTimestamp(timestamp)
+ {
+ if (nullptr == mHwIds) {
+ LOC_LOGE("%s]: new failed to allocate mHwIds", __func__);
+ return;
+ }
+ COPY_IF_NOT_NULL(mHwIds, hwIds, mCount);
+ }
+ inline virtual ~MsgGeofenceBreach() {
+ delete[] mHwIds;
+ }
+ inline virtual void proc() const {
+ mAdapter.geofenceBreach(mCount, mHwIds, mLocation, mBreachType, mTimestamp);
+ }
+ };
+
+ sendMsg(new MsgGeofenceBreach(*this, count, hwIds, location, breachType, timestamp));
+
+}
+
+void
+GeofenceAdapter::geofenceBreach(size_t count, uint32_t* hwIds, const Location& location,
+ GeofenceBreachType breachType, uint64_t timestamp)
+{
+
+ for (auto it = mClientData.begin(); it != mClientData.end(); ++it) {
+ uint32_t* clientIds = new uint32_t[count];
+ if (nullptr == clientIds) {
+ return;
+ }
+ uint32_t index = 0;
+ for (size_t i=0; i < count; ++i) {
+ GeofenceKey key;
+ LocationError err = getGeofenceKeyFromHwId(hwIds[i], key);
+ if (LOCATION_ERROR_SUCCESS == err) {
+ if (key.client == it->first) {
+ clientIds[index++] = key.id;
+ }
+ }
+ }
+ if (index > 0 && it->second.geofenceBreachCb != nullptr) {
+ GeofenceBreachNotification notify = {sizeof(GeofenceBreachNotification),
+ index,
+ clientIds,
+ location,
+ breachType,
+ timestamp};
+
+ it->second.geofenceBreachCb(notify);
+ }
+ delete[] clientIds;
+ }
+}
+
+void
+GeofenceAdapter::geofenceStatusEvent(GeofenceStatusAvailable available)
+{
+ LOC_LOGD("%s]: available %u ", __func__, available);
+
+ struct MsgGeofenceStatus : public LocMsg {
+ GeofenceAdapter& mAdapter;
+ GeofenceStatusAvailable mAvailable;
+ inline MsgGeofenceStatus(GeofenceAdapter& adapter,
+ GeofenceStatusAvailable available) :
+ LocMsg(),
+ mAdapter(adapter),
+ mAvailable(available) {}
+ inline virtual void proc() const {
+ mAdapter.geofenceStatus(mAvailable);
+ }
+ };
+
+ sendMsg(new MsgGeofenceStatus(*this, available));
+}
+
+void
+GeofenceAdapter::geofenceStatus(GeofenceStatusAvailable available)
+{
+ for (auto it = mClientData.begin(); it != mClientData.end(); ++it) {
+ if (it->second.geofenceStatusCb != nullptr) {
+ GeofenceStatusNotification notify = {sizeof(GeofenceStatusNotification),
+ available,
+ LOCATION_TECHNOLOGY_TYPE_GNSS};
+ it->second.geofenceStatusCb(notify);
+ }
+ }
+}
+
+void
+GeofenceAdapter::dump()
+{
+ IF_LOC_LOGV {
+ LOC_LOGV(
+ "HAL | hwId | mask | respon | latitude | longitude | radius | paused | Id | client");
+ for (auto it = mGeofences.begin(); it != mGeofences.end(); ++it) {
+ uint32_t hwId = it->first;
+ GeofenceObject object = it->second;
+ LOC_LOGV(" | %5u | %4u | %6u | %8.2f | %9.2f | %6.2f | %6u | %04x | %p ",
+ hwId, object.breachMask, object.responsiveness,
+ object.latitude, object.longitude, object.radius,
+ object.paused, object.key.id, object.key.client);
+ }
+ }
+}
+
diff --git a/geofence/GeofenceAdapter.h b/geofence/GeofenceAdapter.h
new file mode 100644
index 0000000..38f4823
--- /dev/null
+++ b/geofence/GeofenceAdapter.h
@@ -0,0 +1,136 @@
+/* Copyright (c) 2013-2019, 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 GEOFENCE_ADAPTER_H
+#define GEOFENCE_ADAPTER_H
+
+#include <LocAdapterBase.h>
+#include <LocContext.h>
+#include <LocationAPI.h>
+#include <map>
+
+using namespace loc_core;
+
+#define COPY_IF_NOT_NULL(dest, src, len) do { \
+ if (NULL!=dest && NULL!=src) { \
+ for (size_t i=0; i<len; ++i) { \
+ dest[i] = src[i]; \
+ } \
+ } \
+} while (0)
+
+typedef struct GeofenceKey {
+ LocationAPI* client;
+ uint32_t id;
+ inline GeofenceKey() :
+ client(NULL), id(0) {}
+ inline GeofenceKey(LocationAPI* _client, uint32_t _id) :
+ client(_client), id(_id) {}
+} GeofenceKey;
+inline bool operator <(GeofenceKey const& left, GeofenceKey const& right) {
+ return left.id < right.id || (left.id == right.id && left.client < right.client);
+}
+inline bool operator ==(GeofenceKey const& left, GeofenceKey const& right) {
+ return left.id == right.id && left.client == right.client;
+}
+inline bool operator !=(GeofenceKey const& left, GeofenceKey const& right) {
+ return left.id != right.id || left.client != right.client;
+}
+typedef struct {
+ GeofenceKey key;
+ GeofenceBreachTypeMask breachMask;
+ uint32_t responsiveness;
+ uint32_t dwellTime;
+ double latitude;
+ double longitude;
+ double radius;
+ bool paused;
+} GeofenceObject;
+typedef std::map<uint32_t, GeofenceObject> GeofencesMap; //map of hwId to GeofenceObject
+typedef std::map<GeofenceKey, uint32_t> GeofenceIdMap; //map of GeofenceKey to hwId
+
+class GeofenceAdapter : public LocAdapterBase {
+
+ /* ==== GEOFENCES ====================================================================== */
+ GeofencesMap mGeofences; //map hwId to GeofenceObject
+ GeofenceIdMap mGeofenceIds; //map of GeofenceKey to hwId
+
+protected:
+
+ /* ==== CLIENT ========================================================================= */
+ virtual void updateClientsEventMask();
+ virtual void stopClientSessions(LocationAPI* client);
+
+public:
+
+ GeofenceAdapter();
+ virtual ~GeofenceAdapter() {}
+
+ /* ==== SSR ============================================================================ */
+ /* ======== EVENTS ====(Called from QMI Thread)========================================= */
+ virtual void handleEngineUpEvent();
+ /* ======== UTILITIES ================================================================== */
+ void restartGeofences();
+
+ /* ==== GEOFENCES ====================================================================== */
+ /* ======== COMMANDS ====(Called from Client Thread)==================================== */
+ uint32_t* addGeofencesCommand(LocationAPI* client, size_t count,
+ GeofenceOption* options, GeofenceInfo* info);
+ void removeGeofencesCommand(LocationAPI* client, size_t count, uint32_t* ids);
+ void pauseGeofencesCommand(LocationAPI* client, size_t count, uint32_t* ids);
+ void resumeGeofencesCommand(LocationAPI* client, size_t count, uint32_t* ids);
+ void modifyGeofencesCommand(LocationAPI* client, size_t count, uint32_t* ids,
+ GeofenceOption* options);
+ /* ======== RESPONSES ================================================================== */
+ void reportResponse(LocationAPI* client, size_t count, LocationError* errs, uint32_t* ids);
+ /* ======== UTILITIES ================================================================== */
+ void saveGeofenceItem(LocationAPI* client,
+ uint32_t clientId,
+ uint32_t hwId,
+ const GeofenceOption& options,
+ const GeofenceInfo& info);
+ void removeGeofenceItem(uint32_t hwId);
+ void pauseGeofenceItem(uint32_t hwId);
+ void resumeGeofenceItem(uint32_t hwId);
+ void modifyGeofenceItem(uint32_t hwId, const GeofenceOption& options);
+ LocationError getHwIdFromClient(LocationAPI* client, uint32_t clientId, uint32_t& hwId);
+ LocationError getGeofenceKeyFromHwId(uint32_t hwId, GeofenceKey& key);
+ void dump();
+
+ /* ==== REPORTS ======================================================================== */
+ /* ======== EVENTS ====(Called from QMI Thread)========================================= */
+ void geofenceBreachEvent(size_t count, uint32_t* hwIds, Location& location,
+ GeofenceBreachType breachType, uint64_t timestamp);
+ void geofenceStatusEvent(GeofenceStatusAvailable available);
+ /* ======== UTILITIES ================================================================== */
+ void geofenceBreach(size_t count, uint32_t* hwIds, const Location& location,
+ GeofenceBreachType breachType, uint64_t timestamp);
+ void geofenceStatus(GeofenceStatusAvailable available);
+};
+
+#endif /* GEOFENCE_ADAPTER_H */
diff --git a/geofence/Makefile.am b/geofence/Makefile.am
new file mode 100644
index 0000000..61883ff
--- /dev/null
+++ b/geofence/Makefile.am
@@ -0,0 +1,50 @@
+AM_CFLAGS = -Wundef \
+ -Wno-trigraphs \
+ -g -O0 \
+ -fno-inline \
+ -fno-short-enums \
+ -fpic \
+ ${GPSUTILS_CFLAGS} \
+ ${LOCCORE_CFLAGS} \
+ $(LOCPLA_CFLAGS) \
+ -D__func__=__PRETTY_FUNCTION__ \
+ -std=c++1y
+
+AM_CPPFLAGS = $(AM_CFLAGS)
+
+ACLOCAL_AMFLAGS = -I m4
+
+requiredlibs = \
+ ${LOCCORE_LIBS} \
+ $(GPSUTILS_LIBS) \
+ -llog
+
+h_sources = \
+ GeofenceAdapter.h
+
+c_sources = \
+ GeofenceAdapter.cpp \
+ location_geofence.cpp
+
+libgeofencing_la_SOURCES = $(c_sources)
+if USE_GLIB
+libgeofencing_la_CFLAGS = -DUSE_GLIB @GLIB_CFLAGS@ $(AM_CFLAGS)
+libgeofencing_la_CPPFLAGS = -DUSE_GLIB @GLIB_CFLAGS@ $(AM_CFLAGS) $(AM_CPPFLAGS)
+libgeofencing_la_LDFLAGS = -lstdc++ -Wl,-z,defs @GLIB_LIBS@ $(requiredlibs) -shared -version-info 1:0:0
+libgeofencing_la_LIBDADD = $(requiredlibs) -lstdc++ @GLIB_LIBS@
+else
+libgeofencing_la_CFLAGS = $(AM_CFLAGS)
+libgeofencing_la_CPPFLAGS = $(AM_CFLAGS) $(AM_CPPFLAGS)
+libgeofencing_la_LDFLAGS = -lstdc++ -Wl,-z,defs $(requiredlibs) -shared -version-info 1:0:0
+libgeofencing_la_LIBDADD = $(requiredlibs) -lstdc++
+endif
+
+library_include_HEADERS = $(h_sources)
+
+library_includedir = $(pkgincludedir)
+
+lib_LTLIBRARIES = libgeofencing.la
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = location-geofence.pc
+EXTRA_DIST = $(pkgconfig_DATA)
diff --git a/geofence/configure.ac b/geofence/configure.ac
new file mode 100644
index 0000000..8e3cd81
--- /dev/null
+++ b/geofence/configure.ac
@@ -0,0 +1,72 @@
+AC_PREREQ(2.61)
+AC_INIT([location-geofence], 1.0.0)
+AM_INIT_AUTOMAKE([foreign])
+AC_CONFIG_SRCDIR([Makefile.am])
+AC_CONFIG_HEADERS([config.h])
+AC_CONFIG_MACRO_DIR([m4])
+
+# Check for programs
+AC_PROG_LIBTOOL
+AC_PROG_CXX
+AC_PROG_CC
+AM_PROG_CC_C_O
+AC_PROG_AWK
+AC_PROG_CPP
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+PKG_PROG_PKG_CONFIG
+
+# Check for libraries
+PKG_CHECK_MODULES([GPSUTILS], [gps-utils])
+AC_SUBST([GPSUTILS_CFLAGS])
+AC_SUBST([GPSUTILS_LIBS])
+
+PKG_CHECK_MODULES([LOCCORE], [loc-core])
+AC_SUBST([LOCCORE_CFLAGS])
+AC_SUBST([LOCCORE_LIBS])
+
+AS_CASE([$host],
+ [arm*], [ARM=yes],
+ [ARM=no]
+)
+
+AC_ARG_WITH([locpla_includes],
+ AC_HELP_STRING([--with-locpla-includes=@<:@dir@:>@],
+ [specify the path to locpla-includes in loc-pla_git.bb]),
+ [locpla_incdir=$withval],
+ with_locpla_includes=no)
+
+if test "x$with_locpla_includes" != "xno"; then
+ AC_SUBST(LOCPLA_CFLAGS, "-I${locpla_incdir}")
+fi
+
+AC_ARG_WITH([glib],
+ AC_HELP_STRING([--with-glib],
+ [enable glib, building HLOS systems which use glib]))
+
+if (test "x${with_glib}" = "xyes"); then
+ AC_DEFINE(ENABLE_USEGLIB, 1, [Define if HLOS systems uses glib])
+ PKG_CHECK_MODULES(GTHREAD, gthread-2.0 >= 2.16, dummy=yes,
+ AC_MSG_ERROR(GThread >= 2.16 is required))
+ PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.16, dummy=yes,
+ AC_MSG_ERROR(GLib >= 2.16 is required))
+ GLIB_CFLAGS="$GLIB_CFLAGS $GTHREAD_CFLAGS"
+ GLIB_LIBS="$GLIB_LIBS $GTHREAD_LIBS"
+
+ AC_SUBST(GLIB_CFLAGS)
+ AC_SUBST(GLIB_LIBS)
+fi
+
+AM_CONDITIONAL(USE_GLIB, test "x${with_glib}" = "xyes")
+
+AC_SUBST([CFLAGS])
+AC_SUBST([CPPFLAGS])
+AC_SUBST([LIBS])
+
+AC_CONFIG_FILES([ \
+ Makefile \
+ location-geofence.pc
+ ])
+
+AC_OUTPUT
diff --git a/geofence/location-geofence.pc.in b/geofence/location-geofence.pc.in
new file mode 100644
index 0000000..6a0781f
--- /dev/null
+++ b/geofence/location-geofence.pc.in
@@ -0,0 +1,10 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: location-geofence
+Description: QTI GPS Geofence
+Version: @VERSION
+Libs: -L${libdir} -lgeofencing
+Cflags: -I${includedir}/location-geofence
diff --git a/geofence/location_geofence.cpp b/geofence/location_geofence.cpp
new file mode 100644
index 0000000..66729f4
--- /dev/null
+++ b/geofence/location_geofence.cpp
@@ -0,0 +1,145 @@
+/* Copyright (c) 2017-2019, 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.
+ *
+ */
+#include "GeofenceAdapter.h"
+#include "location_interface.h"
+
+static GeofenceAdapter* gGeofenceAdapter = NULL;
+
+static void initialize();
+static void deinitialize();
+
+static void addClient(LocationAPI* client, const LocationCallbacks& callbacks);
+static void removeClient(LocationAPI* client, removeClientCompleteCallback rmClientCb);
+static void requestCapabilities(LocationAPI* client);
+
+static uint32_t* addGeofences(LocationAPI* client, size_t count, GeofenceOption*, GeofenceInfo*);
+static void removeGeofences(LocationAPI* client, size_t count, uint32_t* ids);
+static void modifyGeofences(LocationAPI* client, size_t count, uint32_t* ids,
+ GeofenceOption* options);
+static void pauseGeofences(LocationAPI* client, size_t count, uint32_t* ids);
+static void resumeGeofences(LocationAPI* client, size_t count, uint32_t* ids);
+
+static const GeofenceInterface gGeofenceInterface = {
+ sizeof(GeofenceInterface),
+ initialize,
+ deinitialize,
+ addClient,
+ removeClient,
+ requestCapabilities,
+ addGeofences,
+ removeGeofences,
+ modifyGeofences,
+ pauseGeofences,
+ resumeGeofences
+};
+
+#ifndef DEBUG_X86
+extern "C" const GeofenceInterface* getGeofenceInterface()
+#else
+const GeofenceInterface* getGeofenceInterface()
+#endif // DEBUG_X86
+{
+ return &gGeofenceInterface;
+}
+
+static void initialize()
+{
+ if (NULL == gGeofenceAdapter) {
+ gGeofenceAdapter = new GeofenceAdapter();
+ }
+}
+
+static void deinitialize()
+{
+ if (NULL != gGeofenceAdapter) {
+ delete gGeofenceAdapter;
+ gGeofenceAdapter = NULL;
+ }
+}
+
+static void addClient(LocationAPI* client, const LocationCallbacks& callbacks)
+{
+ if (NULL != gGeofenceAdapter) {
+ gGeofenceAdapter->addClientCommand(client, callbacks);
+ }
+}
+
+static void removeClient(LocationAPI* client, removeClientCompleteCallback rmClientCb)
+{
+ if (NULL != gGeofenceAdapter) {
+ gGeofenceAdapter->removeClientCommand(client, rmClientCb);
+ }
+}
+
+static void requestCapabilities(LocationAPI* client)
+{
+ if (NULL != gGeofenceAdapter) {
+ gGeofenceAdapter->requestCapabilitiesCommand(client);
+ }
+}
+
+static uint32_t* addGeofences(LocationAPI* client, size_t count,
+ GeofenceOption* options, GeofenceInfo* info)
+{
+ if (NULL != gGeofenceAdapter) {
+ return gGeofenceAdapter->addGeofencesCommand(client, count, options, info);
+ } else {
+ return NULL;
+ }
+}
+
+static void removeGeofences(LocationAPI* client, size_t count, uint32_t* ids)
+{
+ if (NULL != gGeofenceAdapter) {
+ return gGeofenceAdapter->removeGeofencesCommand(client, count, ids);
+ }
+}
+
+static void modifyGeofences(LocationAPI* client, size_t count, uint32_t* ids,
+ GeofenceOption* options)
+{
+ if (NULL != gGeofenceAdapter) {
+ return gGeofenceAdapter->modifyGeofencesCommand(client, count, ids, options);
+ }
+}
+
+static void pauseGeofences(LocationAPI* client, size_t count, uint32_t* ids)
+{
+ if (NULL != gGeofenceAdapter) {
+ return gGeofenceAdapter->pauseGeofencesCommand(client, count, ids);
+ }
+}
+
+static void resumeGeofences(LocationAPI* client, size_t count, uint32_t* ids)
+{
+ if (NULL != gGeofenceAdapter) {
+ return gGeofenceAdapter->resumeGeofencesCommand(client, count, ids);
+ }
+}
+
diff --git a/gnss/Agps.cpp b/gnss/Agps.cpp
index a4f6a30..9de1329 100644
--- a/gnss/Agps.cpp
+++ b/gnss/Agps.cpp
@@ -445,15 +445,14 @@ void AgpsStateMachine::setAPN(char* apn, unsigned int len){
if (NULL != mAPN) {
delete mAPN;
+ mAPN = NULL;
}
- if (apn == NULL || len <= 0) {
+ if (NULL == apn || len <= 0 || len > MAX_APN_LEN || strlen(apn) != len) {
LOC_LOGD("Invalid apn len (%d) or null apn", len);
mAPN = NULL;
mAPNLen = 0;
- }
-
- if (NULL != apn) {
+ } else {
mAPN = new char[len+1];
if (NULL != mAPN) {
memcpy(mAPN, apn, len);
diff --git a/gnss/GnssAdapter.cpp b/gnss/GnssAdapter.cpp
index 016356b..3563ed0 100644
--- a/gnss/GnssAdapter.cpp
+++ b/gnss/GnssAdapter.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019, 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
@@ -50,6 +50,7 @@
#define RAD2DEG (180.0 / M_PI)
#define PROCESS_NAME_ENGINE_SERVICE "engine-service"
+#define MIN_TRACKING_INTERVAL (100) // 100 msec
using namespace loc_core;
@@ -63,9 +64,9 @@ static void agpsCloseResultCb (bool isSuccess, AGpsExtType agpsType, void* userD
GnssAdapter::GnssAdapter() :
LocAdapterBase(0,
- LocDualContext::getLocFgContext(NULL,
+ LocContext::getLocContext(NULL,
NULL,
- LocDualContext::mLocationHalName,
+ LocContext::mLocationHalName,
false), true, nullptr),
mEngHubProxy(new EngineHubProxyBase()),
mLocPositionMode(),
@@ -87,8 +88,13 @@ GnssAdapter::GnssAdapter() :
mSystemStatus(SystemStatus::getInstance(mMsgTask)),
mServerUrl(":"),
mXtraObserver(mSystemStatus->getOsObserver(), mMsgTask),
+ mLocSystemInfo{},
mBlockCPIInfo{},
- mLocSystemInfo{}
+ mNfwCb(NULL),
+ mPowerOn(false),
+ mAllowFlpNetworkFixes(0),
+ mGnssEnergyConsumedCb(nullptr),
+ mPowerStateCb(nullptr)
{
LOC_LOGD("%s]: Constructor %p", __func__, this);
mLocPositionMode.mode = LOC_POSITION_MODE_INVALID;
@@ -428,37 +434,7 @@ GnssAdapter::convertLocationInfo(GnssLocationInfoNotification& out,
}
}
-inline uint32_t
-GnssAdapter::convertGpsLock(const GnssConfigGpsLock gpsLock)
-{
- switch (gpsLock) {
- case GNSS_CONFIG_GPS_LOCK_MO:
- return 1;
- case GNSS_CONFIG_GPS_LOCK_NI:
- return 2;
- case GNSS_CONFIG_GPS_LOCK_MO_AND_NI:
- return 3;
- case GNSS_CONFIG_GPS_LOCK_NONE:
- default:
- return 0;
- }
-}
-inline GnssConfigGpsLock
-GnssAdapter::convertGpsLock(const uint32_t gpsLock)
-{
- switch (gpsLock) {
- case 1:
- return GNSS_CONFIG_GPS_LOCK_MO;
- case 2:
- return GNSS_CONFIG_GPS_LOCK_NI;
- case 3:
- return GNSS_CONFIG_GPS_LOCK_MO_AND_NI;
- case 0:
- default:
- return GNSS_CONFIG_GPS_LOCK_NONE;
- }
-}
inline uint32_t
GnssAdapter::convertSuplVersion(const GnssConfigSuplVersion suplVersion)
@@ -598,8 +574,21 @@ GnssAdapter::readConfigCommand()
mAdapter(adapter),
mContext(context) {}
inline virtual void proc() const {
- // reads config into mContext->mGps_conf
- mContext.readConfig();
+ static bool confReadDone = false;
+ if (!confReadDone) {
+ confReadDone = true;
+ // reads config into mContext->mGps_conf
+ mContext.readConfig();
+
+ uint32_t allowFlpNetworkFixes = 0;
+ static const loc_param_s_type flp_conf_param_table[] =
+ {
+ {"ALLOW_NETWORK_FIXES", &allowFlpNetworkFixes, NULL, 'n'},
+ };
+ UTIL_READ_CONF(LOC_PATH_FLP_CONF, flp_conf_param_table);
+ LOC_LOGd("allowFlpNetworkFixes %u", allowFlpNetworkFixes);
+ mAdapter->setAllowFlpNetworkFixes(allowFlpNetworkFixes);
+ }
}
};
@@ -654,7 +643,10 @@ GnssAdapter::setConfigCommand()
mAdapter(adapter),
mApi(api) {}
inline virtual void proc() const {
-
+ if (!mAdapter.isEngineCapabilitiesKnown()) {
+ mAdapter.mPendingMsgs.push_back(new MsgSetConfig(*this));
+ return;
+ }
// set nmea mask type
uint32_t mask = 0;
if (NMEA_PROVIDER_MP == ContextBase::mGps_conf.NMEA_PROVIDER) {
@@ -681,45 +673,36 @@ GnssAdapter::setConfigCommand()
mApi.sendMsg(new LocApiMsg(
[&adapter, gpsConf, sapConf, oldServerUrl, oldMoServerUrl] () {
-
- std::string serverUrl = adapter.getServerUrl();
- std::string moServerUrl = adapter.getMoServerUrl();
- int serverUrlLen = serverUrl.length();
- int moServerUrlLen = moServerUrl.length();
-
- if (gpsConf.AGPS_CONFIG_INJECT) {
- adapter.mLocApi->setSUPLVersionSync(
- adapter.mLocApi->convertSuplVersion(gpsConf.SUPL_VER));
- adapter.mLocApi->setLPPConfigSync(
- adapter.mLocApi->convertLppProfile(gpsConf.LPP_PROFILE));
- adapter.mLocApi->setAGLONASSProtocolSync(
- gpsConf.A_GLONASS_POS_PROTOCOL_SELECT);
+ //cache the injected configuration with GnssConfigRequested struct
+ GnssConfig gnssConfigRequested = {};
+ gnssConfigRequested.flags |= GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT |
+ GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT |
+ GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT |
+ GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT;
+ gnssConfigRequested.gpsLock = GNSS_CONFIG_GPS_LOCK_NONE;
+ if (0 == adapter.getAfwControlId() || NULL != adapter.mNfwCb) {
+ gnssConfigRequested.gpsLock = gpsConf.GPS_LOCK;
}
- if ((serverUrlLen !=0) && (oldServerUrl.compare(serverUrl) != 0)) {
- LocationError locErr =
- adapter.mLocApi->setServerSync(serverUrl.c_str(), serverUrlLen,
- LOC_AGPS_SUPL_SERVER);
- if (locErr != LOCATION_ERROR_SUCCESS) {
- LOC_LOGe("Error while setting SUPL_HOST server:%s",
- serverUrl.c_str());
- }
- }
- if ((moServerUrlLen != 0) && (oldMoServerUrl.compare(moServerUrl) != 0)) {
- LocationError locErr =
- adapter.mLocApi->setServerSync(moServerUrl.c_str(),
- moServerUrlLen,
- LOC_AGPS_MO_SUPL_SERVER);
- if (locErr != LOCATION_ERROR_SUCCESS) {
- LOC_LOGe("Error while setting MO SUPL_HOST server:%s",
- moServerUrl.c_str());
- }
+ if (gpsConf.AGPS_CONFIG_INJECT) {
+ gnssConfigRequested.flags |= GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT |
+ GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT |
+ GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT;
+ gnssConfigRequested.suplVersion =
+ adapter.mLocApi->convertSuplVersion(gpsConf.SUPL_VER);
+ gnssConfigRequested.lppProfile =
+ adapter.mLocApi->convertLppProfile(gpsConf.LPP_PROFILE);
+ gnssConfigRequested.aGlonassPositionProtocolMask =
+ gpsConf.A_GLONASS_POS_PROTOCOL_SELECT;
}
-
- adapter.mLocApi->setLPPeProtocolCpSync(
- adapter.mLocApi->convertLppeCp(gpsConf.LPPE_CP_TECHNOLOGY));
- adapter.mLocApi->setLPPeProtocolUpSync(
- adapter.mLocApi->convertLppeUp(gpsConf.LPPE_UP_TECHNOLOGY));
+ gnssConfigRequested.lppeControlPlaneMask =
+ adapter.mLocApi->convertLppeCp(gpsConf.LPPE_CP_TECHNOLOGY);
+ gnssConfigRequested.lppeUserPlaneMask =
+ adapter.mLocApi->convertLppeUp(gpsConf.LPPE_UP_TECHNOLOGY);
+ gnssConfigRequested.blacklistedSvIds.assign(adapter.mBlacklistedSvIds.begin(),
+ adapter.mBlacklistedSvIds.end());
+ adapter.gnssUpdateConfig(oldServerUrl, oldMoServerUrl, gnssConfigRequested,
+ gnssConfigRequested);
// set nmea mask type
uint32_t mask = 0;
@@ -778,6 +761,192 @@ GnssAdapter::setConfigCommand()
sendMsg(new MsgSetConfig(*this, *mLocApi));
}
+std::vector<LocationError> GnssAdapter::gnssUpdateConfig(const std::string& oldServerUrl,
+ const std::string& oldMoServerUrl, const GnssConfig& gnssConfigRequested,
+ const GnssConfig& gnssConfigNeedEngineUpdate, size_t count) {
+ loc_gps_cfg_s gpsConf = ContextBase::mGps_conf;
+ size_t index = 0;
+ LocationError err = LOCATION_ERROR_SUCCESS;
+ std::vector<LocationError> errsList = {err};
+ if (count > 0) {
+ errsList.insert(errsList.begin(), count, LOCATION_ERROR_SUCCESS);
+ }
+
+
+ std::string serverUrl = getServerUrl();
+ std::string moServerUrl = getMoServerUrl();
+
+ int serverUrlLen = serverUrl.length();
+ int moServerUrlLen = moServerUrl.length();
+
+ if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT) {
+ if (gnssConfigNeedEngineUpdate.flags & GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT) {
+ err = mLocApi->setGpsLockSync(gnssConfigRequested.gpsLock);
+ if (index < count) {
+ errsList[index] = err;
+ }
+ }
+ index++;
+ }
+
+ if (gnssConfigRequested.flags &
+ GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT) {
+ if (gnssConfigNeedEngineUpdate.flags &
+ GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT) {
+ if (gnssConfigNeedEngineUpdate.assistanceServer.type ==
+ GNSS_ASSISTANCE_TYPE_SUPL) {
+ if ((serverUrlLen != 0) && (oldServerUrl.compare(serverUrl) !=0)) {
+
+ err = mLocApi->setServerSync(
+ serverUrl.c_str(), serverUrlLen, LOC_AGPS_SUPL_SERVER);
+ if (index < count) {
+ errsList[index] = err;
+ }
+ }
+ if ((moServerUrlLen != 0) && (oldMoServerUrl.compare(moServerUrl) != 0)) {
+ LocationError locErr =
+ mLocApi->setServerSync(moServerUrl.c_str(),
+ moServerUrlLen,
+ LOC_AGPS_MO_SUPL_SERVER);
+ if (locErr != LOCATION_ERROR_SUCCESS) {
+ LOC_LOGe("Error while setting MO SUPL_HOST server:%s",
+ moServerUrl.c_str());
+ }
+ }
+ } else if (gnssConfigNeedEngineUpdate.assistanceServer.type ==
+ GNSS_ASSISTANCE_TYPE_C2K) {
+ struct in_addr addr;
+ struct hostent* hp;
+ bool resolveAddrSuccess = true;
+
+ hp = gethostbyname(
+ gnssConfigNeedEngineUpdate.assistanceServer.hostName);
+ if (hp != NULL) { /* DNS OK */
+ memcpy(&addr, hp->h_addr_list[0], hp->h_length);
+ } else {
+ /* Try IP representation */
+ if (inet_aton(
+ gnssConfigNeedEngineUpdate.assistanceServer.hostName,
+ &addr) == 0) {
+ /* IP not valid */
+ LOC_LOGE("%s]: hostname '%s' cannot be resolved ",
+ __func__,
+ gnssConfigNeedEngineUpdate.assistanceServer.hostName);
+ if (index < count) {
+ errsList[index] = LOCATION_ERROR_INVALID_PARAMETER;
+ }
+ } else {
+ resolveAddrSuccess = false;
+ }
+ }
+
+ if (resolveAddrSuccess) {
+ unsigned int ip = htonl(addr.s_addr);
+ err = mLocApi->setServerSync(ip,
+ gnssConfigNeedEngineUpdate.assistanceServer.port,
+ LOC_AGPS_CDMA_PDE_SERVER);
+ if (index < count) {
+ errsList[index] = err;
+ }
+ }
+ }
+ }
+ index++;
+ }
+
+ if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT) {
+ if (gnssConfigNeedEngineUpdate.flags &
+ GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT) {
+ err = mLocApi->setSUPLVersionSync(gnssConfigRequested.suplVersion);
+ if (index < count) {
+ errsList[index] = err;
+ }
+ }
+ index++;
+ }
+
+ if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT) {
+ if (gnssConfigNeedEngineUpdate.flags &
+ GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT) {
+ err = mLocApi->setLPPConfigSync(gnssConfigRequested.lppProfile);
+ if (index < count) {
+ errsList[index] = err;
+ }
+ }
+ index++;
+ }
+
+ if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT) {
+ if (gnssConfigNeedEngineUpdate.flags &
+ GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT) {
+ err = mLocApi->setLPPeProtocolCpSync(
+ gnssConfigRequested.lppeControlPlaneMask);
+ if (index < count) {
+ errsList[index] = err;
+ }
+ }
+ index++;
+ }
+
+ if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT) {
+ if (gnssConfigNeedEngineUpdate.flags &
+ GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT) {
+ err = mLocApi->setLPPeProtocolUpSync(
+ gnssConfigRequested.lppeUserPlaneMask);
+ if (index < count) {
+ errsList[index] = err;
+ }
+ }
+ index++;
+ }
+
+ if (gnssConfigRequested.flags &
+ GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT) {
+ if (gnssConfigNeedEngineUpdate.flags &
+ GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT) {
+ err = mLocApi->setAGLONASSProtocolSync(
+ gnssConfigRequested.aGlonassPositionProtocolMask);
+ if (index < count) {
+ errsList[index] = err;
+ }
+ }
+ index++;
+ }
+ if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT) {
+ // Check if feature is supported
+ if (!ContextBase::isFeatureSupported(
+ LOC_SUPPORTED_FEATURE_CONSTELLATION_ENABLEMENT_V02)) {
+ LOC_LOGe("Feature constellation enablement not supported.");
+ err = LOCATION_ERROR_NOT_SUPPORTED;
+ } else {
+ // Send the SV ID Config to Modem
+ mBlacklistedSvIds.assign(gnssConfigRequested.blacklistedSvIds.begin(),
+ gnssConfigRequested.blacklistedSvIds.end());
+ err = gnssSvIdConfigUpdateSync(gnssConfigRequested.blacklistedSvIds);
+ if (LOCATION_ERROR_SUCCESS != err) {
+ LOC_LOGe("Failed to send config to modem, err %d", err);
+ }
+ }
+ if (index < count) {
+ errsList[index] = err;
+ }
+ index++;
+ }
+ if (gnssConfigRequested.flags &
+ GNSS_CONFIG_FLAGS_EMERGENCY_EXTENSION_SECONDS_BIT) {
+ if (gnssConfigNeedEngineUpdate.flags &
+ GNSS_CONFIG_FLAGS_EMERGENCY_EXTENSION_SECONDS_BIT) {
+ err = mLocApi->setEmergencyExtensionWindowSync(
+ gnssConfigRequested.emergencyExtensionSeconds);
+ if (index < count) {
+ errsList[index] = err;
+ }
+ }
+ index++;
+ }
+ return errsList;
+}
+
uint32_t*
GnssAdapter::gnssUpdateConfigCommand(GnssConfig config)
{
@@ -832,7 +1001,10 @@ GnssAdapter::gnssUpdateConfigCommand(GnssConfig config)
}
inline virtual void proc() const {
-
+ if (!mAdapter.isEngineCapabilitiesKnown()) {
+ mAdapter.mPendingMsgs.push_back(new MsgGnssUpdateConfig(*this));
+ return;
+ }
GnssAdapter& adapter = mAdapter;
size_t countOfConfigs = mCount;
GnssConfig gnssConfigRequested = mConfig;
@@ -845,14 +1017,15 @@ GnssAdapter::gnssUpdateConfigCommand(GnssConfig config)
int index = 0;
if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT) {
- uint32_t newGpsLock = mAdapter.convertGpsLock(gnssConfigRequested.gpsLock);
- ContextBase::mGps_conf.GPS_LOCK = newGpsLock;
- if (0 == ContextBase::mGps_conf.GPS_LOCK) {
- ContextBase::mGps_conf.GPS_LOCK = 3;
+ GnssConfigGpsLock newGpsLock = gnssConfigRequested.gpsLock;
+ if (GNSS_CONFIG_GPS_LOCK_NONE == newGpsLock) {
+ newGpsLock = GNSS_CONFIG_GPS_LOCK_MO;
}
- if (0 != mAdapter.getPowerVoteId()) {
+ if (newGpsLock == ContextBase::mGps_conf.GPS_LOCK ||
+ 0 != mAdapter.getAfwControlId()) {
gnssConfigNeedEngineUpdate.flags &= ~(GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT);
}
+ ContextBase::mGps_conf.GPS_LOCK = newGpsLock;
index++;
}
if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT) {
@@ -924,24 +1097,24 @@ GnssAdapter::gnssUpdateConfigCommand(GnssConfig config)
~(GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT);
}
index++;
- }
- if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT) {
+ }
+ if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT) {
uint32_t newEP4ES = mAdapter.convertEP4ES(
gnssConfigRequested.emergencyPdnForEmergencySupl);
if (newEP4ES != ContextBase::mGps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL) {
ContextBase::mGps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL = newEP4ES;
}
index++;
- }
- if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT) {
+ }
+ if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT) {
uint32_t newSuplEs = mAdapter.convertSuplEs(
gnssConfigRequested.suplEmergencyServices);
if (newSuplEs != ContextBase::mGps_conf.SUPL_ES) {
ContextBase::mGps_conf.SUPL_ES = newSuplEs;
}
index++;
- }
- if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_SUPL_MODE_BIT) {
+ }
+ if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_SUPL_MODE_BIT) {
uint32_t newSuplMode = mAdapter.convertSuplMode(gnssConfigRequested.suplModeMask);
if (newSuplMode != ContextBase::mGps_conf.SUPL_MODE) {
ContextBase::mGps_conf.SUPL_MODE = newSuplMode;
@@ -961,148 +1134,11 @@ GnssAdapter::gnssUpdateConfigCommand(GnssConfig config)
mApi.sendMsg(new LocApiMsg(
[&adapter, gnssConfigRequested, gnssConfigNeedEngineUpdate,
countOfConfigs, configCollectiveResponse, errs, oldServerUrl] () {
-
- size_t index = 0;
- LocationError err = LOCATION_ERROR_SUCCESS;
- std::vector<LocationError> errsList(errs);
-
std::string serverUrl = adapter.getServerUrl();
int serverUrlLen = serverUrl.length();
+ std::vector<LocationError> errsList = adapter.gnssUpdateConfig(oldServerUrl,
+ "", gnssConfigRequested, gnssConfigNeedEngineUpdate, countOfConfigs);
- if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT) {
- if (gnssConfigNeedEngineUpdate.flags & GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT) {
- err = adapter.mLocApi->setGpsLockSync(gnssConfigRequested.gpsLock);
- if (index < countOfConfigs) {
- errsList[index] = err;
- }
- }
- index++;
- }
- if (gnssConfigRequested.flags &
- GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT) {
- if (gnssConfigNeedEngineUpdate.flags &
- GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT) {
- if (gnssConfigNeedEngineUpdate.assistanceServer.type ==
- GNSS_ASSISTANCE_TYPE_SUPL) {
- if ((serverUrlLen != 0) && (oldServerUrl.compare(serverUrl) !=0)) {
- err = adapter.mLocApi->setServerSync(
- serverUrl.c_str(), serverUrlLen, LOC_AGPS_SUPL_SERVER);
- if (index < countOfConfigs) {
- errsList[index] = err;
- }
- }
- } else if (gnssConfigNeedEngineUpdate.assistanceServer.type ==
- GNSS_ASSISTANCE_TYPE_C2K) {
- struct in_addr addr;
- struct hostent* hp;
- bool resolveAddrSuccess = true;
-
- hp = gethostbyname(
- gnssConfigNeedEngineUpdate.assistanceServer.hostName);
- if (hp != NULL) { /* DNS OK */
- memcpy(&addr, hp->h_addr_list[0], hp->h_length);
- } else {
- /* Try IP representation */
- if (inet_aton(
- gnssConfigNeedEngineUpdate.assistanceServer.hostName,
- &addr) == 0) {
- /* IP not valid */
- LOC_LOGE("%s]: hostname '%s' cannot be resolved ",
- __func__,
- gnssConfigNeedEngineUpdate.assistanceServer.hostName);
- if (index < countOfConfigs) {
- errsList[index] = LOCATION_ERROR_INVALID_PARAMETER;
- }
- } else {
- resolveAddrSuccess = false;
- }
- }
-
- if (resolveAddrSuccess) {
- unsigned int ip = htonl(addr.s_addr);
- err = adapter.mLocApi->setServerSync(ip,
- gnssConfigNeedEngineUpdate.assistanceServer.port,
- LOC_AGPS_CDMA_PDE_SERVER);
- if (index < countOfConfigs) {
- errsList[index] = err;
- }
- }
- }
- }
- index++;
- }
- if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT) {
- if (gnssConfigNeedEngineUpdate.flags &
- GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT) {
- err = adapter.mLocApi->setSUPLVersionSync(gnssConfigRequested.suplVersion);
- if (index < countOfConfigs) {
- errsList[index] = err;
- }
- }
- index++;
- }
- if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT) {
- if (gnssConfigNeedEngineUpdate.flags &
- GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT) {
- err = adapter.mLocApi->setLPPConfigSync(gnssConfigRequested.lppProfile);
- if (index < countOfConfigs) {
- errsList[index] = err;
- }
- }
- index++;
- }
- if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT) {
- if (gnssConfigNeedEngineUpdate.flags &
- GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT) {
- err = adapter.mLocApi->setLPPeProtocolCpSync(
- gnssConfigRequested.lppeControlPlaneMask);
- if (index < countOfConfigs) {
- errsList[index] = err;
- }
- }
- index++;
- }
- if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT) {
- if (gnssConfigNeedEngineUpdate.flags &
- GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT) {
- err = adapter.mLocApi->setLPPeProtocolUpSync(
- gnssConfigRequested.lppeUserPlaneMask);
- if (index < countOfConfigs) {
- errsList[index] = err;
- }
- }
- index++;
- }
- if (gnssConfigRequested.flags &
- GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT) {
- if (gnssConfigNeedEngineUpdate.flags &
- GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT) {
- err = adapter.mLocApi->setAGLONASSProtocolSync(
- gnssConfigRequested.aGlonassPositionProtocolMask);
- if (index < countOfConfigs) {
- errsList[index] = err;
- }
- }
- index++;
- }
- if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT) {
- // Check if feature is supported
- if (!ContextBase::isFeatureSupported(
- LOC_SUPPORTED_FEATURE_CONSTELLATION_ENABLEMENT_V02)) {
- LOC_LOGe("Feature constellation enablement not supported.");
- err = LOCATION_ERROR_NOT_SUPPORTED;
- } else {
- // Send the SV ID Config to Modem
- err = adapter.gnssSvIdConfigUpdateSync(gnssConfigRequested.blacklistedSvIds);
- if (LOCATION_ERROR_SUCCESS != err) {
- LOC_LOGe("Failed to send config to modem, err %d", err);
- }
- }
- if (index < countOfConfigs) {
- errsList[index] = err;
- }
- index++;
- }
configCollectiveResponse->returnToSender(errsList);
}));
}
@@ -1224,7 +1260,10 @@ GnssAdapter::gnssGetConfigCommand(GnssConfigFlagsMask configMask) {
delete[] mIds;
}
inline virtual void proc() const {
-
+ if (!mAdapter.isEngineCapabilitiesKnown()) {
+ mAdapter.mPendingMsgs.push_back(new MsgGnssGetConfig(*this));
+ return;
+ }
LocationError* errs = new LocationError[mCount];
LocationError err = LOCATION_ERROR_SUCCESS;
uint32_t index = 0;
@@ -1300,6 +1339,12 @@ GnssAdapter::gnssGetConfigCommand(GnssConfigFlagsMask configMask) {
errs[index++] = err;
}
}
+ if (mConfigMask & GNSS_CONFIG_FLAGS_EMERGENCY_EXTENSION_SECONDS_BIT) {
+ err = LOCATION_ERROR_NOT_SUPPORTED;
+ if (index < mCount) {
+ errs[index++] = LOCATION_ERROR_NOT_SUPPORTED;
+ }
+ }
mAdapter.reportResponse(index, errs, mIds);
delete[] errs;
@@ -1493,7 +1538,10 @@ GnssAdapter::gnssUpdateSvTypeConfigCommand(GnssSvTypeConfig config)
mApi(api),
mConfig(config) {}
inline virtual void proc() const {
-
+ if (!mAdapter->isEngineCapabilitiesKnown()) {
+ mAdapter->mPendingMsgs.push_back(new MsgGnssUpdateSvTypeConfig(*this));
+ return;
+ }
// Check if feature is supported
if (!ContextBase::isFeatureSupported(
LOC_SUPPORTED_FEATURE_CONSTELLATION_ENABLEMENT_V02)) {
@@ -1583,7 +1631,10 @@ GnssAdapter::gnssGetSvTypeConfigCommand(GnssSvTypeConfigCallback callback)
mApi(api),
mCallback(callback) {}
inline virtual void proc() const {
-
+ if (!mAdapter->isEngineCapabilitiesKnown()) {
+ mAdapter->mPendingMsgs.push_back(new MsgGnssGetSvTypeConfig(*this));
+ return;
+ }
if (!ContextBase::isFeatureSupported(
LOC_SUPPORTED_FEATURE_CONSTELLATION_ENABLEMENT_V02)) {
LOC_LOGe("Feature not supported.");
@@ -1612,7 +1663,10 @@ GnssAdapter::gnssResetSvTypeConfigCommand()
mAdapter(adapter),
mApi(api) {}
inline virtual void proc() const {
-
+ if (!mAdapter->isEngineCapabilitiesKnown()) {
+ mAdapter->mPendingMsgs.push_back(new MsgGnssResetSvTypeConfig(*this));
+ return;
+ }
if (!ContextBase::isFeatureSupported(
LOC_SUPPORTED_FEATURE_CONSTELLATION_ENABLEMENT_V02)) {
LOC_LOGe("Feature not supported.");
@@ -1859,43 +1913,32 @@ GnssAdapter::addClientCommand(LocationAPI* client, const LocationCallbacks& call
}
void
-GnssAdapter::removeClientCommand(LocationAPI* client,
- removeClientCompleteCallback rmClientCb)
+GnssAdapter::stopClientSessions(LocationAPI* client)
{
LOC_LOGD("%s]: client %p", __func__, client);
- struct MsgRemoveClient : public LocMsg {
- GnssAdapter& mAdapter;
- LocationAPI* mClient;
- removeClientCompleteCallback mRmClientCb;
- inline MsgRemoveClient(GnssAdapter& adapter,
- LocationAPI* client,
- removeClientCompleteCallback rmCb) :
- LocMsg(),
- mAdapter(adapter),
- mClient(client),
- mRmClientCb(rmCb){}
- inline virtual void proc() const {
- mAdapter.stopClientSessions(mClient);
- mAdapter.eraseClient(mClient);
- if (nullptr != mRmClientCb) {
- mRmClientCb(mClient);
- }
+ /* Time-based Tracking */
+ std::vector<LocationSessionKey> vTimeBasedTrackingClient;
+ for (auto it : mTimeBasedTrackingSessions) {
+ if (client == it.first.client) {
+ vTimeBasedTrackingClient.emplace_back(it.first.client, it.first.id);
}
- };
-
- sendMsg(new MsgRemoveClient(*this, client, rmClientCb));
-}
+ }
+ for (auto key : vTimeBasedTrackingClient) {
+ stopTimeBasedTrackingMultiplex(key.client, key.id);
+ }
-void
-GnssAdapter::stopClientSessions(LocationAPI* client)
-{
- LOC_LOGD("%s]: client %p", __func__, client);
- for (auto it = mTrackingSessions.begin(); it != mTrackingSessions.end();) {
+ /* Distance-based Tracking */
+ for (auto it = mDistanceBasedTrackingSessions.begin();
+ it != mDistanceBasedTrackingSessions.end(); /* no increment here*/) {
if (client == it->first.client) {
- stopTrackingMultiplex(it->first.client, it->first.id);
- it = mTrackingSessions.erase(it);
- continue;
+ mLocApi->stopDistanceBasedTracking(it->first.id, new LocApiResponse(*getContext(),
+ [this, client, id=it->first.id] (LocationError err) {
+ if (LOCATION_ERROR_SUCCESS == err) {
+ eraseTrackingSession(client, id);
+ }
+ }
+ ));
}
++it; // increment only when not erasing an iterator
}
@@ -1938,10 +1981,12 @@ GnssAdapter::updateClientsEventMask()
if((1 == ContextBase::mGps_conf.EXTERNAL_DR_ENABLED) ||
(true == initEngHubProxy())) {
mask |= LOC_API_ADAPTER_BIT_GNSS_MEASUREMENT;
+ mask |= LOC_API_ADAPTER_BIT_GNSS_NHZ_MEASUREMENT;
mask |= LOC_API_ADAPTER_BIT_GNSS_SV_POLYNOMIAL_REPORT;
mask |= LOC_API_ADAPTER_BIT_PARSED_UNPROPAGATED_POSITION_REPORT;
mask |= LOC_API_ADAPTER_BIT_GNSS_SV_EPHEMERIS_REPORT;
mask |= LOC_API_ADAPTER_BIT_LOC_SYSTEM_INFO;
+ mask |= LOC_API_ADAPTER_BIT_EVENT_REPORT_INFO;
LOC_LOGd("Auto usecase, Enable MEAS/POLY/EPHEMERIS - mask 0x%" PRIx64 "",
mask);
@@ -1973,11 +2018,15 @@ GnssAdapter::handleEngineUpEvent()
LocMsg(),
mAdapter(adapter) {}
virtual void proc() const {
+ mAdapter.setEngineCapabilitiesKnown(true);
mAdapter.broadcastCapabilities(mAdapter.getCapabilities());
- // restart sessions
mAdapter.restartSessions();
mAdapter.gnssSvIdConfigUpdate();
mAdapter.gnssSvTypeConfigUpdate();
+ for (auto msg: mAdapter.mPendingMsgs) {
+ mAdapter.sendMsg(msg);
+ }
+ mAdapter.mPendingMsgs.clear();
}
};
@@ -1994,130 +2043,37 @@ GnssAdapter::restartSessions()
// odcpi session is no longer active after restart
mOdcpiRequestActive = false;
- if (mTrackingSessions.empty()) {
- return;
- }
-
- // get the LocationOptions that has the smallest interval, which should be the active one
- TrackingOptions smallestIntervalOptions = {}; // size is zero until set for the first time
- TrackingOptions highestPowerTrackingOptions = {};
- for (auto it = mTrackingSessions.begin(); it != mTrackingSessions.end(); ++it) {
- // size of zero means we havent set it yet
- if (0 == smallestIntervalOptions.size ||
- it->second.minInterval < smallestIntervalOptions.minInterval) {
- smallestIntervalOptions = it->second;
- }
- GnssPowerMode powerMode = it->second.powerMode;
- // Size of zero means we havent set it yet
- if (0 == highestPowerTrackingOptions.size ||
- (GNSS_POWER_MODE_INVALID != powerMode &&
- powerMode < highestPowerTrackingOptions.powerMode)) {
- highestPowerTrackingOptions = it->second;
- }
- }
-
- LocPosMode locPosMode = {};
- highestPowerTrackingOptions.setLocationOptions(smallestIntervalOptions);
- convertOptions(locPosMode, highestPowerTrackingOptions);
- mLocApi->startFix(locPosMode, nullptr);
-}
-
-void
-GnssAdapter::requestCapabilitiesCommand(LocationAPI* client)
-{
- LOC_LOGD("%s]: ", __func__);
-
- struct MsgRequestCapabilities : public LocMsg {
- GnssAdapter& mAdapter;
- LocationAPI* mClient;
- inline MsgRequestCapabilities(GnssAdapter& adapter,
- LocationAPI* client) :
- LocMsg(),
- mAdapter(adapter),
- mClient(client) {}
- inline virtual void proc() const {
- LocationCallbacks callbacks = mAdapter.getClientCallbacks(mClient);
- if (callbacks.capabilitiesCb == nullptr) {
- LOC_LOGE("%s]: capabilitiesCb is NULL", __func__);
- return;
+ if (!mTimeBasedTrackingSessions.empty()) {
+ // get the LocationOptions that has the smallest interval, which should be the active one
+ TrackingOptions smallestIntervalOptions; // size is zero until set for the first time
+ TrackingOptions highestPowerTrackingOptions;
+ memset(&smallestIntervalOptions, 0, sizeof(smallestIntervalOptions));
+ memset(&highestPowerTrackingOptions, 0, sizeof(highestPowerTrackingOptions));
+ for (auto it = mTimeBasedTrackingSessions.begin(); it != mTimeBasedTrackingSessions.end(); ++it) {
+ // size of zero means we havent set it yet
+ if (0 == smallestIntervalOptions.size ||
+ it->second.minInterval < smallestIntervalOptions.minInterval) {
+ smallestIntervalOptions = it->second;
+ }
+ GnssPowerMode powerMode = it->second.powerMode;
+ // Size of zero means we havent set it yet
+ if (0 == highestPowerTrackingOptions.size ||
+ (GNSS_POWER_MODE_INVALID != powerMode &&
+ powerMode < highestPowerTrackingOptions.powerMode)) {
+ highestPowerTrackingOptions = it->second;
}
-
- LocationCapabilitiesMask mask = mAdapter.getCapabilities();
- callbacks.capabilitiesCb(mask);
}
- };
-
- if (ContextBase::isEngineCapabilitiesKnown()) {
- sendMsg(new MsgRequestCapabilities(*this, client));
- }
-}
-
-LocationCapabilitiesMask
-GnssAdapter::getCapabilities()
-{
- LocationCapabilitiesMask mask = 0;
- uint32_t carrierCapabilities = ContextBase::getCarrierCapabilities();
- // time based tracking always supported
- mask |= LOCATION_CAPABILITIES_TIME_BASED_TRACKING_BIT;
- // geofence always supported
- mask |= LOCATION_CAPABILITIES_GEOFENCE_BIT;
- if (carrierCapabilities & LOC_GPS_CAPABILITY_MSB) {
- mask |= LOCATION_CAPABILITIES_GNSS_MSB_BIT;
- }
- if (LOC_GPS_CAPABILITY_MSA & carrierCapabilities) {
- mask |= LOCATION_CAPABILITIES_GNSS_MSA_BIT;
- }
- if (ContextBase::isMessageSupported(LOC_API_ADAPTER_MESSAGE_DISTANCE_BASE_LOCATION_BATCHING)) {
- mask |= LOCATION_CAPABILITIES_TIME_BASED_BATCHING_BIT |
- LOCATION_CAPABILITIES_DISTANCE_BASED_BATCHING_BIT;
- }
- if (ContextBase::isMessageSupported(LOC_API_ADAPTER_MESSAGE_DISTANCE_BASE_TRACKING)) {
- mask |= LOCATION_CAPABILITIES_DISTANCE_BASED_TRACKING_BIT;
- }
- if (ContextBase::isMessageSupported(LOC_API_ADAPTER_MESSAGE_OUTDOOR_TRIP_BATCHING)) {
- mask |= LOCATION_CAPABILITIES_OUTDOOR_TRIP_BATCHING_BIT;
- }
- if (ContextBase::gnssConstellationConfig()) {
- mask |= LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT;
- }
- if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_DEBUG_NMEA_V02)) {
- mask |= LOCATION_CAPABILITIES_DEBUG_NMEA_BIT;
- }
- if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_CONSTELLATION_ENABLEMENT_V02)) {
- mask |= LOCATION_CAPABILITIES_CONSTELLATION_ENABLEMENT_BIT;
- }
- if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_AGPM_V02)) {
- mask |= LOCATION_CAPABILITIES_AGPM_BIT;
- }
- return mask;
-}
-void
-GnssAdapter::broadcastCapabilities(LocationCapabilitiesMask mask)
-{
- for (auto clientData : mClientData) {
- if (nullptr != clientData.second.capabilitiesCb) {
- clientData.second.capabilitiesCb(mask);
- }
+ highestPowerTrackingOptions.setLocationOptions(smallestIntervalOptions);
+ mLocApi->startTimeBasedTracking(highestPowerTrackingOptions, nullptr);
}
-}
-LocationCallbacks
-GnssAdapter::getClientCallbacks(LocationAPI* client)
-{
- LocationCallbacks callbacks = {};
- auto it = mClientData.find(client);
- if (it != mClientData.end()) {
- callbacks = it->second;
+ for (auto it = mDistanceBasedTrackingSessions.begin();
+ it != mDistanceBasedTrackingSessions.end(); ++it) {
+ mLocApi->startDistanceBasedTracking(it->first.id, it->second,
+ new LocApiResponse(*getContext(),
+ [] (LocationError /*err*/) {}));
}
- return callbacks;
-}
-
-void
-GnssAdapter::saveClient(LocationAPI* client, const LocationCallbacks& callbacks)
-{
- mClientData[client] = callbacks;
- updateClientsEventMask();
}
void
@@ -2149,21 +2105,25 @@ GnssAdapter::notifyClientOfCachedLocationSystemInfo(
}
}
-void
-GnssAdapter::eraseClient(LocationAPI* client)
+bool
+GnssAdapter::hasTrackingCallback(LocationAPI* client)
{
auto it = mClientData.find(client);
- if (it != mClientData.end()) {
- mClientData.erase(it);
- }
- updateClientsEventMask();
+ return (it != mClientData.end() && (it->second.trackingCb || it->second.gnssLocationInfoCb));
}
bool
-GnssAdapter::hasTrackingCallback(LocationAPI* client)
+GnssAdapter::isTimeBasedTrackingSession(LocationAPI* client, uint32_t sessionId)
{
- auto it = mClientData.find(client);
- return (it != mClientData.end() && (it->second.trackingCb || it->second.gnssLocationInfoCb));
+ LocationSessionKey key(client, sessionId);
+ return (mTimeBasedTrackingSessions.find(key) != mTimeBasedTrackingSessions.end());
+}
+
+bool
+GnssAdapter::isDistanceBasedTrackingSession(LocationAPI* client, uint32_t sessionId)
+{
+ LocationSessionKey key(client, sessionId);
+ return (mDistanceBasedTrackingSessions.find(key) != mDistanceBasedTrackingSessions.end());
}
bool
@@ -2177,27 +2137,75 @@ bool
GnssAdapter::isTrackingSession(LocationAPI* client, uint32_t sessionId)
{
LocationSessionKey key(client, sessionId);
- return (mTrackingSessions.find(key) != mTrackingSessions.end());
+ return (mTimeBasedTrackingSessions.find(key) != mTimeBasedTrackingSessions.end());
+}
+
+void
+GnssAdapter::reportPowerStateIfChanged()
+{
+ bool newPowerOn = !mTimeBasedTrackingSessions.empty() ||
+ !mDistanceBasedTrackingSessions.empty();
+ if (newPowerOn != mPowerOn) {
+ mPowerOn = newPowerOn;
+ if (mPowerStateCb != nullptr) {
+ mPowerStateCb(mPowerOn);
+ }
+ }
+}
+
+void
+GnssAdapter::getPowerStateChangesCommand(void* powerStateCb)
+{
+ LOC_LOGD("%s]: ", __func__);
+
+ struct MsgReportLocation : public LocMsg {
+ GnssAdapter& mAdapter;
+ powerStateCallback mPowerStateCb;
+ inline MsgReportLocation(GnssAdapter& adapter,
+ powerStateCallback powerStateCb) :
+ LocMsg(),
+ mAdapter(adapter),
+ mPowerStateCb(powerStateCb) {}
+ inline virtual void proc() const {
+ mAdapter.savePowerStateCallback(mPowerStateCb);
+ mPowerStateCb(mAdapter.getPowerState());
+ }
+ };
+
+ sendMsg(new MsgReportLocation(*this, (powerStateCallback)powerStateCb));
}
void
GnssAdapter::saveTrackingSession(LocationAPI* client, uint32_t sessionId,
- const TrackingOptions& trackingOptions)
+ const TrackingOptions& options)
{
LocationSessionKey key(client, sessionId);
- mTrackingSessions[key] = trackingOptions;
+ if ((options.minDistance > 0) &&
+ ContextBase::isMessageSupported(LOC_API_ADAPTER_MESSAGE_DISTANCE_BASE_TRACKING)) {
+ mDistanceBasedTrackingSessions[key] = options;
+ } else {
+ mTimeBasedTrackingSessions[key] = options;
+ }
+ reportPowerStateIfChanged();
}
void
GnssAdapter::eraseTrackingSession(LocationAPI* client, uint32_t sessionId)
{
LocationSessionKey key(client, sessionId);
- auto itr = mTrackingSessions.find(key);
- if (itr != mTrackingSessions.end()) {
- mTrackingSessions.erase(itr);
+ auto it = mTimeBasedTrackingSessions.find(key);
+ if (it != mTimeBasedTrackingSessions.end()) {
+ mTimeBasedTrackingSessions.erase(it);
+ } else {
+ auto itr = mDistanceBasedTrackingSessions.find(key);
+ if (itr != mDistanceBasedTrackingSessions.end()) {
+ mDistanceBasedTrackingSessions.erase(itr);
+ }
}
+ reportPowerStateIfChanged();
}
+
bool GnssAdapter::setLocPositionMode(const LocPosMode& mode) {
if (!mLocPositionMode.equals(mode)) {
mLocPositionMode = mode;
@@ -2271,45 +2279,62 @@ GnssAdapter::startTrackingCommand(LocationAPI* client, TrackingOptions& options)
LocApiBase& mApi;
LocationAPI* mClient;
uint32_t mSessionId;
- mutable TrackingOptions mTrackingOptions;
+ mutable TrackingOptions mOptions;
inline MsgStartTracking(GnssAdapter& adapter,
LocApiBase& api,
LocationAPI* client,
uint32_t sessionId,
- TrackingOptions trackingOptions) :
+ TrackingOptions options) :
LocMsg(),
mAdapter(adapter),
mApi(api),
mClient(client),
mSessionId(sessionId),
- mTrackingOptions(trackingOptions) {}
+ mOptions(options) {}
inline virtual void proc() const {
+ // distance based tracking will need to know engine capabilities before it can start
+ if (!mAdapter.isEngineCapabilitiesKnown() && mOptions.minDistance > 0) {
+ mAdapter.mPendingMsgs.push_back(new MsgStartTracking(*this));
+ return;
+ }
LocationError err = LOCATION_ERROR_SUCCESS;
if (!mAdapter.hasTrackingCallback(mClient) &&
!mAdapter.hasMeasurementsCallback(mClient)) {
err = LOCATION_ERROR_CALLBACK_MISSING;
- } else if (0 == mTrackingOptions.size) {
+ } else if (0 == mOptions.size) {
err = LOCATION_ERROR_INVALID_PARAMETER;
} else {
- if (GNSS_POWER_MODE_INVALID != mTrackingOptions.powerMode &&
- !ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_AGPM_V02)) {
- LOC_LOGv("Ignoring power mode, feature not supported.");
- mTrackingOptions.powerMode = GNSS_POWER_MODE_INVALID;
+ if (mOptions.minInterval < MIN_TRACKING_INTERVAL) {
+ mOptions.minInterval = MIN_TRACKING_INTERVAL;
}
- if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_AGPM_V02) &&
- GNSS_POWER_MODE_M4 == mTrackingOptions.powerMode &&
- mTrackingOptions.tbm > TRACKING_TBM_THRESHOLD_MILLIS) {
- LOC_LOGd("TBM (%d) > %d Falling back to M2 power mode",
- mTrackingOptions.tbm, TRACKING_TBM_THRESHOLD_MILLIS);
- mTrackingOptions.powerMode = GNSS_POWER_MODE_M2;
- }
- // Api doesn't support multiple clients for time based tracking, so mutiplex
- bool reportToClientWithNoWait =
- mAdapter.startTrackingMultiplex(mClient, mSessionId, mTrackingOptions);
- mAdapter.saveTrackingSession(mClient, mSessionId, mTrackingOptions);
+ if (mOptions.minDistance > 0 &&
+ ContextBase::isMessageSupported(
+ LOC_API_ADAPTER_MESSAGE_DISTANCE_BASE_TRACKING)) {
+ mAdapter.saveTrackingSession(mClient, mSessionId, mOptions);
+ mApi.startDistanceBasedTracking(mSessionId, mOptions,
+ new LocApiResponse(*mAdapter.getContext(),
+ [&mAdapter = mAdapter, mSessionId = mSessionId, mClient = mClient]
+ (LocationError err) {
+ if (LOCATION_ERROR_SUCCESS != err) {
+ mAdapter.eraseTrackingSession(mClient, mSessionId);
+ }
+ mAdapter.reportResponse(mClient, err, mSessionId);
+ }));
+ } else {
+ if (GNSS_POWER_MODE_M4 == mOptions.powerMode &&
+ mOptions.tbm > TRACKING_TBM_THRESHOLD_MILLIS) {
+ LOC_LOGd("TBM (%d) > %d Falling back to M2 power mode",
+ mOptions.tbm, TRACKING_TBM_THRESHOLD_MILLIS);
+ mOptions.powerMode = GNSS_POWER_MODE_M2;
+ }
+ // Api doesn't support multiple clients for time based tracking, so mutiplex
+ bool reportToClientWithNoWait =
+ mAdapter.startTimeBasedTrackingMultiplex(mClient, mSessionId, mOptions);
+ mAdapter.saveTrackingSession(mClient, mSessionId, mOptions);
- if (reportToClientWithNoWait) {
- mAdapter.reportResponse(mClient, LOCATION_ERROR_SUCCESS, mSessionId);
+ if (reportToClientWithNoWait) {
+ mAdapter.reportResponse(mClient, LOCATION_ERROR_SUCCESS, mSessionId);
+ }
}
}
}
@@ -2321,13 +2346,13 @@ GnssAdapter::startTrackingCommand(LocationAPI* client, TrackingOptions& options)
}
bool
-GnssAdapter::startTrackingMultiplex(LocationAPI* client, uint32_t sessionId,
- const TrackingOptions& options)
+GnssAdapter::startTimeBasedTrackingMultiplex(LocationAPI* client, uint32_t sessionId,
+ const TrackingOptions& options)
{
bool reportToClientWithNoWait = true;
- if (mTrackingSessions.empty()) {
- startTracking(client, sessionId, options);
+ if (mTimeBasedTrackingSessions.empty()) {
+ startTimeBasedTracking(client, sessionId, options);
// need to wait for QMI callback
reportToClientWithNoWait = false;
} else {
@@ -2335,7 +2360,7 @@ GnssAdapter::startTrackingMultiplex(LocationAPI* client, uint32_t sessionId,
TrackingOptions multiplexedOptions = {}; // size is 0 until set for the first time
GnssPowerMode multiplexedPowerMode = GNSS_POWER_MODE_INVALID;
memset(&multiplexedOptions, 0, sizeof(multiplexedOptions));
- for (auto it = mTrackingSessions.begin(); it != mTrackingSessions.end(); ++it) {
+ for (auto it = mTimeBasedTrackingSessions.begin(); it != mTimeBasedTrackingSessions.end(); ++it) {
// if not set or there is a new smallest interval, then set the new interval
if (0 == multiplexedOptions.size ||
it->second.minInterval < multiplexedOptions.minInterval) {
@@ -2361,7 +2386,8 @@ GnssAdapter::startTrackingMultiplex(LocationAPI* client, uint32_t sessionId,
}
if (updateOptions) {
// restart time based tracking with the newly updated options
- startTracking(client, sessionId, multiplexedOptions);
+
+ startTimeBasedTracking(client, sessionId, multiplexedOptions);
// need to wait for QMI callback
reportToClientWithNoWait = false;
}
@@ -2372,9 +2398,13 @@ GnssAdapter::startTrackingMultiplex(LocationAPI* client, uint32_t sessionId,
}
void
-GnssAdapter::startTracking(LocationAPI* client, uint32_t sessionId,
+GnssAdapter::startTimeBasedTracking(LocationAPI* client, uint32_t sessionId,
const TrackingOptions& trackingOptions)
{
+ LOC_LOGd("minInterval %u minDistance %u mode %u powermode %u tbm %u",
+ trackingOptions.minInterval, trackingOptions.minDistance,
+ trackingOptions.mode, trackingOptions.powerMode, trackingOptions.tbm);
+
LocPosMode locPosMode = {};
convertOptions(locPosMode, trackingOptions);
@@ -2382,7 +2412,7 @@ GnssAdapter::startTracking(LocationAPI* client, uint32_t sessionId,
mEngHubProxy->gnssSetFixMode(locPosMode);
mEngHubProxy->gnssStartFix();
- mLocApi->startFix(locPosMode, new LocApiResponse(*getContext(),
+ mLocApi->startTimeBasedTracking(trackingOptions, new LocApiResponse(*getContext(),
[this, client, sessionId] (LocationError err) {
if (LOCATION_ERROR_SUCCESS != err) {
eraseTrackingSession(client, sessionId);
@@ -2404,7 +2434,7 @@ GnssAdapter::updateTracking(LocationAPI* client, uint32_t sessionId,
mEngHubProxy->gnssSetFixMode(locPosMode);
mEngHubProxy->gnssStartFix();
- mLocApi->startFix(locPosMode, new LocApiResponse(*getContext(),
+ mLocApi->startTimeBasedTracking(updatedOptions, new LocApiResponse(*getContext(),
[this, client, sessionId, oldOptions] (LocationError err) {
if (LOCATION_ERROR_SUCCESS != err) {
// restore the old LocationOptions
@@ -2417,35 +2447,6 @@ GnssAdapter::updateTracking(LocationAPI* client, uint32_t sessionId,
}
void
-GnssAdapter::setPositionModeCommand(LocPosMode& locPosMode)
-{
- LOC_LOGD("%s]: min_interval %u mode %u",
- __func__, locPosMode.min_interval, locPosMode.mode);
-
- struct MsgSetPositionMode : public LocMsg {
- GnssAdapter& mAdapter;
- LocApiBase& mApi;
- LocPosMode mLocPosMode;
- inline MsgSetPositionMode(GnssAdapter& adapter,
- LocApiBase& api,
- LocPosMode& locPosMode) :
- LocMsg(),
- mAdapter(adapter),
- mApi(api),
- mLocPosMode(locPosMode) {}
- inline virtual void proc() const {
- // saves the mode in adapter to be used when startTrackingCommand is called from ULP
- if (mAdapter.setLocPositionMode(mLocPosMode)) {
- mAdapter.mEngHubProxy->gnssSetFixMode(mLocPosMode);
- mApi.setPositionMode(mLocPosMode);
- }
- }
- };
-
- sendMsg(new MsgSetPositionMode(*this, *mLocApi, locPosMode));
-}
-
-void
GnssAdapter::updateTrackingOptionsCommand(LocationAPI* client, uint32_t id,
TrackingOptions& options)
{
@@ -2457,49 +2458,108 @@ GnssAdapter::updateTrackingOptionsCommand(LocationAPI* client, uint32_t id,
LocApiBase& mApi;
LocationAPI* mClient;
uint32_t mSessionId;
- mutable TrackingOptions mTrackingOptions;
+ mutable TrackingOptions mOptions;
inline MsgUpdateTracking(GnssAdapter& adapter,
LocApiBase& api,
LocationAPI* client,
uint32_t sessionId,
- TrackingOptions trackingOptions) :
+ TrackingOptions options) :
LocMsg(),
mAdapter(adapter),
mApi(api),
mClient(client),
mSessionId(sessionId),
- mTrackingOptions(trackingOptions) {}
+ mOptions(options) {}
inline virtual void proc() const {
- if (mAdapter.isTrackingSession(mClient, mSessionId)) {
- LocationError err = LOCATION_ERROR_SUCCESS;
- if (0 == mTrackingOptions.size) {
- err = LOCATION_ERROR_INVALID_PARAMETER;
- } else {
- if (GNSS_POWER_MODE_INVALID != mTrackingOptions.powerMode &&
- !ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_AGPM_V02)) {
- LOC_LOGv("Ignoring power mode, feature not supported.");
- mTrackingOptions.powerMode = GNSS_POWER_MODE_INVALID;
- }
- if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_AGPM_V02) &&
- GNSS_POWER_MODE_M4 == mTrackingOptions.powerMode &&
- mTrackingOptions.tbm > TRACKING_TBM_THRESHOLD_MILLIS) {
- LOC_LOGd("TBM (%d) > %d Falling back to M2 power mode",
- mTrackingOptions.tbm, TRACKING_TBM_THRESHOLD_MILLIS);
- mTrackingOptions.powerMode = GNSS_POWER_MODE_M2;
+ // distance based tracking will need to know engine capabilities before it can start
+ if (!mAdapter.isEngineCapabilitiesKnown() && mOptions.minDistance > 0) {
+ mAdapter.mPendingMsgs.push_back(new MsgUpdateTracking(*this));
+ return;
+ }
+ LocationError err = LOCATION_ERROR_SUCCESS;
+ bool isTimeBased = mAdapter.isTimeBasedTrackingSession(mClient, mSessionId);
+ bool isDistanceBased = mAdapter.isDistanceBasedTrackingSession(mClient, mSessionId);
+ if (!isTimeBased && !isDistanceBased) {
+ err = LOCATION_ERROR_ID_UNKNOWN;
+ } else if (0 == mOptions.size) {
+ err = LOCATION_ERROR_INVALID_PARAMETER;
+ }
+ if (LOCATION_ERROR_SUCCESS != err) {
+ mAdapter.reportResponse(mClient, err, mSessionId);
+ } else {
+ if (GNSS_POWER_MODE_M4 == mOptions.powerMode &&
+ mOptions.tbm > TRACKING_TBM_THRESHOLD_MILLIS) {
+ LOC_LOGd("TBM (%d) > %d Falling back to M2 power mode",
+ mOptions.tbm, TRACKING_TBM_THRESHOLD_MILLIS);
+ mOptions.powerMode = GNSS_POWER_MODE_M2;
+ }
+ if (mOptions.minInterval < MIN_TRACKING_INTERVAL) {
+ mOptions.minInterval = MIN_TRACKING_INTERVAL;
+ }
+ // Now update session as required
+ if (isTimeBased && mOptions.minDistance > 0) {
+ // switch from time based to distance based
+ // Api doesn't support multiple clients for time based tracking, so mutiplex
+ bool reportToClientWithNoWait =
+ mAdapter.stopTimeBasedTrackingMultiplex(mClient, mSessionId);
+ // erases the time based Session
+ mAdapter.eraseTrackingSession(mClient, mSessionId);
+ if (reportToClientWithNoWait) {
+ mAdapter.reportResponse(mClient, LOCATION_ERROR_SUCCESS, mSessionId);
}
+ // saves as distance based Session
+ mAdapter.saveTrackingSession(mClient, mSessionId, mOptions);
+ mApi.startDistanceBasedTracking(mSessionId, mOptions,
+ new LocApiResponse(*mAdapter.getContext(),
+ [] (LocationError /*err*/) {}));
+ } else if (isDistanceBased && mOptions.minDistance == 0) {
+ // switch from distance based to time based
+ mAdapter.eraseTrackingSession(mClient, mSessionId);
+ mApi.stopDistanceBasedTracking(mSessionId, new LocApiResponse(
+ *mAdapter.getContext(),
+ [&mAdapter = mAdapter, mSessionId = mSessionId, mOptions = mOptions,
+ mClient = mClient] (LocationError /*err*/) {
+ // Api doesn't support multiple clients for time based tracking,
+ // so mutiplex
+ bool reportToClientWithNoWait =
+ mAdapter.startTimeBasedTrackingMultiplex(mClient, mSessionId,
+ mOptions);
+ mAdapter.saveTrackingSession(mClient, mSessionId, mOptions);
+
+ if (reportToClientWithNoWait) {
+ mAdapter.reportResponse(mClient, LOCATION_ERROR_SUCCESS, mSessionId);
+ }
+ }));
+ } else if (isTimeBased) {
+ // update time based tracking
// Api doesn't support multiple clients for time based tracking, so mutiplex
bool reportToClientWithNoWait =
- mAdapter.updateTrackingMultiplex(mClient, mSessionId, mTrackingOptions);
- mAdapter.saveTrackingSession(mClient, mSessionId, mTrackingOptions);
+ mAdapter.updateTrackingMultiplex(mClient, mSessionId, mOptions);
+ mAdapter.saveTrackingSession(mClient, mSessionId, mOptions);
if (reportToClientWithNoWait) {
mAdapter.reportResponse(mClient, err, mSessionId);
}
+ } else if (isDistanceBased) {
+ // restart distance based tracking
+ mApi.stopDistanceBasedTracking(mSessionId, new LocApiResponse(
+ *mAdapter.getContext(),
+ [&mAdapter = mAdapter, mSessionId = mSessionId, mOptions = mOptions,
+ mClient = mClient, &mApi = mApi] (LocationError err) {
+ if (LOCATION_ERROR_SUCCESS == err) {
+ mApi.startDistanceBasedTracking(mSessionId, mOptions,
+ new LocApiResponse(*mAdapter.getContext(),
+ [&mAdapter, mClient, mSessionId, mOptions]
+ (LocationError err) {
+ if (LOCATION_ERROR_SUCCESS == err) {
+ mAdapter.saveTrackingSession(mClient, mSessionId, mOptions);
+ }
+ mAdapter.reportResponse(mClient, err, mSessionId);
+ }));
+ }
+ }));
}
}
- // we do not reportResponse for the case where there is no existing tracking session
- // for the client and id being used, since updateTrackingCommand can be sent to both
- // GnssAdapter & FlpAdapter by LocationAPI and we want to avoid incorrect error response
}
};
@@ -2514,19 +2574,21 @@ GnssAdapter::updateTrackingMultiplex(LocationAPI* client, uint32_t id,
LocationSessionKey key(client, id);
// get the session we are updating
- auto it = mTrackingSessions.find(key);
+ auto it = mTimeBasedTrackingSessions.find(key);
// cache the clients existing LocationOptions
TrackingOptions oldOptions = it->second;
// if session we are updating exists and the minInterval or powerMode has changed
- if (it != mTrackingSessions.end() && (it->second.minInterval != trackingOptions.minInterval ||
+ if (it != mTimeBasedTrackingSessions.end() &&
+ (it->second.minInterval != trackingOptions.minInterval ||
it->second.powerMode != trackingOptions.powerMode)) {
// find the smallest interval and powerMode, other than the session we are updating
TrackingOptions multiplexedOptions = {}; // size is 0 until set for the first time
GnssPowerMode multiplexedPowerMode = GNSS_POWER_MODE_INVALID;
memset(&multiplexedOptions, 0, sizeof(multiplexedOptions));
- for (auto it2 = mTrackingSessions.begin(); it2 != mTrackingSessions.end(); ++it2) {
+ for (auto it2 = mTimeBasedTrackingSessions.begin();
+ it2 != mTimeBasedTrackingSessions.end(); ++it2) {
// if session is not the one we are updating and either interval
// is not set or there is a new smallest interval, then set the new interval
if (it2->first != key && (0 == multiplexedOptions.size ||
@@ -2553,7 +2615,7 @@ GnssAdapter::updateTrackingMultiplex(LocationAPI* client, uint32_t id,
updateOptions = true;
}
// if only one session exists, then tracking should be updated with it
- if (1 == mTrackingSessions.size()) {
+ if (1 == mTimeBasedTrackingSessions.size()) {
multiplexedOptions = trackingOptions;
updateOptions = true;
}
@@ -2588,19 +2650,33 @@ GnssAdapter::stopTrackingCommand(LocationAPI* client, uint32_t id)
mClient(client),
mSessionId(sessionId) {}
inline virtual void proc() const {
- if (mAdapter.isTrackingSession(mClient, mSessionId)) {
- // Api doesn't support multiple clients for time based tracking, so mutiplex
- bool reportToClientWithNoWait =
- mAdapter.stopTrackingMultiplex(mClient, mSessionId);
- mAdapter.eraseTrackingSession(mClient, mSessionId);
-
- if (reportToClientWithNoWait) {
- mAdapter.reportResponse(mClient, LOCATION_ERROR_SUCCESS, mSessionId);
+ bool isTimeBased = mAdapter.isTimeBasedTrackingSession(mClient, mSessionId);
+ bool isDistanceBased = mAdapter.isDistanceBasedTrackingSession(mClient, mSessionId);
+ if (isTimeBased || isDistanceBased) {
+ if (isTimeBased) {
+ // Api doesn't support multiple clients for time based tracking, so mutiplex
+ bool reportToClientWithNoWait =
+ mAdapter.stopTimeBasedTrackingMultiplex(mClient, mSessionId);
+ mAdapter.eraseTrackingSession(mClient, mSessionId);
+
+ if (reportToClientWithNoWait) {
+ mAdapter.reportResponse(mClient, LOCATION_ERROR_SUCCESS, mSessionId);
+ }
+ } else if (isDistanceBased) {
+ mApi.stopDistanceBasedTracking(mSessionId, new LocApiResponse(
+ *mAdapter.getContext(),
+ [&mAdapter = mAdapter, mSessionId = mSessionId, mClient = mClient]
+ (LocationError err) {
+ if (LOCATION_ERROR_SUCCESS == err) {
+ mAdapter.eraseTrackingSession(mClient, mSessionId);
+ }
+ mAdapter.reportResponse(mClient, err, mSessionId);
+ }));
}
+ } else {
+ mAdapter.reportResponse(mClient, LOCATION_ERROR_ID_UNKNOWN, mSessionId);
}
- // we do not reportResponse for the case where there is no existing tracking session
- // for the client and id being used, since stopTrackingCommand can be sent to both
- // GnssAdapter & FlpAdapter by LocationAPI and we want to avoid incorrect error response
+
}
};
@@ -2608,11 +2684,11 @@ GnssAdapter::stopTrackingCommand(LocationAPI* client, uint32_t id)
}
bool
-GnssAdapter::stopTrackingMultiplex(LocationAPI* client, uint32_t id)
+GnssAdapter::stopTimeBasedTrackingMultiplex(LocationAPI* client, uint32_t id)
{
bool reportToClientWithNoWait = true;
- if (1 == mTrackingSessions.size()) {
+ if (1 == mTimeBasedTrackingSessions.size()) {
stopTracking(client, id);
// need to wait for QMI callback
reportToClientWithNoWait = false;
@@ -2620,13 +2696,14 @@ GnssAdapter::stopTrackingMultiplex(LocationAPI* client, uint32_t id)
LocationSessionKey key(client, id);
// get the session we are stopping
- auto it = mTrackingSessions.find(key);
- if (it != mTrackingSessions.end()) {
+ auto it = mTimeBasedTrackingSessions.find(key);
+ if (it != mTimeBasedTrackingSessions.end()) {
// find the smallest interval and powerMode, other than the session we are stopping
TrackingOptions multiplexedOptions = {}; // size is 0 until set for the first time
GnssPowerMode multiplexedPowerMode = GNSS_POWER_MODE_INVALID;
memset(&multiplexedOptions, 0, sizeof(multiplexedOptions));
- for (auto it2 = mTrackingSessions.begin(); it2 != mTrackingSessions.end(); ++it2) {
+ for (auto it2 = mTimeBasedTrackingSessions.begin();
+ it2 != mTimeBasedTrackingSessions.end(); ++it2) {
// if session is not the one we are stopping and either interval
// is not set or there is a new smallest interval, then set the new interval
if (it2->first != key && (0 == multiplexedOptions.size ||
@@ -2646,7 +2723,7 @@ GnssAdapter::stopTrackingMultiplex(LocationAPI* client, uint32_t id)
it->second.powerMode < multiplexedPowerMode) {
multiplexedOptions.powerMode = multiplexedPowerMode;
// restart time based tracking with the newly updated options
- startTracking(client, id, multiplexedOptions);
+ startTimeBasedTracking(client, id, multiplexedOptions);
// need to wait for QMI callback
reportToClientWithNoWait = false;
}
@@ -2765,7 +2842,6 @@ GnssAdapter::gnssNiResponseCommand(GnssNiResponse response, void* rawRequest)
inline virtual ~MsgGnssNiResponse() {
}
inline virtual void proc() const {
- const void *rawPayload = mPayload;
mApi.informNiResponse(mResponse, mPayload);
}
};
@@ -2799,21 +2875,24 @@ GnssAdapter::enableCommand(LocationTechnologyType techType)
mTechType(techType) {}
inline virtual void proc() const {
LocationError err = LOCATION_ERROR_SUCCESS;
- uint32_t powerVoteId = mAdapter.getPowerVoteId();
+ uint32_t powerVoteId = mAdapter.getAfwControlId();
if (mTechType != LOCATION_TECHNOLOGY_TYPE_GNSS) {
err = LOCATION_ERROR_INVALID_PARAMETER;
} else if (powerVoteId > 0) {
err = LOCATION_ERROR_ALREADY_STARTED;
} else {
mContext.modemPowerVote(true);
- mAdapter.setPowerVoteId(mSessionId);
+ mAdapter.setAfwControlId(mSessionId);
- mApi.sendMsg(new LocApiMsg([&mApi = mApi] () {
- mApi.setGpsLockSync(GNSS_CONFIG_GPS_LOCK_NONE);
- }));
-
- mAdapter.mXtraObserver.updateLockStatus(
- mAdapter.convertGpsLock(GNSS_CONFIG_GPS_LOCK_NONE));
+ GnssConfigGpsLock gpsLock = GNSS_CONFIG_GPS_LOCK_NONE;
+ if (NULL != mAdapter.mNfwCb) {
+ ContextBase::mGps_conf.GPS_LOCK &= GNSS_CONFIG_GPS_LOCK_NI;
+ gpsLock = ContextBase::mGps_conf.GPS_LOCK;
+ }
+ mApi.sendMsg(new LocApiMsg([&mApi = mApi, gpsLock]() {
+ mApi.setGpsLockSync(gpsLock);
+ }));
+ mAdapter.mXtraObserver.updateLockStatus(gpsLock);
}
mAdapter.reportResponse(err, mSessionId);
}
@@ -2849,20 +2928,23 @@ GnssAdapter::disableCommand(uint32_t id)
mSessionId(sessionId) {}
inline virtual void proc() const {
LocationError err = LOCATION_ERROR_SUCCESS;
- uint32_t powerVoteId = mAdapter.getPowerVoteId();
+ uint32_t powerVoteId = mAdapter.getAfwControlId();
if (powerVoteId != mSessionId) {
err = LOCATION_ERROR_ID_UNKNOWN;
} else {
mContext.modemPowerVote(false);
- mAdapter.setPowerVoteId(0);
+ mAdapter.setAfwControlId(0);
- GnssConfigGpsLock gpsLock =
- mAdapter.convertGpsLock(ContextBase::mGps_conf.GPS_LOCK);
+ if (NULL != mAdapter.mNfwCb) {
+ /* We need to disable MO (AFW) */
+ ContextBase::mGps_conf.GPS_LOCK |= GNSS_CONFIG_GPS_LOCK_MO;
+ }
+ GnssConfigGpsLock gpsLock = ContextBase::mGps_conf.GPS_LOCK;
mApi.sendMsg(new LocApiMsg([&mApi = mApi,gpsLock] () {
mApi.setGpsLockSync(gpsLock);
}));
mAdapter.mXtraObserver.updateLockStatus(
- mAdapter.convertGpsLock(ContextBase::mGps_conf.GPS_LOCK));
+ ContextBase::mGps_conf.GPS_LOCK);
}
mAdapter.reportResponse(err, mSessionId);
}
@@ -2962,9 +3044,9 @@ GnssAdapter::reportPositionEvent(const UlpLocation& ulpLocation,
}
bool
-GnssAdapter::needReport(const UlpLocation& ulpLocation,
- enum loc_sess_status status,
- LocPosTechMask techMask) {
+GnssAdapter::needReportForGnssClient(const UlpLocation& ulpLocation,
+ enum loc_sess_status status,
+ LocPosTechMask techMask) {
bool reported = false;
// if engine hub is enabled, aka, any of the engine services is enabled,
@@ -2977,53 +3059,83 @@ GnssAdapter::needReport(const UlpLocation& ulpLocation,
return reported;
}
+bool
+GnssAdapter::needReportForFlpClient(enum loc_sess_status status,
+ LocPosTechMask techMask) {
+ if ((status == LOC_SESS_INTERMEDIATE) &&
+ !(techMask & LOC_POS_TECH_MASK_SENSORS) &&
+ (!getAllowFlpNetworkFixes())) {
+ return false;
+ } else {
+ return true;
+ }
+}
+
+bool
+GnssAdapter::isFlpClient(LocationCallbacks& locationCallbacks)
+{
+ return (locationCallbacks.gnssLocationInfoCb == nullptr &&
+ locationCallbacks.gnssSvCb == nullptr &&
+ locationCallbacks.gnssNmeaCb == nullptr &&
+ locationCallbacks.gnssDataCb == nullptr &&
+ locationCallbacks.gnssMeasurementsCb == nullptr);
+}
+
void
GnssAdapter::reportPosition(const UlpLocation& ulpLocation,
const GpsLocationExtended& locationExtended,
enum loc_sess_status status,
LocPosTechMask techMask)
{
- bool reported = needReport(ulpLocation, status, techMask);
- mGnssSvIdUsedInPosAvail = false;
- if (reported) {
- if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_GNSS_SV_USED_DATA) {
- mGnssSvIdUsedInPosAvail = true;
- mGnssSvIdUsedInPosition = locationExtended.gnss_sv_used_ids;
- }
+ bool reportToGnssClient = needReportForGnssClient(ulpLocation, status, techMask);
+ bool reportToFlpClient = needReportForFlpClient(status, techMask);
+ if (reportToGnssClient || reportToFlpClient) {
GnssLocationInfoNotification locationInfo = {};
convertLocationInfo(locationInfo, locationExtended);
convertLocation(locationInfo.location, ulpLocation, locationExtended, techMask);
for (auto it=mClientData.begin(); it != mClientData.end(); ++it) {
- if (nullptr != it->second.gnssLocationInfoCb) {
- it->second.gnssLocationInfoCb(locationInfo);
- } else if (nullptr != it->second.trackingCb) {
- it->second.trackingCb(locationInfo.location);
+ if ((reportToFlpClient && isFlpClient(it->second)) ||
+ (reportToGnssClient && !isFlpClient(it->second))) {
+ if (nullptr != it->second.gnssLocationInfoCb) {
+ it->second.gnssLocationInfoCb(locationInfo);
+ } else if (nullptr != it->second.trackingCb) {
+ it->second.trackingCb(locationInfo.location);
+ }
}
}
- // if engine hub is running and the fix is from sensor, e.g.: DRE,
- // inject DRE fix to modem
- if ((1 == ContextBase::mGps_conf.POSITION_ASSISTED_CLOCK_ESTIMATOR_ENABLED) &&
- (true == initEngHubProxy()) && (LOC_POS_TECH_MASK_SENSORS & techMask)) {
- mLocApi->injectPosition(locationInfo, false);
+ mGnssSvIdUsedInPosAvail = false;
+ if (reportToGnssClient) {
+ if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_GNSS_SV_USED_DATA) {
+ mGnssSvIdUsedInPosAvail = true;
+ mGnssSvIdUsedInPosition = locationExtended.gnss_sv_used_ids;
+ }
+
+ // if engine hub is running and the fix is from sensor, e.g.: DRE,
+ // inject DRE fix to modem
+ if ((1 == ContextBase::mGps_conf.POSITION_ASSISTED_CLOCK_ESTIMATOR_ENABLED) &&
+ (true == initEngHubProxy()) && (LOC_POS_TECH_MASK_SENSORS & techMask)) {
+ mLocApi->injectPosition(locationInfo, false);
+ }
}
}
- if (NMEA_PROVIDER_AP == ContextBase::mGps_conf.NMEA_PROVIDER && !mTrackingSessions.empty()) {
+ if (NMEA_PROVIDER_AP == ContextBase::mGps_conf.NMEA_PROVIDER &&
+ !mTimeBasedTrackingSessions.empty()) {
/*Only BlankNMEA sentence needs to be processed and sent, if both lat, long is 0 &
horReliability is not set. */
bool blank_fix = ((0 == ulpLocation.gpsLocation.latitude) &&
(0 == ulpLocation.gpsLocation.longitude) &&
(LOC_RELIABILITY_NOT_SET == locationExtended.horizontal_reliability));
- uint8_t generate_nmea = (reported && status != LOC_SESS_FAILURE && !blank_fix);
+ uint8_t generate_nmea = (reportToGnssClient && status != LOC_SESS_FAILURE && !blank_fix);
std::vector<std::string> nmeaArraystr;
loc_nmea_generate_pos(ulpLocation, locationExtended, mLocSystemInfo,
generate_nmea, nmeaArraystr);
stringstream ss;
- for (auto sentence : nmeaArraystr) {
- ss << sentence;
+ for (auto itor = nmeaArraystr.begin(); itor != nmeaArraystr.end(); ++itor) {
+ ss << *itor;
}
string s = ss.str();
reportNmea(s.c_str(), s.length());
@@ -3114,12 +3226,13 @@ GnssAdapter::reportSv(GnssSvNotification& svNotify)
}
}
- if (NMEA_PROVIDER_AP == ContextBase::mGps_conf.NMEA_PROVIDER && !mTrackingSessions.empty()) {
+ if (NMEA_PROVIDER_AP == ContextBase::mGps_conf.NMEA_PROVIDER &&
+ !mTimeBasedTrackingSessions.empty()) {
std::vector<std::string> nmeaArraystr;
loc_nmea_generate_sv(svNotify, nmeaArraystr);
stringstream ss;
- for (auto sentence : nmeaArraystr) {
- ss << sentence;
+ for (auto itor = nmeaArraystr.begin(); itor != nmeaArraystr.end(); ++itor) {
+ ss << *itor;
}
string s = ss.str();
reportNmea(s.c_str(), s.length());
@@ -3309,8 +3422,8 @@ GnssAdapter::reportLocationSystemInfo(const LocationSystemInfo & locationSystemI
LEAP_SECOND_SYS_INFO_CURRENT_LEAP_SECONDS_BIT;
dstLeapSecondSysInfo.leapSecondCurrent = srcLeapSecondSysInfo.leapSecondCurrent;
}
- // once leap second change event is complete, modem may send up event invalidate the leap second
- // change info while AP is still processing report during leap second transition
+ // once leap second change event is complete, modem may send up event invalidate the leap
+ // second change info while AP is still processing report during leap second transition
// so, we choose to keep this info around even though it is old
if (srcLeapSecondSysInfo.leapSecondInfoMask & LEAP_SECOND_SYS_INFO_LEAP_SECOND_CHANGE_BIT) {
dstLeapSecondSysInfo.leapSecondInfoMask |= LEAP_SECOND_SYS_INFO_LEAP_SECOND_CHANGE_BIT;
@@ -3462,20 +3575,21 @@ GnssAdapter::requestNiNotify(const GnssNiNotification& notify, const void* data)
}
void
-GnssAdapter::reportGnssMeasurementDataEvent(const GnssMeasurementsNotification& measurements,
+GnssAdapter::reportGnssMeasurementsEvent(const GnssMeasurements& gnssMeasurements,
int msInWeek)
{
LOC_LOGD("%s]: msInWeek=%d", __func__, msInWeek);
struct MsgReportGnssMeasurementData : public LocMsg {
GnssAdapter& mAdapter;
+ GnssMeasurements mGnssMeasurements;
GnssMeasurementsNotification mMeasurementsNotify;
inline MsgReportGnssMeasurementData(GnssAdapter& adapter,
- const GnssMeasurementsNotification& measurements,
+ const GnssMeasurements& gnssMeasurements,
int msInWeek) :
LocMsg(),
mAdapter(adapter),
- mMeasurementsNotify(measurements) {
+ mMeasurementsNotify(gnssMeasurements.gnssMeasNotification) {
if (-1 != msInWeek) {
mAdapter.getAgcInformation(mMeasurementsNotify, msInWeek);
}
@@ -3485,7 +3599,8 @@ GnssAdapter::reportGnssMeasurementDataEvent(const GnssMeasurementsNotification&
}
};
- sendMsg(new MsgReportGnssMeasurementData(*this, measurements, msInWeek));
+ sendMsg(new MsgReportGnssMeasurementData(*this, gnssMeasurements, msInWeek));
+ mEngHubProxy->gnssReportSvMeasurement(gnssMeasurements.gnssSvMeasurementSet);
}
void
@@ -3499,13 +3614,6 @@ GnssAdapter::reportGnssMeasurementData(const GnssMeasurementsNotification& measu
}
void
-GnssAdapter::reportSvMeasurementEvent(GnssSvMeasurementSet &svMeasurementSet)
-{
- LOC_LOGD("%s]: ", __func__);
- mEngHubProxy->gnssReportSvMeasurement(svMeasurementSet);
-}
-
-void
GnssAdapter::reportSvPolynomialEvent(GnssSvPolynomial &svPolynomial)
{
LOC_LOGD("%s]: ", __func__);
@@ -3587,24 +3695,24 @@ void GnssAdapter::requestOdcpi(const OdcpiRequestInfo& request)
bool GnssAdapter::reportDeleteAidingDataEvent(GnssAidingData& aidingData)
{
LOC_LOGD("%s]:", __func__);
+ mEngHubProxy->gnssDeleteAidingData(aidingData);
+ return true;
+}
- struct MsgHandleDeleteAidingDataEvent : public LocMsg {
- GnssAdapter& mAdapter;
- GnssAidingData mData;
- inline MsgHandleDeleteAidingDataEvent(GnssAdapter& adapter,
- GnssAidingData& data) :
- LocMsg(),
- mAdapter(adapter),
- mData(data) {}
- inline virtual void proc() const {
- mAdapter.mEngHubProxy->gnssDeleteAidingData(mData);
- }
- };
-
- sendMsg(new MsgHandleDeleteAidingDataEvent(*this, aidingData));
+bool GnssAdapter::reportKlobucharIonoModelEvent(GnssKlobucharIonoModel & ionoModel)
+{
+ LOC_LOGD("%s]:", __func__);
+ mEngHubProxy->gnssReportKlobucharIonoModel(ionoModel);
return true;
}
+bool GnssAdapter::reportGnssAdditionalSystemInfoEvent(
+ GnssAdditionalSystemInfo & additionalSystemInfo)
+{
+ LOC_LOGD("%s]:", __func__);
+ mEngHubProxy->gnssReportAdditionalSystemInfo(additionalSystemInfo);
+ return true;
+}
void GnssAdapter::initOdcpiCommand(const OdcpiRequestCallback& callback)
{
@@ -3821,6 +3929,52 @@ void GnssAdapter::initAgpsCommand(const AgpsCbInfo& cbInfo){
sendMsg(new AgpsMsgInit(cbInfo, *this));
}
+void GnssAdapter::initNfwCommand(const NfwCbInfo& cbInfo) {
+ LOC_LOGi("GnssAdapter::initNfwCommand");
+
+ /* Message to initialize NFW */
+ struct MsgInitNfw : public LocMsg {
+ const NfwCbInfo mCbInfo;
+ GnssAdapter& mAdapter;
+
+ inline MsgInitNfw(const NfwCbInfo& cbInfo,
+ GnssAdapter& adapter) :
+ LocMsg(), mCbInfo(cbInfo), mAdapter(adapter) {
+ LOC_LOGv("MsgInitNfw");
+ }
+
+ inline virtual void proc() const {
+ LOC_LOGv("MsgInitNfw::proc()");
+ mAdapter.initNfw(mCbInfo);
+ }
+ };
+
+ /* Send message to initialize NFW */
+ sendMsg(new MsgInitNfw(cbInfo, *this));
+}
+
+void GnssAdapter::reportNfwNotificationEvent(GnssNfwNotification& notification) {
+ LOC_LOGi("GnssAdapter::reportNfwNotificationEvent");
+
+ struct MsgReportNfwNotification : public LocMsg {
+ const GnssNfwNotification mNotification;
+ GnssAdapter& mAdapter;
+
+ inline MsgReportNfwNotification(const GnssNfwNotification& notification,
+ GnssAdapter& adapter) :
+ LocMsg(), mNotification(notification), mAdapter(adapter) {
+ LOC_LOGv("MsgReportNfwNotification");
+ }
+
+ inline virtual void proc() const {
+ LOC_LOGv("MsgReportNfwNotification::proc()");
+ mAdapter.reportNfwNotification(mNotification);
+ }
+ };
+
+ sendMsg(new MsgReportNfwNotification(notification, *this));
+}
+
/* GnssAdapter::requestATL
* Method triggered in QMI thread as part of handling below message:
* eQMI_LOC_SERVER_REQUEST_OPEN_V02
@@ -3895,6 +4049,8 @@ void GnssAdapter::dataConnOpenCommand(
LOC_LOGV("AgpsMsgAtlOpenSuccess");
if (mApnName == nullptr) {
LOC_LOGE("%s] new allocation failed, fatal error.", __func__);
+ // Reporting the failure here
+ mAgpsManager->reportAtlClosed(mAgpsType);
return;
}
memcpy(mApnName, apnName, apnLen);
@@ -3911,9 +4067,15 @@ void GnssAdapter::dataConnOpenCommand(
mAgpsManager->reportAtlOpenSuccess(mAgpsType, mApnName, mApnLen, mBearerType);
}
};
-
- sendMsg( new AgpsMsgAtlOpenSuccess(
- &mAgpsManager, agpsType, apnName, apnLen, bearerType));
+ // Added inital length checks for apnlen check to avoid security issues
+ // In case of failure reporting the same
+ if (NULL == apnName || apnLen <= 0 || apnLen > MAX_APN_LEN || (strlen(apnName) != apnLen)) {
+ LOC_LOGe("%s]: incorrect apnlen length or incorrect apnName", __func__);
+ mAgpsManager.reportAtlClosed(agpsType);
+ } else {
+ sendMsg( new AgpsMsgAtlOpenSuccess(
+ &mAgpsManager, agpsType, apnName, apnLen, bearerType));
+ }
}
void GnssAdapter::dataConnClosedCommand(AGpsExtType agpsType){
@@ -4402,6 +4564,37 @@ GnssAdapter::getGnssEnergyConsumedCommand(GnssEnergyConsumedCallback energyConsu
sendMsg(new MsgGetGnssEnergyConsumed(*this, *mLocApi, energyConsumedCb));
}
+void
+GnssAdapter::nfwControlCommand(bool enable) {
+ struct MsgenableNfwLocationAccess : public LocMsg {
+ GnssAdapter& mAdapter;
+ LocApiBase& mApi;
+ bool mEnable;
+ inline MsgenableNfwLocationAccess(GnssAdapter& adapter, LocApiBase& api,
+ bool enable) :
+ LocMsg(),
+ mAdapter(adapter),
+ mApi(api),
+ mEnable(enable) {}
+ inline virtual void proc() const {
+ GnssConfigGpsLock gpsLock;
+
+ gpsLock = ContextBase::mGps_conf.GPS_LOCK;
+ if (mEnable) {
+ gpsLock &= ~GNSS_CONFIG_GPS_LOCK_NI;
+ } else {
+ gpsLock |= GNSS_CONFIG_GPS_LOCK_NI;
+ }
+ ContextBase::mGps_conf.GPS_LOCK = gpsLock;
+ mApi.sendMsg(new LocApiMsg([&mApi = mApi, gpsLock]() {
+ mApi.setGpsLockSync((GnssConfigGpsLock)gpsLock);
+ }));
+ }
+ };
+
+ sendMsg(new MsgenableNfwLocationAccess(*this, *mLocApi, enable));
+}
+
/* ==== Eng Hub Proxy ================================================================= */
/* ======== UTILITIES ================================================================= */
void
diff --git a/gnss/GnssAdapter.h b/gnss/GnssAdapter.h
index 1682f02..9720ba4 100644
--- a/gnss/GnssAdapter.h
+++ b/gnss/GnssAdapter.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019, 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
@@ -30,13 +30,14 @@
#define GNSS_ADAPTER_H
#include <LocAdapterBase.h>
-#include <LocDualContext.h>
+#include <LocContext.h>
#include <IOsObserver.h>
#include <EngineHubProxyBase.h>
#include <LocationAPI.h>
#include <Agps.h>
#include <SystemStatus.h>
#include <XtraSystemStatusObserver.h>
+#include <map>
#define MAX_URL_LEN 256
#define NMEA_SENTENCE_MAX_LENGTH 200
@@ -48,6 +49,9 @@
class GnssAdapter;
+typedef std::map<LocationSessionKey, LocationOptions> LocationSessionMap;
+typedef std::map<LocationSessionKey, TrackingOptions> TrackingOptionsMap;
+
class OdcpiTimer : public LocTimer {
public:
OdcpiTimer(GnssAdapter* adapter) :
@@ -128,19 +132,16 @@ typedef std::function<void(
uint64_t gnssEnergyConsumedFromFirstBoot
)> GnssEnergyConsumedCallback;
-typedef void (*removeClientCompleteCallback)(LocationAPI* client);
+typedef void (*powerStateCallback)(bool on);
class GnssAdapter : public LocAdapterBase {
/* ==== Engine Hub ===================================================================== */
EngineHubProxyBase* mEngHubProxy;
- /* ==== CLIENT ========================================================================= */
- typedef std::map<LocationAPI*, LocationCallbacks> ClientDataMap;
- ClientDataMap mClientData;
-
/* ==== TRACKING ======================================================================= */
- TrackingOptionsMap mTrackingSessions;
+ TrackingOptionsMap mTimeBasedTrackingSessions;
+ LocationSessionMap mDistanceBasedTrackingSessions;
LocPosMode mLocPositionMode;
GnssSvUsedInPosition mGnssSvIdUsedInPosition;
bool mGnssSvIdUsedInPosAvail;
@@ -162,6 +163,12 @@ class GnssAdapter : public LocAdapterBase {
AgpsCbInfo mAgpsCbInfo;
void initAgps(const AgpsCbInfo& cbInfo);
+ /* ==== NFW =========================================================================== */
+ NfwStatusCb mNfwCb;
+ inline void initNfw(const NfwCbInfo& cbInfo) {
+ mNfwCb = (NfwStatusCb)cbInfo.visibilityControlCb;
+ }
+
/* ==== ODCPI ========================================================================== */
OdcpiRequestCallback mOdcpiRequestCb;
bool mOdcpiRequestActive;
@@ -175,12 +182,16 @@ class GnssAdapter : public LocAdapterBase {
std::string mMoServerUrl;
XtraSystemStatusObserver mXtraObserver;
LocationSystemInfo mLocSystemInfo;
+ std::vector<GnssSvIdSource> mBlacklistedSvIds;
/* === Misc ===================================================================== */
BlockCPIInfo mBlockCPIInfo;
+ bool mPowerOn;
+ uint32_t mAllowFlpNetworkFixes;
/* === Misc callback from QMI LOC API ============================================== */
GnssEnergyConsumedCallback mGnssEnergyConsumedCb;
+ powerStateCallback mPowerStateCb;
/*==== CONVERSION ===================================================================*/
static void convertOptions(LocPosMode& out, const TrackingOptions& trackingOptions);
@@ -193,6 +204,13 @@ class GnssAdapter : public LocAdapterBase {
/* ======== UTILITIES ================================================================== */
inline void initOdcpi(const OdcpiRequestCallback& callback);
inline void injectOdcpi(const Location& location);
+ static bool isFlpClient(LocationCallbacks& locationCallbacks);
+
+protected:
+
+ /* ==== CLIENT ========================================================================= */
+ virtual void updateClientsEventMask();
+ virtual void stopClientSessions(LocationAPI* client);
public:
@@ -207,21 +225,7 @@ public:
/* ==== CLIENT ========================================================================= */
/* ======== COMMANDS ====(Called from Client Thread)==================================== */
- void addClientCommand(LocationAPI* client, const LocationCallbacks& callbacks);
- void removeClientCommand(LocationAPI* client,
- removeClientCompleteCallback rmClientCb);
- void requestCapabilitiesCommand(LocationAPI* client);
- /* ======== UTILITIES ================================================================== */
- void saveClient(LocationAPI* client, const LocationCallbacks& callbacks);
- void eraseClient(LocationAPI* client);
- void notifyClientOfCachedLocationSystemInfo(LocationAPI* client,
- const LocationCallbacks& callbacks);
- void updateClientsEventMask();
- void stopClientSessions(LocationAPI* client);
- LocationCallbacks getClientCallbacks(LocationAPI* client);
- LocationCapabilitiesMask getCapabilities();
- void broadcastCapabilities(LocationCapabilitiesMask);
- void setSuplHostServer(const char* server, int port, LocServerType type);
+ virtual void addClientCommand(LocationAPI* client, const LocationCallbacks& callbacks);
/* ==== TRACKING ======================================================================= */
/* ======== COMMANDS ====(Called from Client Thread)==================================== */
@@ -230,11 +234,12 @@ public:
void updateTrackingOptionsCommand(
LocationAPI* client, uint32_t id, TrackingOptions& trackingOptions);
void stopTrackingCommand(LocationAPI* client, uint32_t id);
- virtual void setPositionModeCommand(LocPosMode& locPosMode);
/* ======== RESPONSES ================================================================== */
void reportResponse(LocationAPI* client, LocationError err, uint32_t sessionId);
/* ======== UTILITIES ================================================================== */
bool hasTrackingCallback(LocationAPI* client);
+ bool isTimeBasedTrackingSession(LocationAPI* client, uint32_t sessionId);
+ bool isDistanceBasedTrackingSession(LocationAPI* client, uint32_t sessionId);
bool hasMeasurementsCallback(LocationAPI* client);
bool isTrackingSession(LocationAPI* client, uint32_t sessionId);
void saveTrackingSession(LocationAPI* client, uint32_t sessionId,
@@ -244,16 +249,16 @@ public:
bool setLocPositionMode(const LocPosMode& mode);
LocPosMode& getLocPositionMode() { return mLocPositionMode; }
- bool startTrackingMultiplex(LocationAPI* client, uint32_t sessionId,
- const TrackingOptions& trackingOptions);
- void startTracking(LocationAPI* client, uint32_t sessionId,
- const TrackingOptions& trackingOptions);
- bool stopTrackingMultiplex(LocationAPI* client, uint32_t id);
+ bool startTimeBasedTrackingMultiplex(LocationAPI* client, uint32_t sessionId,
+ const TrackingOptions& trackingOptions);
+ void startTimeBasedTracking(LocationAPI* client, uint32_t sessionId,
+ const TrackingOptions& trackingOptions);
+ bool stopTimeBasedTrackingMultiplex(LocationAPI* client, uint32_t id);
void stopTracking(LocationAPI* client, uint32_t id);
bool updateTrackingMultiplex(LocationAPI* client, uint32_t id,
- const TrackingOptions& trackingOptions);
+ const TrackingOptions& trackingOptions);
void updateTracking(LocationAPI* client, uint32_t sessionId,
- const TrackingOptions& updatedOptions, const TrackingOptions& oldOptions);
+ const TrackingOptions& updatedOptions, const TrackingOptions& oldOptions);
/* ==== NI ============================================================================= */
/* ======== COMMANDS ====(Called from Client Thread)==================================== */
@@ -278,6 +283,9 @@ public:
uint32_t gnssDeleteAidingDataCommand(GnssAidingData& data);
void deleteAidingData(const GnssAidingData &data, uint32_t sessionId);
void gnssUpdateXtraThrottleCommand(const bool enabled);
+ std::vector<LocationError> gnssUpdateConfig(const std::string& oldServerUrl,
+ const std::string& oldMoServerUrl, const GnssConfig& gnssConfigRequested,
+ const GnssConfig& gnssConfigNeedEngineUpdate, size_t count = 0);
/* ==== GNSS SV TYPE CONFIG ============================================================ */
/* ==== COMMANDS ====(Called from Client Thread)======================================== */
@@ -304,11 +312,13 @@ public:
/* ======== COMMANDS ====(Called from Client Thread)==================================== */
void initDefaultAgpsCommand();
void initAgpsCommand(const AgpsCbInfo& cbInfo);
+ void initNfwCommand(const NfwCbInfo& cbInfo);
void dataConnOpenCommand(AGpsExtType agpsType,
const char* apnName, int apnLen, AGpsBearerType bearerType);
void dataConnClosedCommand(AGpsExtType agpsType);
void dataConnFailedCommand(AGpsExtType agpsType);
void getGnssEnergyConsumedCommand(GnssEnergyConsumedCallback energyConsumedCb);
+ void nfwControlCommand(bool enable);
/* ========= ODCPI ===================================================================== */
/* ======== COMMANDS ====(Called from Client Thread)==================================== */
@@ -321,9 +331,11 @@ public:
LocationControlCallbacks& getControlCallbacks() { return mControlCallbacks; }
void setControlCallbacks(const LocationControlCallbacks& controlCallbacks)
{ mControlCallbacks = controlCallbacks; }
+ void setAfwControlId(uint32_t id) { mPowerVoteId = id; }
+ uint32_t getAfwControlId() { return mPowerVoteId; }
void setPowerVoteId(uint32_t id) { mPowerVoteId = id; }
uint32_t getPowerVoteId() { return mPowerVoteId; }
- virtual bool isInSession() { return !mTrackingSessions.empty(); }
+ virtual bool isInSession() { return !mTimeBasedTrackingSessions.empty(); }
void initDefaultAgps();
bool initEngHubProxy();
void odcpiTimerExpireEvent();
@@ -342,9 +354,8 @@ public:
virtual void reportNmeaEvent(const char* nmea, size_t length);
virtual void reportDataEvent(const GnssDataNotification& dataNotify, int msInWeek);
virtual bool requestNiNotifyEvent(const GnssNiNotification& notify, const void* data);
- virtual void reportGnssMeasurementDataEvent(const GnssMeasurementsNotification& measurements,
+ virtual void reportGnssMeasurementsEvent(const GnssMeasurements& gnssMeasurements,
int msInWeek);
- virtual void reportSvMeasurementEvent(GnssSvMeasurementSet &svMeasurementSet);
virtual void reportSvPolynomialEvent(GnssSvPolynomial &svPolynomial);
virtual void reportSvEphemerisEvent(GnssSvEphemerisReport & svEphemeris);
virtual void reportGnssSvIdConfigEvent(const GnssSvIdConfig& config);
@@ -356,10 +367,15 @@ public:
virtual bool releaseATL(int connHandle);
virtual bool requestOdcpiEvent(OdcpiRequestInfo& request);
virtual bool reportDeleteAidingDataEvent(GnssAidingData& aidingData);
+ virtual bool reportKlobucharIonoModelEvent(GnssKlobucharIonoModel& ionoModel);
+ virtual bool reportGnssAdditionalSystemInfoEvent(
+ GnssAdditionalSystemInfo& additionalSystemInfo);
+ virtual void reportNfwNotificationEvent(GnssNfwNotification& notification);
/* ======== UTILITIES ================================================================= */
- bool needReport(const UlpLocation& ulpLocation,
+ bool needReportForGnssClient(const UlpLocation& ulpLocation,
enum loc_sess_status status, LocPosTechMask techMask);
+ bool needReportForFlpClient(enum loc_sess_status status, LocPosTechMask techMask);
void reportPosition(const UlpLocation &ulpLocation,
const GpsLocationExtended &locationExtended,
enum loc_sess_status status,
@@ -375,6 +391,11 @@ public:
void invokeGnssEnergyConsumedCallback(uint64_t energyConsumedSinceFirstBoot);
void saveGnssEnergyConsumedCallback(GnssEnergyConsumedCallback energyConsumedCb);
void reportLocationSystemInfo(const LocationSystemInfo & locationSystemInfo);
+ inline void reportNfwNotification(const GnssNfwNotification& notification) {
+ if (NULL != mNfwCb) {
+ mNfwCb(notification);
+ }
+ }
/*======== GNSSDEBUG ================================================================*/
bool getDebugReport(GnssDebugReport& report);
@@ -389,8 +410,6 @@ public:
std::string& getMoServerUrl(void) { return mMoServerUrl; }
/*==== CONVERSION ===================================================================*/
- static uint32_t convertGpsLock(const GnssConfigGpsLock gpsLock);
- static GnssConfigGpsLock convertGpsLock(const uint32_t gpsLock);
static uint32_t convertSuplVersion(const GnssConfigSuplVersion suplVersion);
static uint32_t convertLppProfile(const GnssConfigLppProfile lppProfile);
static uint32_t convertEP4ES(const GnssConfigEmergencyPdnForEmergencySupl);
@@ -414,6 +433,19 @@ public:
void injectTimeCommand(int64_t time, int64_t timeReference, int32_t uncertainty);
void blockCPICommand(double latitude, double longitude, float accuracy,
int blockDurationMsec, double latLonDiffThreshold);
+
+ /* ==== MISCELLANEOUS ================================================================== */
+ /* ======== COMMANDS ====(Called from Client Thread)==================================== */
+ void getPowerStateChangesCommand(void* powerStateCb);
+ /* ======== UTILITIES ================================================================== */
+ void reportPowerStateIfChanged();
+ void savePowerStateCallback(powerStateCallback powerStateCb){ mPowerStateCb = powerStateCb; }
+ bool getPowerState() { return mPowerOn; }
+ void setAllowFlpNetworkFixes(uint32_t allow) { mAllowFlpNetworkFixes = allow; }
+ uint32_t getAllowFlpNetworkFixes() { return mAllowFlpNetworkFixes; }
+ void setSuplHostServer(const char* server, int port, LocServerType type);
+ void notifyClientOfCachedLocationSystemInfo(LocationAPI* client,
+ const LocationCallbacks& callbacks);
};
#endif //GNSS_ADAPTER_H
diff --git a/gnss/XtraSystemStatusObserver.cpp b/gnss/XtraSystemStatusObserver.cpp
index 6df5480..6e1902c 100644
--- a/gnss/XtraSystemStatusObserver.cpp
+++ b/gnss/XtraSystemStatusObserver.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017, 2019, 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
@@ -56,7 +56,7 @@ using namespace loc_core;
#endif
#define LOG_TAG "LocSvc_XSSO"
-bool XtraSystemStatusObserver::updateLockStatus(uint32_t lock) {
+bool XtraSystemStatusObserver::updateLockStatus(GnssConfigGpsLock lock) {
mGpsLock = lock;
if (!mReqStatusReceived) {
@@ -69,17 +69,21 @@ bool XtraSystemStatusObserver::updateLockStatus(uint32_t lock) {
return ( send(LOC_IPC_XTRA, ss.str()) );
}
-bool XtraSystemStatusObserver::updateConnections(uint64_t allConnections) {
+bool XtraSystemStatusObserver::updateConnections(uint64_t allConnections,
+ uint64_t wifiNetworkHandle, uint64_t mobileNetworkHandle) {
mIsConnectivityStatusKnown = true;
mConnections = allConnections;
+ mWifiNetworkHandle = wifiNetworkHandle;
+ mMobileNetworkHandle = mobileNetworkHandle;
if (!mReqStatusReceived) {
return true;
}
stringstream ss;
- ss << "connection";
- ss << " " << mConnections;
+ ss << "connection" << endl << mConnections << endl << wifiNetworkHandle
+ << endl << mobileNetworkHandle;
+
return ( send(LOC_IPC_XTRA, ss.str()) );
}
@@ -134,6 +138,7 @@ inline bool XtraSystemStatusObserver::onStatusRequested(int32_t xtraStatusUpdate
ss << "respondStatus" << endl;
(mGpsLock == -1 ? ss : ss << mGpsLock) << endl;
(mConnections == (uint64_t)~0 ? ss : ss << mConnections) << endl
+ << mWifiNetworkHandle << endl << mMobileNetworkHandle << endl
<< mTac << endl << mMccmnc << endl << mIsConnectivityStatusKnown;
return ( send(LOC_IPC_XTRA, ss.str()) );
@@ -219,8 +224,11 @@ void XtraSystemStatusObserver::notify(const list<IDataItemCore*>& dlist)
}
inline ~HandleOsObserverUpdateMsg() {
- for (auto each : mDataItemList) {
- delete each;
+ for (auto itor = mDataItemList.begin(); itor != mDataItemList.end(); ++itor) {
+ if (*itor != nullptr) {
+ delete *itor;
+ *itor = nullptr;
+ }
}
}
@@ -232,7 +240,11 @@ void XtraSystemStatusObserver::notify(const list<IDataItemCore*>& dlist)
{
NetworkInfoDataItemBase* networkInfo =
static_cast<NetworkInfoDataItemBase*>(each);
- mXtraSysStatObj->updateConnections(networkInfo->getAllTypes());
+ mXtraSysStatObj->updateConnections(networkInfo->getAllTypes(),
+ (NetworkHandle) networkInfo->getNetworkHandle(
+ loc_core::NetworkInfoDataItemBase::TYPE_WIFI),
+ (NetworkHandle) networkInfo->getNetworkHandle(
+ loc_core::NetworkInfoDataItemBase::TYPE_MOBILE));
}
break;
diff --git a/gnss/XtraSystemStatusObserver.h b/gnss/XtraSystemStatusObserver.h
index b49a0bc..b93ecf2 100644
--- a/gnss/XtraSystemStatusObserver.h
+++ b/gnss/XtraSystemStatusObserver.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019, 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
@@ -46,7 +46,7 @@ public :
inline XtraSystemStatusObserver(IOsObserver* sysStatObs, const MsgTask* msgTask):
mSystemStatusObsrvr(sysStatObs), mMsgTask(msgTask),
mGpsLock(-1), mConnections(~0), mXtraThrottle(true), mReqStatusReceived(false),
- mDelayLocTimer(*this), mIsConnectivityStatusKnown (false) {
+ mIsConnectivityStatusKnown (false), mDelayLocTimer(*this) {
subscribe(true);
startListeningNonBlocking(LOC_IPC_HAL);
mDelayLocTimer.start(100 /*.1 sec*/, false);
@@ -60,8 +60,9 @@ public :
inline virtual void getName(string& name);
virtual void notify(const list<IDataItemCore*>& dlist);
- bool updateLockStatus(uint32_t lock);
- bool updateConnections(uint64_t allConnections);
+ bool updateLockStatus(GnssConfigGpsLock lock);
+ bool updateConnections(uint64_t allConnections,
+ uint64_t wifiNetworkHandle, uint64_t mobileNetworkHandle);
bool updateTac(const string& tac);
bool updateMccMnc(const string& mccmnc);
bool updateXtraThrottle(const bool enabled);
@@ -74,8 +75,10 @@ protected:
private:
IOsObserver* mSystemStatusObsrvr;
const MsgTask* mMsgTask;
- int32_t mGpsLock;
+ GnssConfigGpsLock mGpsLock;
uint64_t mConnections;
+ uint64_t mWifiNetworkHandle;
+ uint64_t mMobileNetworkHandle;
string mTac;
string mMccmnc;
bool mXtraThrottle;
diff --git a/gnss/location_gnss.cpp b/gnss/location_gnss.cpp
index f9fbddc..43665b4 100644
--- a/gnss/location_gnss.cpp
+++ b/gnss/location_gnss.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019, 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
@@ -65,8 +65,12 @@ static void agpsDataConnOpen(AGpsExtType agpsType, const char* apnName, int apnL
static void agpsDataConnClosed(AGpsExtType agpsType);
static void agpsDataConnFailed(AGpsExtType agpsType);
static void getDebugReport(GnssDebugReport& report);
-static void updateConnectionStatus(bool connected, int8_t type);
+static void updateConnectionStatus(bool connected, int8_t type, bool roaming = false,
+ NetworkHandle networkHandle = NETWORK_HANDLE_UNKNOWN);
static void getGnssEnergyConsumed(GnssEnergyConsumedCallback energyConsumedCb);
+static void enableNfwLocationAccess(bool enable);
+static void nfwInit(const NfwCbInfo& cbInfo);
+static void getPowerStateChanges(void* powerStateCb);
static void odcpiInit(const OdcpiRequestCallback& callback);
static void odcpiInject(const Location& location);
@@ -106,7 +110,10 @@ static const GnssInterface gGnssInterface = {
odcpiInit,
odcpiInject,
blockCPI,
- getGnssEnergyConsumed
+ getGnssEnergyConsumed,
+ enableNfwLocationAccess,
+ nfwInit,
+ getPowerStateChanges
};
#ifndef DEBUG_X86
@@ -313,9 +320,11 @@ static void getDebugReport(GnssDebugReport& report) {
}
}
-static void updateConnectionStatus(bool connected, int8_t type) {
+static void updateConnectionStatus(bool connected, int8_t type,
+ bool roaming, NetworkHandle networkHandle) {
if (NULL != gGnssAdapter) {
- gGnssAdapter->getSystemStatus()->eventConnectionStatus(connected, type);
+ gGnssAdapter->getSystemStatus()->eventConnectionStatus(
+ connected, type, roaming, networkHandle);
}
}
@@ -346,3 +355,21 @@ static void getGnssEnergyConsumed(GnssEnergyConsumedCallback energyConsumedCb) {
gGnssAdapter->getGnssEnergyConsumedCommand(energyConsumedCb);
}
}
+
+static void enableNfwLocationAccess(bool enable) {
+ if (NULL != gGnssAdapter) {
+ gGnssAdapter->nfwControlCommand(enable);
+ }
+}
+
+static void nfwInit(const NfwCbInfo& cbInfo) {
+ if (NULL != gGnssAdapter) {
+ gGnssAdapter->initNfwCommand(cbInfo);
+ }
+}
+static void getPowerStateChanges(void* powerStateCb)
+{
+ if (NULL != gGnssAdapter) {
+ gGnssAdapter->getPowerStateChangesCommand(powerStateCb);
+ }
+}
diff --git a/gps_vendor_board.mk b/gps_vendor_board.mk
new file mode 100644
index 0000000..be346dc
--- /dev/null
+++ b/gps_vendor_board.mk
@@ -0,0 +1,3 @@
+# Flags from BoardConfigVendor.mk
+BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE := default
+
diff --git a/gps_vendor_product.mk b/gps_vendor_product.mk
index cfe2b90..6e938b3 100644
--- a/gps_vendor_product.mk
+++ b/gps_vendor_product.mk
@@ -3,8 +3,12 @@ PRODUCT_PACKAGES += android.hardware.gnss@1.0-impl-qti
PRODUCT_PACKAGES += android.hardware.gnss@1.0-service-qti
PRODUCT_PACKAGES += android.hardware.gnss@1.1-impl-qti
PRODUCT_PACKAGES += android.hardware.gnss@1.1-service-qti
+PRODUCT_PACKAGES += android.hardware.gnss@2.0-impl-qti
+PRODUCT_PACKAGES += android.hardware.gnss@2.0-service-qti
PRODUCT_PACKAGES += gps.conf
PRODUCT_PACKAGES += libloc_core
PRODUCT_PACKAGES += libgnss
PRODUCT_PACKAGES += liblocation_api
PRODUCT_PACKAGES += libgps.utils
+PRODUCT_PACKAGES += libbatching
+PRODUCT_PACKAGES += libgeofencing
diff --git a/location/LocationAPI.cpp b/location/LocationAPI.cpp
index 4d859b3..a43178d 100644
--- a/location/LocationAPI.cpp
+++ b/location/LocationAPI.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019 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
@@ -34,15 +34,11 @@
#include <log_util.h>
#include <pthread.h>
#include <map>
+#include <loc_misc_utils.h>
-typedef void* (getLocationInterface)();
-
-typedef uint16_t LocationAdapterTypeMask;
-typedef enum {
- LOCATION_ADAPTER_GNSS_TYPE_BIT = (1<<0), // adapter type is GNSS
- LOCATION_ADAPTER_FLP_TYPE_BIT = (1<<1), // adapter type is FLP
- LOCATION_ADAPTER_GEOFENCE_TYPE_BIT = (1<<2) // adapter type is geo fence
-} LocationAdapterTypeBits;
+typedef const GnssInterface* (getGnssInterface)();
+typedef const GeofenceInterface* (getGeofenceInterface)();
+typedef const BatchingInterface* (getBatchingInterface)();
typedef struct {
// bit mask of the adpaters that we need to wait for the removeClientCompleteCallback
@@ -64,22 +60,24 @@ typedef struct {
LocationControlCallbacks controlCallbacks;
GnssInterface* gnssInterface;
GeofenceInterface* geofenceInterface;
- FlpInterface* flpInterface;
+ BatchingInterface* batchingInterface;
} LocationAPIData;
static LocationAPIData gData = {};
static pthread_mutex_t gDataMutex = PTHREAD_MUTEX_INITIALIZER;
static bool gGnssLoadFailed = false;
-static bool gFlpLoadFailed = false;
+static bool gBatchingLoadFailed = false;
static bool gGeofenceLoadFailed = false;
-static bool needsGnssTrackingInfo(LocationCallbacks& locationCallbacks)
-{
- return (locationCallbacks.gnssLocationInfoCb != nullptr ||
- locationCallbacks.gnssSvCb != nullptr ||
- locationCallbacks.gnssNmeaCb != nullptr ||
- locationCallbacks.gnssDataCb != nullptr ||
- locationCallbacks.gnssMeasurementsCb != nullptr);
+template <typename T1, typename T2>
+static const T1* loadLocationInterface(const char* library, const char* name) {
+ void* libhandle = nullptr;
+ T2* getter = (T2*)dlGetSymFromLib(libhandle, library, name);
+ if (nullptr == getter) {
+ return (const T1*) getter;
+ }else {
+ return (*getter)();
+ }
}
static bool isGnssClient(LocationCallbacks& locationCallbacks)
@@ -90,10 +88,9 @@ static bool isGnssClient(LocationCallbacks& locationCallbacks)
locationCallbacks.gnssMeasurementsCb != nullptr);
}
-static bool isFlpClient(LocationCallbacks& locationCallbacks)
+static bool isBatchingClient(LocationCallbacks& locationCallbacks)
{
- return (locationCallbacks.trackingCb != nullptr ||
- locationCallbacks.batchingCb != nullptr);
+ return (locationCallbacks.batchingCb != nullptr);
}
static bool isGeofenceClient(LocationCallbacks& locationCallbacks)
@@ -102,41 +99,14 @@ static bool isGeofenceClient(LocationCallbacks& locationCallbacks)
locationCallbacks.geofenceStatusCb != nullptr);
}
-static void* loadLocationInterface(const char* library, const char* name)
-{
- LOC_LOGD("%s]: loading %s::%s ...", __func__, library, name);
- if (NULL == library || NULL == name) {
- return NULL;
- }
- getLocationInterface* getter = NULL;
- const char *error = NULL;
- dlerror();
- void *handle = dlopen(library, RTLD_NOW);
- if (NULL == handle || (error = dlerror()) != NULL) {
- LOC_LOGW("dlopen for %s failed, error = %s", library, error);
- } else {
- getter = (getLocationInterface*)dlsym(handle, name);
- if ((error = dlerror()) != NULL) {
- LOC_LOGW("dlsym for %s::%s failed, error = %s", library, name, error);
- getter = NULL;
- }
- }
- if (NULL == getter) {
- return (void*)getter;
- } else {
- return (*getter)();
- }
-}
-
-void onRemoveClientCompleteCb (
- LocationAPI* client, LocationAdapterTypeMask adapterType)
+void LocationAPI::onRemoveClientCompleteCb (LocationAdapterTypeMask adapterType)
{
bool invokeCallback = false;
locationApiDestroyCompleteCallback destroyCompleteCb;
LOC_LOGd("adatper type %x", adapterType);
pthread_mutex_lock(&gDataMutex);
- auto it = gData.destroyClientData.find(client);
+ auto it = gData.destroyClientData.find(this);
if (it != gData.destroyClientData.end()) {
it->second.waitAdapterMask &= ~adapterType;
if (it->second.waitAdapterMask == 0) {
@@ -151,22 +121,24 @@ void onRemoveClientCompleteCb (
LOC_LOGd("invoke client destroy cb");
(destroyCompleteCb) ();
LOC_LOGd("finish invoke client destroy cb");
+
+ delete this;
}
}
void onGnssRemoveClientCompleteCb (LocationAPI* client)
{
- onRemoveClientCompleteCb (client, LOCATION_ADAPTER_GNSS_TYPE_BIT);
+ client->onRemoveClientCompleteCb (LOCATION_ADAPTER_GNSS_TYPE_BIT);
}
-void onFlpRemoveClientCompleteCb (LocationAPI* client)
+void onBatchingRemoveClientCompleteCb (LocationAPI* client)
{
- onRemoveClientCompleteCb (client, LOCATION_ADAPTER_FLP_TYPE_BIT);
+ client->onRemoveClientCompleteCb (LOCATION_ADAPTER_BATCHING_TYPE_BIT);
}
void onGeofenceRemoveClientCompleteCb (LocationAPI* client)
{
- onRemoveClientCompleteCb (client, LOCATION_ADAPTER_GEOFENCE_TYPE_BIT);
+ client->onRemoveClientCompleteCb (LOCATION_ADAPTER_GEOFENCE_TYPE_BIT);
}
LocationAPI*
@@ -186,7 +158,8 @@ LocationAPI::createInstance(LocationCallbacks& locationCallbacks)
if (isGnssClient(locationCallbacks)) {
if (NULL == gData.gnssInterface && !gGnssLoadFailed) {
gData.gnssInterface =
- (GnssInterface*)loadLocationInterface("libgnss.so", "getGnssInterface");
+ (GnssInterface*)loadLocationInterface<GnssInterface,
+ getGnssInterface>("libgnss.so", "getGnssInterface");
if (NULL == gData.gnssInterface) {
gGnssLoadFailed = true;
LOC_LOGW("%s:%d]: No gnss interface available", __func__, __LINE__);
@@ -203,21 +176,22 @@ LocationAPI::createInstance(LocationCallbacks& locationCallbacks)
}
}
- if (isFlpClient(locationCallbacks)) {
- if (NULL == gData.flpInterface && !gFlpLoadFailed) {
- gData.flpInterface =
- (FlpInterface*)loadLocationInterface("libflp.so", "getFlpInterface");
- if (NULL == gData.flpInterface) {
- gFlpLoadFailed = true;
- LOC_LOGW("%s:%d]: No flp interface available", __func__, __LINE__);
+ if (isBatchingClient(locationCallbacks)) {
+ if (NULL == gData.batchingInterface && !gBatchingLoadFailed) {
+ gData.batchingInterface =
+ (BatchingInterface*)loadLocationInterface<BatchingInterface,
+ getBatchingInterface>("libbatching.so", "getBatchingInterface");
+ if (NULL == gData.batchingInterface) {
+ gBatchingLoadFailed = true;
+ LOC_LOGW("%s:%d]: No batching interface available", __func__, __LINE__);
} else {
- gData.flpInterface->initialize();
+ gData.batchingInterface->initialize();
}
}
- if (NULL != gData.flpInterface) {
- gData.flpInterface->addClient(newLocationAPI, locationCallbacks);
+ if (NULL != gData.batchingInterface) {
+ gData.batchingInterface->addClient(newLocationAPI, locationCallbacks);
if (!requestedCapabilities) {
- gData.flpInterface->requestCapabilities(newLocationAPI);
+ gData.batchingInterface->requestCapabilities(newLocationAPI);
requestedCapabilities = true;
}
}
@@ -226,7 +200,8 @@ LocationAPI::createInstance(LocationCallbacks& locationCallbacks)
if (isGeofenceClient(locationCallbacks)) {
if (NULL == gData.geofenceInterface && !gGeofenceLoadFailed) {
gData.geofenceInterface =
- (GeofenceInterface*)loadLocationInterface("libgeofence.so", "getGeofenceInterface");
+ (GeofenceInterface*)loadLocationInterface<GeofenceInterface,
+ getGeofenceInterface>("libgeofencing.so", "getGeofenceInterface");
if (NULL == gData.geofenceInterface) {
gGeofenceLoadFailed = true;
LOC_LOGW("%s:%d]: No geofence interface available", __func__, __LINE__);
@@ -260,13 +235,14 @@ LocationAPI::destroy(locationApiDestroyCompleteCallback destroyCompleteCb)
if (it != gData.clientData.end()) {
bool removeFromGnssInf =
(isGnssClient(it->second) && NULL != gData.gnssInterface);
- bool removeFromFlpInf =
- (isFlpClient(it->second) && NULL != gData.flpInterface);
+ bool removeFromBatchingInf =
+ (isBatchingClient(it->second) && NULL != gData.batchingInterface);
bool removeFromGeofenceInf =
(isGeofenceClient(it->second) && NULL != gData.geofenceInterface);
- bool needToWait = (removeFromGnssInf || removeFromFlpInf || removeFromGeofenceInf);
- LOC_LOGe("removeFromGnssInf: %d, removeFromFlpInf: %d, removeFromGeofenceInf: %d, need %d",
- removeFromGnssInf, removeFromFlpInf, removeFromGeofenceInf, needToWait);
+ bool needToWait = (removeFromGnssInf || removeFromBatchingInf || removeFromGeofenceInf);
+ LOC_LOGe("removeFromGnssInf: %d, removeFromBatchingInf: %d, removeFromGeofenceInf: %d,"
+ "need %d", removeFromGnssInf, removeFromBatchingInf, removeFromGeofenceInf,
+ needToWait);
if ((NULL != destroyCompleteCb) && (true == needToWait)) {
LocationAPIDestroyCbData destroyCbData = {};
@@ -277,7 +253,7 @@ LocationAPI::destroy(locationApiDestroyCompleteCallback destroyCompleteCb)
destroyCbData.waitAdapterMask =
(removeFromGnssInf ? LOCATION_ADAPTER_GNSS_TYPE_BIT : 0);
destroyCbData.waitAdapterMask |=
- (removeFromFlpInf ? LOCATION_ADAPTER_FLP_TYPE_BIT : 0);
+ (removeFromBatchingInf ? LOCATION_ADAPTER_BATCHING_TYPE_BIT : 0);
destroyCbData.waitAdapterMask |=
(removeFromGeofenceInf ? LOCATION_ADAPTER_GEOFENCE_TYPE_BIT : 0);
gData.destroyClientData[this] = destroyCbData;
@@ -288,9 +264,9 @@ LocationAPI::destroy(locationApiDestroyCompleteCallback destroyCompleteCb)
gData.gnssInterface->removeClient(it->first,
onGnssRemoveClientCompleteCb);
}
- if (removeFromFlpInf) {
- gData.flpInterface->removeClient(it->first,
- onFlpRemoveClientCompleteCb);
+ if (removeFromBatchingInf) {
+ gData.batchingInterface->removeClient(it->first,
+ onBatchingRemoveClientCompleteCb);
}
if (removeFromGeofenceInf) {
gData.geofenceInterface->removeClient(it->first,
@@ -310,6 +286,7 @@ LocationAPI::destroy(locationApiDestroyCompleteCallback destroyCompleteCb)
pthread_mutex_unlock(&gDataMutex);
if (invokeDestroyCb == true) {
(destroyCompleteCb) ();
+ delete this;
}
}
@@ -321,6 +298,7 @@ LocationAPI::LocationAPI()
// private destructor
LocationAPI::~LocationAPI()
{
+ LOC_LOGD("LOCATION API DESTRUCTOR");
}
void
@@ -337,7 +315,8 @@ LocationAPI::updateCallbacks(LocationCallbacks& locationCallbacks)
if (isGnssClient(locationCallbacks)) {
if (NULL == gData.gnssInterface && !gGnssLoadFailed) {
gData.gnssInterface =
- (GnssInterface*)loadLocationInterface("libgnss.so", "getGnssInterface");
+ (GnssInterface*)loadLocationInterface<GnssInterface,
+ getGnssInterface>("libgnss.so", "getGnssInterface");
if (NULL == gData.gnssInterface) {
gGnssLoadFailed = true;
LOC_LOGW("%s:%d]: No gnss interface available", __func__, __LINE__);
@@ -351,27 +330,29 @@ LocationAPI::updateCallbacks(LocationCallbacks& locationCallbacks)
}
}
- if (isFlpClient(locationCallbacks)) {
- if (NULL == gData.flpInterface && !gFlpLoadFailed) {
- gData.flpInterface =
- (FlpInterface*)loadLocationInterface("libflp.so", "getFlpInterface");
- if (NULL == gData.flpInterface) {
- gFlpLoadFailed = true;
- LOC_LOGW("%s:%d]: No flp interface available", __func__, __LINE__);
+ if (isBatchingClient(locationCallbacks)) {
+ if (NULL == gData.batchingInterface && !gBatchingLoadFailed) {
+ gData.batchingInterface =
+ (BatchingInterface*)loadLocationInterface<BatchingInterface,
+ getBatchingInterface>("libbatching.so", "getBatchingInterface");
+ if (NULL == gData.batchingInterface) {
+ gBatchingLoadFailed = true;
+ LOC_LOGW("%s:%d]: No batching interface available", __func__, __LINE__);
} else {
- gData.flpInterface->initialize();
+ gData.batchingInterface->initialize();
}
}
- if (NULL != gData.flpInterface) {
+ if (NULL != gData.batchingInterface) {
// either adds new Client or updates existing Client
- gData.flpInterface->addClient(this, locationCallbacks);
+ gData.batchingInterface->addClient(this, locationCallbacks);
}
}
if (isGeofenceClient(locationCallbacks)) {
if (NULL == gData.geofenceInterface && !gGeofenceLoadFailed) {
gData.geofenceInterface =
- (GeofenceInterface*)loadLocationInterface("libgeofence.so", "getGeofenceInterface");
+ (GeofenceInterface*)loadLocationInterface<GeofenceInterface,
+ getGeofenceInterface>("libgeofencing.so", "getGeofenceInterface");
if (NULL == gData.geofenceInterface) {
gGeofenceLoadFailed = true;
LOC_LOGW("%s:%d]: No geofence interface available", __func__, __LINE__);
@@ -398,16 +379,10 @@ LocationAPI::startTracking(TrackingOptions& trackingOptions)
auto it = gData.clientData.find(this);
if (it != gData.clientData.end()) {
- if (NULL != gData.flpInterface && trackingOptions.minDistance > 0) {
- id = gData.flpInterface->startTracking(this, trackingOptions);
- } else if (NULL != gData.gnssInterface && needsGnssTrackingInfo(it->second)) {
- id = gData.gnssInterface->startTracking(this, trackingOptions);
- } else if (NULL != gData.flpInterface) {
- id = gData.flpInterface->startTracking(this, trackingOptions);
- } else if (NULL != gData.gnssInterface) {
+ if (NULL != gData.gnssInterface) {
id = gData.gnssInterface->startTracking(this, trackingOptions);
} else {
- LOC_LOGE("%s:%d]: No gnss/flp interface available for Location API client %p ",
+ LOC_LOGE("%s:%d]: No gnss interface available for Location API client %p ",
__func__, __LINE__, this);
}
} else {
@@ -426,16 +401,10 @@ LocationAPI::stopTracking(uint32_t id)
auto it = gData.clientData.find(this);
if (it != gData.clientData.end()) {
- // we don't know if tracking was started on flp or gnss, so we call stop on both, where
- // stopTracking call to the incorrect interface will fail without response back to client
if (gData.gnssInterface != NULL) {
gData.gnssInterface->stopTracking(this, id);
- }
- if (gData.flpInterface != NULL) {
- gData.flpInterface->stopTracking(this, id);
- }
- if (gData.flpInterface == NULL && gData.gnssInterface == NULL) {
- LOC_LOGE("%s:%d]: No gnss/flp interface available for Location API client %p ",
+ } else {
+ LOC_LOGE("%s:%d]: No gnss interface available for Location API client %p ",
__func__, __LINE__, this);
}
} else {
@@ -454,16 +423,10 @@ LocationAPI::updateTrackingOptions(
auto it = gData.clientData.find(this);
if (it != gData.clientData.end()) {
- // we don't know if tracking was started on flp or gnss, so we call update on both, where
- // updateTracking call to the incorrect interface will fail without response back to client
if (gData.gnssInterface != NULL) {
gData.gnssInterface->updateTrackingOptions(this, id, trackingOptions);
- }
- if (gData.flpInterface != NULL) {
- gData.flpInterface->updateTrackingOptions(this, id, trackingOptions);
- }
- if (gData.flpInterface == NULL && gData.gnssInterface == NULL) {
- LOC_LOGE("%s:%d]: No gnss/flp interface available for Location API client %p ",
+ } else {
+ LOC_LOGE("%s:%d]: No gnss interface available for Location API client %p ",
__func__, __LINE__, this);
}
} else {
@@ -480,10 +443,10 @@ LocationAPI::startBatching(BatchingOptions &batchingOptions)
uint32_t id = 0;
pthread_mutex_lock(&gDataMutex);
- if (NULL != gData.flpInterface) {
- id = gData.flpInterface->startBatching(this, batchingOptions);
+ if (NULL != gData.batchingInterface) {
+ id = gData.batchingInterface->startBatching(this, batchingOptions);
} else {
- LOC_LOGE("%s:%d]: No flp interface available for Location API client %p ",
+ LOC_LOGE("%s:%d]: No batching interface available for Location API client %p ",
__func__, __LINE__, this);
}
@@ -496,10 +459,10 @@ LocationAPI::stopBatching(uint32_t id)
{
pthread_mutex_lock(&gDataMutex);
- if (NULL != gData.flpInterface) {
- gData.flpInterface->stopBatching(this, id);
+ if (NULL != gData.batchingInterface) {
+ gData.batchingInterface->stopBatching(this, id);
} else {
- LOC_LOGE("%s:%d]: No flp interface available for Location API client %p ",
+ LOC_LOGE("%s:%d]: No batching interface available for Location API client %p ",
__func__, __LINE__, this);
}
@@ -511,10 +474,10 @@ LocationAPI::updateBatchingOptions(uint32_t id, BatchingOptions& batchOptions)
{
pthread_mutex_lock(&gDataMutex);
- if (NULL != gData.flpInterface) {
- gData.flpInterface->updateBatchingOptions(this, id, batchOptions);
+ if (NULL != gData.batchingInterface) {
+ gData.batchingInterface->updateBatchingOptions(this, id, batchOptions);
} else {
- LOC_LOGE("%s:%d]: No flp interface available for Location API client %p ",
+ LOC_LOGE("%s:%d]: No batching interface available for Location API client %p ",
__func__, __LINE__, this);
}
@@ -526,10 +489,10 @@ LocationAPI::getBatchedLocations(uint32_t id, size_t count)
{
pthread_mutex_lock(&gDataMutex);
- if (gData.flpInterface != NULL) {
- gData.flpInterface->getBatchedLocations(this, id, count);
+ if (gData.batchingInterface != NULL) {
+ gData.batchingInterface->getBatchedLocations(this, id, count);
} else {
- LOC_LOGE("%s:%d]: No flp interface available for Location API client %p ",
+ LOC_LOGE("%s:%d]: No batching interface available for Location API client %p ",
__func__, __LINE__, this);
}
@@ -637,7 +600,8 @@ LocationControlAPI::createInstance(LocationControlCallbacks& locationControlCall
if (nullptr != locationControlCallbacks.responseCb && NULL == gData.controlAPI) {
if (NULL == gData.gnssInterface && !gGnssLoadFailed) {
gData.gnssInterface =
- (GnssInterface*)loadLocationInterface("libgnss.so", "getGnssInterface");
+ (GnssInterface*)loadLocationInterface<GnssInterface,
+ getGnssInterface>("libgnss.so", "getGnssInterface");
if (NULL == gData.gnssInterface) {
gGnssLoadFailed = true;
LOC_LOGW("%s:%d]: No gnss interface available", __func__, __LINE__);
diff --git a/location/LocationAPI.h b/location/LocationAPI.h
index c270ef4..6f5987c 100644
--- a/location/LocationAPI.h
+++ b/location/LocationAPI.h
@@ -52,6 +52,8 @@ public:
*/
void destroy(locationApiDestroyCompleteCallback destroyCompleteCb=nullptr);
+ void onRemoveClientCompleteCb (LocationAdapterTypeMask adapterType);
+
/* updates/changes the callbacks that will be called.
mandatory callbacks must be present for callbacks to be successfully updated
no return value */
diff --git a/location/LocationAPIClientBase.h b/location/LocationAPIClientBase.h
index da87535..fddae60 100644
--- a/location/LocationAPIClientBase.h
+++ b/location/LocationAPIClientBase.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019 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
diff --git a/location/LocationDataTypes.h b/location/LocationDataTypes.h
index 61598be..f8bb6cb 100644
--- a/location/LocationDataTypes.h
+++ b/location/LocationDataTypes.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2018 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2018-2019 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
@@ -38,7 +38,7 @@
#define GNSS_NI_REQUESTOR_MAX (256)
#define GNSS_NI_MESSAGE_ID_MAX (2048)
#define GNSS_SV_MAX (176)
-#define GNSS_MEASUREMENTS_MAX (64)
+#define GNSS_MEASUREMENTS_MAX (128)
#define GNSS_UTC_TIME_OFFSET (3657)
#define GNSS_BUGREPORT_GPS_MIN (1)
@@ -48,6 +48,8 @@
#define GNSS_BUGREPORT_BDS_MIN (1)
#define GNSS_BUGREPORT_GAL_MIN (1)
+#define GNSS_MAX_NAME_LENGTH (8)
+
typedef enum {
LOCATION_ERROR_SUCCESS = 0,
LOCATION_ERROR_GENERAL_FAILURE,
@@ -223,12 +225,13 @@ typedef enum {
} LocationTechnologyType;
// Configures how GPS is locked when GPS is disabled (through GnssDisable)
-typedef enum {
+enum {
GNSS_CONFIG_GPS_LOCK_NONE = 0, // gps is not locked when GPS is disabled (GnssDisable)
GNSS_CONFIG_GPS_LOCK_MO, // gps mobile originated (MO) is locked when GPS is disabled
GNSS_CONFIG_GPS_LOCK_NI, // gps network initiated (NI) is locked when GPS is disabled
GNSS_CONFIG_GPS_LOCK_MO_AND_NI,// gps MO and NI is locked when GPS is disabled
-} GnssConfigGpsLock;
+};
+typedef int32_t GnssConfigGpsLock;
// SUPL version
typedef enum {
@@ -303,6 +306,7 @@ typedef enum {
GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT = (1<<8),
GNSS_CONFIG_FLAGS_SUPL_MODE_BIT = (1<<9),
GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT = (1<<10),
+ GNSS_CONFIG_FLAGS_EMERGENCY_EXTENSION_SECONDS_BIT = (1<<11),
} GnssConfigFlagsBits;
typedef enum {
@@ -374,6 +378,8 @@ typedef enum {
typedef enum {
GNSS_ASSISTANCE_TYPE_SUPL = 0,
GNSS_ASSISTANCE_TYPE_C2K,
+ GNSS_ASSISTANCE_TYPE_SUPL_EIMS,
+ GNSS_ASSISTANCE_TYPE_SUPL_IMS,
} GnssAssistanceType;
typedef enum {
@@ -396,12 +402,31 @@ typedef enum {
typedef uint16_t GnssMeasurementsAdrStateMask;
typedef enum {
- GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_UNKNOWN = 0,
- GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_VALID_BIT = (1<<0),
- GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_RESET_BIT = (1<<1),
- GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_CYCLE_SLIP_BIT = (1<<2),
+ GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_UNKNOWN = 0,
+ GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_VALID_BIT = (1<<0),
+ GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_RESET_BIT = (1<<1),
+ GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_CYCLE_SLIP_BIT = (1<<2),
+ GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_HALF_CYCLE_RESOLVED_BIT = (1<<3),
} GnssMeasurementsAdrStateBits;
+typedef enum {
+ GNSS_MEASUREMENTS_CODE_TYPE_A = 0,
+ GNSS_MEASUREMENTS_CODE_TYPE_B = 1,
+ GNSS_MEASUREMENTS_CODE_TYPE_C = 2,
+ GNSS_MEASUREMENTS_CODE_TYPE_I = 3,
+ GNSS_MEASUREMENTS_CODE_TYPE_L = 4,
+ GNSS_MEASUREMENTS_CODE_TYPE_M = 5,
+ GNSS_MEASUREMENTS_CODE_TYPE_P = 6,
+ GNSS_MEASUREMENTS_CODE_TYPE_Q = 7,
+ GNSS_MEASUREMENTS_CODE_TYPE_S = 8,
+ GNSS_MEASUREMENTS_CODE_TYPE_W = 9,
+ GNSS_MEASUREMENTS_CODE_TYPE_X = 10,
+ GNSS_MEASUREMENTS_CODE_TYPE_Y = 11,
+ GNSS_MEASUREMENTS_CODE_TYPE_Z = 12,
+ GNSS_MEASUREMENTS_CODE_TYPE_N = 13,
+ GNSS_MEASUREMENTS_CODE_TYPE_OTHER = 255,
+} GnssMeasurementsCodeType;
+
typedef uint32_t GnssMeasurementsDataFlagsMask;
typedef enum {
GNSS_MEASUREMENTS_DATA_SV_ID_BIT = (1<<0),
@@ -441,6 +466,9 @@ typedef enum {
GNSS_MEASUREMENTS_STATE_GAL_E1C_2ND_CODE_LOCK_BIT = (1<<11),
GNSS_MEASUREMENTS_STATE_GAL_E1B_PAGE_SYNC_BIT = (1<<12),
GNSS_MEASUREMENTS_STATE_SBAS_SYNC_BIT = (1<<13),
+ GNSS_MEASUREMENTS_STATE_TOW_KNOWN_BIT = (1<<14),
+ GNSS_MEASUREMENTS_STATE_GLO_TOD_KNOWN_BIT = (1<<15),
+ GNSS_MEASUREMENTS_STATE_2ND_CODE_LOCK_BIT = (1<<16),
} GnssMeasurementsStateBits;
typedef enum {
@@ -488,6 +516,22 @@ typedef enum {
GNSS_AIDING_DATA_SV_TYPE_GALILEO_BIT = (1<<4),
} GnssAidingDataSvTypeBits;
+/* Gnss constellation type mask */
+typedef uint16_t GnssConstellationTypeMask;
+typedef enum {
+ GNSS_CONSTELLATION_TYPE_GPS_BIT = (1<<0),
+ GNSS_CONSTELLATION_TYPE_GLONASS_BIT = (1<<1),
+ GNSS_CONSTELLATION_TYPE_QZSS_BIT = (1<<2),
+ GNSS_CONSTELLATION_TYPE_BEIDOU_BIT = (1<<3),
+ GNSS_CONSTELLATION_TYPE_GALILEO_BIT = (1<<4),
+ GNSS_CONSTELLATION_TYPE_SBAS_BIT = (1<<5)
+} GnssConstellationTypeBits;
+
+#define GNSS_CONSTELLATION_TYPE_MASK_ALL\
+ (GNSS_CONSTELLATION_TYPE_GPS_BIT | GNSS_CONSTELLATION_TYPE_GLONASS_BIT |\
+ GNSS_CONSTELLATION_TYPE_QZSS_BIT | GNSS_CONSTELLATION_TYPE_BEIDOU_BIT |\
+ GNSS_CONSTELLATION_TYPE_GALILEO_BIT | GNSS_CONSTELLATION_TYPE_SBAS_BIT)
+
/** GNSS Signal Type and RF Band */
typedef uint32_t GnssSignalTypeMask;
typedef enum {
@@ -529,21 +573,29 @@ typedef enum {
GNSS_SIGNAL_SBAS_L1 = (1<<17)
} GnssSignalTypeBits;
+#define GNSS_SIGNAL_TYPE_MASK_ALL\
+ (GNSS_SIGNAL_GPS_L1CA | GNSS_SIGNAL_GPS_L1C | GNSS_SIGNAL_GPS_L2 |\
+ GNSS_SIGNAL_GPS_L5| GNSS_SIGNAL_GLONASS_G1 | GNSS_SIGNAL_GLONASS_G2 |\
+ GNSS_SIGNAL_GALILEO_E1 | GNSS_SIGNAL_GALILEO_E5A | GNSS_SIGNAL_GALILEO_E5B |\
+ GNSS_SIGNAL_BEIDOU_B1I | GNSS_SIGNAL_BEIDOU_B1C | GNSS_SIGNAL_BEIDOU_B2I|\
+ GNSS_SIGNAL_BEIDOU_B2AI | GNSS_SIGNAL_QZSS_L1CA | GNSS_SIGNAL_QZSS_L1S |\
+ GNSS_SIGNAL_QZSS_L2| GNSS_SIGNAL_QZSS_L5 | GNSS_SIGNAL_SBAS_L1)
+
typedef enum
{
+ GNSS_LOC_SV_SYSTEM_UNKNOWN = 0,
+ /** unknown sv system. */
GNSS_LOC_SV_SYSTEM_GPS = 1,
/**< GPS satellite. */
GNSS_LOC_SV_SYSTEM_GALILEO = 2,
/**< GALILEO satellite. */
GNSS_LOC_SV_SYSTEM_SBAS = 3,
/**< SBAS satellite. */
- GNSS_LOC_SV_SYSTEM_COMPASS = 4,
- /**< COMPASS satellite. */
- GNSS_LOC_SV_SYSTEM_GLONASS = 5,
+ GNSS_LOC_SV_SYSTEM_GLONASS = 4,
/**< GLONASS satellite. */
- GNSS_LOC_SV_SYSTEM_BDS = 6,
+ GNSS_LOC_SV_SYSTEM_BDS = 5,
/**< BDS satellite. */
- GNSS_LOC_SV_SYSTEM_QZSS = 7
+ GNSS_LOC_SV_SYSTEM_QZSS = 6
/**< QZSS satellite. */
} Gnss_LocSvSystemEnumType;
@@ -590,7 +642,7 @@ typedef enum {
typedef uint32_t GnssGloTimeStructTypeFlags;
typedef enum {
GNSS_CLO_DAYS_VALID = (1 << 0),
- GNSS_GLOS_MSEC_VALID = (1 << 1),
+ GNSS_GLO_MSEC_VALID = (1 << 1),
GNSS_GLO_CLK_TIME_BIAS_VALID = (1 << 2),
GNSS_GLO_CLK_TIME_BIAS_UNC_VALID = (1 << 3),
GNSS_GLO_REF_FCOUNT_VALID = (1 << 4),
@@ -624,7 +676,7 @@ typedef struct {
} GnssAidingData;
typedef struct {
- size_t size; // set to sizeof(Location)
+ uint32_t size; // set to sizeof(Location)
LocationFlagsMask flags; // bitwise OR of LocationFlagsBits to mark which params are valid
uint64_t timestamp; // UTC timestamp for location fix, milliseconds since January 1, 1970
double latitude; // in degrees
@@ -641,7 +693,7 @@ typedef struct {
} Location;
struct LocationOptions {
- size_t size; // set to sizeof(LocationOptions)
+ uint32_t size; // set to sizeof(LocationOptions)
uint32_t minInterval; // in milliseconds
uint32_t minDistance; // in meters. if minDistance > 0, gnssSvCallback/gnssNmeaCallback/
// gnssMeasurementsCallback may not be called
@@ -668,7 +720,7 @@ struct TrackingOptions : LocationOptions {
inline TrackingOptions() :
LocationOptions(), powerMode(GNSS_POWER_MODE_INVALID), tbm(0) {}
- inline TrackingOptions(size_t s, GnssPowerMode m, uint32_t t) :
+ inline TrackingOptions(uint32_t s, GnssPowerMode m, uint32_t t) :
LocationOptions(), powerMode(m), tbm(t) { LocationOptions::size = s; }
inline TrackingOptions(const LocationOptions& options) :
LocationOptions(options), powerMode(GNSS_POWER_MODE_INVALID), tbm(0) {}
@@ -692,7 +744,7 @@ struct BatchingOptions : LocationOptions {
inline BatchingOptions() :
LocationOptions(), batchingMode(BATCHING_MODE_ROUTINE) {}
- inline BatchingOptions(size_t s, BatchingMode m) :
+ inline BatchingOptions(uint32_t s, BatchingMode m) :
LocationOptions(), batchingMode(m) { LocationOptions::size = s; }
inline BatchingOptions(const LocationOptions& options) :
LocationOptions(options), batchingMode(BATCHING_MODE_ROUTINE) {}
@@ -704,27 +756,27 @@ struct BatchingOptions : LocationOptions {
};
typedef struct {
- size_t size;
+ uint32_t size;
BatchingStatus batchingStatus;
} BatchingStatusInfo;
typedef struct {
- size_t size; // set to sizeof(GeofenceOption)
+ uint32_t size; // set to sizeof(GeofenceOption)
GeofenceBreachTypeMask breachTypeMask; // bitwise OR of GeofenceBreachTypeBits
uint32_t responsiveness; // in milliseconds
uint32_t dwellTime; // in seconds
} GeofenceOption;
typedef struct {
- size_t size; // set to sizeof(GeofenceInfo)
+ uint32_t size; // set to sizeof(GeofenceInfo)
double latitude; // in degrees
double longitude; // in degrees
double radius; // in meters
} GeofenceInfo;
typedef struct {
- size_t size; // set to sizeof(GeofenceBreachNotification)
- size_t count; // number of ids in array
+ uint32_t size; // set to sizeof(GeofenceBreachNotification)
+ uint32_t count; // number of ids in array
uint32_t* ids; // array of ids that have breached
Location location; // location associated with breach
GeofenceBreachType type; // type of breach
@@ -732,7 +784,7 @@ typedef struct {
} GeofenceBreachNotification;
typedef struct {
- size_t size; // set to sizeof(GeofenceBreachNotification)
+ uint32_t size; // set to sizeof(GeofenceBreachNotification)
GeofenceStatusAvailable available; // GEOFENCE_STATUS_AVAILABILE_NO/_YES
LocationTechnologyType techType; // GNSS
} GeofenceStatusNotification;
@@ -866,7 +918,7 @@ typedef struct {
} GnssSystemTime;
typedef struct {
- size_t size; // set to sizeof(GnssLocationInfo)
+ uint32_t size; // set to sizeof(GnssLocationInfo)
GnssLocationInfoFlagMask flags; // bitwise OR of GnssLocationInfoBits for param validity
float altitudeMeanSeaLevel; // altitude wrt mean sea level
float pdop; // position dilusion of precision
@@ -902,7 +954,7 @@ typedef struct {
} GnssLocationInfoNotification;
typedef struct {
- size_t size; // set to sizeof(GnssNiNotification)
+ uint32_t size; // set to sizeof(GnssNiNotification)
GnssNiType type; // type of NI (Voice, SUPL, Control Plane)
GnssNiOptionsMask options; // bitwise OR of GnssNiOptionsBits
uint32_t timeout; // time (seconds) to wait for user input
@@ -915,7 +967,7 @@ typedef struct {
} GnssNiNotification;
typedef struct {
- size_t size; // set to sizeof(GnssSv)
+ uint32_t size; // set to sizeof(GnssSv)
uint16_t svId; // Unique Identifier
GnssSvType type; // type of SV (GPS, SBAS, GLONASS, QZSS, BEIDOU, GALILEO)
float cN0Dbhz; // signal strength
@@ -927,7 +979,7 @@ typedef struct {
} GnssSv;
struct GnssConfigSetAssistanceServer {
- size_t size; // set to sizeof(GnssConfigSetAssistanceServer)
+ uint32_t size; // set to sizeof(GnssConfigSetAssistanceServer)
GnssAssistanceType type; // SUPL or C2K
const char* hostName; // null terminated string
uint32_t port; // port of server
@@ -944,7 +996,7 @@ struct GnssConfigSetAssistanceServer {
};
typedef struct {
- size_t size; // set to sizeof(GnssMeasurementsData)
+ uint32_t size; // set to sizeof(GnssMeasurementsData)
GnssMeasurementsDataFlagsMask flags; // bitwise OR of GnssMeasurementsDataFlagsBits
int16_t svId;
GnssSvType svType;
@@ -965,10 +1017,12 @@ typedef struct {
GnssMeasurementsMultipathIndicator multipathIndicator;
double signalToNoiseRatioDb;
double agcLevelDb;
+ GnssMeasurementsCodeType codeType;
+ char otherCodeTypeName[GNSS_MAX_NAME_LENGTH];
} GnssMeasurementsData;
typedef struct {
- size_t size; // set to sizeof(GnssMeasurementsClock)
+ uint32_t size; // set to sizeof(GnssMeasurementsClock)
GnssMeasurementsClockFlagsMask flags; // bitwise OR of GnssMeasurementsClockFlagsBits
int16_t leapSecond;
int64_t timeNs;
@@ -982,29 +1036,29 @@ typedef struct {
} GnssMeasurementsClock;
typedef struct {
- size_t size; // set to sizeof(GnssSvNotification)
- size_t count; // number of SVs in the GnssSv array
+ uint32_t size; // set to sizeof(GnssSvNotification)
+ uint32_t count; // number of SVs in the GnssSv array
bool gnssSignalTypeMaskValid;
GnssSv gnssSvs[GNSS_SV_MAX]; // information on a number of SVs
} GnssSvNotification;
typedef struct {
- size_t size; // set to sizeof(GnssNmeaNotification)
+ uint32_t size; // set to sizeof(GnssNmeaNotification)
uint64_t timestamp; // timestamp
const char* nmea; // nmea text
- size_t length; // length of the nmea text
+ uint32_t length; // length of the nmea text
} GnssNmeaNotification;
typedef struct {
- size_t size; // set to sizeof(GnssDataNotification)
+ uint32_t size; // set to sizeof(GnssDataNotification)
GnssDataMask gnssDataMask[GNSS_LOC_MAX_NUMBER_OF_SIGNAL_TYPES]; // bitwise OR of GnssDataBits
double jammerInd[GNSS_LOC_MAX_NUMBER_OF_SIGNAL_TYPES]; // Jammer Indication
double agc[GNSS_LOC_MAX_NUMBER_OF_SIGNAL_TYPES]; // Automatic gain control
} GnssDataNotification;
typedef struct {
- size_t size; // set to sizeof(GnssMeasurementsNotification)
- size_t count; // number of items in GnssMeasurements array
+ uint32_t size; // set to sizeof(GnssMeasurementsNotification)
+ uint32_t count; // number of items in GnssMeasurements array
GnssMeasurementsData measurements[GNSS_MEASUREMENTS_MAX];
GnssMeasurementsClock clock; // clock
} GnssMeasurementsNotification;
@@ -1012,9 +1066,9 @@ typedef struct {
typedef uint32_t GnssSvId;
struct GnssSvIdSource{
- size_t size; // set to sizeof(GnssSvIdSource)
- GnssSvType constellation; // constellation for the sv to blacklist
- GnssSvId svId; // sv id to blacklist
+ uint32_t size; // set to sizeof(GnssSvIdSource)
+ GnssSvType constellation; // constellation for the sv to blacklist
+ GnssSvId svId; // sv id to blacklist
};
inline bool operator ==(GnssSvIdSource const& left, GnssSvIdSource const& right) {
return left.size == right.size &&
@@ -1023,7 +1077,7 @@ inline bool operator ==(GnssSvIdSource const& left, GnssSvIdSource const& right)
#define GNSS_SV_CONFIG_ALL_BITS_ENABLED_MASK ((uint64_t)0xFFFFFFFFFFFFFFFF)
typedef struct {
- size_t size; // set to sizeof(GnssSvIdConfig)
+ uint32_t size; // set to sizeof(GnssSvIdConfig)
// GLONASS - SV 65 maps to bit 0
#define GNSS_SV_CONFIG_GLO_INITIAL_SV_ID 65
@@ -1043,7 +1097,7 @@ typedef struct {
} GnssSvIdConfig;
struct GnssConfig{
- size_t size; // set to sizeof(GnssConfig)
+ uint32_t size; // set to sizeof(GnssConfig)
GnssConfigFlagsMask flags; // bitwise OR of GnssConfigFlagsBits to mark which params are valid
GnssConfigGpsLock gpsLock;
GnssConfigSuplVersion suplVersion;
@@ -1056,6 +1110,7 @@ struct GnssConfig{
GnssConfigSuplEmergencyServices suplEmergencyServices;
GnssConfigSuplModeMask suplModeMask; //bitwise OR of GnssConfigSuplModeBits
std::vector<GnssSvIdSource> blacklistedSvIds;
+ uint32_t emergencyExtensionSeconds;
inline bool equals(const GnssConfig& config) {
if (flags == config.flags &&
@@ -1069,7 +1124,8 @@ struct GnssConfig{
emergencyPdnForEmergencySupl == config.emergencyPdnForEmergencySupl &&
suplEmergencyServices == config.suplEmergencyServices &&
suplModeMask == config.suplModeMask &&
- blacklistedSvIds == config.blacklistedSvIds) {
+ blacklistedSvIds == config.blacklistedSvIds &&
+ emergencyExtensionSeconds == config.emergencyExtensionSeconds) {
return true;
}
return false;
@@ -1077,7 +1133,7 @@ struct GnssConfig{
};
typedef struct {
- size_t size; // set to sizeof
+ uint32_t size; // set to sizeof
bool mValid;
Location mLocation;
double verticalAccuracyMeters;
@@ -1087,7 +1143,7 @@ typedef struct {
} GnssDebugLocation;
typedef struct {
- size_t size; // set to sizeof
+ uint32_t size; // set to sizeof
bool mValid;
int64_t timeEstimate;
float timeUncertaintyNs;
@@ -1095,7 +1151,7 @@ typedef struct {
} GnssDebugTime;
typedef struct {
- size_t size; // set to sizeof
+ uint32_t size; // set to sizeof
uint32_t svid;
GnssSvType constellation;
GnssEphemerisType mEphemerisType;
@@ -1107,7 +1163,7 @@ typedef struct {
} GnssDebugSatelliteInfo;
typedef struct {
- size_t size; // set to sizeof
+ uint32_t size; // set to sizeof
GnssDebugLocation mLocation;
GnssDebugTime mTime;
std::vector<GnssDebugSatelliteInfo> mSatelliteInfo;
@@ -1182,7 +1238,7 @@ typedef std::function<void(
collectiveResponseCallback is called for every geofence API call.
ids array and LocationError array are only valid until collectiveResponseCallback returns. */
typedef std::function<void(
- size_t count, // number of locations in arrays
+ uint32_t count, // number of locations in arrays
LocationError* errs, // array of LocationError associated to the request
uint32_t* ids // array of ids to be associated to the request
)> collectiveResponseCallback;
@@ -1198,7 +1254,7 @@ typedef std::function<void(
batchingCallback is called when delivering locations in a batching session.
broadcasted to all clients, no matter if a session has started by client */
typedef std::function<void(
- size_t count, // number of locations in array
+ uint32_t count, // number of locations in array
Location* location, // array of locations
BatchingOptions batchingOptions // Batching options
)> batchingCallback;
@@ -1277,8 +1333,15 @@ typedef std::function<void(
typedef std::function<void(
)> locationApiDestroyCompleteCallback;
+typedef uint16_t LocationAdapterTypeMask;
+typedef enum {
+ LOCATION_ADAPTER_GNSS_TYPE_BIT = (1<<0), // adapter type is GNSS
+ LOCATION_ADAPTER_BATCHING_TYPE_BIT = (1<<1), // adapter type is BATCHING
+ LOCATION_ADAPTER_GEOFENCE_TYPE_BIT = (1<<2) // adapter type is geo fence
+} LocationAdapterTypeBits;
+
typedef struct {
- size_t size; // set to sizeof(LocationCallbacks)
+ uint32_t size; // set to sizeof(LocationCallbacks)
capabilitiesCallback capabilitiesCb; // mandatory
responseCallback responseCb; // mandatory
collectiveResponseCallback collectiveResponseCb; // mandatory
diff --git a/location/location_interface.h b/location/location_interface.h
index 480bbdb..4235a13 100644
--- a/location/location_interface.h
+++ b/location/location_interface.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019 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
@@ -76,29 +76,29 @@ struct GnssInterface {
void (*agpsDataConnClosed)(AGpsExtType agpsType);
void (*agpsDataConnFailed)(AGpsExtType agpsType);
void (*getDebugReport)(GnssDebugReport& report);
- void (*updateConnectionStatus)(bool connected, int8_t type);
+ void (*updateConnectionStatus)(bool connected, int8_t type, bool roaming,
+ NetworkHandle networkHandle);
void (*odcpiInit)(const OdcpiRequestCallback& callback);
void (*odcpiInject)(const Location& location);
void (*blockCPI)(double latitude, double longitude, float accuracy,
int blockDurationMsec, double latLonDiffThreshold);
void (*getGnssEnergyConsumed)(GnssEnergyConsumedCallback energyConsumedCb);
+ void (*enableNfwLocationAccess)(bool enable);
+ void (*nfwInit)(const NfwCbInfo& cbInfo);
+ void (*getPowerStateChanges)(void* powerStateCb);
};
-struct FlpInterface {
+struct BatchingInterface {
size_t size;
void (*initialize)(void);
void (*deinitialize)(void);
void (*addClient)(LocationAPI* client, const LocationCallbacks& callbacks);
void (*removeClient)(LocationAPI* client, removeClientCompleteCallback rmClientCb);
void (*requestCapabilities)(LocationAPI* client);
- uint32_t (*startTracking)(LocationAPI* client, TrackingOptions&);
- void (*updateTrackingOptions)(LocationAPI* client, uint32_t id, TrackingOptions&);
- void (*stopTracking)(LocationAPI* client, uint32_t id);
uint32_t (*startBatching)(LocationAPI* client, BatchingOptions&);
void (*stopBatching)(LocationAPI* client, uint32_t id);
void (*updateBatchingOptions)(LocationAPI* client, uint32_t id, BatchingOptions&);
void (*getBatchedLocations)(LocationAPI* client, uint32_t id, size_t count);
- void (*getPowerStateChanges)(void* powerStateCb);
};
struct GeofenceInterface {
diff --git a/pla/oe/loc_pla.h b/pla/oe/loc_pla.h
index 9446888..e795a23 100644
--- a/pla/oe/loc_pla.h
+++ b/pla/oe/loc_pla.h
@@ -30,7 +30,10 @@
#define __LOC_PLA__
#ifdef __cplusplus
+#ifndef FEATURE_EXTERNAL_AP
#include <utils/SystemClock.h>
+#endif /* FEATURE_EXTERNAL_AP */
+#include <inttypes.h>
#include <sys/time.h>
#include <time.h>
@@ -47,10 +50,14 @@ inline int64_t uptimeMillis()
extern "C" {
#endif
+#ifndef FEATURE_EXTERNAL_AP
#include <cutils/properties.h>
#include <cutils/threads.h>
#include <cutils/sched_policy.h>
+#endif /* FEATURE_EXTERNAL_AP */
+#include <pthread.h>
#include <sys/time.h>
+#include <sys/types.h>
#include <string.h>
#include <stdlib.h>
#ifndef OFF_TARGET
@@ -76,6 +83,16 @@ extern "C" {
#define LOC_PATH_XTWIFI_CONF_STR "/etc/xtwifi.conf"
#define LOC_PATH_QUIPC_CONF_STR "/etc/quipc.conf"
+#ifdef FEATURE_EXTERNAL_AP
+#define PROPERTY_VALUE_MAX 92
+
+inline int property_get(const char* key, char* value, const char* default_value)
+{
+ strlcpy(value, default_value, PROPERTY_VALUE_MAX - 1);
+ return strlen(value);
+}
+#endif /* FEATURE_EXTERNAL_AP */
+
#ifdef __cplusplus
}
#endif /*__cplusplus */
diff --git a/utils/Android.mk b/utils/Android.mk
index ec6bf05..3887696 100644
--- a/utils/Android.mk
+++ b/utils/Android.mk
@@ -9,6 +9,7 @@ include $(CLEAR_VARS)
## Libs
LOCAL_SHARED_LIBRARIES := \
+ libdl \
libutils \
libcutils \
liblog \
diff --git a/utils/LocIpc.h b/utils/LocIpc.h
index 87f2ff8..90f9e1b 100644
--- a/utils/LocIpc.h
+++ b/utils/LocIpc.h
@@ -27,8 +27,8 @@
*
*/
-#ifndef __LOC_SOCKET__
-#define __LOC_SOCKET__
+#ifndef __LOC_IPC__
+#define __LOC_IPC__
#include <string>
#include <memory>
@@ -105,7 +105,7 @@ public:
// This class hides generated fd and destination address object from user.
inline LocIpcSender(const char* destSocket):
LocIpcSender(std::make_shared<int>(::socket(AF_UNIX, SOCK_DGRAM, 0)), destSocket) {
- if (-1 == *mSocket) {
+ if (mSocket != nullptr && -1 == *mSocket) {
mSocket = nullptr;
}
}
@@ -149,4 +149,4 @@ private:
}
-#endif //__LOC_SOCKET__
+#endif //__LOC_IPC__
diff --git a/utils/LocSharedLock.h b/utils/LocSharedLock.h
index 7fe6237..a7af35e 100644
--- a/utils/LocSharedLock.h
+++ b/utils/LocSharedLock.h
@@ -30,10 +30,28 @@
#define __LOC_SHARED_LOCK__
#include <stddef.h>
+#ifndef FEATURE_EXTERNAL_AP
#include <cutils/atomic.h>
+#endif /* FEATURE_EXTERNAL_AP */
#include <pthread.h>
-// This is a utility created for use cases such that there are more than
+#ifdef FEATURE_EXTERNAL_AP
+#include <atomic>
+
+inline int32_t android_atomic_inc(volatile int32_t *addr)
+{
+ volatile std::atomic_int_least32_t* a = (volatile std::atomic_int_least32_t*)addr;
+ return std::atomic_fetch_add_explicit(a, 1, std::memory_order_release);
+}
+
+inline int32_t android_atomic_dec(volatile int32_t *addr)
+{
+ volatile std::atomic_int_least32_t* a = (volatile std::atomic_int_least32_t*)addr;
+ return std::atomic_fetch_sub_explicit(a, 1, std::memory_order_release);
+}
+
+#endif /* FEATURE_EXTERNAL_AP */
+ // This is a utility created for use cases such that there are more than
// one client who need to share the same lock, but it is not predictable
// which of these clients is to last to go away. This shared lock deletes
// itself when the last client calls its drop() method. To add a cient,
diff --git a/utils/LocThread.cpp b/utils/LocThread.cpp
index c1052cb..568a6bb 100644
--- a/utils/LocThread.cpp
+++ b/utils/LocThread.cpp
@@ -85,8 +85,8 @@ LocThreadDelegate::LocThreadDelegate(LocThread::tCreate creator,
if (mThandle) {
// set thread name
char lname[16];
- int len = (sizeof(lname)>sizeof(threadName)) ?
- (sizeof(threadName) -1):(sizeof(lname) - 1);
+ int len = (sizeof(lname) > (strlen(threadName) + 1)) ?
+ (strlen(threadName)):(sizeof(lname) - 1);
memcpy(lname, threadName, len);
lname[len] = 0;
// set the thread name here
diff --git a/utils/Makefile.am b/utils/Makefile.am
index 33afc1b..50e1e9a 100644
--- a/utils/Makefile.am
+++ b/utils/Makefile.am
@@ -61,7 +61,7 @@ libgps_utils_la_LDFLAGS = -Wl,-z,defs -lpthread -shared -version-info 1:0:0
libgps_utils_la_CPPFLAGS = $(AM_CFLAGS) $(AM_CPPFLAGS)
endif
-libgps_utils_la_LIBADD = $(CUTILS_LIBS)
+libgps_utils_la_LIBADD = $(CUTILS_LIBS) -ldl
#Create and Install libraries
lib_LTLIBRARIES = libgps_utils.la
diff --git a/utils/MsgTask.cpp b/utils/MsgTask.cpp
index ad95a83..73a77fd 100644
--- a/utils/MsgTask.cpp
+++ b/utils/MsgTask.cpp
@@ -83,8 +83,10 @@ void MsgTask::sendMsg(const LocMsg* msg) const {
}
void MsgTask::prerun() {
+#ifndef FEATURE_EXTERNAL_AP
// make sure we do not run in background scheduling group
set_sched_policy(gettid(), SP_FOREGROUND);
+#endif /* FEATURE_EXTERNAL_AP */
}
bool MsgTask::run() {
diff --git a/utils/configure.ac b/utils/configure.ac
index 639f8c4..fd16494 100644
--- a/utils/configure.ac
+++ b/utils/configure.ac
@@ -28,10 +28,20 @@ AC_PROG_LN_S
AC_PROG_MAKE_SET
PKG_PROG_PKG_CONFIG
-# Checks for libraries.
-PKG_CHECK_MODULES([CUTILS], [libcutils])
-AC_SUBST([CUTILS_CFLAGS])
-AC_SUBST([CUTILS_LIBS])
+AC_ARG_WITH([external_ap],
+ AC_HELP_STRING([--with-external_ap=@<:@dir@:>@],
+ [Using External Application Processor]),
+ [],
+ with_external_ap=no)
+
+if test "x$with_external_ap" != "xno"; then
+ CPPFLAGS="${CPPFLAGS} -DFEATURE_EXTERNAL_AP"
+else
+ # Checks for libraries.
+ PKG_CHECK_MODULES([CUTILS], [libcutils])
+ AC_SUBST([CUTILS_CFLAGS])
+ AC_SUBST([CUTILS_LIBS])
+fi
AC_ARG_WITH([core_includes],
AC_HELP_STRING([--with-core-includes=@<:@dir@:>@],
diff --git a/utils/gps_extended_c.h b/utils/gps_extended_c.h
index 8ddf488..242fe84 100644
--- a/utils/gps_extended_c.h
+++ b/utils/gps_extended_c.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2018 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2019 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
@@ -199,6 +199,11 @@ typedef struct {
AgpsCbPriority cbPriority;
} AgpsCbInfo;
+typedef struct {
+ void* visibilityControlCb;
+ void* isInEmergencySession;
+} NfwCbInfo;
+
/** GPS extended callback structure. */
typedef struct {
/** set to sizeof(LocGpsCallbacks) */
@@ -407,9 +412,18 @@ typedef uint32_t LocPosDataMask;
/* Bitmask to specify whether Navigation data has Body pitch Unc*/
#define LOC_NAV_DATA_HAS_PITCH_UNC ((LocPosDataMask)0x0200)
+typedef uint32_t GnssAdditionalSystemInfoMask;
+/* Bitmask to specify whether Tauc is valid */
+#define GNSS_ADDITIONAL_SYSTEMINFO_HAS_TAUC ((GnssAdditionalSystemInfoMask)0x0001)
+/* Bitmask to specify whether leapSec is valid */
+#define GNSS_ADDITIONAL_SYSTEMINFO_HAS_LEAP_SEC ((GnssAdditionalSystemInfoMask)0x0002)
+
+
/** GPS PRN Range */
#define GPS_SV_PRN_MIN 1
#define GPS_SV_PRN_MAX 32
+#define SBAS_SV_PRN_MIN 33
+#define SBAS_SV_PRN_MAX 64
#define GLO_SV_PRN_MIN 65
#define GLO_SV_PRN_MAX 96
#define QZSS_SV_PRN_MIN 193
@@ -838,8 +852,8 @@ enum loc_api_adapter_event_index {
LOC_API_ADAPTER_BATCH_FULL, // Batching on full
LOC_API_ADAPTER_BATCHED_POSITION_REPORT, // Batching on fix
LOC_API_ADAPTER_BATCHED_GENFENCE_BREACH_REPORT, //
- LOC_API_ADAPTER_GNSS_MEASUREMENT_REPORT, //GNSS Measurement Report
- LOC_API_ADAPTER_GNSS_SV_POLYNOMIAL_REPORT, //GNSS SV Polynomial Report
+ LOC_API_ADAPTER_GNSS_MEASUREMENT_REPORT, // GNSS Measurement Report
+ LOC_API_ADAPTER_GNSS_SV_POLYNOMIAL_REPORT, // GNSS SV Polynomial Report
LOC_API_ADAPTER_GDT_UPLOAD_BEGIN_REQ, // GDT upload start request
LOC_API_ADAPTER_GDT_UPLOAD_END_REQ, // GDT upload end request
LOC_API_ADAPTER_GNSS_MEASUREMENT, // GNSS Measurement report
@@ -853,6 +867,8 @@ enum loc_api_adapter_event_index {
LOC_API_ADAPTER_BS_OBS_DATA_SERVICE_REQ, // BS observation data request
LOC_API_ADAPTER_GNSS_SV_EPHEMERIS_REPORT, // GNSS SV Ephemeris Report
LOC_API_ADAPTER_LOC_SYSTEM_INFO, // Location system info event
+ LOC_API_ADAPTER_GNSS_NHZ_MEASUREMENT_REPORT, // GNSS SV nHz measurement report
+ LOC_API_ADAPTER_EVENT_REPORT_INFO, // Event report info
LOC_API_ADAPTER_EVENT_MAX
};
@@ -893,6 +909,8 @@ enum loc_api_adapter_event_index {
#define LOC_API_ADAPTER_BIT_BS_OBS_DATA_SERVICE_REQ (1ULL<<LOC_API_ADAPTER_BS_OBS_DATA_SERVICE_REQ)
#define LOC_API_ADAPTER_BIT_GNSS_SV_EPHEMERIS_REPORT (1ULL<<LOC_API_ADAPTER_GNSS_SV_EPHEMERIS_REPORT)
#define LOC_API_ADAPTER_BIT_LOC_SYSTEM_INFO (1ULL<<LOC_API_ADAPTER_LOC_SYSTEM_INFO)
+#define LOC_API_ADAPTER_BIT_GNSS_NHZ_MEASUREMENT (1ULL<<LOC_API_ADAPTER_GNSS_NHZ_MEASUREMENT_REPORT)
+#define LOC_API_ADAPTER_BIT_EVENT_REPORT_INFO (1ULL<<LOC_API_ADAPTER_EVENT_REPORT_INFO)
typedef uint64_t LOC_API_ADAPTER_EVENT_MASK_T;
@@ -925,7 +943,8 @@ typedef uint32_t LOC_GPS_LOCK_MASK;
#define GNSS_SV_POLY_XYZ_0_TH_ORDER_COEFF_MAX_SIZE 3
#define GNSS_SV_POLY_XYZ_N_TH_ORDER_COEFF_MAX_SIZE 9
#define GNSS_SV_POLY_SV_CLKBIAS_COEFF_MAX_SIZE 4
-#define GNSS_LOC_SV_MEAS_LIST_MAX_SIZE 16
+/** Max number of GNSS SV measurement */
+#define GNSS_LOC_SV_MEAS_LIST_MAX_SIZE 128
enum ulp_gnss_sv_measurement_valid_flags{
@@ -1055,71 +1074,12 @@ typedef struct
/**< System-1 to System-2 Time Bias uncertainty \n
- Units: msec \n
*/
-}Gnss_InterSystemBiasStructType;
-
-
-typedef struct
-{
- size_t size;
- uint16_t systemWeek;
- /**< System week number for GPS, BDS and GAL satellite systems. \n
- Set to 65535 when invalid or not available. \n
- Not valid for GLONASS system. \n
- */
-
- uint32_t systemMsec;
- /**< System time msec. Time of Week for GPS, BDS, GAL and
- Time of Day for GLONASS.
- - Units: msec \n
- */
- float systemClkTimeBias;
- /**< System clock time bias \n
- - Units: msec \n
- System time = systemMsec - systemClkTimeBias \n
- */
- float systemClkTimeUncMs;
- /**< Single sided maximum time bias uncertainty \n
- - Units: msec \n
- */
-}Gnss_LocSystemTimeStructType;
-
-typedef struct {
-
- size_t size;
- uint8_t gloFourYear;
- /**< GLONASS four year number from 1996. Refer to GLONASS ICD.\n
- Applicable only for GLONASS and shall be ignored for other constellations. \n
- If unknown shall be set to 255
- */
-
- uint16_t gloDays;
- /**< GLONASS day number in four years. Refer to GLONASS ICD.
- Applicable only for GLONASS and shall be ignored for other constellations. \n
- If unknown shall be set to 65535
- */
-
- uint32_t gloMsec;
- /**< GLONASS time of day in msec. Refer to GLONASS ICD.
- - Units: msec \n
- */
-
- float gloClkTimeBias;
- /**< System clock time bias (sub-millisecond) \n
- - Units: msec \n
- System time = systemMsec - systemClkTimeBias \n
- */
+} Gnss_InterSystemBiasStructType;
- float gloClkTimeUncMs;
- /**< Single sided maximum time bias uncertainty \n
- - Units: msec \n
- */
-}Gnss_LocGloTimeStructType; /* Type */
typedef struct {
size_t size;
- uint32_t refFCount;
- /**< Receiver frame counter value at reference tick */
uint8_t systemRtc_valid;
/**< Validity indicator for System RTC */
@@ -1129,13 +1089,8 @@ typedef struct {
- Units: msec \n
*/
- uint32_t sourceOfTime;
- /**< Source of time information */
-
}Gnss_LocGnssTimeExtStructType;
-
-
typedef enum
{
GNSS_LOC_MEAS_STATUS_NULL = 0x00000000,
@@ -1231,6 +1186,9 @@ typedef enum
typedef struct
{
size_t size;
+ Gnss_LocSvSystemEnumType gnssSystem;
+ // 0 signal type mask indicates invalid value
+ GnssSignalTypeMask gnssSignalTypeMask;
uint16_t gnssSvId;
/**< GNSS SV ID.
\begin{itemize1}
@@ -1367,73 +1325,84 @@ typedef struct
} Gnss_SVMeasurementStructType;
-/**< Maximum number of satellites in measurement block for given system. */
-
-typedef struct
-{
- size_t size;
- Gnss_LocSvSystemEnumType system;
- /**< Specifies the Satellite System Type
- */
- bool isSystemTimeValid;
- /**< Indicates whether System Time is Valid:\n
- - 0x01 (TRUE) -- System Time is valid \n
- - 0x00 (FALSE) -- System Time is not valid
- */
- Gnss_LocSystemTimeStructType systemTime;
- /**< System Time Information \n
- */
- bool isGloTime_valid;
- Gnss_LocGloTimeStructType gloTime;
-
- bool isSystemTimeExt_valid;
- Gnss_LocGnssTimeExtStructType systemTimeExt;
- uint8_t numSvs;
- /* Number of SVs in this report block */
+typedef uint64_t GpsSvMeasHeaderFlags;
+#define GNSS_SV_MEAS_HEADER_HAS_LEAP_SECOND 0x00000001
+#define GNSS_SV_MEAS_HEADER_HAS_CLOCK_FREQ 0x00000002
+#define GNSS_SV_MEAS_HEADER_HAS_AP_TIMESTAMP 0x00000004
+#define GNSS_SV_MEAS_HEADER_HAS_GPS_GLO_INTER_SYSTEM_BIAS 0x00000008
+#define GNSS_SV_MEAS_HEADER_HAS_GPS_BDS_INTER_SYSTEM_BIAS 0x00000010
+#define GNSS_SV_MEAS_HEADER_HAS_GPS_GAL_INTER_SYSTEM_BIAS 0x00000020
+#define GNSS_SV_MEAS_HEADER_HAS_BDS_GLO_INTER_SYSTEM_BIAS 0x00000040
+#define GNSS_SV_MEAS_HEADER_HAS_GAL_GLO_INTER_SYSTEM_BIAS 0x00000080
+#define GNSS_SV_MEAS_HEADER_HAS_GAL_BDS_INTER_SYSTEM_BIAS 0x00000100
+#define GNSS_SV_MEAS_HEADER_HAS_GPS_SYSTEM_TIME 0x00000200
+#define GNSS_SV_MEAS_HEADER_HAS_GAL_SYSTEM_TIME 0x00000400
+#define GNSS_SV_MEAS_HEADER_HAS_BDS_SYSTEM_TIME 0x00000800
+#define GNSS_SV_MEAS_HEADER_HAS_QZSS_SYSTEM_TIME 0x00001000
+#define GNSS_SV_MEAS_HEADER_HAS_GLO_SYSTEM_TIME 0x00002000
+#define GNSS_SV_MEAS_HEADER_HAS_GPS_SYSTEM_TIME_EXT 0x00004000
+#define GNSS_SV_MEAS_HEADER_HAS_GAL_SYSTEM_TIME_EXT 0x00008000
+#define GNSS_SV_MEAS_HEADER_HAS_BDS_SYSTEM_TIME_EXT 0x00010000
+#define GNSS_SV_MEAS_HEADER_HAS_QZSS_SYSTEM_TIME_EXT 0x00020000
+#define GNSS_SV_MEAS_HEADER_HAS_GPSL1L5_TIME_BIAS 0x00040000
+#define GNSS_SV_MEAS_HEADER_HAS_GALE1E5A_TIME_BIAS 0x00080000
- Gnss_SVMeasurementStructType svMeasurement[GNSS_LOC_SV_MEAS_LIST_MAX_SIZE];
- /**< Satellite measurement Information \n
- */
-} Gnss_ClockMeasurementStructType;
typedef struct
{
size_t size;
- uint8_t seqNum;
- /**< Current message Number */
- uint8_t maxMessageNum;
- /**< Maximum number of message that will be sent for present time epoch. */
+ // see defines in GNSS_SV_MEAS_HEADER_HAS_XXX_XXX
+ uint64_t flags;
- bool leapSecValid;
Gnss_LeapSecondInfoStructType leapSec;
- Gnss_InterSystemBiasStructType gpsGloInterSystemBias;
+ Gnss_LocRcvrClockFrequencyInfoStructType clockFreq; /* Freq */
- Gnss_InterSystemBiasStructType gpsBdsInterSystemBias;
+ Gnss_ApTimeStampStructType apBootTimeStamp;
+ Gnss_InterSystemBiasStructType gpsGloInterSystemBias;
+ Gnss_InterSystemBiasStructType gpsBdsInterSystemBias;
Gnss_InterSystemBiasStructType gpsGalInterSystemBias;
-
Gnss_InterSystemBiasStructType bdsGloInterSystemBias;
-
Gnss_InterSystemBiasStructType galGloInterSystemBias;
-
Gnss_InterSystemBiasStructType galBdsInterSystemBias;
+ Gnss_InterSystemBiasStructType gpsL1L5TimeBias;
+ Gnss_InterSystemBiasStructType galE1E5aTimeBias;
+
+ GnssSystemTimeStructType gpsSystemTime;
+ GnssSystemTimeStructType galSystemTime;
+ GnssSystemTimeStructType bdsSystemTime;
+ GnssSystemTimeStructType qzssSystemTime;
+ GnssGloTimeStructType gloSystemTime;
+
+ /** GPS system RTC time information. */
+ Gnss_LocGnssTimeExtStructType gpsSystemTimeExt;
+ /** GAL system RTC time information. */
+ Gnss_LocGnssTimeExtStructType galSystemTimeExt;
+ /** BDS system RTC time information. */
+ Gnss_LocGnssTimeExtStructType bdsSystemTimeExt;
+ /** QZSS system RTC time information. */
+ Gnss_LocGnssTimeExtStructType qzssSystemTimeExt;
+
+} GnssSvMeasurementHeader;
- bool clockFreqValid;
- Gnss_LocRcvrClockFrequencyInfoStructType clockFreq; /* Freq */
- bool gnssMeasValid;
- Gnss_ClockMeasurementStructType gnssMeas;
- Gnss_ApTimeStampStructType timeStamp;
- /* Extended Time Information - Cumulative Number of Clock Resets */
- uint8_t numClockResets_valid; /**< Must be set to true if numClockResets is being passed */
- uint32_t numClockResets;
- bool gnssSignalTypeMaskValid;
- GnssSignalTypeMask gnssSignalTypeMask;
+typedef struct {
+ size_t size;
+ bool isNhz;
+ GnssSvMeasurementHeader svMeasSetHeader;
+ uint32_t svMeasCount;
+ Gnss_SVMeasurementStructType svMeas[GNSS_LOC_SV_MEAS_LIST_MAX_SIZE];
} GnssSvMeasurementSet;
+typedef struct {
+ uint32_t size; // set to sizeof(GnssMeasurements)
+ GnssSvMeasurementSet gnssSvMeasurementSet;
+ GnssMeasurementsNotification gnssMeasNotification;
+} GnssMeasurements;
+
typedef enum
{
GNSS_SV_POLY_COEFF_VALID = 0x01,
@@ -1916,6 +1885,10 @@ typedef struct {
Mandatory field */
Gnss_LocSvSystemEnumType gnssConstellation;
+ /** GPS System Time of the ephemeris report */
+ bool isSystemTimeValid;
+ GnssSystemTimeStructType systemTime;
+
union {
/** GPS Ephemeris */
GpsEphemerisResponse gpsEphemeris;
@@ -1930,6 +1903,73 @@ typedef struct {
} ephInfo;
} GnssSvEphemerisReport;
+typedef struct {
+ /** GPS System Time of the iono model report */
+ bool isSystemTimeValid;
+ GnssSystemTimeStructType systemTime;
+
+ /** Indicates GNSS Constellation Type */
+ Gnss_LocSvSystemEnumType gnssConstellation;
+
+ float alpha0;
+ /**< Klobuchar Model Parameter Alpha 0.
+ - Type: float
+ - Unit: Seconds
+ */
+
+ float alpha1;
+ /**< Klobuchar Model Parameter Alpha 1.
+ - Type: float
+ - Unit: Seconds / Semi-Circle
+ */
+
+ float alpha2;
+ /**< Klobuchar Model Parameter Alpha 2.
+ - Type: float
+ - Unit: Seconds / Semi-Circle^2
+ */
+
+ float alpha3;
+ /**< Klobuchar Model Parameter Alpha 3.
+ - Type: float
+ - Unit: Seconds / Semi-Circle^3
+ */
+
+ float beta0;
+ /**< Klobuchar Model Parameter Beta 0.
+ - Type: float
+ - Unit: Seconds
+ */
+
+ float beta1;
+ /**< Klobuchar Model Parameter Beta 1.
+ - Type: float
+ - Unit: Seconds / Semi-Circle
+ */
+
+ float beta2;
+ /**< Klobuchar Model Parameter Beta 2.
+ - Type: float
+ - Unit: Seconds / Semi-Circle^2
+ */
+
+ float beta3;
+ /**< Klobuchar Model Parameter Beta 3.
+ - Type: float
+ - Unit: Seconds / Semi-Circle^3
+ */
+} GnssKlobucharIonoModel;
+
+typedef struct {
+ /** GPS System Time of the report */
+ bool isSystemTimeValid;
+ GnssSystemTimeStructType systemTime;
+
+ GnssAdditionalSystemInfoMask validityMask;
+ double tauC;
+ int8_t leapSec;
+} GnssAdditionalSystemInfo;
+
/* Various Short Range Node Technology type*/
typedef enum {
SRN_AP_DATA_TECH_TYPE_NONE,
@@ -2009,6 +2049,46 @@ struct AGnssExtStatusIpV6 {
uint8_t ipV6Addr[16];
};
+/*
+* Represents the the Nfw Notification structure
+*/
+#define GNSS_MAX_NFW_STRING_LEN 20
+
+typedef enum {
+ GNSS_NFW_CTRL_PLANE = 0,
+ GNSS_NFW_SUPL = 1,
+ GNSS_NFW_IMS = 10,
+ GNSS_NFW_SIM = 11,
+ GNSS_NFW_OTHER_PROTOCOL_STACK = 100
+} GnssNfwProtocolStack;
+
+typedef enum {
+ GNSS_NFW_CARRIER = 0,
+ GNSS_NFW_OEM = 10,
+ GNSS_NFW_MODEM_CHIPSET_VENDOR = 11,
+ GNSS_NFW_GNSS_CHIPSET_VENDOR = 12,
+ GNSS_NFW_OTHER_CHIPSET_VENDOR = 13,
+ GNSS_NFW_AUTOMOBILE_CLIENT = 20,
+ GNSS_NFW_OTHER_REQUESTOR = 100
+} GnssNfwRequestor;
+
+typedef enum {
+ GNSS_NFW_REJECTED = 0,
+ GNSS_NFW_ACCEPTED_NO_LOCATION_PROVIDED = 1,
+ GNSS_NFW_ACCEPTED_LOCATION_PROVIDED = 2,
+} GnssNfwResponseType;
+
+typedef struct {
+ char proxyAppPackageName[GNSS_MAX_NFW_STRING_LEN];
+ GnssNfwProtocolStack protocolStack;
+ char otherProtocolStackName[GNSS_MAX_NFW_STRING_LEN];
+ GnssNfwRequestor requestor;
+ char requestorId[GNSS_MAX_NFW_STRING_LEN];
+ GnssNfwResponseType responseType;
+ bool inEmergencyMode;
+ bool isCachedLocation;
+} GnssNfwNotification;
+
/* ODCPI Request Info */
enum OdcpiRequestType {
ODCPI_REQUEST_TYPE_START,
@@ -2031,6 +2111,11 @@ typedef std::function<void(const OdcpiRequestInfo& request)> OdcpiRequestCallbac
typedef void (*AgnssStatusIpV4Cb)(AGnssExtStatusIpV4 status);
/*
+* Callback with NFW information.
+*/
+typedef void(*NfwStatusCb)(GnssNfwNotification notification);
+
+/*
* Callback with AGNSS(IpV6) status information.
*
* @param status Will be of type AGnssExtStatusIpV6.
@@ -2053,6 +2138,10 @@ typedef void (*LocAgpsCloseResultCb)(bool isSuccess, AGpsExtType agpsType, void*
#define SOCKET_DIR_TO_CLIENT "/dev/socket/loc_client/"
#define SOCKET_TO_LOCATION_CLIENT_BASE "/dev/socket/loc_client/toclient"
+#define SOCKET_TO_EXTERANL_AP_LOCATION_CLIENT_BASE "/dev/socket/loc_client/extap.toclient"
+
+typedef uint64_t NetworkHandle;
+#define NETWORK_HANDLE_UNKNOWN ~0
#ifdef __cplusplus
}
diff --git a/utils/linked_list.h b/utils/linked_list.h
index a85f09a..0b33ecb 100644
--- a/utils/linked_list.h
+++ b/utils/linked_list.h
@@ -50,6 +50,8 @@ typedef enum
/**< Failed because an there were not enough resources. */
eLINKED_LIST_INSUFFICIENT_BUFFER = -5,
/**< Failed because an the supplied buffer was too small. */
+ eLINKED_LIST_EMPTY = -6
+ /**< Failed because list is empty. */
}linked_list_err_type;
/*===========================================================================
diff --git a/utils/loc_cfg.cpp b/utils/loc_cfg.cpp
index 8160cc1..de887ee 100644
--- a/utils/loc_cfg.cpp
+++ b/utils/loc_cfg.cpp
@@ -465,14 +465,9 @@ void loc_read_conf(const char* conf_file_name, const loc_param_s_type* config_ta
#define LOC_FEATURE_MASK_GTP_WIFI_PREMIUM 0X02
#define LOC_FEATURE_MASK_GTP_CELL_BASIC 0X04
#define LOC_FEATURE_MASK_GTP_CELL_PREMIUM 0X08
-#define LOC_FEATURE_MASK_GTP_AP_CELL_BASIC LOC_FEATURE_MASK_GTP_CELL_BASIC
-#define LOC_FEATURE_MASK_GTP_AP_CELL_PREMIUM LOC_FEATURE_MASK_GTP_CELL_PREMIUM
#define LOC_FEATURE_MASK_SAP_BASIC 0x40
#define LOC_FEATURE_MASK_SAP_PREMIUM 0X80
-#define LOC_FEATURE_MASK_GTP_WAA_BASIC 0X100
-#define LOC_FEATURE_MASK_GTP_WAA_PREMIUM 0x200
#define LOC_FEATURE_MASK_GTP_MODEM_CELL_BASIC 0X400
-#define LOC_FEATURE_MASK_GTP_MODEM_CELL_PREMIUM 0X800
#define LOC_FEATURE_MASK_ODCPI 0x1000
#define LOC_FEATURE_MASK_FREE_WIFI_SCAN_INJECT 0x2000
#define LOC_FEATURE_MASK_SUPL_WIFI 0x4000
@@ -572,8 +567,6 @@ int loc_read_process_conf(const char* conf_file_name, uint32_t * process_count_p
char config_mask = 0;
unsigned char proc_list_length=0;
int gtp_cell_ap_enabled = 0;
- char arg_gtp_waa[LOC_PROCESS_MAX_ARG_STR_LENGTH] = "--";
- char arg_gtp_ap_cell[LOC_PROCESS_MAX_ARG_STR_LENGTH] = "--";
char arg_gtp_modem_cell[LOC_PROCESS_MAX_ARG_STR_LENGTH] = "--";
char arg_gtp_wifi[LOC_PROCESS_MAX_ARG_STR_LENGTH] = "--";
char arg_sap[LOC_PROCESS_MAX_ARG_STR_LENGTH] = "--";
@@ -589,8 +582,6 @@ int loc_read_process_conf(const char* conf_file_name, uint32_t * process_count_p
UTIL_READ_CONF(LOC_PATH_GPS_CONF, gps_conf_parameter_table);
//Form argument strings
- strlcat(arg_gtp_waa, LOC_FEATURE_GTP_WAA, LOC_PROCESS_MAX_ARG_STR_LENGTH-3);
- strlcat(arg_gtp_ap_cell, LOC_FEATURE_GTP_AP_CELL, LOC_PROCESS_MAX_ARG_STR_LENGTH-3);
strlcat(arg_gtp_modem_cell, LOC_FEATURE_GTP_MODEM_CELL, LOC_PROCESS_MAX_ARG_STR_LENGTH-3);
strlcat(arg_gtp_wifi, LOC_FEATURE_GTP_WIFI, LOC_PROCESS_MAX_ARG_STR_LENGTH-3);
strlcat(arg_sap, LOC_FEATURE_SAP, LOC_PROCESS_MAX_ARG_STR_LENGTH-3);
@@ -622,9 +613,6 @@ int loc_read_process_conf(const char* conf_file_name, uint32_t * process_count_p
" Setting GTP WIFI to default mode: DISABLED", __func__, __LINE__);
}
- //Set service mask for GTP_WAA
- LOC_LOGD("%s:%d]: GTP WAA DISABLED", __func__, __LINE__);
-
//Set service mask for SAP
if(strcmp(conf.feature_sap, "PREMIUM") == 0) {
LOC_LOGD("%s:%d]: Setting SAP to mode: PREMIUM", __func__, __LINE__);
@@ -931,51 +919,13 @@ int loc_read_process_conf(const char* conf_file_name, uint32_t * process_count_p
}
if(conf.loc_feature_mask &
(LOC_FEATURE_MASK_GTP_CELL_BASIC | LOC_FEATURE_MASK_GTP_CELL_PREMIUM )) {
- if(loc_service_mask & LOC_FEATURE_MASK_GTP_AP_CELL_BASIC){
- strlcpy(child_proc[j].args[i++], arg_gtp_ap_cell,
- LOC_PROCESS_MAX_ARG_STR_LENGTH);
- strlcpy(child_proc[j].args[i++], arg_basic,
- LOC_PROCESS_MAX_ARG_STR_LENGTH);
- strlcpy(child_proc[j].args[i++], arg_gtp_modem_cell,
- LOC_PROCESS_MAX_ARG_STR_LENGTH);
- strlcpy(child_proc[j].args[i++], arg_disabled,
- LOC_PROCESS_MAX_ARG_STR_LENGTH);
- }
- else if(loc_service_mask & LOC_FEATURE_MASK_GTP_AP_CELL_PREMIUM){
- strlcpy(child_proc[j].args[i++], arg_gtp_ap_cell,
- LOC_PROCESS_MAX_ARG_STR_LENGTH);
- strlcpy(child_proc[j].args[i++], arg_premium,
- LOC_PROCESS_MAX_ARG_STR_LENGTH);
- strlcpy(child_proc[j].args[i++], arg_gtp_modem_cell,
- LOC_PROCESS_MAX_ARG_STR_LENGTH);
- strlcpy(child_proc[j].args[i++], arg_disabled,
- LOC_PROCESS_MAX_ARG_STR_LENGTH);
- }
- else if(loc_service_mask & LOC_FEATURE_MASK_GTP_MODEM_CELL_BASIC) {
+ if(loc_service_mask & LOC_FEATURE_MASK_GTP_MODEM_CELL_BASIC) {
strlcpy(child_proc[j].args[i++], arg_gtp_modem_cell,
LOC_PROCESS_MAX_ARG_STR_LENGTH);
strlcpy(child_proc[j].args[i++], arg_basic,
LOC_PROCESS_MAX_ARG_STR_LENGTH);
- strlcpy(child_proc[j].args[i++], arg_gtp_ap_cell,
- LOC_PROCESS_MAX_ARG_STR_LENGTH);
- strlcpy(child_proc[j].args[i++], arg_disabled,
- LOC_PROCESS_MAX_ARG_STR_LENGTH);
- }
- else if(loc_service_mask & LOC_FEATURE_MASK_GTP_MODEM_CELL_PREMIUM) {
- strlcpy(child_proc[j].args[i++], arg_gtp_modem_cell,
- LOC_PROCESS_MAX_ARG_STR_LENGTH);
- strlcpy(child_proc[j].args[i++], arg_premium,
- LOC_PROCESS_MAX_ARG_STR_LENGTH);
- strlcpy(child_proc[j].args[i++], arg_gtp_ap_cell,
- LOC_PROCESS_MAX_ARG_STR_LENGTH);
- strlcpy(child_proc[j].args[i++], arg_disabled,
- LOC_PROCESS_MAX_ARG_STR_LENGTH);
}
else {
- strlcpy(child_proc[j].args[i++], arg_gtp_ap_cell,
- LOC_PROCESS_MAX_ARG_STR_LENGTH);
- strlcpy(child_proc[j].args[i++], arg_disabled,
- LOC_PROCESS_MAX_ARG_STR_LENGTH);
strlcpy(child_proc[j].args[i++], arg_gtp_modem_cell,
LOC_PROCESS_MAX_ARG_STR_LENGTH);
strlcpy(child_proc[j].args[i++], arg_disabled,
@@ -983,28 +933,6 @@ int loc_read_process_conf(const char* conf_file_name, uint32_t * process_count_p
}
}
if(conf.loc_feature_mask &
- (LOC_FEATURE_MASK_GTP_WAA_BASIC | LOC_FEATURE_MASK_GTP_WAA_PREMIUM)) {
- if(loc_service_mask & LOC_FEATURE_MASK_GTP_WAA_BASIC) {
- strlcpy(child_proc[j].args[i++], arg_gtp_waa,
- LOC_PROCESS_MAX_ARG_STR_LENGTH);
- strlcpy(child_proc[j].args[i++], arg_basic,
- LOC_PROCESS_MAX_ARG_STR_LENGTH);
- }
- else if(loc_service_mask & LOC_FEATURE_MASK_GTP_WAA_PREMIUM) {
- strlcpy(child_proc[j].args[i++], arg_gtp_waa,
- LOC_PROCESS_MAX_ARG_STR_LENGTH);
- strlcpy(child_proc[j].args[i++], arg_premium,
- LOC_PROCESS_MAX_ARG_STR_LENGTH);
- }
- else
- {
- strlcpy(child_proc[j].args[i++], arg_gtp_waa,
- LOC_PROCESS_MAX_ARG_STR_LENGTH);
- strlcpy(child_proc[j].args[i++], arg_disabled,
- LOC_PROCESS_MAX_ARG_STR_LENGTH);
- }
- }
- if(conf.loc_feature_mask &
(LOC_FEATURE_MASK_SAP_BASIC | LOC_FEATURE_MASK_SAP_PREMIUM)) {
if(loc_service_mask & LOC_FEATURE_MASK_SAP_BASIC) {
strlcpy(child_proc[j].args[i++], arg_sap,
diff --git a/utils/loc_misc_utils.cpp b/utils/loc_misc_utils.cpp
index b7c8406..70fdbc3 100644
--- a/utils/loc_misc_utils.cpp
+++ b/utils/loc_misc_utils.cpp
@@ -30,6 +30,7 @@
#define LOG_TAG "LocSvc_misc_utils"
#include <stdio.h>
#include <string.h>
+#include <dlfcn.h>
#include <log_util.h>
#include <loc_misc_utils.h>
#include <ctype.h>
@@ -112,3 +113,33 @@ void loc_util_trim_space(char *org_string)
err:
return;
}
+
+inline void logDlError(const char* failedCall) {
+ const char * err = dlerror();
+ LOC_LOGe("%s error: %s", failedCall, (nullptr == err) ? "unknown" : err);
+}
+
+void* dlGetSymFromLib(void*& libHandle, const char* libName, const char* symName)
+{
+ void* sym = nullptr;
+ if ((nullptr != libHandle || nullptr != libName) && nullptr != symName) {
+ if (nullptr == libHandle) {
+ libHandle = dlopen(libName, RTLD_NOW);
+ if (nullptr == libHandle) {
+ logDlError("dlopen");
+ }
+ }
+ // NOT else, as libHandle gets assigned 5 line above
+ if (nullptr != libHandle) {
+ sym = dlsym(libHandle, symName);
+ if (nullptr == sym) {
+ logDlError("dlsym");
+ }
+ }
+ } else {
+ LOC_LOGe("Either libHandle (%p) or libName (%p) must not be null; "
+ "symName (%p) can not be null.", libHandle, libName, symName);
+ }
+
+ return sym;
+}
diff --git a/utils/loc_misc_utils.h b/utils/loc_misc_utils.h
index 7d66d84..fad1b6d 100644
--- a/utils/loc_misc_utils.h
+++ b/utils/loc_misc_utils.h
@@ -92,6 +92,34 @@ SIDE EFFECTS
N/A
===========================================================================*/
void loc_util_trim_space(char *org_string);
+
+/*===========================================================================
+FUNCTION dlGetSymFromLib
+
+DESCRIPTION
+ Handy function to get a pointer to a symbol from a library.
+
+ If libHandle is not null, it will be used as the handle to the library. In
+ that case libName wll not be used;
+ libHandle is an in / out parameter.
+ If libHandle is null, libName will be used to dlopen.
+ Either libHandle or libName must not be nullptr.
+ symName must not be null.
+
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ pointer to symName. Could be nullptr if
+ Parameters are incorrect; or
+ libName can not be opened; or
+ symName can not be found.
+
+SIDE EFFECTS
+ N/A
+===========================================================================*/
+void* dlGetSymFromLib(void*& libHandle, const char* libName, const char* symName);
+
#ifdef __cplusplus
}
#endif
diff --git a/utils/loc_nmea.cpp b/utils/loc_nmea.cpp
index e9a8f84..9cd3472 100644
--- a/utils/loc_nmea.cpp
+++ b/utils/loc_nmea.cpp
@@ -44,9 +44,9 @@
#define SYSTEM_ID_GPS 1
#define SYSTEM_ID_GLONASS 2
#define SYSTEM_ID_GALILEO 3
-// Extended systems
-#define SYSTEM_ID_BEIDOU 4
+#define SYSTEM_ID_BDS 4
#define SYSTEM_ID_QZSS 5
+#define SYSTEM_ID_NAVIC 6
//GNSS signal id according to NMEA spec
#define SIGNAL_ID_ALL_SIGNALS 0
@@ -74,11 +74,35 @@
#define SIGNAL_ID_GAL_L1A 6
#define SIGNAL_ID_GAL_L1BC 7
-//Extended signal id
#define SIGNAL_ID_BDS_B1I 1
-#define SIGNAL_ID_BDS_B1C 2
-#define SIGNAL_ID_BDS_B2I 3
-#define SIGNAL_ID_BDS_B2AI 4
+#define SIGNAL_ID_BDS_B1Q 2
+#define SIGNAL_ID_BDS_B1C 3
+#define SIGNAL_ID_BDS_B1A 4
+#define SIGNAL_ID_BDS_B2A 5
+#define SIGNAL_ID_BDS_B2B 6
+#define SIGNAL_ID_BDS_B2AB 7
+#define SIGNAL_ID_BDS_B3I 8
+#define SIGNAL_ID_BDS_B3Q 9
+#define SIGNAL_ID_BDS_B3A 0xA
+#define SIGNAL_ID_BDS_B2I 0xB
+#define SIGNAL_ID_BDS_B2Q 0xC
+
+#define SIGNAL_ID_QZSS_L1CA 1
+#define SIGNAL_ID_QZSS_L1CD 2
+#define SIGNAL_ID_QZSS_L1CP 3
+#define SIGNAL_ID_QZSS_LIS 4
+#define SIGNAL_ID_QZSS_L2CM 5
+#define SIGNAL_ID_QZSS_L2CL 6
+#define SIGNAL_ID_QZSS_L5I 7
+#define SIGNAL_ID_QZSS_L5Q 8
+#define SIGNAL_ID_QZSS_L6D 9
+#define SIGNAL_ID_QZSS_L6E 0xA
+
+#define SIGNAL_ID_NAVIC_L5SPS 1
+#define SIGNAL_ID_NAVIC_SSPS 2
+#define SIGNAL_ID_NAVIC_L5RS 3
+#define SIGNAL_ID_NAVIC_SRS 4
+#define SIGNAL_ID_NAVIC_L1SPS 5
typedef struct loc_nmea_sv_meta_s
@@ -280,13 +304,13 @@ static uint32_t convert_signalType_to_signalId(GnssSignalTypeMask signalType)
signalId = SIGNAL_ID_GAL_E5B;
break;
case GNSS_SIGNAL_QZSS_L1CA:
- signalId = SIGNAL_ID_GPS_L1CA;
+ signalId = SIGNAL_ID_QZSS_L1CA;
break;
case GNSS_SIGNAL_QZSS_L2:
- signalId = SIGNAL_ID_GPS_L2CL;
+ signalId = SIGNAL_ID_QZSS_L2CL;
break;
case GNSS_SIGNAL_QZSS_L5:
- signalId = SIGNAL_ID_GPS_L5Q;
+ signalId = SIGNAL_ID_QZSS_L5Q;
break;
case GNSS_SIGNAL_BEIDOU_B1I:
signalId = SIGNAL_ID_BDS_B1I;
@@ -298,7 +322,7 @@ static uint32_t convert_signalType_to_signalId(GnssSignalTypeMask signalType)
signalId = SIGNAL_ID_BDS_B2I;
break;
case GNSS_SIGNAL_BEIDOU_B2AI:
- signalId = SIGNAL_ID_BDS_B2AI;
+ signalId = SIGNAL_ID_BDS_B2A;
break;
default:
signalId = SIGNAL_ID_ALL_SIGNALS;
@@ -371,7 +395,7 @@ static loc_nmea_sv_meta* loc_nmea_sv_meta_init(loc_nmea_sv_meta& sv_meta,
}
break;
case GNSS_SV_TYPE_QZSS:
- sv_meta.talker[0] = 'P';
+ sv_meta.talker[0] = 'G';
sv_meta.talker[1] = 'Q';
sv_meta.mask = sv_cache_info.qzss_used_mask;
// QZSS SV ids are from 193-197. So keep svIdOffset 0
@@ -383,11 +407,11 @@ static loc_nmea_sv_meta* loc_nmea_sv_meta_init(loc_nmea_sv_meta& sv_meta,
}
break;
case GNSS_SV_TYPE_BEIDOU:
- sv_meta.talker[0] = 'P';
- sv_meta.talker[1] = 'Q';
+ sv_meta.talker[0] = 'G';
+ sv_meta.talker[1] = 'B';
sv_meta.mask = sv_cache_info.bds_used_mask;
// BDS SV ids are from 201-235. So keep svIdOffset 0
- sv_meta.systemId = SYSTEM_ID_BEIDOU;
+ sv_meta.systemId = SYSTEM_ID_BDS;
if (GNSS_SIGNAL_BEIDOU_B1I == signalType) {
sv_meta.svCount = sv_cache_info.bds_b1_count;
} else if (GNSS_SIGNAL_BEIDOU_B2AI == signalType) {
@@ -626,7 +650,7 @@ static void loc_nmea_generate_GSV(const GnssSvNotification &svNotify,
if (svCount <= 0)
{
// no svs in view, so just send a blank $--GSV sentence
- snprintf(sentence, lengthRemaining, "$%sGSV,1,1,0,%d", talker, sv_meta_p->signalId);
+ snprintf(sentence, lengthRemaining, "$%sGSV,1,1,0,%X", talker, sv_meta_p->signalId);
length = loc_nmea_put_checksum(sentence, bufSize);
nmeaArraystr.push_back(sentence);
return;
@@ -674,6 +698,9 @@ static void loc_nmea_generate_GSV(const GnssSvNotification &svNotify,
case GNSS_SV_TYPE_BEIDOU:
signalType = GNSS_SIGNAL_BEIDOU_B1I;
break;
+ case GNSS_SV_TYPE_SBAS:
+ signalType = GNSS_SIGNAL_SBAS_L1;
+ break;
default:
LOC_LOGE("NMEA Error unknow constellation type: %d",
svNotify.gnssSvs[svNumber - 1].type);
@@ -717,7 +744,7 @@ static void loc_nmea_generate_GSV(const GnssSvNotification &svNotify,
}
// append signalId
- length = snprintf(pMarker, lengthRemaining,",%d",sv_meta_p->signalId);
+ length = snprintf(pMarker, lengthRemaining,",%X",sv_meta_p->signalId);
pMarker += length;
lengthRemaining -= length;
@@ -953,6 +980,7 @@ void loc_nmea_generate_pos(const UlpLocation &location,
char sentence[NMEA_SENTENCE_MAX_LENGTH] = {0};
char sentence_DTM[NMEA_SENTENCE_MAX_LENGTH] = {0};
char sentence_RMC[NMEA_SENTENCE_MAX_LENGTH] = {0};
+ char sentence_GNS[NMEA_SENTENCE_MAX_LENGTH] = {0};
char sentence_GGA[NMEA_SENTENCE_MAX_LENGTH] = {0};
char* pMarker = sentence;
int lengthRemaining = sizeof(sentence);
@@ -1051,11 +1079,12 @@ void loc_nmea_generate_pos(const UlpLocation &location,
count = loc_nmea_generate_GSA(locationExtended, sentence, sizeof(sentence),
loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_QZSS,
- GNSS_SIGNAL_QZSS_L1CA, false), nmeaArraystr);
+ GNSS_SIGNAL_QZSS_L1CA, true), nmeaArraystr);
if (count > 0)
{
svUsedCount += count;
- // talker should be default "GP". If GPS, GLO etc is used, it should be "GN"
+ talker[0] = sv_meta.talker[0];
+ talker[1] = sv_meta.talker[1];
}
// ----------------------------
@@ -1063,11 +1092,12 @@ void loc_nmea_generate_pos(const UlpLocation &location,
// ----------------------------
count = loc_nmea_generate_GSA(locationExtended, sentence, sizeof(sentence),
loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_BEIDOU,
- GNSS_SIGNAL_BEIDOU_B1I, false), nmeaArraystr);
+ GNSS_SIGNAL_BEIDOU_B1I, true), nmeaArraystr);
if (count > 0)
{
svUsedCount += count;
- // talker should be default "GP". If GPS, GLO etc is used, it should be "GN"
+ talker[0] = sv_meta.talker[0];
+ talker[1] = sv_meta.talker[1];
}
// -------------------
@@ -1345,6 +1375,145 @@ void loc_nmea_generate_pos(const UlpLocation &location,
length = loc_nmea_put_checksum(sentence_RMC, sizeof(sentence_RMC));
// -------------------
+ // ------$--GNS-------
+ // -------------------
+
+ pMarker = sentence_GNS;
+ lengthRemaining = sizeof(sentence_GNS);
+
+ length = snprintf(pMarker, lengthRemaining, "$%sGNS,%02d%02d%02d.%02d," ,
+ talker, utcHours, utcMinutes, utcSeconds, utcMSeconds/10);
+
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+
+ if (location.gpsLocation.flags & LOC_GPS_LOCATION_HAS_LAT_LONG)
+ {
+ double latitude = ref_lla.lat;
+ double longitude = ref_lla.lon;
+ char latHemisphere;
+ char lonHemisphere;
+ double latMinutes;
+ double lonMinutes;
+
+ if (latitude > 0)
+ {
+ latHemisphere = 'N';
+ }
+ else
+ {
+ latHemisphere = 'S';
+ latitude *= -1.0;
+ }
+
+ if (longitude < 0)
+ {
+ lonHemisphere = 'W';
+ longitude *= -1.0;
+ }
+ else
+ {
+ lonHemisphere = 'E';
+ }
+
+ latMinutes = fmod(latitude * 60.0 , 60.0);
+ lonMinutes = fmod(longitude * 60.0 , 60.0);
+
+ length = snprintf(pMarker, lengthRemaining, "%02d%09.6lf,%c,%03d%09.6lf,%c,",
+ (uint8_t)floor(latitude), latMinutes, latHemisphere,
+ (uint8_t)floor(longitude),lonMinutes, lonHemisphere);
+ }
+ else
+ {
+ length = snprintf(pMarker, lengthRemaining,",,,,");
+ }
+
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+
+ if (!(location.gpsLocation.flags & LOC_GPS_LOCATION_HAS_LAT_LONG))
+ // N means no fix
+ length = snprintf(pMarker, lengthRemaining, "%c,", 'N');
+ else if (LOC_NAV_MASK_SBAS_CORRECTION_IONO & locationExtended.navSolutionMask)
+ // D means differential
+ length = snprintf(pMarker, lengthRemaining, "%c,", 'D');
+ else if (LOC_POS_TECH_MASK_SENSORS == locationExtended.tech_mask)
+ // E means estimated (dead reckoning)
+ length = snprintf(pMarker, lengthRemaining, "%c,", 'E');
+ else // A means autonomous
+ length = snprintf(pMarker, lengthRemaining, "%c,", 'A');
+
+ pMarker += length;
+ lengthRemaining -= length;
+
+ if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_DOP) {
+ length = snprintf(pMarker, lengthRemaining, "%02d,%.1f,",
+ svUsedCount, locationExtended.hdop);
+ }
+ else { // no hdop
+ length = snprintf(pMarker, lengthRemaining, "%02d,,",
+ svUsedCount);
+ }
+
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+
+ if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_ALTITUDE_MEAN_SEA_LEVEL)
+ {
+ length = snprintf(pMarker, lengthRemaining, "%.1lf,",
+ locationExtended.altitudeMeanSeaLevel);
+ }
+ else
+ {
+ length = snprintf(pMarker, lengthRemaining,",");
+ }
+
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+
+ if ((location.gpsLocation.flags & LOC_GPS_LOCATION_HAS_ALTITUDE) &&
+ (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_ALTITUDE_MEAN_SEA_LEVEL))
+ {
+ length = snprintf(pMarker, lengthRemaining, "%.1lf,,",
+ ref_lla.alt - locationExtended.altitudeMeanSeaLevel);
+ }
+ else
+ {
+ length = snprintf(pMarker, lengthRemaining,",,");
+ }
+
+ pMarker += length;
+ lengthRemaining -= length;
+
+ // hardcode Navigation Status field to 'V'
+ length = snprintf(pMarker, lengthRemaining, ",%c", 'V');
+ pMarker += length;
+ lengthRemaining -= length;
+
+ length = loc_nmea_put_checksum(sentence_GNS, sizeof(sentence_GNS));
+
+
+ // -------------------
// ------$--GGA-------
// -------------------
@@ -1482,25 +1651,31 @@ void loc_nmea_generate_pos(const UlpLocation &location,
// ------$--DTM-------
nmeaArraystr.push_back(sentence_DTM);
}
+ // ------$--GNS-------
+ nmeaArraystr.push_back(sentence_GNS);
+ if(LOC_GNSS_DATUM_PZ90 == datum_type) {
+ // ------$--DTM-------
+ nmeaArraystr.push_back(sentence_DTM);
+ }
// ------$--GGA-------
nmeaArraystr.push_back(sentence_GGA);
}
//Send blank NMEA reports for non-final fixes
else {
- strlcpy(sentence, "$GPGSA,A,1,,,,,,,,,,,,,,,", sizeof(sentence));
+ strlcpy(sentence, "$GPGSA,A,1,,,,,,,,,,,,,,,,", sizeof(sentence));
length = loc_nmea_put_checksum(sentence, sizeof(sentence));
nmeaArraystr.push_back(sentence);
- strlcpy(sentence, "$GNGSA,A,1,,,,,,,,,,,,,,,", sizeof(sentence));
+ strlcpy(sentence, "$GNGSA,A,1,,,,,,,,,,,,,,,,", sizeof(sentence));
length = loc_nmea_put_checksum(sentence, sizeof(sentence));
nmeaArraystr.push_back(sentence);
- strlcpy(sentence, "$PQGSA,A,1,,,,,,,,,,,,,,,", sizeof(sentence));
+ strlcpy(sentence, "$GPVTG,,T,,M,,N,,K,N", sizeof(sentence));
length = loc_nmea_put_checksum(sentence, sizeof(sentence));
nmeaArraystr.push_back(sentence);
- strlcpy(sentence, "$GPVTG,,T,,M,,N,,K,N", sizeof(sentence));
+ strlcpy(sentence, "$GPDTM,,,,,,,,", sizeof(sentence));
length = loc_nmea_put_checksum(sentence, sizeof(sentence));
nmeaArraystr.push_back(sentence);
@@ -1508,6 +1683,10 @@ void loc_nmea_generate_pos(const UlpLocation &location,
length = loc_nmea_put_checksum(sentence, sizeof(sentence));
nmeaArraystr.push_back(sentence);
+ strlcpy(sentence, "$GPGNS,,,,,,N,,,,,,,V", sizeof(sentence));
+ length = loc_nmea_put_checksum(sentence, sizeof(sentence));
+ nmeaArraystr.push_back(sentence);
+
strlcpy(sentence, "$GPGGA,,,,,,0,,,,,,,,", sizeof(sentence));
length = loc_nmea_put_checksum(sentence, sizeof(sentence));
nmeaArraystr.push_back(sentence);
diff --git a/utils/log_util.h b/utils/log_util.h
index 4fed90b..ed7e19e 100644
--- a/utils/log_util.h
+++ b/utils/log_util.h
@@ -47,6 +47,14 @@
#endif /* LOG_TAG */
// LE targets with no logcat support
+#ifdef FEATURE_EXTERNAL_AP
+#include <syslog.h>
+#define ALOGE(...) syslog(LOG_ERR, "LOC_LOGE: " __VA_ARGS__);
+#define ALOGW(...) syslog(LOG_WARNING, "LOC_LOGW: " __VA_ARGS__);
+#define ALOGI(...) syslog(LOG_NOTICE, "LOC_LOGI: " __VA_ARGS__);
+#define ALOGD(...) syslog(LOG_DEBUG, "LOC_LOGD: " __VA_ARGS__);
+#define ALOGV(...) syslog(LOG_NOTICE, "LOC_LOGV: " __VA_ARGS__);
+#else /* FEATURE_EXTERNAL_AP */
#define TS_PRINTF(format, x...) \
{ \
struct timeval tv; \
@@ -64,6 +72,7 @@
#define ALOGI(format, x...) TS_PRINTF("I/%s (%d): " format , LOG_TAG, getpid(), ##x)
#define ALOGD(format, x...) TS_PRINTF("D/%s (%d): " format , LOG_TAG, getpid(), ##x)
#define ALOGV(format, x...) TS_PRINTF("V/%s (%d): " format , LOG_TAG, getpid(), ##x)
+#endif /* FEATURE_EXTERNAL_AP */
#endif /* #if defined (USE_ANDROID_LOGGING) || defined (ANDROID) */
diff --git a/utils/msg_q.c b/utils/msg_q.c
index 76c1478..2d49b4a 100644
--- a/utils/msg_q.c
+++ b/utils/msg_q.c
@@ -267,6 +267,51 @@ msq_q_err_type msg_q_rcv(void* msg_q_data, void** msg_obj)
/*===========================================================================
+ FUNCTION: msg_q_rmv
+
+ ===========================================================================*/
+msq_q_err_type msg_q_rmv(void* msg_q_data, void** msg_obj)
+{
+ msq_q_err_type rv;
+ if (msg_q_data == NULL) {
+ LOC_LOGE("%s: Invalid msg_q_data parameter!\n", __FUNCTION__);
+ return eMSG_Q_INVALID_HANDLE;
+ }
+
+ if (msg_obj == NULL) {
+ LOC_LOGE("%s: Invalid msg_obj parameter!\n", __FUNCTION__);
+ return eMSG_Q_INVALID_PARAMETER;
+ }
+
+ msg_q* p_msg_q = (msg_q*)msg_q_data;
+
+ pthread_mutex_lock(&p_msg_q->list_mutex);
+
+ if (p_msg_q->unblocked) {
+ LOC_LOGE("%s: Message queue has been unblocked.\n", __FUNCTION__);
+ pthread_mutex_unlock(&p_msg_q->list_mutex);
+ return eMSG_Q_UNAVAILABLE_RESOURCE;
+ }
+
+ if (linked_list_empty(p_msg_q->msg_list)) {
+ LOC_LOGW("%s: list is empty !!\n", __FUNCTION__);
+ pthread_mutex_unlock(&p_msg_q->list_mutex);
+ return eLINKED_LIST_EMPTY;
+ }
+
+ rv = convert_linked_list_err_type(linked_list_remove(p_msg_q->msg_list, msg_obj));
+
+ pthread_mutex_unlock(&p_msg_q->list_mutex);
+
+ LOC_LOGV("%s: Removed message %p rv = %d\n", __FUNCTION__, *msg_obj, rv);
+
+ return rv;
+}
+
+
+
+/*===========================================================================
+
FUNCTION: msg_q_flush
===========================================================================*/
diff --git a/utils/msg_q.h b/utils/msg_q.h
index 453b8ce..16df494 100644
--- a/utils/msg_q.h
+++ b/utils/msg_q.h
@@ -158,6 +158,29 @@ SIDE EFFECTS
msq_q_err_type msg_q_rcv(void* msg_q_data, void** msg_obj);
/*===========================================================================
+FUNCTION msg_q_rmv
+
+DESCRIPTION
+ Remove data from the message queue. msg_obj is the oldest message received
+ and pointer is simply removed from message queue.
+
+ msg_q_data: Message Queue to copy data from into msgp.
+ msg_obj: Pointer to space to copy msg_q contents to.
+
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ Look at error codes above.
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+msq_q_err_type msg_q_rmv(void* msg_q_data, void** msg_obj);
+
+
+/*===========================================================================
FUNCTION msg_q_flush
DESCRIPTION