Snap for 8562061 from a3344c8386fa80b7a2ffd53f6e7612b4ec20fb5e to mainline-media-release
Change-Id: I42c4cd3ab752c44171ff19bd14de2a9aeb49de6f
diff --git a/Android.bp b/Android.bp
new file mode 100644
index 0000000..3c3e893
--- /dev/null
+++ b/Android.bp
@@ -0,0 +1,65 @@
+soong_namespace {
+}
+
+package {
+ default_applicable_licenses: ["hardware_qcom_sm7250_gps_license"],
+}
+
+// Added automatically by a large-scale-change that took the approach of
+// 'apply every license found to every target'. While this makes sure we respect
+// every license restriction, it may not be entirely correct.
+//
+// e.g. GPL in an MIT project might only apply to the contrib/ directory.
+//
+// Please consider splitting the single license below into multiple licenses,
+// taking care not to lose any license_kind information, and overriding the
+// default license using the 'licenses: [...]' property on targets as needed.
+//
+// For unused files, consider creating a 'fileGroup' with "//visibility:private"
+// to attach the license to, and including a comment whether the files may be
+// used in the current project.
+// See: http://go/android-license-faq
+license {
+ name: "hardware_qcom_sm7250_gps_license",
+ visibility: [":__subpackages__"],
+ license_kinds: [
+ "SPDX-license-identifier-Apache-2.0",
+ "SPDX-license-identifier-BSD",
+ "legacy_not_a_contribution",
+ ],
+ // large-scale-change unable to identify any license_text files
+}
+
+GNSS_CFLAGS = [
+ "-Werror",
+ "-Wno-error=unused-parameter",
+ "-Wno-error=macro-redefined",
+ "-Wno-error=reorder",
+ "-Wno-error=missing-braces",
+ "-Wno-error=self-assign",
+ "-Wno-error=enum-conversion",
+ "-Wno-error=logical-op-parentheses",
+ "-Wno-error=null-arithmetic",
+ "-Wno-error=null-conversion",
+ "-Wno-error=parentheses-equality",
+ "-Wno-error=undefined-bool-conversion",
+ "-Wno-error=tautological-compare",
+ "-Wno-error=switch",
+ "-Wno-error=date-time",
+]
+
+/* Activate the following for debug purposes only,
+ comment out for production */
+GNSS_SANITIZE_DIAG = {
+/*
+ diag: {
+ cfi: true,
+ misc_undefined: [
+ "bounds",
+ "null",
+ "unreachable",
+ "integer",
+ ],
+ },
+*/
+}
diff --git a/Android.mk b/Android.mk
index f1088a4..88bb0f4 100644
--- a/Android.mk
+++ b/Android.mk
@@ -1,5 +1,41 @@
ifneq ($(BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE),)
-LOCAL_PATH := $(call my-dir)
-include $(LOCAL_PATH)/build/target_specific_features.mk
-include $(call all-makefiles-under,$(LOCAL_PATH))
+
+# Set required flags
+GNSS_CFLAGS := \
+ -Werror \
+ -Wno-error=unused-parameter \
+ -Wno-error=macro-redefined \
+ -Wno-error=reorder \
+ -Wno-error=missing-braces \
+ -Wno-error=self-assign \
+ -Wno-error=enum-conversion \
+ -Wno-error=logical-op-parentheses \
+ -Wno-error=null-arithmetic \
+ -Wno-error=null-conversion \
+ -Wno-error=parentheses-equality \
+ -Wno-error=undefined-bool-conversion \
+ -Wno-error=tautological-compare \
+ -Wno-error=switch \
+ -Wno-error=date-time
+
+GNSS_HIDL_VERSION = 2.1
+
+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
+
+LOCAL_PATH := $(call my-dir)
+include $(call all-makefiles-under,$(LOCAL_PATH))
+
+GNSS_SANITIZE_DIAG := cfi bounds null unreachable integer address
+
+endif # ifneq ($(BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE),)
diff --git a/METADATA b/METADATA
new file mode 100644
index 0000000..d97975c
--- /dev/null
+++ b/METADATA
@@ -0,0 +1,3 @@
+third_party {
+ license_type: NOTICE
+}
diff --git a/android/1.0/AGnssRil.cpp b/android/1.0/AGnssRil.cpp
index 0437cf1..6879174 100644
--- a/android/1.0/AGnssRil.cpp
+++ b/android/1.0/AGnssRil.cpp
@@ -54,32 +54,33 @@
const int NetworkType_BLUETOOTH = 7;
const int NetworkType_ETHERNET = 9;
const int NetworkType_PROXY = 16;
+ std::string apn("");
// for XTRA
if (nullptr != mGnss && ( nullptr != mGnss->getGnssInterface() )) {
- int8_t typeout = loc_core::NetworkInfoDataItemBase::TYPE_UNKNOWN;
+ int8_t typeout = loc_core::TYPE_UNKNOWN;
switch(type)
{
case IAGnssRil::NetworkType::MOBILE:
- typeout = loc_core::NetworkInfoDataItemBase::TYPE_MOBILE;
+ typeout = loc_core::TYPE_MOBILE;
break;
case IAGnssRil::NetworkType::WIFI:
- typeout = loc_core::NetworkInfoDataItemBase::TYPE_WIFI;
+ typeout = loc_core::TYPE_WIFI;
break;
case IAGnssRil::NetworkType::MMS:
- typeout = loc_core::NetworkInfoDataItemBase::TYPE_MMS;
+ typeout = loc_core::TYPE_MMS;
break;
case IAGnssRil::NetworkType::SUPL:
- typeout = loc_core::NetworkInfoDataItemBase::TYPE_SUPL;
+ typeout = loc_core::TYPE_SUPL;
break;
case IAGnssRil::NetworkType::DUN:
- typeout = loc_core::NetworkInfoDataItemBase::TYPE_DUN;
+ typeout = loc_core::TYPE_DUN;
break;
case IAGnssRil::NetworkType::HIPRI:
- typeout = loc_core::NetworkInfoDataItemBase::TYPE_HIPRI;
+ typeout = loc_core::TYPE_HIPRI;
break;
case IAGnssRil::NetworkType::WIMAX:
- typeout = loc_core::NetworkInfoDataItemBase::TYPE_WIMAX;
+ typeout = loc_core::TYPE_WIMAX;
break;
default:
{
@@ -88,21 +89,21 @@
switch(networkType)
{
case NetworkType_BLUETOOTH:
- typeout = loc_core::NetworkInfoDataItemBase::TYPE_BLUETOOTH;
+ typeout = loc_core::TYPE_BLUETOOTH;
break;
case NetworkType_ETHERNET:
- typeout = loc_core::NetworkInfoDataItemBase::TYPE_ETHERNET;
+ typeout = loc_core::TYPE_ETHERNET;
break;
case NetworkType_PROXY:
- typeout = loc_core::NetworkInfoDataItemBase::TYPE_PROXY;
+ typeout = loc_core::TYPE_PROXY;
break;
default:
- typeout = loc_core::NetworkInfoDataItemBase::TYPE_UNKNOWN;
+ typeout = loc_core::TYPE_UNKNOWN;
}
}
break;
}
- mGnss->getGnssInterface()->updateConnectionStatus(connected, false, typeout, 0);
+ mGnss->getGnssInterface()->updateConnectionStatus(connected, typeout, false, 0, apn);
}
return true;
}
diff --git a/android/1.0/Android.mk b/android/1.0/Android.mk
index 797ecce..27c697b 100644
--- a/android/1.0/Android.mk
+++ b/android/1.0/Android.mk
@@ -2,7 +2,8 @@
include $(CLEAR_VARS)
LOCAL_MODULE := android.hardware.gnss@1.0-impl-qti
-LOCAL_SANITIZE += $(GNSS_SANITIZE)
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 SPDX-license-identifier-BSD legacy_not_a_contribution
+LOCAL_LICENSE_CONDITIONS := by_exception_only not_allowed notice
# activate the following line for debug purposes only, comment out for production
#LOCAL_SANITIZE_DIAG += $(GNSS_SANITIZE_DIAG)
LOCAL_VENDOR_MODULE := true
@@ -42,6 +43,7 @@
android.hardware.gnss@1.0 \
android.hardware.health@1.0 \
android.hardware.health@2.0 \
+ android.hardware.health@2.1 \
android.hardware.power@1.2 \
libbase
@@ -58,7 +60,8 @@
include $(CLEAR_VARS)
LOCAL_MODULE := android.hardware.gnss@1.0-service-qti
-LOCAL_SANITIZE += $(GNSS_SANITIZE)
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 SPDX-license-identifier-BSD legacy_not_a_contribution
+LOCAL_LICENSE_CONDITIONS := by_exception_only not_allowed notice
# activate the following line for debug purposes only, comment out for production
#LOCAL_SANITIZE_DIAG += $(GNSS_SANITIZE_DIAG)
LOCAL_VINTF_FRAGMENTS := android.hardware.gnss@1.0-service-qti.xml
diff --git a/android/1.0/Gnss.cpp b/android/1.0/Gnss.cpp
index adb5232..308cc7c 100644
--- a/android/1.0/Gnss.cpp
+++ b/android/1.0/Gnss.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
* Not a Contribution
*/
/*
@@ -28,6 +28,7 @@
#include "Gnss.h"
#include <LocationUtil.h>
#include "battery_listener.h"
+#include "loc_misc_utils.h"
typedef const GnssInterface* (getLocationInterface)();
@@ -42,6 +43,7 @@
LOC_LOGE("%s] service died. cookie: %llu, who: %p",
__FUNCTION__, static_cast<unsigned long long>(cookie), &who);
if (mGnss != nullptr) {
+ mGnss->getGnssInterface()->resetNetworkInfo();
mGnss->stop();
mGnss->cleanup();
}
@@ -69,7 +71,7 @@
Gnss::~Gnss() {
ENTRY_LOG_CALLFLOW();
if (mApi != nullptr) {
- delete mApi;
+ mApi->destroy();
mApi = nullptr;
}
sGnss = nullptr;
@@ -102,22 +104,11 @@
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;
- }
- }
+ void * libHandle = nullptr;
+ getLocationInterface* getter = (getLocationInterface*)
+ dlGetSymFromLib(libHandle, "libgnss.so", "getGnssInterface");
- if (NULL == getter) {
+ if (nullptr == getter) {
getGnssInterfaceFailed = true;
} else {
mGnssInterface = (const GnssInterface*)(*getter)();
@@ -185,7 +176,7 @@
}
if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT) {
mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT;
- mPendingConfig.lppProfile = gnssConfig.lppProfile;
+ mPendingConfig.lppProfileMask = gnssConfig.lppProfileMask;
}
if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT) {
mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT;
diff --git a/android/1.0/GnssBatching.cpp b/android/1.0/GnssBatching.cpp
index 3e5a9f4..f92697f 100644
--- a/android/1.0/GnssBatching.cpp
+++ b/android/1.0/GnssBatching.cpp
@@ -46,7 +46,7 @@
GnssBatching::~GnssBatching() {
if (mApi != nullptr) {
- delete mApi;
+ mApi->destroy();
mApi = nullptr;
}
}
@@ -56,7 +56,7 @@
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->destroy();
mApi = nullptr;
}
diff --git a/android/1.0/GnssConfiguration.cpp b/android/1.0/GnssConfiguration.cpp
index 73c9d5c..a7f64fa 100644
--- a/android/1.0/GnssConfiguration.cpp
+++ b/android/1.0/GnssConfiguration.cpp
@@ -80,7 +80,6 @@
default:
LOC_LOGE("%s]: invalid version: 0x%x.", __FUNCTION__, version);
return false;
- break;
}
return mGnss->updateConfiguration(config);
@@ -112,39 +111,33 @@
default:
LOC_LOGE("%s]: invalid mode: %d.", __FUNCTION__, mode);
return false;
- break;
}
return mGnss->updateConfiguration(config);
}
-Return<bool> GnssConfiguration::setLppProfile(uint8_t lppProfile) {
+Return<bool> GnssConfiguration::setLppProfile(uint8_t lppProfileMask) {
if (mGnss == nullptr) {
LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
return false;
}
- GnssConfig config;
- memset(&config, 0, sizeof(GnssConfig));
+ GnssConfig config = {};
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;
+ config.lppProfileMask = GNSS_CONFIG_LPP_PROFILE_RRLP_ON_LTE; //default
+
+ if (lppProfileMask & (1<<0)) {
+ config.lppProfileMask |= GNSS_CONFIG_LPP_PROFILE_USER_PLANE_BIT;
+ }
+ if (lppProfileMask & (1<<1)) {
+ config.lppProfileMask |= GNSS_CONFIG_LPP_PROFILE_CONTROL_PLANE_BIT;
+ }
+ if (lppProfileMask & (1<<2)) {
+ config.lppProfileMask |= GNSS_CONFIG_LPP_PROFILE_USER_PLANE_OVER_NR5G_SA_BIT;
+ }
+ if (lppProfileMask & (1<<3)) {
+ config.lppProfileMask |= GNSS_CONFIG_LPP_PROFILE_CONTROL_PLANE_OVER_NR5G_SA_BIT;
}
return mGnss->updateConfiguration(config);
@@ -203,7 +196,6 @@
default:
LOC_LOGE("%s]: invalid lock: %d.", __FUNCTION__, lock);
return false;
- break;
}
return mGnss->updateConfiguration(config);
diff --git a/android/1.0/GnssConfiguration.h b/android/1.0/GnssConfiguration.h
index 1629e06..d0e2ba8 100644
--- a/android/1.0/GnssConfiguration.h
+++ b/android/1.0/GnssConfiguration.h
@@ -53,7 +53,7 @@
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> setLppProfile(uint8_t lppProfileMask) override;
Return<bool> setGlonassPositioningProtocol(uint8_t protocol) override;
Return<bool> setEmergencySuplPdn(bool enable) override;
Return<bool> setGpsLock(uint8_t lock) override;
diff --git a/android/1.0/GnssGeofencing.cpp b/android/1.0/GnssGeofencing.cpp
index 2a8ff88..4be6d8a 100644
--- a/android/1.0/GnssGeofencing.cpp
+++ b/android/1.0/GnssGeofencing.cpp
@@ -45,7 +45,7 @@
GnssGeofencing::~GnssGeofencing() {
if (mApi != nullptr) {
- delete mApi;
+ mApi->destroy();
mApi = nullptr;
}
}
diff --git a/android/1.0/GnssMeasurement.cpp b/android/1.0/GnssMeasurement.cpp
index 1c65bd6..7af9e27 100644
--- a/android/1.0/GnssMeasurement.cpp
+++ b/android/1.0/GnssMeasurement.cpp
@@ -46,7 +46,7 @@
GnssMeasurement::~GnssMeasurement() {
if (mApi) {
- delete mApi;
+ mApi->destroy();
mApi = nullptr;
}
}
diff --git a/android/1.0/location_api/BatchingAPIClient.cpp b/android/1.0/location_api/BatchingAPIClient.cpp
index 264ab83..94a234d 100644
--- a/android/1.0/location_api/BatchingAPIClient.cpp
+++ b/android/1.0/location_api/BatchingAPIClient.cpp
@@ -30,6 +30,7 @@
#define LOG_NDEBUG 0
#define LOG_TAG "LocSvc_BatchingAPIClient"
+#include <inttypes.h>
#include <log_util.h>
#include <loc_cfg.h>
@@ -153,7 +154,7 @@
void BatchingAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)
{
- LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask);
+ LOC_LOGD("%s]: (%" PRIu64 ")", __FUNCTION__, capabilitiesMask);
mLocationCapabilitiesMask = capabilitiesMask;
}
diff --git a/android/1.0/location_api/BatchingAPIClient.h b/android/1.0/location_api/BatchingAPIClient.h
index 5d64df3..c3b0a7b 100644
--- a/android/1.0/location_api/BatchingAPIClient.h
+++ b/android/1.0/location_api/BatchingAPIClient.h
@@ -46,7 +46,6 @@
{
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);
@@ -61,6 +60,8 @@
void onBatchingCb(size_t count, Location* location, BatchingOptions batchOptions) final;
private:
+ ~BatchingAPIClient();
+
sp<V1_0::IGnssBatchingCallback> mGnssBatchingCbIface;
uint32_t mDefaultId;
LocationCapabilitiesMask mLocationCapabilitiesMask;
diff --git a/android/1.0/location_api/GeofenceAPIClient.cpp b/android/1.0/location_api/GeofenceAPIClient.cpp
index 774a049..6feb841 100644
--- a/android/1.0/location_api/GeofenceAPIClient.cpp
+++ b/android/1.0/location_api/GeofenceAPIClient.cpp
@@ -141,7 +141,7 @@
// callbacks
void GeofenceAPIClient::onGeofenceBreachCb(GeofenceBreachNotification geofenceBreachNotification)
{
- LOC_LOGD("%s]: (%zu)", __FUNCTION__, geofenceBreachNotification.count);
+ LOC_LOGD("%s]: (%d)", __FUNCTION__, geofenceBreachNotification.count);
if (mGnssGeofencingCbIface != nullptr) {
for (size_t i = 0; i < geofenceBreachNotification.count; i++) {
GnssLocation gnssLocation;
diff --git a/android/1.0/location_api/GeofenceAPIClient.h b/android/1.0/location_api/GeofenceAPIClient.h
index dc99ddd..b6a009b 100644
--- a/android/1.0/location_api/GeofenceAPIClient.h
+++ b/android/1.0/location_api/GeofenceAPIClient.h
@@ -46,7 +46,6 @@
{
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,
@@ -65,6 +64,8 @@
void onResumeGeofencesCb(size_t count, LocationError* errors, uint32_t* ids) final;
private:
+ virtual ~GeofenceAPIClient() = default;
+
sp<V1_0::IGnssGeofenceCallback> mGnssGeofencingCbIface;
};
diff --git a/android/1.0/location_api/GnssAPIClient.cpp b/android/1.0/location_api/GnssAPIClient.cpp
index eb78591..9cef2ba 100644
--- a/android/1.0/location_api/GnssAPIClient.cpp
+++ b/android/1.0/location_api/GnssAPIClient.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2020, 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,6 +31,7 @@
#define LOG_TAG "LocSvc_GnssAPIClient"
#define SINGLE_SHOT_MIN_TRACKING_INTERVAL_MSEC (590 * 60 * 60 * 1000) // 590 hours
+#include <inttypes.h>
#include <log_util.h>
#include <loc_cfg.h>
@@ -110,9 +111,7 @@
locationCallbacks.gnssNiCb = nullptr;
loc_core::ContextBase* context =
- loc_core::LocContext::getLocContext(
- NULL, NULL,
- loc_core::LocContext::mLocationHalName, false);
+ loc_core::LocContext::getLocContext(loc_core::LocContext::mLocationHalName);
if (mGnssNiCbIface != nullptr && !context->hasAgpsExtendedCapabilities()) {
LOC_LOGD("Registering NI CB");
locationCallbacks.gnssNiCb = [this](uint32_t id, GnssNiNotification gnssNiNotification) {
@@ -301,7 +300,7 @@
// callbacks
void GnssAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)
{
- LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask);
+ LOC_LOGD("%s]: (%" PRIu64 ")", __FUNCTION__, capabilitiesMask);
mLocationCapabilitiesMask = capabilitiesMask;
mLocationCapabilitiesCached = true;
@@ -331,16 +330,17 @@
}
}
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;
+ IGnssCallback::GnssSystemInfo gnssInfo = { .yearOfHw = 2015 };
+
+ if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT) {
+ gnssInfo.yearOfHw++; // 2016
+ if (capabilitiesMask & LOCATION_CAPABILITIES_DEBUG_NMEA_BIT) {
+ gnssInfo.yearOfHw++; // 2017
+ if (capabilitiesMask & LOCATION_CAPABILITIES_CONSTELLATION_ENABLEMENT_BIT ||
+ capabilitiesMask & LOCATION_CAPABILITIES_AGPM_BIT) {
+ gnssInfo.yearOfHw++; // 2018
+ }
+ }
}
LOC_LOGV("%s:%d] set_system_info_cb (%d)", __FUNCTION__, __LINE__, gnssInfo.yearOfHw);
auto r = gnssCbIface->gnssSetSystemInfoCb(gnssInfo);
@@ -446,7 +446,7 @@
void GnssAPIClient::onGnssSvCb(GnssSvNotification gnssSvNotification)
{
- LOC_LOGD("%s]: (count: %zu)", __FUNCTION__, gnssSvNotification.count);
+ LOC_LOGD("%s]: (count: %u)", __FUNCTION__, gnssSvNotification.count);
mMutex.lock();
auto gnssCbIface(mGnssCbIface);
mMutex.unlock();
@@ -479,7 +479,7 @@
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__,
+ LOC_LOGE("%s] Error from gnssNmeaCb nmea=%s length=%u description=%s", __func__,
gnssNmeaNotification.nmea, gnssNmeaNotification.length,
r.description().c_str());
}
@@ -540,7 +540,7 @@
}
for (size_t i = 0; i < out.numSvs; i++) {
IGnssCallback::GnssSvInfo& info = out.gnssSvList[i];
- info.svid = in.gnssSvs[i].svId;
+ convertGnssSvid(in.gnssSvs[i], info.svid);
convertGnssConstellationType(in.gnssSvs[i].type, info.constellation);
info.cN0Dbhz = in.gnssSvs[i].cN0Dbhz;
info.elevationDegrees = in.gnssSvs[i].elevation;
diff --git a/android/1.0/location_api/GnssAPIClient.h b/android/1.0/location_api/GnssAPIClient.h
index 4e4b4a9..427b0db 100644
--- a/android/1.0/location_api/GnssAPIClient.h
+++ b/android/1.0/location_api/GnssAPIClient.h
@@ -50,7 +50,6 @@
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;
@@ -92,6 +91,8 @@
void onStopTrackingCb(LocationError error) final;
private:
+ virtual ~GnssAPIClient();
+
sp<V1_0::IGnssCallback> mGnssCbIface;
sp<V1_0::IGnssNiCallback> mGnssNiCbIface;
std::mutex mMutex;
diff --git a/android/1.0/location_api/LocationUtil.cpp b/android/1.0/location_api/LocationUtil.cpp
index 102593b..a37d8de 100644
--- a/android/1.0/location_api/LocationUtil.cpp
+++ b/android/1.0/location_api/LocationUtil.cpp
@@ -28,6 +28,7 @@
*/
#include <LocationUtil.h>
+#include <gps_extended_c.h>
namespace android {
namespace hardware {
@@ -147,6 +148,74 @@
}
}
+void convertGnssSvid(GnssSv& in, int16_t& out)
+{
+ switch(in.type){
+ case GNSS_SV_TYPE_GPS:
+ out = in.svId;
+ break;
+ case GNSS_SV_TYPE_SBAS:
+ out = in.svId;
+ break;
+ case GNSS_SV_TYPE_GLONASS:
+ if (!isGloSlotUnknown(in.svId)) { // OSN is known
+ out = in.svId - GLO_SV_PRN_MIN + 1;
+ } else { // OSN is not known, report FCN
+ out = in.gloFrequency + 92;
+ }
+ break;
+ case GNSS_SV_TYPE_QZSS:
+ out = in.svId;
+ break;
+ case GNSS_SV_TYPE_BEIDOU:
+ out = in.svId - BDS_SV_PRN_MIN + 1;
+ break;
+ case GNSS_SV_TYPE_GALILEO:
+ out = in.svId - GAL_SV_PRN_MIN + 1;
+ break;
+ case GNSS_SV_TYPE_NAVIC:
+ out = in.svId - NAVIC_SV_PRN_MIN + 1;
+ break;
+ default:
+ out = in.svId;
+ break;
+ }
+}
+
+void convertGnssSvid(GnssMeasurementsData& in, int16_t& out)
+{
+ switch (in.svType) {
+ case GNSS_SV_TYPE_GPS:
+ out = in.svId;
+ break;
+ case GNSS_SV_TYPE_SBAS:
+ out = in.svId;
+ break;
+ case GNSS_SV_TYPE_GLONASS:
+ if (!isGloSlotUnknown(in.svId)) { // OSN is known
+ out = in.svId - GLO_SV_PRN_MIN + 1;
+ } else { // OSN is not known, report FCN
+ out = in.gloFrequency + 92;
+ }
+ break;
+ case GNSS_SV_TYPE_QZSS:
+ out = in.svId;
+ break;
+ case GNSS_SV_TYPE_BEIDOU:
+ out = in.svId - BDS_SV_PRN_MIN + 1;
+ break;
+ case GNSS_SV_TYPE_GALILEO:
+ out = in.svId - GAL_SV_PRN_MIN + 1;
+ break;
+ case GNSS_SV_TYPE_NAVIC:
+ out = in.svId - NAVIC_SV_PRN_MIN + 1;
+ break;
+ default:
+ out = in.svId;
+ break;
+ }
+}
+
void convertGnssEphemerisType(GnssEphemerisType& in, GnssDebug::SatelliteEphemerisType& out)
{
switch(in) {
diff --git a/android/1.0/location_api/LocationUtil.h b/android/1.0/location_api/LocationUtil.h
index 9e0cd36..f6760e5 100644
--- a/android/1.0/location_api/LocationUtil.h
+++ b/android/1.0/location_api/LocationUtil.h
@@ -43,6 +43,8 @@
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 convertGnssSvid(GnssSv& in, int16_t& out);
+void convertGnssSvid(GnssMeasurementsData& in, int16_t& out);
void convertGnssEphemerisType(GnssEphemerisType& in, GnssDebug::SatelliteEphemerisType& out);
void convertGnssEphemerisSource(GnssEphemerisSource& in, GnssDebug::SatelliteEphemerisSource& out);
void convertGnssEphemerisHealth(GnssEphemerisHealth& in, GnssDebug::SatelliteEphemerisHealth& out);
diff --git a/android/1.0/location_api/MeasurementAPIClient.cpp b/android/1.0/location_api/MeasurementAPIClient.cpp
index 73709e3..8dd039b 100644
--- a/android/1.0/location_api/MeasurementAPIClient.cpp
+++ b/android/1.0/location_api/MeasurementAPIClient.cpp
@@ -125,7 +125,7 @@
void MeasurementAPIClient::onGnssMeasurementsCb(
GnssMeasurementsNotification gnssMeasurementsNotification)
{
- LOC_LOGD("%s]: (count: %zu active: %d)",
+ LOC_LOGD("%s]: (count: %u active: %d)",
__FUNCTION__, gnssMeasurementsNotification.count, mTracking);
if (mTracking) {
mMutex.lock();
@@ -163,7 +163,7 @@
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;
+ convertGnssSvid(in, out.svid);
convertGnssConstellationType(in.svType, out.constellation);
out.timeOffsetNs = in.timeOffsetNs;
if (in.stateMask & GNSS_MEASUREMENTS_STATE_CODE_LOCK_BIT)
diff --git a/android/1.0/location_api/MeasurementAPIClient.h b/android/1.0/location_api/MeasurementAPIClient.h
index c357313..225deac 100644
--- a/android/1.0/location_api/MeasurementAPIClient.h
+++ b/android/1.0/location_api/MeasurementAPIClient.h
@@ -49,7 +49,6 @@
{
public:
MeasurementAPIClient();
- virtual ~MeasurementAPIClient();
MeasurementAPIClient(const MeasurementAPIClient&) = delete;
MeasurementAPIClient& operator=(const MeasurementAPIClient&) = delete;
@@ -63,6 +62,8 @@
void onGnssMeasurementsCb(GnssMeasurementsNotification gnssMeasurementsNotification) final;
private:
+ virtual ~MeasurementAPIClient();
+
std::mutex mMutex;
sp<V1_0::IGnssMeasurementCallback> mGnssMeasurementCbIface;
diff --git a/android/1.1/AGnssRil.cpp b/android/1.1/AGnssRil.cpp
index 1e774f1..af519a7 100644
--- a/android/1.1/AGnssRil.cpp
+++ b/android/1.1/AGnssRil.cpp
@@ -54,32 +54,33 @@
const int NetworkType_BLUETOOTH = 7;
const int NetworkType_ETHERNET = 9;
const int NetworkType_PROXY = 16;
+ std::string apn("");
// for XTRA
if (nullptr != mGnss && ( nullptr != mGnss->getGnssInterface() )) {
- int8_t typeout = loc_core::NetworkInfoDataItemBase::TYPE_UNKNOWN;
+ int8_t typeout = loc_core::TYPE_UNKNOWN;
switch(type)
{
case IAGnssRil::NetworkType::MOBILE:
- typeout = loc_core::NetworkInfoDataItemBase::TYPE_MOBILE;
+ typeout = loc_core::TYPE_MOBILE;
break;
case IAGnssRil::NetworkType::WIFI:
- typeout = loc_core::NetworkInfoDataItemBase::TYPE_WIFI;
+ typeout = loc_core::TYPE_WIFI;
break;
case IAGnssRil::NetworkType::MMS:
- typeout = loc_core::NetworkInfoDataItemBase::TYPE_MMS;
+ typeout = loc_core::TYPE_MMS;
break;
case IAGnssRil::NetworkType::SUPL:
- typeout = loc_core::NetworkInfoDataItemBase::TYPE_SUPL;
+ typeout = loc_core::TYPE_SUPL;
break;
case IAGnssRil::NetworkType::DUN:
- typeout = loc_core::NetworkInfoDataItemBase::TYPE_DUN;
+ typeout = loc_core::TYPE_DUN;
break;
case IAGnssRil::NetworkType::HIPRI:
- typeout = loc_core::NetworkInfoDataItemBase::TYPE_HIPRI;
+ typeout = loc_core::TYPE_HIPRI;
break;
case IAGnssRil::NetworkType::WIMAX:
- typeout = loc_core::NetworkInfoDataItemBase::TYPE_WIMAX;
+ typeout = loc_core::TYPE_WIMAX;
break;
default:
{
@@ -88,21 +89,21 @@
switch(networkType)
{
case NetworkType_BLUETOOTH:
- typeout = loc_core::NetworkInfoDataItemBase::TYPE_BLUETOOTH;
+ typeout = loc_core::TYPE_BLUETOOTH;
break;
case NetworkType_ETHERNET:
- typeout = loc_core::NetworkInfoDataItemBase::TYPE_ETHERNET;
+ typeout = loc_core::TYPE_ETHERNET;
break;
case NetworkType_PROXY:
- typeout = loc_core::NetworkInfoDataItemBase::TYPE_PROXY;
+ typeout = loc_core::TYPE_PROXY;
break;
default:
- typeout = loc_core::NetworkInfoDataItemBase::TYPE_UNKNOWN;
+ typeout = loc_core::TYPE_UNKNOWN;
}
}
break;
}
- mGnss->getGnssInterface()->updateConnectionStatus(connected, false, typeout, 0);
+ mGnss->getGnssInterface()->updateConnectionStatus(connected, typeout, false, 0, apn);
}
return true;
}
diff --git a/android/1.1/Android.mk b/android/1.1/Android.mk
index 66abd06..0a8f1d3 100644
--- a/android/1.1/Android.mk
+++ b/android/1.1/Android.mk
@@ -2,7 +2,8 @@
include $(CLEAR_VARS)
LOCAL_MODULE := android.hardware.gnss@1.1-impl-qti
-LOCAL_SANITIZE += $(GNSS_SANITIZE)
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 SPDX-license-identifier-BSD legacy_not_a_contribution
+LOCAL_LICENSE_CONDITIONS := by_exception_only not_allowed notice
# activate the following line for debug purposes only, comment out for production
#LOCAL_SANITIZE_DIAG += $(GNSS_SANITIZE_DIAG)
LOCAL_VENDOR_MODULE := true
@@ -43,6 +44,7 @@
android.hardware.gnss@1.1 \
android.hardware.health@1.0 \
android.hardware.health@2.0 \
+ android.hardware.health@2.1 \
android.hardware.power@1.2 \
libbase
@@ -59,7 +61,8 @@
include $(CLEAR_VARS)
LOCAL_MODULE := android.hardware.gnss@1.1-service-qti
-LOCAL_SANITIZE += $(GNSS_SANITIZE)
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 SPDX-license-identifier-BSD legacy_not_a_contribution
+LOCAL_LICENSE_CONDITIONS := by_exception_only not_allowed notice
# activate the following line for debug purposes only, comment out for production
#LOCAL_SANITIZE_DIAG += $(GNSS_SANITIZE_DIAG)
LOCAL_VINTF_FRAGMENTS := android.hardware.gnss@1.1-service-qti.xml
diff --git a/android/1.1/Gnss.cpp b/android/1.1/Gnss.cpp
index 260f999..537f6a6 100644
--- a/android/1.1/Gnss.cpp
+++ b/android/1.1/Gnss.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
* Not a Contribution
*/
/*
@@ -29,6 +29,7 @@
#include <LocationUtil.h>
#include "battery_listener.h"
+#include "loc_misc_utils.h"
typedef const GnssInterface* (getLocationInterface)();
@@ -83,6 +84,7 @@
LOC_LOGE("%s] service died. cookie: %llu, who: %p",
__FUNCTION__, static_cast<unsigned long long>(cookie), &who);
if (mGnss != nullptr) {
+ mGnss->getGnssInterface()->resetNetworkInfo();
mGnss->stop();
mGnss->cleanup();
}
@@ -110,7 +112,7 @@
Gnss::~Gnss() {
ENTRY_LOG_CALLFLOW();
if (mApi != nullptr) {
- delete mApi;
+ mApi->destroy();
mApi = nullptr;
}
sGnss = nullptr;
@@ -143,22 +145,11 @@
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;
- }
- }
+ void * libHandle = nullptr;
+ getLocationInterface* getter = (getLocationInterface*)
+ dlGetSymFromLib(libHandle, "libgnss.so", "getGnssInterface");
- if (NULL == getter) {
+ if (nullptr == getter) {
getGnssInterfaceFailed = true;
} else {
mGnssInterface = (const GnssInterface*)(*getter)();
@@ -226,7 +217,7 @@
}
if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT) {
mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT;
- mPendingConfig.lppProfile = gnssConfig.lppProfile;
+ mPendingConfig.lppProfileMask = gnssConfig.lppProfileMask;
}
if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT) {
mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT;
@@ -389,7 +380,7 @@
OdcpiRequestCallback cb = [this](const OdcpiRequestInfo& odcpiRequest) {
odcpiRequestCb(odcpiRequest);
};
- gnssInterface->odcpiInit(cb);
+ gnssInterface->odcpiInit(cb, OdcpiPrioritytype::ODCPI_HANDLER_PRIORITY_LOW);
}
return setCallback(callback);
}
@@ -439,6 +430,9 @@
void Gnss::odcpiRequestCb(const OdcpiRequestInfo& request) {
ENTRY_LOG_CALLFLOW();
+ if (ODCPI_REQUEST_TYPE_STOP == request.type) {
+ return;
+ }
if (mGnssCbIface_1_1 != nullptr) {
// For emergency mode, request DBH (Device based hybrid) location
// Mark Independent from GNSS flag to false.
diff --git a/android/1.1/GnssBatching.cpp b/android/1.1/GnssBatching.cpp
index 9701aff..8ab264d 100644
--- a/android/1.1/GnssBatching.cpp
+++ b/android/1.1/GnssBatching.cpp
@@ -46,7 +46,7 @@
GnssBatching::~GnssBatching() {
if (mApi != nullptr) {
- delete mApi;
+ mApi->destroy();
mApi = nullptr;
}
}
@@ -56,7 +56,7 @@
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->destroy();
mApi = nullptr;
}
diff --git a/android/1.1/GnssConfiguration.cpp b/android/1.1/GnssConfiguration.cpp
index 708e2c1..c50ed9b 100644
--- a/android/1.1/GnssConfiguration.cpp
+++ b/android/1.1/GnssConfiguration.cpp
@@ -80,7 +80,6 @@
default:
LOC_LOGE("%s]: invalid version: 0x%x.", __FUNCTION__, version);
return false;
- break;
}
return mGnss->updateConfiguration(config);
@@ -112,39 +111,33 @@
default:
LOC_LOGE("%s]: invalid mode: %d.", __FUNCTION__, mode);
return false;
- break;
}
return mGnss->updateConfiguration(config);
}
-Return<bool> GnssConfiguration::setLppProfile(uint8_t lppProfile) {
+Return<bool> GnssConfiguration::setLppProfile(uint8_t lppProfileMask) {
if (mGnss == nullptr) {
LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
return false;
}
- GnssConfig config;
- memset(&config, 0, sizeof(GnssConfig));
+ GnssConfig config = {};
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;
+ config.lppProfileMask = GNSS_CONFIG_LPP_PROFILE_RRLP_ON_LTE; //default
+
+ if (lppProfileMask & (1<<0)) {
+ config.lppProfileMask |= GNSS_CONFIG_LPP_PROFILE_USER_PLANE_BIT;
+ }
+ if (lppProfileMask & (1<<1)) {
+ config.lppProfileMask |= GNSS_CONFIG_LPP_PROFILE_CONTROL_PLANE_BIT;
+ }
+ if (lppProfileMask & (1<<2)) {
+ config.lppProfileMask |= GNSS_CONFIG_LPP_PROFILE_USER_PLANE_OVER_NR5G_SA_BIT;
+ }
+ if (lppProfileMask & (1<<3)) {
+ config.lppProfileMask |= GNSS_CONFIG_LPP_PROFILE_CONTROL_PLANE_OVER_NR5G_SA_BIT;
}
return mGnss->updateConfiguration(config);
@@ -203,7 +196,6 @@
default:
LOC_LOGE("%s]: invalid lock: %d.", __FUNCTION__, lock);
return false;
- break;
}
return mGnss->updateConfiguration(config);
@@ -297,7 +289,7 @@
break;
default:
copyToSource.constellation = GNSS_SV_TYPE_UNKNOWN;
- LOC_LOGe("Invalid constellation %d", copyFromSource.constellation);
+ LOC_LOGe("Invalid constellation %hhu", copyFromSource.constellation);
retVal = false;
break;
}
diff --git a/android/1.1/GnssConfiguration.h b/android/1.1/GnssConfiguration.h
index 96681b6..daea159 100644
--- a/android/1.1/GnssConfiguration.h
+++ b/android/1.1/GnssConfiguration.h
@@ -53,7 +53,7 @@
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> setLppProfile(uint8_t lppProfileMask) override;
Return<bool> setGlonassPositioningProtocol(uint8_t protocol) override;
Return<bool> setEmergencySuplPdn(bool enable) override;
Return<bool> setGpsLock(uint8_t lock) override;
diff --git a/android/1.1/GnssGeofencing.cpp b/android/1.1/GnssGeofencing.cpp
index d57a666..a4aaf88 100644
--- a/android/1.1/GnssGeofencing.cpp
+++ b/android/1.1/GnssGeofencing.cpp
@@ -45,7 +45,7 @@
GnssGeofencing::~GnssGeofencing() {
if (mApi != nullptr) {
- delete mApi;
+ mApi->destroy();
mApi = nullptr;
}
}
diff --git a/android/1.1/GnssMeasurement.cpp b/android/1.1/GnssMeasurement.cpp
index ffe5c52..6f8c14d 100644
--- a/android/1.1/GnssMeasurement.cpp
+++ b/android/1.1/GnssMeasurement.cpp
@@ -46,7 +46,7 @@
GnssMeasurement::~GnssMeasurement() {
if (mApi) {
- delete mApi;
+ mApi->destroy();
mApi = nullptr;
}
}
diff --git a/android/1.1/location_api/BatchingAPIClient.cpp b/android/1.1/location_api/BatchingAPIClient.cpp
index 82a803f..6ec27a9 100644
--- a/android/1.1/location_api/BatchingAPIClient.cpp
+++ b/android/1.1/location_api/BatchingAPIClient.cpp
@@ -30,6 +30,7 @@
#define LOG_NDEBUG 0
#define LOG_TAG "LocSvc_BatchingAPIClient"
+#include <inttypes.h>
#include <log_util.h>
#include <loc_cfg.h>
@@ -153,7 +154,7 @@
void BatchingAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)
{
- LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask);
+ LOC_LOGD("%s]: (%" PRIu64 ")", __FUNCTION__, capabilitiesMask);
mLocationCapabilitiesMask = capabilitiesMask;
}
diff --git a/android/1.1/location_api/BatchingAPIClient.h b/android/1.1/location_api/BatchingAPIClient.h
index 64d47a0..4c90626 100644
--- a/android/1.1/location_api/BatchingAPIClient.h
+++ b/android/1.1/location_api/BatchingAPIClient.h
@@ -46,7 +46,6 @@
{
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);
@@ -61,6 +60,8 @@
void onBatchingCb(size_t count, Location* location, BatchingOptions batchOptions) final;
private:
+ ~BatchingAPIClient();
+
sp<V1_0::IGnssBatchingCallback> mGnssBatchingCbIface;
uint32_t mDefaultId;
LocationCapabilitiesMask mLocationCapabilitiesMask;
diff --git a/android/1.1/location_api/GeofenceAPIClient.cpp b/android/1.1/location_api/GeofenceAPIClient.cpp
index 93d175e..f6d1dc3 100644
--- a/android/1.1/location_api/GeofenceAPIClient.cpp
+++ b/android/1.1/location_api/GeofenceAPIClient.cpp
@@ -141,7 +141,7 @@
// callbacks
void GeofenceAPIClient::onGeofenceBreachCb(GeofenceBreachNotification geofenceBreachNotification)
{
- LOC_LOGD("%s]: (%zu)", __FUNCTION__, geofenceBreachNotification.count);
+ LOC_LOGD("%s]: (%d)", __FUNCTION__, geofenceBreachNotification.count);
if (mGnssGeofencingCbIface != nullptr) {
for (size_t i = 0; i < geofenceBreachNotification.count; i++) {
GnssLocation gnssLocation;
diff --git a/android/1.1/location_api/GeofenceAPIClient.h b/android/1.1/location_api/GeofenceAPIClient.h
index c74a59a..0ffff91 100644
--- a/android/1.1/location_api/GeofenceAPIClient.h
+++ b/android/1.1/location_api/GeofenceAPIClient.h
@@ -46,7 +46,6 @@
{
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,
@@ -65,6 +64,8 @@
void onResumeGeofencesCb(size_t count, LocationError* errors, uint32_t* ids) final;
private:
+ virtual ~GeofenceAPIClient() = default;
+
sp<V1_0::IGnssGeofenceCallback> mGnssGeofencingCbIface;
};
diff --git a/android/1.1/location_api/GnssAPIClient.cpp b/android/1.1/location_api/GnssAPIClient.cpp
index be4d659..dbb5fe4 100644
--- a/android/1.1/location_api/GnssAPIClient.cpp
+++ b/android/1.1/location_api/GnssAPIClient.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2020, 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,6 +31,7 @@
#define LOG_TAG "LocSvc_GnssAPIClient"
#define SINGLE_SHOT_MIN_TRACKING_INTERVAL_MSEC (590 * 60 * 60 * 1000) // 590 hours
+#include <inttypes.h>
#include <log_util.h>
#include <loc_cfg.h>
@@ -110,9 +111,7 @@
locationCallbacks.gnssNiCb = nullptr;
loc_core::ContextBase* context =
- loc_core::LocContext::getLocContext(
- NULL, NULL,
- loc_core::LocContext::mLocationHalName, false);
+ loc_core::LocContext::getLocContext(loc_core::LocContext::mLocationHalName);
if (mGnssNiCbIface != nullptr && !context->hasAgpsExtendedCapabilities()) {
LOC_LOGD("Registering NI CB");
locationCallbacks.gnssNiCb = [this](uint32_t id, GnssNiNotification gnssNiNotification) {
@@ -301,7 +300,7 @@
// callbacks
void GnssAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)
{
- LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask);
+ LOC_LOGD("%s]: (%" PRIu64 ")", __FUNCTION__, capabilitiesMask);
mLocationCapabilitiesMask = capabilitiesMask;
mLocationCapabilitiesCached = true;
@@ -331,16 +330,17 @@
}
}
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;
+ IGnssCallback::GnssSystemInfo gnssInfo = { .yearOfHw = 2015 };
+
+ if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT) {
+ gnssInfo.yearOfHw++; // 2016
+ if (capabilitiesMask & LOCATION_CAPABILITIES_DEBUG_NMEA_BIT) {
+ gnssInfo.yearOfHw++; // 2017
+ if (capabilitiesMask & LOCATION_CAPABILITIES_CONSTELLATION_ENABLEMENT_BIT ||
+ capabilitiesMask & LOCATION_CAPABILITIES_AGPM_BIT) {
+ gnssInfo.yearOfHw++; // 2018
+ }
+ }
}
LOC_LOGV("%s:%d] set_system_info_cb (%d)", __FUNCTION__, __LINE__, gnssInfo.yearOfHw);
auto r = gnssCbIface->gnssSetSystemInfoCb(gnssInfo);
@@ -446,7 +446,7 @@
void GnssAPIClient::onGnssSvCb(GnssSvNotification gnssSvNotification)
{
- LOC_LOGD("%s]: (count: %zu)", __FUNCTION__, gnssSvNotification.count);
+ LOC_LOGD("%s]: (count: %u)", __FUNCTION__, gnssSvNotification.count);
mMutex.lock();
auto gnssCbIface(mGnssCbIface);
mMutex.unlock();
@@ -479,7 +479,7 @@
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__,
+ LOC_LOGE("%s] Error from gnssNmeaCb nmea=%s length=%u description=%s", __func__,
gnssNmeaNotification.nmea, gnssNmeaNotification.length,
r.description().c_str());
}
@@ -540,7 +540,7 @@
}
for (size_t i = 0; i < out.numSvs; i++) {
IGnssCallback::GnssSvInfo& info = out.gnssSvList[i];
- info.svid = in.gnssSvs[i].svId;
+ convertGnssSvid(in.gnssSvs[i], info.svid);
convertGnssConstellationType(in.gnssSvs[i].type, info.constellation);
info.cN0Dbhz = in.gnssSvs[i].cN0Dbhz;
info.elevationDegrees = in.gnssSvs[i].elevation;
diff --git a/android/1.1/location_api/GnssAPIClient.h b/android/1.1/location_api/GnssAPIClient.h
index 82f8fbf..3829265 100644
--- a/android/1.1/location_api/GnssAPIClient.h
+++ b/android/1.1/location_api/GnssAPIClient.h
@@ -50,7 +50,6 @@
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;
@@ -92,6 +91,8 @@
void onStopTrackingCb(LocationError error) final;
private:
+ virtual ~GnssAPIClient();
+
sp<V1_0::IGnssCallback> mGnssCbIface;
sp<V1_0::IGnssNiCallback> mGnssNiCbIface;
std::mutex mMutex;
diff --git a/android/1.1/location_api/LocationUtil.cpp b/android/1.1/location_api/LocationUtil.cpp
index f1d051c..aacec07 100644
--- a/android/1.1/location_api/LocationUtil.cpp
+++ b/android/1.1/location_api/LocationUtil.cpp
@@ -28,6 +28,7 @@
*/
#include <LocationUtil.h>
+#include <gps_extended_c.h>
namespace android {
namespace hardware {
@@ -147,6 +148,74 @@
}
}
+void convertGnssSvid(GnssSv& in, int16_t& out)
+{
+ switch(in.type){
+ case GNSS_SV_TYPE_GPS:
+ out = in.svId;
+ break;
+ case GNSS_SV_TYPE_SBAS:
+ out = in.svId;
+ break;
+ case GNSS_SV_TYPE_GLONASS:
+ if (!isGloSlotUnknown(in.svId)) { // OSN is known
+ out = in.svId - GLO_SV_PRN_MIN + 1;
+ } else { //OSN is not known, report FCN
+ out = in.gloFrequency + 92;
+ }
+ break;
+ case GNSS_SV_TYPE_QZSS:
+ out = in.svId;
+ break;
+ case GNSS_SV_TYPE_BEIDOU:
+ out = in.svId - BDS_SV_PRN_MIN + 1;
+ break;
+ case GNSS_SV_TYPE_GALILEO:
+ out = in.svId - GAL_SV_PRN_MIN + 1;
+ break;
+ case GNSS_SV_TYPE_NAVIC:
+ out = in.svId - NAVIC_SV_PRN_MIN + 1;
+ break;
+ default:
+ out = in.svId;
+ break;
+ }
+}
+
+void convertGnssSvid(GnssMeasurementsData& in, int16_t& out)
+{
+ switch (in.svType) {
+ case GNSS_SV_TYPE_GPS:
+ out = in.svId;
+ break;
+ case GNSS_SV_TYPE_SBAS:
+ out = in.svId;
+ break;
+ case GNSS_SV_TYPE_GLONASS:
+ if (!isGloSlotUnknown(in.svId)) { // OSN is known
+ out = in.svId - GLO_SV_PRN_MIN + 1;
+ } else { // OSN is not known, report FCN
+ out = in.gloFrequency + 92;
+ }
+ break;
+ case GNSS_SV_TYPE_QZSS:
+ out = in.svId;
+ break;
+ case GNSS_SV_TYPE_BEIDOU:
+ out = in.svId - BDS_SV_PRN_MIN + 1;
+ break;
+ case GNSS_SV_TYPE_GALILEO:
+ out = in.svId - GAL_SV_PRN_MIN + 1;
+ break;
+ case GNSS_SV_TYPE_NAVIC:
+ out = in.svId - NAVIC_SV_PRN_MIN + 1;
+ break;
+ default:
+ out = in.svId;
+ break;
+ }
+}
+
void convertGnssEphemerisType(GnssEphemerisType& in, GnssDebug::SatelliteEphemerisType& out)
{
switch(in) {
diff --git a/android/1.1/location_api/LocationUtil.h b/android/1.1/location_api/LocationUtil.h
index 63f4f6f..af3c93f 100644
--- a/android/1.1/location_api/LocationUtil.h
+++ b/android/1.1/location_api/LocationUtil.h
@@ -43,6 +43,8 @@
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 convertGnssSvid(GnssSv& in, int16_t& out);
+void convertGnssSvid(GnssMeasurementsData& in, int16_t& out);
void convertGnssEphemerisType(GnssEphemerisType& in, GnssDebug::SatelliteEphemerisType& out);
void convertGnssEphemerisSource(GnssEphemerisSource& in, GnssDebug::SatelliteEphemerisSource& out);
void convertGnssEphemerisHealth(GnssEphemerisHealth& in, GnssDebug::SatelliteEphemerisHealth& out);
diff --git a/android/1.1/location_api/MeasurementAPIClient.cpp b/android/1.1/location_api/MeasurementAPIClient.cpp
index 6f25067..af8095c 100644
--- a/android/1.1/location_api/MeasurementAPIClient.cpp
+++ b/android/1.1/location_api/MeasurementAPIClient.cpp
@@ -148,7 +148,7 @@
void MeasurementAPIClient::onGnssMeasurementsCb(
GnssMeasurementsNotification gnssMeasurementsNotification)
{
- LOC_LOGD("%s]: (count: %zu active: %d)",
+ LOC_LOGD("%s]: (count: %u active: %d)",
__FUNCTION__, gnssMeasurementsNotification.count, mTracking);
if (mTracking) {
mMutex.lock();
@@ -197,7 +197,7 @@
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;
+ convertGnssSvid(in, out.svid);
convertGnssConstellationType(in.svType, out.constellation);
out.timeOffsetNs = in.timeOffsetNs;
if (in.stateMask & GNSS_MEASUREMENTS_STATE_CODE_LOCK_BIT)
diff --git a/android/1.1/location_api/MeasurementAPIClient.h b/android/1.1/location_api/MeasurementAPIClient.h
index 38811c5..5fb307c 100644
--- a/android/1.1/location_api/MeasurementAPIClient.h
+++ b/android/1.1/location_api/MeasurementAPIClient.h
@@ -49,7 +49,6 @@
{
public:
MeasurementAPIClient();
- virtual ~MeasurementAPIClient();
MeasurementAPIClient(const MeasurementAPIClient&) = delete;
MeasurementAPIClient& operator=(const MeasurementAPIClient&) = delete;
@@ -69,6 +68,8 @@
void onGnssMeasurementsCb(GnssMeasurementsNotification gnssMeasurementsNotification) final;
private:
+ virtual ~MeasurementAPIClient();
+
std::mutex mMutex;
sp<V1_0::IGnssMeasurementCallback> mGnssMeasurementCbIface;
sp<IGnssMeasurementCallback> mGnssMeasurementCbIface_1_1;
diff --git a/android/2.0/AGnssRil.cpp b/android/2.0/AGnssRil.cpp
index a477fc2..d8005e4 100644
--- a/android/2.0/AGnssRil.cpp
+++ b/android/2.0/AGnssRil.cpp
@@ -54,6 +54,7 @@
const int NetworkType_BLUETOOTH = 7;
const int NetworkType_ETHERNET = 9;
const int NetworkType_PROXY = 16;
+ std::string apn("");
// for XTRA
if (nullptr != mGnss && ( nullptr != mGnss->getGnssInterface() )) {
@@ -102,13 +103,13 @@
}
break;
}
- mGnss->getGnssInterface()->updateConnectionStatus(connected, false, typeout, 0);
+ mGnss->getGnssInterface()->updateConnectionStatus(connected, typeout, false, 0, apn);
}
return true;
}
Return<bool> AGnssRil::updateNetworkState_2_0(const V2_0::IAGnssRil::NetworkAttributes& attributes) {
ENTRY_LOG_CALLFLOW();
-
+ std::string apn = attributes.apn;
if (nullptr != mGnss && (nullptr != mGnss->getGnssInterface())) {
int8_t typeout = loc_core::TYPE_UNKNOWN;
bool roaming = false;
@@ -120,8 +121,9 @@
if (attributes.capabilities & IAGnssRil::NetworkCapability::NOT_ROAMING) {
roaming = false;
}
+ LOC_LOGd("apn string received is: %s", apn.c_str());
mGnss->getGnssInterface()->updateConnectionStatus(attributes.isConnected,
- typeout, roaming, (NetworkHandle) attributes.networkHandle);
+ typeout, roaming, (NetworkHandle) attributes.networkHandle, apn);
}
return true;
}
diff --git a/android/2.0/Android.mk b/android/2.0/Android.mk
index b6790c5..a0af746 100644
--- a/android/2.0/Android.mk
+++ b/android/2.0/Android.mk
@@ -2,7 +2,8 @@
include $(CLEAR_VARS)
LOCAL_MODULE := android.hardware.gnss@2.0-impl-qti
-LOCAL_SANITIZE += $(GNSS_SANITIZE)
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 SPDX-license-identifier-BSD legacy_not_a_contribution
+LOCAL_LICENSE_CONDITIONS := by_exception_only not_allowed notice
# activate the following line for debug purposes only, comment out for production
#LOCAL_SANITIZE_DIAG += $(GNSS_SANITIZE_DIAG)
LOCAL_VENDOR_MODULE := true
@@ -17,8 +18,8 @@
GnssGeofencing.cpp \
GnssNi.cpp \
GnssDebug.cpp \
- ../measurement_corrections/1.0/MeasurementCorrections.cpp \
- ../visibility_control/1.0/GnssVisibilityControl.cpp
+ MeasurementCorrections.cpp \
+ GnssVisibilityControl.cpp
LOCAL_SRC_FILES += \
location_api/GnssAPIClient.cpp \
@@ -33,9 +34,8 @@
endif
LOCAL_C_INCLUDES:= \
- $(LOCAL_PATH)/location_api \
- $(LOCAL_PATH)/../measurement_corrections/1.0 \
- $(LOCAL_PATH)/../visibility_control/1.0
+ $(LOCAL_PATH)/location_api
+
LOCAL_HEADER_LIBRARIES := \
libgps.utils_headers \
libloc_core_headers \
@@ -55,6 +55,7 @@
android.hardware.gnss.visibility_control@1.0 \
android.hardware.health@1.0 \
android.hardware.health@2.0 \
+ android.hardware.health@2.1 \
android.hardware.power@1.2 \
libbase
@@ -71,7 +72,8 @@
include $(CLEAR_VARS)
LOCAL_MODULE := android.hardware.gnss@2.0-service-qti
-LOCAL_SANITIZE += $(GNSS_SANITIZE)
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 SPDX-license-identifier-BSD legacy_not_a_contribution
+LOCAL_LICENSE_CONDITIONS := by_exception_only not_allowed notice
# activate the following line for debug purposes only, comment out for production
#LOCAL_SANITIZE_DIAG += $(GNSS_SANITIZE_DIAG)
LOCAL_VINTF_FRAGMENTS := android.hardware.gnss@2.0-service-qti.xml
diff --git a/android/2.0/Gnss.cpp b/android/2.0/Gnss.cpp
index 1b3ea1d..823ef6e 100644
--- a/android/2.0/Gnss.cpp
+++ b/android/2.0/Gnss.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
* Not a Contribution
*/
/*
@@ -28,6 +28,7 @@
#include "Gnss.h"
#include "LocationUtil.h"
#include "battery_listener.h"
+#include "loc_misc_utils.h"
typedef const GnssInterface* (getLocationInterface)();
@@ -83,6 +84,7 @@
LOC_LOGE("%s] service died. cookie: %llu, who: %p",
__FUNCTION__, static_cast<unsigned long long>(cookie), &who);
if (mGnss != nullptr) {
+ mGnss->getGnssInterface()->resetNetworkInfo();
mGnss->cleanup();
}
}
@@ -108,7 +110,7 @@
Gnss::~Gnss() {
ENTRY_LOG_CALLFLOW();
if (mApi != nullptr) {
- delete mApi;
+ mApi->destroy();
mApi = nullptr;
}
sGnss = nullptr;
@@ -145,26 +147,16 @@
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) {
+ if (nullptr == mGnssInterface && !getGnssInterfaceFailed) {
+ void * libHandle = nullptr;
+ getLocationInterface* getter = (getLocationInterface*)
+ dlGetSymFromLib(libHandle, "libgnss.so", "getGnssInterface");
+
+ if (nullptr == getter) {
getGnssInterfaceFailed = true;
} else {
- mGnssInterface = (const GnssInterface*)(*getter)();
+ mGnssInterface = (GnssInterface*)(*getter)();
}
}
return mGnssInterface;
@@ -246,7 +238,7 @@
}
if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT) {
mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT;
- mPendingConfig.lppProfile = gnssConfig.lppProfile;
+ mPendingConfig.lppProfileMask = gnssConfig.lppProfileMask;
}
if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT) {
mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT;
@@ -454,7 +446,7 @@
OdcpiRequestCallback cb = [this](const OdcpiRequestInfo& odcpiRequest) {
odcpiRequestCb(odcpiRequest);
};
- gnssInterface->odcpiInit(cb);
+ gnssInterface->odcpiInit(cb, OdcpiPrioritytype::ODCPI_HANDLER_PRIORITY_LOW);
}
GnssAPIClient* api = getApi();
@@ -517,6 +509,9 @@
void Gnss::odcpiRequestCb(const OdcpiRequestInfo& request) {
ENTRY_LOG_CALLFLOW();
+ if (ODCPI_REQUEST_TYPE_STOP == request.type) {
+ return;
+ }
if (mGnssCbIface_2_0 != nullptr) {
// For emergency mode, request DBH (Device based hybrid) location
// Mark Independent from GNSS flag to false.
@@ -584,7 +579,7 @@
OdcpiRequestCallback cb = [this](const OdcpiRequestInfo& odcpiRequest) {
odcpiRequestCb(odcpiRequest);
};
- gnssInterface->odcpiInit(cb);
+ gnssInterface->odcpiInit(cb, OdcpiPrioritytype::ODCPI_HANDLER_PRIORITY_LOW);
}
GnssAPIClient* api = getApi();
@@ -662,11 +657,7 @@
}
Return<sp<V2_0::IGnssBatching>> Gnss::getExtensionGnssBatching_2_0() {
- ENTRY_LOG_CALLFLOW();
- if (mGnssBatching == nullptr) {
- mGnssBatching = new GnssBatching();
- }
- return mGnssBatching;
+ return nullptr;
}
V1_0::IGnss* HIDL_FETCH_IGnss(const char* hal) {
diff --git a/android/2.0/GnssBatching.cpp b/android/2.0/GnssBatching.cpp
index 7a937fc..6a2a09e 100644
--- a/android/2.0/GnssBatching.cpp
+++ b/android/2.0/GnssBatching.cpp
@@ -46,7 +46,7 @@
GnssBatching::~GnssBatching() {
if (mApi != nullptr) {
- delete mApi;
+ mApi->destroy();
mApi = nullptr;
}
}
@@ -56,7 +56,7 @@
Return<bool> GnssBatching::init(const sp<V1_0::IGnssBatchingCallback>& callback) {
if (mApi != nullptr) {
LOC_LOGD("%s]: mApi is NOT nullptr, delete it first", __FUNCTION__);
- delete mApi;
+ mApi->destroy();
mApi = nullptr;
}
@@ -135,7 +135,7 @@
Return<bool> GnssBatching::init_2_0(const sp<V2_0::IGnssBatchingCallback>& callback) {
if (mApi != nullptr) {
LOC_LOGD("%s]: mApi is NOT nullptr, delete it first", __FUNCTION__);
- delete mApi;
+ mApi->destroy();
mApi = nullptr;
}
diff --git a/android/2.0/GnssConfiguration.cpp b/android/2.0/GnssConfiguration.cpp
index 069c036..55a70dc 100644
--- a/android/2.0/GnssConfiguration.cpp
+++ b/android/2.0/GnssConfiguration.cpp
@@ -70,7 +70,6 @@
default:
LOC_LOGE("%s]: invalid version: 0x%x.", __FUNCTION__, version);
return false;
- break;
}
return mGnss->updateConfiguration(config);
@@ -102,13 +101,12 @@
default:
LOC_LOGE("%s]: invalid mode: %d.", __FUNCTION__, mode);
return false;
- break;
}
return mGnss->updateConfiguration(config);
}
-Return<bool> GnssConfiguration::setLppProfile(uint8_t lppProfile) {
+Return<bool> GnssConfiguration::setLppProfile(uint8_t lppProfileMask) {
if (mGnss == nullptr) {
LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
return false;
@@ -117,23 +115,19 @@
GnssConfig config = {};
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;
+ config.lppProfileMask = GNSS_CONFIG_LPP_PROFILE_RRLP_ON_LTE; //default
+
+ if (lppProfileMask & (1<<0)) {
+ config.lppProfileMask |= GNSS_CONFIG_LPP_PROFILE_USER_PLANE_BIT;
+ }
+ if (lppProfileMask & (1<<1)) {
+ config.lppProfileMask |= GNSS_CONFIG_LPP_PROFILE_CONTROL_PLANE_BIT;
+ }
+ if (lppProfileMask & (1<<2)) {
+ config.lppProfileMask |= GNSS_CONFIG_LPP_PROFILE_USER_PLANE_OVER_NR5G_SA_BIT;
+ }
+ if (lppProfileMask & (1<<3)) {
+ config.lppProfileMask |= GNSS_CONFIG_LPP_PROFILE_CONTROL_PLANE_OVER_NR5G_SA_BIT;
}
return mGnss->updateConfiguration(config);
@@ -192,7 +186,6 @@
default:
LOC_LOGE("%s]: invalid lock: %d.", __FUNCTION__, lock);
return false;
- break;
}
mGnss->updateConfiguration(config);
diff --git a/android/2.0/GnssConfiguration.h b/android/2.0/GnssConfiguration.h
index 202a9fd..c3de2c9 100644
--- a/android/2.0/GnssConfiguration.h
+++ b/android/2.0/GnssConfiguration.h
@@ -52,7 +52,7 @@
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> setLppProfile(uint8_t lppProfileMask) override;
Return<bool> setGlonassPositioningProtocol(uint8_t protocol) override;
Return<bool> setEmergencySuplPdn(bool enable) override;
Return<bool> setGpsLock(uint8_t lock) override;
diff --git a/android/2.0/GnssGeofencing.cpp b/android/2.0/GnssGeofencing.cpp
index b72d835..b6fc94b 100644
--- a/android/2.0/GnssGeofencing.cpp
+++ b/android/2.0/GnssGeofencing.cpp
@@ -45,7 +45,7 @@
GnssGeofencing::~GnssGeofencing() {
if (mApi != nullptr) {
- delete mApi;
+ mApi->destroy();
mApi = nullptr;
}
}
diff --git a/android/2.0/GnssMeasurement.cpp b/android/2.0/GnssMeasurement.cpp
index 721a48c..6cb55ca 100644
--- a/android/2.0/GnssMeasurement.cpp
+++ b/android/2.0/GnssMeasurement.cpp
@@ -46,7 +46,7 @@
GnssMeasurement::~GnssMeasurement() {
if (mApi) {
- delete mApi;
+ mApi->destroy();
mApi = nullptr;
}
}
@@ -71,18 +71,15 @@
return ret;
}
+ clearInterfaces();
+
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();
- }
-
+void GnssMeasurement::clearInterfaces() {
if (mGnssMeasurementCbIface != nullptr) {
mGnssMeasurementCbIface->unlinkToDeath(mGnssMeasurementDeathRecipient);
mGnssMeasurementCbIface = nullptr;
@@ -95,6 +92,15 @@
mGnssMeasurementCbIface_2_0->unlinkToDeath(mGnssMeasurementDeathRecipient);
mGnssMeasurementCbIface_2_0 = nullptr;
}
+}
+
+Return<void> GnssMeasurement::close() {
+ if (mApi == nullptr) {
+ LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+ return Void();
+ }
+
+ clearInterfaces();
mApi->measurementClose();
return Void();
@@ -120,6 +126,8 @@
return ret;
}
+ clearInterfaces();
+
mGnssMeasurementCbIface_1_1 = callback;
mGnssMeasurementCbIface_1_1->linkToDeath(mGnssMeasurementDeathRecipient, 0);
@@ -149,6 +157,8 @@
return ret;
}
+ clearInterfaces();
+
mGnssMeasurementCbIface_2_0 = callback;
mGnssMeasurementCbIface_2_0->linkToDeath(mGnssMeasurementDeathRecipient, 0);
diff --git a/android/2.0/GnssMeasurement.h b/android/2.0/GnssMeasurement.h
index 000b00f..7fa66b4 100644
--- a/android/2.0/GnssMeasurement.h
+++ b/android/2.0/GnssMeasurement.h
@@ -75,6 +75,7 @@
sp<V1_1::IGnssMeasurementCallback> mGnssMeasurementCbIface_1_1 = nullptr;
sp<V2_0::IGnssMeasurementCallback> mGnssMeasurementCbIface_2_0 = nullptr;
MeasurementAPIClient* mApi;
+ void clearInterfaces();
};
} // namespace implementation
diff --git a/android/visibility_control/1.0/GnssVisibilityControl.cpp b/android/2.0/GnssVisibilityControl.cpp
similarity index 100%
rename from android/visibility_control/1.0/GnssVisibilityControl.cpp
rename to android/2.0/GnssVisibilityControl.cpp
diff --git a/android/visibility_control/1.0/GnssVisibilityControl.h b/android/2.0/GnssVisibilityControl.h
similarity index 100%
rename from android/visibility_control/1.0/GnssVisibilityControl.h
rename to android/2.0/GnssVisibilityControl.h
diff --git a/android/measurement_corrections/1.0/MeasurementCorrections.cpp b/android/2.0/MeasurementCorrections.cpp
similarity index 90%
rename from android/measurement_corrections/1.0/MeasurementCorrections.cpp
rename to android/2.0/MeasurementCorrections.cpp
index 2c93cb3..bb75073 100644
--- a/android/measurement_corrections/1.0/MeasurementCorrections.cpp
+++ b/android/2.0/MeasurementCorrections.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019-2020, 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
@@ -54,7 +54,9 @@
MeasurementCorrections::~MeasurementCorrections() {
}
-Return<bool> MeasurementCorrections::setCorrections(const ::android::hardware::gnss::measurement_corrections::V1_0::MeasurementCorrections& /*corrections*/) {
+Return<bool> MeasurementCorrections::setCorrections(
+ const ::android::hardware::gnss::measurement_corrections::
+ V1_0::MeasurementCorrections& /*corrections*/) {
return true;
}
diff --git a/android/measurement_corrections/1.0/MeasurementCorrections.h b/android/2.0/MeasurementCorrections.h
similarity index 92%
rename from android/measurement_corrections/1.0/MeasurementCorrections.h
rename to android/2.0/MeasurementCorrections.h
index ad534dc..96b1120 100644
--- a/android/measurement_corrections/1.0/MeasurementCorrections.h
+++ b/android/2.0/MeasurementCorrections.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019-2020, 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
@@ -59,10 +59,11 @@
~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> setCorrections(
+ const ::android::hardware::gnss::measurement_corrections::
+ V1_0::MeasurementCorrections& corrections) override;
Return<bool> setCallback(const sp<IMeasurementCorrectionsCallback>& callback) override;
-
};
diff --git a/android/2.0/location_api/BatchingAPIClient.cpp b/android/2.0/location_api/BatchingAPIClient.cpp
index 49cd18a..766c37a 100644
--- a/android/2.0/location_api/BatchingAPIClient.cpp
+++ b/android/2.0/location_api/BatchingAPIClient.cpp
@@ -30,6 +30,7 @@
#define LOG_NDEBUG 0
#define LOG_TAG "LocSvc_BatchingAPIClient"
+#include <inttypes.h>
#include <log_util.h>
#include <loc_cfg.h>
@@ -191,7 +192,7 @@
void BatchingAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)
{
- LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask);
+ LOC_LOGD("%s]: (%" PRIu64 ")", __FUNCTION__, capabilitiesMask);
mLocationCapabilitiesMask = capabilitiesMask;
}
diff --git a/android/2.0/location_api/BatchingAPIClient.h b/android/2.0/location_api/BatchingAPIClient.h
index 7198341..d2d9b4a 100644
--- a/android/2.0/location_api/BatchingAPIClient.h
+++ b/android/2.0/location_api/BatchingAPIClient.h
@@ -50,7 +50,6 @@
BatchingAPIClient(const sp<V2_0::IGnssBatchingCallback>& callback);
void gnssUpdateCallbacks(const sp<V1_0::IGnssBatchingCallback>& callback);
void gnssUpdateCallbacks_2_0(const sp<V2_0::IGnssBatchingCallback>& callback);
- ~BatchingAPIClient();
int getBatchSize();
int startSession(const V1_0::IGnssBatching::Options& options);
int updateSessionOptions(const V1_0::IGnssBatching::Options& options);
@@ -66,6 +65,8 @@
private:
void setCallbacks();
+ ~BatchingAPIClient();
+
std::mutex mMutex;
sp<V1_0::IGnssBatchingCallback> mGnssBatchingCbIface;
uint32_t mDefaultId;
diff --git a/android/2.0/location_api/GeofenceAPIClient.h b/android/2.0/location_api/GeofenceAPIClient.h
index 71049de..5bce476 100644
--- a/android/2.0/location_api/GeofenceAPIClient.h
+++ b/android/2.0/location_api/GeofenceAPIClient.h
@@ -46,7 +46,6 @@
{
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,
@@ -65,6 +64,8 @@
void onResumeGeofencesCb(size_t count, LocationError* errors, uint32_t* ids) final;
private:
+ virtual ~GeofenceAPIClient() = default;
+
sp<V1_0::IGnssGeofenceCallback> mGnssGeofencingCbIface;
};
diff --git a/android/2.0/location_api/GnssAPIClient.cpp b/android/2.0/location_api/GnssAPIClient.cpp
index d505241..44007d9 100644
--- a/android/2.0/location_api/GnssAPIClient.cpp
+++ b/android/2.0/location_api/GnssAPIClient.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2020, 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,6 +31,7 @@
#define LOG_TAG "LocSvc_GnssAPIClient"
#define SINGLE_SHOT_MIN_TRACKING_INTERVAL_MSEC (590 * 60 * 60 * 1000) // 590 hours
+#include <inttypes.h>
#include <log_util.h>
#include <loc_cfg.h>
@@ -123,9 +124,7 @@
locationCallbacks.gnssNiCb = nullptr;
if (mGnssNiCbIface != nullptr) {
loc_core::ContextBase* context =
- loc_core::LocContext::getLocContext(
- NULL, NULL,
- loc_core::LocContext::mLocationHalName, false);
+ loc_core::LocContext::getLocContext(loc_core::LocContext::mLocationHalName);
if (!context->hasAgpsExtendedCapabilities()) {
LOC_LOGD("Registering NI CB");
locationCallbacks.gnssNiCb = [this](uint32_t id, GnssNiNotification gnssNiNotify) {
@@ -351,7 +350,7 @@
// callbacks
void GnssAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)
{
- LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask);
+ LOC_LOGD("%s]: (%" PRIu64 ")", __FUNCTION__, capabilitiesMask);
mLocationCapabilitiesMask = capabilitiesMask;
mLocationCapabilitiesCached = true;
@@ -380,18 +379,20 @@
if (capabilitiesMask & LOCATION_CAPABILITIES_CONSTELLATION_ENABLEMENT_BIT)
data |= IGnssCallback::Capabilities::SATELLITE_BLACKLIST;
- IGnssCallback::GnssSystemInfo gnssInfo;
- if (capabilitiesMask & LOCATION_CAPABILITIES_PRIVACY_BIT) {
- gnssInfo.yearOfHw = 2019;
- } else 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;
+ IGnssCallback::GnssSystemInfo gnssInfo = { .yearOfHw = 2015 };
+
+ if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT) {
+ gnssInfo.yearOfHw++; // 2016
+ if (capabilitiesMask & LOCATION_CAPABILITIES_DEBUG_NMEA_BIT) {
+ gnssInfo.yearOfHw++; // 2017
+ if (capabilitiesMask & LOCATION_CAPABILITIES_CONSTELLATION_ENABLEMENT_BIT ||
+ capabilitiesMask & LOCATION_CAPABILITIES_AGPM_BIT) {
+ gnssInfo.yearOfHw++; // 2018
+ if (capabilitiesMask & LOCATION_CAPABILITIES_PRIVACY_BIT) {
+ gnssInfo.yearOfHw++; // 2019
+ }
+ }
+ }
}
LOC_LOGV("%s:%d] set_system_info_cb (%d)", __FUNCTION__, __LINE__, gnssInfo.yearOfHw);
@@ -678,7 +679,7 @@
out.numSvs = static_cast<uint32_t>(V1_0::GnssMax::SVS_COUNT);
}
for (size_t i = 0; i < out.numSvs; i++) {
- out.gnssSvList[i].svid = in.gnssSvs[i].svId;
+ convertGnssSvid(in.gnssSvs[i], out.gnssSvList[i].svid);
convertGnssConstellationType(in.gnssSvs[i].type, out.gnssSvList[i].constellation);
out.gnssSvList[i].cN0Dbhz = in.gnssSvs[i].cN0Dbhz;
out.gnssSvList[i].elevationDegrees = in.gnssSvs[i].elevation;
@@ -701,7 +702,7 @@
{
out.resize(in.count);
for (size_t i = 0; i < in.count; i++) {
- out[i].v1_0.svid = in.gnssSvs[i].svId;
+ convertGnssSvid(in.gnssSvs[i], out[i].v1_0.svid);
out[i].v1_0.cN0Dbhz = in.gnssSvs[i].cN0Dbhz;
out[i].v1_0.elevationDegrees = in.gnssSvs[i].elevation;
out[i].v1_0.azimuthDegrees = in.gnssSvs[i].azimuth;
diff --git a/android/2.0/location_api/GnssAPIClient.h b/android/2.0/location_api/GnssAPIClient.h
index 63b4561..cfa78c7 100644
--- a/android/2.0/location_api/GnssAPIClient.h
+++ b/android/2.0/location_api/GnssAPIClient.h
@@ -50,7 +50,6 @@
GnssAPIClient(const sp<V1_0::IGnssCallback>& gpsCb,
const sp<V1_0::IGnssNiCallback>& niCb);
GnssAPIClient(const sp<V2_0::IGnssCallback>& gpsCb);
- virtual ~GnssAPIClient();
GnssAPIClient(const GnssAPIClient&) = delete;
GnssAPIClient& operator=(const GnssAPIClient&) = delete;
@@ -93,6 +92,8 @@
void onStopTrackingCb(LocationError error) final;
private:
+ virtual ~GnssAPIClient();
+
void setCallbacks();
void initLocationOptions();
sp<V1_0::IGnssCallback> mGnssCbIface;
diff --git a/android/2.0/location_api/LocationUtil.cpp b/android/2.0/location_api/LocationUtil.cpp
index 7e6810c..961b7b1 100644
--- a/android/2.0/location_api/LocationUtil.cpp
+++ b/android/2.0/location_api/LocationUtil.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2020, 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,6 +30,8 @@
#include <LocationUtil.h>
#include <log_util.h>
#include <inttypes.h>
+#include <gps_extended_c.h>
+#include <loc_misc_utils.h>
namespace android {
namespace hardware {
@@ -38,6 +40,7 @@
namespace implementation {
using ::android::hardware::gnss::V2_0::GnssLocation;
+using ::android::hardware::gnss::V2_0::ElapsedRealtimeFlags;
using ::android::hardware::gnss::V2_0::GnssConstellationType;
using ::android::hardware::gnss::V1_0::GnssLocationFlags;
@@ -81,73 +84,21 @@
out.timestamp = static_cast<V1_0::GnssUtcTime>(in.timestamp);
}
-bool getCurrentTime(struct timespec& currentTime, int64_t& sinceBootTimeNanos)
-{
- struct timespec sinceBootTime;
- struct timespec sinceBootTimeTest;
- bool clockGetTimeSuccess = false;
- const uint32_t MAX_TIME_DELTA_VALUE_NANOS = 10000;
- const uint32_t MAX_GET_TIME_COUNT = 20;
- /* Attempt to get CLOCK_REALTIME and CLOCK_BOOTIME in succession without an interruption
- or context switch (for up to MAX_GET_TIME_COUNT times) to avoid errors in the calculation */
- for (uint32_t i = 0; i < MAX_GET_TIME_COUNT; i++) {
- if (clock_gettime(CLOCK_BOOTTIME, &sinceBootTime) != 0) {
- break;
- };
- if (clock_gettime(CLOCK_REALTIME, ¤tTime) != 0) {
- break;
- }
- if (clock_gettime(CLOCK_BOOTTIME, &sinceBootTimeTest) != 0) {
- break;
- };
- sinceBootTimeNanos = sinceBootTime.tv_sec * 1000000000 + sinceBootTime.tv_nsec;
- int64_t sinceBootTimeTestNanos =
- sinceBootTimeTest.tv_sec * 1000000000 + sinceBootTimeTest.tv_nsec;
- int64_t sinceBootTimeDeltaNanos = sinceBootTimeTestNanos - sinceBootTimeNanos;
-
- /* sinceBootTime and sinceBootTimeTest should have a close value if there was no
- interruption or context switch between clock_gettime for CLOCK_BOOTIME and
- clock_gettime for CLOCK_REALTIME */
- if (sinceBootTimeDeltaNanos < MAX_TIME_DELTA_VALUE_NANOS) {
- clockGetTimeSuccess = true;
- break;
- } else {
- LOC_LOGd("Delta:%" PRIi64 "ns time too large, retry number #%u...",
- sinceBootTimeDeltaNanos, i + 1);
- }
- }
- return clockGetTimeSuccess;
-}
-
void convertGnssLocation(Location& in, V2_0::GnssLocation& out)
{
memset(&out, 0, sizeof(V2_0::GnssLocation));
convertGnssLocation(in, out.v1_0);
- struct timespec currentTime;
- int64_t sinceBootTimeNanos;
-
- if (getCurrentTime(currentTime, sinceBootTimeNanos)) {
- int64_t currentTimeNanos = currentTime.tv_sec*1000000000 + currentTime.tv_nsec;
- int64_t locationTimeNanos = in.timestamp*1000000;
- LOC_LOGD("%s]: sinceBootTimeNanos:%" PRIi64 " currentTimeNanos:%" PRIi64 ""
- " locationTimeNanos:%" PRIi64 "",
- __FUNCTION__, sinceBootTimeNanos, currentTimeNanos, locationTimeNanos);
- if (currentTimeNanos >= locationTimeNanos) {
- int64_t ageTimeNanos = currentTimeNanos - locationTimeNanos;
- LOC_LOGD("%s]: ageTimeNanos:%" PRIi64 ")", __FUNCTION__, ageTimeNanos);
- if (ageTimeNanos >= 0 && ageTimeNanos <= sinceBootTimeNanos) {
- out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIMESTAMP_NS;
- out.elapsedRealtime.timestampNs = sinceBootTimeNanos - ageTimeNanos;
- out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS;
- // time uncertainty is 1 ms since it is calculated from utc time that is in ms
- out.elapsedRealtime.timeUncertaintyNs = 1000000;
- LOC_LOGD("%s]: timestampNs:%" PRIi64 ")",
- __FUNCTION__, out.elapsedRealtime.timestampNs);
- }
- }
- } else {
- LOC_LOGe("Failed to calculate elapsedRealtimeNanos timestamp");
+ if (in.flags & LOCATION_HAS_ELAPSED_REAL_TIME) {
+ out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIMESTAMP_NS;
+ out.elapsedRealtime.timestampNs = in.elapsedRealTime;
+ out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS;
+ out.elapsedRealtime.timeUncertaintyNs = in.elapsedRealTimeUnc;
+ LOC_LOGd("out.elapsedRealtime.timestampNs=%" PRIi64 ""
+ " out.elapsedRealtime.timeUncertaintyNs=%" PRIi64 ""
+ " out.elapsedRealtime.flags=0x%X",
+ out.elapsedRealtime.timestampNs,
+ out.elapsedRealtime.timeUncertaintyNs, out.elapsedRealtime.flags);
}
}
@@ -256,6 +207,74 @@
}
}
+void convertGnssSvid(GnssSv& in, int16_t& out)
+{
+ switch (in.type) {
+ case GNSS_SV_TYPE_GPS:
+ out = in.svId;
+ break;
+ case GNSS_SV_TYPE_SBAS:
+ out = in.svId;
+ break;
+ case GNSS_SV_TYPE_GLONASS:
+ if (!isGloSlotUnknown(in.svId)) { // OSN is known
+ out = in.svId - GLO_SV_PRN_MIN + 1;
+ } else { // OSN is not known, report FCN
+ out = in.gloFrequency + 92;
+ }
+ break;
+ case GNSS_SV_TYPE_QZSS:
+ out = in.svId;
+ break;
+ case GNSS_SV_TYPE_BEIDOU:
+ out = in.svId - BDS_SV_PRN_MIN + 1;
+ break;
+ case GNSS_SV_TYPE_GALILEO:
+ out = in.svId - GAL_SV_PRN_MIN + 1;
+ break;
+ case GNSS_SV_TYPE_NAVIC:
+ out = in.svId - NAVIC_SV_PRN_MIN + 1;
+ break;
+ default:
+ out = in.svId;
+ break;
+ }
+}
+
+void convertGnssSvid(GnssMeasurementsData& in, int16_t& out)
+{
+ switch (in.svType) {
+ case GNSS_SV_TYPE_GPS:
+ out = in.svId;
+ break;
+ case GNSS_SV_TYPE_SBAS:
+ out = in.svId;
+ break;
+ case GNSS_SV_TYPE_GLONASS:
+ if (!isGloSlotUnknown(in.svId)) { // OSN is known
+ out = in.svId - GLO_SV_PRN_MIN + 1;
+ } else { // OSN is not known, report FCN
+ out = in.gloFrequency + 92;
+ }
+ break;
+ case GNSS_SV_TYPE_QZSS:
+ out = in.svId;
+ break;
+ case GNSS_SV_TYPE_BEIDOU:
+ out = in.svId - BDS_SV_PRN_MIN + 1;
+ break;
+ case GNSS_SV_TYPE_GALILEO:
+ out = in.svId - GAL_SV_PRN_MIN + 1;
+ break;
+ case GNSS_SV_TYPE_NAVIC:
+ out = in.svId - NAVIC_SV_PRN_MIN + 1;
+ break;
+ default:
+ out = in.svId;
+ break;
+ }
+}
+
void convertGnssEphemerisType(GnssEphemerisType& in, GnssDebug::SatelliteEphemerisType& out)
{
switch(in) {
diff --git a/android/2.0/location_api/LocationUtil.h b/android/2.0/location_api/LocationUtil.h
index d3dce23..70729e4 100644
--- a/android/2.0/location_api/LocationUtil.h
+++ b/android/2.0/location_api/LocationUtil.h
@@ -46,10 +46,11 @@
void convertGnssLocation(const V2_0::GnssLocation& in, Location& out);
void convertGnssConstellationType(GnssSvType& in, V1_0::GnssConstellationType& out);
void convertGnssConstellationType(GnssSvType& in, V2_0::GnssConstellationType& out);
+void convertGnssSvid(GnssSv& in, int16_t& out);
+void convertGnssSvid(GnssMeasurementsData& in, int16_t& out);
void convertGnssEphemerisType(GnssEphemerisType& in, GnssDebug::SatelliteEphemerisType& out);
void convertGnssEphemerisSource(GnssEphemerisSource& in, GnssDebug::SatelliteEphemerisSource& out);
void convertGnssEphemerisHealth(GnssEphemerisHealth& in, GnssDebug::SatelliteEphemerisHealth& out);
-bool getCurrentTime(struct timespec& currentTime, int64_t& sinceBootTimeNanos);
} // namespace implementation
} // namespace V2_0
diff --git a/android/2.0/location_api/MeasurementAPIClient.cpp b/android/2.0/location_api/MeasurementAPIClient.cpp
index b87e508..425415f 100644
--- a/android/2.0/location_api/MeasurementAPIClient.cpp
+++ b/android/2.0/location_api/MeasurementAPIClient.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2020, 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,6 +36,7 @@
#include "LocationUtil.h"
#include "MeasurementAPIClient.h"
+#include <loc_misc_utils.h>
namespace android {
namespace hardware {
@@ -57,6 +58,8 @@
static void convertGnssClock(GnssMeasurementsClock& in, IGnssMeasurementCallback::GnssClock& out);
static void convertGnssMeasurementsCodeType(GnssMeasurementsCodeType& in,
::android::hardware::hidl_string& out);
+static void convertElapsedRealtimeNanos(GnssMeasurementsNotification& in,
+ ::android::hardware::gnss::V2_0::ElapsedRealtime& elapsedRealtimeNanos);
MeasurementAPIClient::MeasurementAPIClient() :
mGnssMeasurementCbIface(nullptr),
@@ -72,6 +75,13 @@
LOC_LOGD("%s]: ()", __FUNCTION__);
}
+void MeasurementAPIClient::clearInterfaces()
+{
+ mGnssMeasurementCbIface = nullptr;
+ mGnssMeasurementCbIface_1_1 = nullptr;
+ mGnssMeasurementCbIface_2_0 = nullptr;
+}
+
// for GpsInterface
Return<IGnssMeasurement::GnssMeasurementStatus>
MeasurementAPIClient::measurementSetCallback(const sp<V1_0::IGnssMeasurementCallback>& callback)
@@ -79,6 +89,7 @@
LOC_LOGD("%s]: (%p)", __FUNCTION__, &callback);
mMutex.lock();
+ clearInterfaces();
mGnssMeasurementCbIface = callback;
mMutex.unlock();
@@ -94,6 +105,7 @@
__FUNCTION__, &callback, (int)powerMode, timeBetweenMeasurement);
mMutex.lock();
+ clearInterfaces();
mGnssMeasurementCbIface_1_1 = callback;
mMutex.unlock();
@@ -109,6 +121,7 @@
__FUNCTION__, &callback, (int)powerMode, timeBetweenMeasurement);
mMutex.lock();
+ clearInterfaces();
mGnssMeasurementCbIface_2_0 = callback;
mMutex.unlock();
@@ -231,7 +244,7 @@
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;
+ convertGnssSvid(in, out.svid);
convertGnssConstellationType(in.svType, out.constellation);
out.timeOffsetNs = in.timeOffsetNs;
if (in.stateMask & GNSS_MEASUREMENTS_STATE_CODE_LOCK_BIT)
@@ -296,7 +309,7 @@
static void convertGnssClock(GnssMeasurementsClock& in, IGnssMeasurementCallback::GnssClock& out)
{
- memset(&out, 0, sizeof(IGnssMeasurementCallback::GnssClock));
+ memset(&out, 0, sizeof(out));
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)
@@ -325,6 +338,7 @@
static void convertGnssData(GnssMeasurementsNotification& in,
V1_0::IGnssMeasurementCallback::GnssData& out)
{
+ memset(&out, 0, sizeof(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.",
@@ -340,6 +354,7 @@
static void convertGnssData_1_1(GnssMeasurementsNotification& in,
V1_1::IGnssMeasurementCallback::GnssData& out)
{
+ memset(&out, 0, sizeof(out));
out.measurements.resize(in.count);
for (size_t i = 0; i < in.count; i++) {
convertGnssMeasurement(in.measurements[i], out.measurements[i].v1_0);
@@ -362,6 +377,7 @@
static void convertGnssData_2_0(GnssMeasurementsNotification& in,
V2_0::IGnssMeasurementCallback::GnssData& out)
{
+ memset(&out, 0, sizeof(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);
@@ -415,40 +431,21 @@
out.measurements[i].state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_2ND_CODE_LOCK;
}
convertGnssClock(in.clock, out.clock);
+ convertElapsedRealtimeNanos(in, out.elapsedRealtime);
+}
- const uint32_t UTC_TO_GPS_SECONDS = 315964800;
- struct timespec currentTime;
- int64_t sinceBootTimeNanos;
-
- if (getCurrentTime(currentTime, sinceBootTimeNanos) &&
- in.clock.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_LEAP_SECOND_BIT &&
- in.clock.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_FULL_BIAS_BIT &&
- in.clock.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_BIAS_BIT &&
- in.clock.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_BIAS_UNCERTAINTY_BIT) {
- int64_t currentTimeNanos = currentTime.tv_sec * 1000000000 + currentTime.tv_nsec;
- int64_t measTimeNanos = (int64_t)in.clock.timeNs - (int64_t)in.clock.fullBiasNs
- - (int64_t)in.clock.biasNs - (int64_t)in.clock.leapSecond * 1000000000
- + (int64_t)UTC_TO_GPS_SECONDS * 1000000000;
-
- LOC_LOGd("sinceBootTimeNanos:%" PRIi64 " currentTimeNanos:%" PRIi64 ""
- " measTimeNanos:%" PRIi64 "",
- sinceBootTimeNanos, currentTimeNanos, measTimeNanos);
- if (currentTimeNanos >= measTimeNanos) {
- int64_t ageTimeNanos = currentTimeNanos - measTimeNanos;
- LOC_LOGD("%s]: ageTimeNanos:%" PRIi64 ")", __FUNCTION__, ageTimeNanos);
- if (ageTimeNanos >= 0 && ageTimeNanos <= sinceBootTimeNanos) {
- out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIMESTAMP_NS;
- out.elapsedRealtime.timestampNs = sinceBootTimeNanos - ageTimeNanos;
- out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS;
- // time uncertainty is 1 ms since it is calculated from utc time that is in ms
- out.elapsedRealtime.timeUncertaintyNs = 1000000;
- LOC_LOGd("timestampNs:%" PRIi64 ") timeUncertaintyNs:%" PRIi64 ")",
- out.elapsedRealtime.timestampNs,
- out.elapsedRealtime.timeUncertaintyNs);
- }
- }
- } else {
- LOC_LOGe("Failed to calculate elapsedRealtimeNanos timestamp");
+static void convertElapsedRealtimeNanos(GnssMeasurementsNotification& in,
+ ::android::hardware::gnss::V2_0::ElapsedRealtime& elapsedRealtime)
+{
+ if (in.clock.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_ELAPSED_REAL_TIME_BIT) {
+ elapsedRealtime.flags |= V2_0::ElapsedRealtimeFlags::HAS_TIMESTAMP_NS;
+ elapsedRealtime.timestampNs = in.clock.elapsedRealTime;
+ elapsedRealtime.flags |= V2_0::ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS;
+ elapsedRealtime.timeUncertaintyNs = in.clock.elapsedRealTimeUnc;
+ LOC_LOGd("elapsedRealtime.timestampNs=%" PRIi64 ""
+ " elapsedRealtime.timeUncertaintyNs=%" PRIi64 " elapsedRealtime.flags=0x%X",
+ elapsedRealtime.timestampNs,
+ elapsedRealtime.timeUncertaintyNs, elapsedRealtime.flags);
}
}
diff --git a/android/2.0/location_api/MeasurementAPIClient.h b/android/2.0/location_api/MeasurementAPIClient.h
index 4146a13..6c2d38d 100644
--- a/android/2.0/location_api/MeasurementAPIClient.h
+++ b/android/2.0/location_api/MeasurementAPIClient.h
@@ -49,7 +49,6 @@
{
public:
MeasurementAPIClient();
- virtual ~MeasurementAPIClient();
MeasurementAPIClient(const MeasurementAPIClient&) = delete;
MeasurementAPIClient& operator=(const MeasurementAPIClient&) = delete;
@@ -73,12 +72,14 @@
void onGnssMeasurementsCb(GnssMeasurementsNotification gnssMeasurementsNotification) final;
private:
+ virtual ~MeasurementAPIClient();
+
std::mutex mMutex;
sp<V1_0::IGnssMeasurementCallback> mGnssMeasurementCbIface;
sp<V1_1::IGnssMeasurementCallback> mGnssMeasurementCbIface_1_1;
sp<V2_0::IGnssMeasurementCallback> mGnssMeasurementCbIface_2_0;
-
bool mTracking;
+ void clearInterfaces();
};
} // namespace implementation
diff --git a/android/2.0/service.cpp b/android/2.0/service.cpp
index 664c661..fd957de 100644
--- a/android/2.0/service.cpp
+++ b/android/2.0/service.cpp
@@ -60,20 +60,18 @@
status = registerPassthroughServiceImplementation<IGnss>();
if (status == OK) {
- if (vendorEnhanced) {
#ifdef LOC_HIDL_VERSION
- #define VENDOR_ENHANCED_LIB "vendor.qti.gnss@" LOC_HIDL_VERSION "-service.so"
+ #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
+ void* libHandle = NULL;
+ vendorEnhancedServiceMain* vendorEnhancedMainMethod = (vendorEnhancedServiceMain*)
+ dlGetSymFromLib(libHandle, VENDOR_ENHANCED_LIB, "main");
+ if (NULL != vendorEnhancedMainMethod) {
+ (*vendorEnhancedMainMethod)(0, NULL);
}
+ #else
+ ALOGI("LOC_HIDL_VERSION not defined.");
+ #endif
joinRpcThreadpool();
diff --git a/android/2.1/AGnss.cpp b/android/2.1/AGnss.cpp
new file mode 100644
index 0000000..ce7b3aa
--- /dev/null
+++ b/android/2.1/AGnss.cpp
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 2017-2020, 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_1 {
+namespace implementation {
+
+static AGnss* spAGnss = nullptr;
+
+AGnss::AGnss(Gnss* gnss) : mGnss(gnss), mType(LOC_AGPS_TYPE_INVALID) {
+ 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;
+
+ // cache the AGps Type
+ mType = type;
+
+ 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.atlType = AGPS_ATL_TYPE_SUPL | AGPS_ATL_TYPE_SUPL_ES;
+
+ 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;
+ }
+
+ std::string apnString(apn.c_str());
+ // During Emergency SUPL, an apn name of "sos" means that no
+ // apn was found, like in the simless case, so apn is cleared
+ if (LOC_AGPS_TYPE_SUPL_ES == mType && "sos" == apnString) {
+ LOC_LOGD("dataConnOpen APN name = [sos] cleared");
+ apnString.clear();
+ }
+
+ LOC_LOGD("dataConnOpen APN name = [%s]", apnString.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, apnString.c_str(), apnString.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_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/android/2.1/AGnss.h b/android/2.1/AGnss.h
new file mode 100644
index 0000000..cf9c8a7
--- /dev/null
+++ b/android/2.1/AGnss.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2017-2020, 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_1 {
+namespace implementation {
+
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+using ::android::hardware::gnss::V2_0::IAGnssCallback;
+
+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<V2_0::IAGnssCallback> mAGnssCbIface = nullptr;
+
+ AGpsExtType mType;
+};
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V2_0_AGNSS_H
diff --git a/android/2.1/AGnssRil.cpp b/android/2.1/AGnssRil.cpp
new file mode 100644
index 0000000..f413e93
--- /dev/null
+++ b/android/2.1/AGnssRil.cpp
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2017-2020, 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_1 {
+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;
+ std::string apn("");
+
+ // for XTRA
+ if (nullptr != mGnss && ( nullptr != mGnss->getGnssInterface() )) {
+ int8_t typeout = loc_core::TYPE_UNKNOWN;
+ switch(type)
+ {
+ case IAGnssRil::NetworkType::MOBILE:
+ typeout = loc_core::TYPE_MOBILE;
+ break;
+ case IAGnssRil::NetworkType::WIFI:
+ typeout = loc_core::TYPE_WIFI;
+ break;
+ case IAGnssRil::NetworkType::MMS:
+ typeout = loc_core::TYPE_MMS;
+ break;
+ case IAGnssRil::NetworkType::SUPL:
+ typeout = loc_core::TYPE_SUPL;
+ break;
+ case IAGnssRil::NetworkType::DUN:
+ typeout = loc_core::TYPE_DUN;
+ break;
+ case IAGnssRil::NetworkType::HIPRI:
+ typeout = loc_core::TYPE_HIPRI;
+ break;
+ case IAGnssRil::NetworkType::WIMAX:
+ typeout = loc_core::TYPE_WIMAX;
+ break;
+ default:
+ {
+ int networkType = (int) type;
+ // Handling network types not available in IAgnssRil
+ switch(networkType)
+ {
+ case NetworkType_BLUETOOTH:
+ typeout = loc_core::TYPE_BLUETOOTH;
+ break;
+ case NetworkType_ETHERNET:
+ typeout = loc_core::TYPE_ETHERNET;
+ break;
+ case NetworkType_PROXY:
+ typeout = loc_core::TYPE_PROXY;
+ break;
+ default:
+ typeout = loc_core::TYPE_UNKNOWN;
+ }
+ }
+ break;
+ }
+ mGnss->getGnssInterface()->updateConnectionStatus(connected, typeout, false, 0, apn);
+ }
+ return true;
+}
+Return<bool> AGnssRil::updateNetworkState_2_0(const V2_0::IAGnssRil::NetworkAttributes& attributes) {
+ ENTRY_LOG_CALLFLOW();
+ std::string apn = attributes.apn;
+ if (nullptr != mGnss && (nullptr != mGnss->getGnssInterface())) {
+ int8_t typeout = loc_core::TYPE_UNKNOWN;
+ bool roaming = false;
+ if (attributes.capabilities & IAGnssRil::NetworkCapability::NOT_METERED) {
+ typeout = loc_core::TYPE_WIFI;
+ } else {
+ typeout = loc_core::TYPE_MOBILE;
+ }
+ if (attributes.capabilities & IAGnssRil::NetworkCapability::NOT_ROAMING) {
+ roaming = false;
+ }
+ LOC_LOGd("apn string received is: %s", apn.c_str());
+ mGnss->getGnssInterface()->updateConnectionStatus(attributes.isConnected,
+ typeout, roaming, (NetworkHandle) attributes.networkHandle, apn);
+ }
+ return true;
+}
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/android/2.1/AGnssRil.h b/android/2.1/AGnssRil.h
new file mode 100644
index 0000000..2bf6156
--- /dev/null
+++ b/android/2.1/AGnssRil.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2017-2020, 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_1 {
+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_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V2_0_AGNSSRIL_H_
diff --git a/android/2.1/Android.mk b/android/2.1/Android.mk
new file mode 100644
index 0000000..6bd2be1
--- /dev/null
+++ b/android/2.1/Android.mk
@@ -0,0 +1,118 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.gnss@2.1-impl-qti
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 SPDX-license-identifier-BSD legacy_not_a_contribution
+LOCAL_LICENSE_CONDITIONS := by_exception_only not_allowed notice
+# activate the following line for debug purposes only, comment out for production
+#LOCAL_SANITIZE_DIAG += $(GNSS_SANITIZE_DIAG)
+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 \
+ GnssAntennaInfo.cpp \
+ MeasurementCorrections.cpp \
+ 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_HEADER_LIBRARIES := \
+ libgps.utils_headers \
+ libloc_core_headers \
+ libloc_pla_headers \
+ liblocation_api_headers \
+ liblocbatterylistener_headers
+
+LOCAL_SHARED_LIBRARIES := \
+ liblog \
+ libhidlbase \
+ libcutils \
+ libutils \
+ android.hardware.gnss@1.0 \
+ android.hardware.gnss@1.1 \
+ android.hardware.gnss@2.0 \
+ android.hardware.gnss@2.1 \
+ android.hardware.gnss.measurement_corrections@1.0 \
+ android.hardware.gnss.measurement_corrections@1.1 \
+ android.hardware.gnss.visibility_control@1.0 \
+ android.hardware.health@1.0 \
+ android.hardware.health@2.0 \
+ android.hardware.health@2.1 \
+ android.hardware.power@1.2 \
+ libbase
+
+LOCAL_SHARED_LIBRARIES += \
+ libloc_core \
+ libgps.utils \
+ libdl \
+ liblocation_api \
+
+LOCAL_CFLAGS += $(GNSS_CFLAGS)
+LOCAL_STATIC_LIBRARIES := liblocbatterylistener
+LOCAL_STATIC_LIBRARIES += libhealthhalutils
+include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.gnss@2.1-service-qti
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 SPDX-license-identifier-BSD legacy_not_a_contribution
+LOCAL_LICENSE_CONDITIONS := by_exception_only not_allowed notice
+# activate the following line for debug purposes only, comment out for production
+#LOCAL_SANITIZE_DIAG += $(GNSS_SANITIZE_DIAG)
+LOCAL_VINTF_FRAGMENTS := android.hardware.gnss@2.1-service-qti.xml
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_INIT_RC := android.hardware.gnss@2.1-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 += \
+ libhidlbase \
+ android.hardware.gnss@1.0 \
+ android.hardware.gnss@1.1 \
+ android.hardware.gnss@2.0 \
+ android.hardware.gnss@2.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/2.1/Gnss.cpp b/android/2.1/Gnss.cpp
new file mode 100644
index 0000000..37e1cc5
--- /dev/null
+++ b/android/2.1/Gnss.cpp
@@ -0,0 +1,800 @@
+/*
+ * Copyright (c) 2017-2020, 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"
+#define LOG_NDEBUG 0
+
+#include <fstream>
+#include <log_util.h>
+#include <dlfcn.h>
+#include <cutils/properties.h>
+#include "Gnss.h"
+#include "LocationUtil.h"
+#include "battery_listener.h"
+#include "loc_misc_utils.h"
+
+typedef const GnssInterface* (getLocationInterface)();
+
+#define IMAGES_INFO_FILE "/sys/devices/soc0/images"
+#define DELIMITER ";"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_1 {
+namespace implementation {
+
+using ::android::hardware::gnss::visibility_control::V1_0::implementation::GnssVisibilityControl;
+using ::android::hardware::gnss::measurement_corrections::V1_1::
+ implementation::MeasurementCorrections;
+static sp<Gnss> sGnss;
+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->getGnssInterface()->resetNetworkInfo();
+ mGnss->cleanup();
+ }
+}
+
+void location_on_battery_status_changed(bool charging) {
+ LOC_LOGd("battery status changed to %s charging", charging ? "" : "not");
+ if (sGnss != nullptr) {
+ sGnss->getGnssInterface()->updateBatteryStatus(charging);
+ }
+}
+Gnss::Gnss() {
+ ENTRY_LOG_CALLFLOW();
+ sGnss = this;
+ // initilize gnss interface at first in case needing notify battery status
+ sGnss->getGnssInterface()->initialize();
+ // register health client to listen on battery change
+ loc_extn_battery_properties_listener_init(location_on_battery_status_changed);
+ // clear pending GnssConfig
+ memset(&mPendingConfig, 0, sizeof(GnssConfig));
+ mGnssDeathRecipient = new GnssDeathRecipient(this);
+}
+
+Gnss::~Gnss() {
+ ENTRY_LOG_CALLFLOW();
+ if (mApi != nullptr) {
+ mApi->destroy();
+ mApi = nullptr;
+ }
+ sGnss = nullptr;
+}
+
+GnssAPIClient* Gnss::getApi() {
+ if (mApi != nullptr) {
+ return mApi;
+ }
+
+ if (mGnssCbIface_2_1 != nullptr) {
+ mApi = new GnssAPIClient(mGnssCbIface_2_1);
+ } else if (mGnssCbIface_2_0 != nullptr) {
+ mApi = new GnssAPIClient(mGnssCbIface_2_0);
+ } else if (mGnssCbIface_1_1 != nullptr) {
+ mApi = new GnssAPIClient(mGnssCbIface_1_1, mGnssNiCbIface);
+ } else if (mGnssCbIface != nullptr) {
+ mApi = new GnssAPIClient(mGnssCbIface, mGnssNiCbIface);
+ } else {
+ LOC_LOGW("%s] GnssAPIClient is not ready", __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);
+ }
+ }
+
+ return mApi;
+}
+
+const GnssInterface* Gnss::getGnssInterface() {
+ static bool getGnssInterfaceFailed = false;
+ if (mGnssInterface == nullptr && !getGnssInterfaceFailed) {
+ void * libHandle = nullptr;
+ getLocationInterface* getter = (getLocationInterface*)
+ dlGetSymFromLib(libHandle, "libgnss.so", "getGnssInterface");
+ if (NULL == getter) {
+ getGnssInterfaceFailed = true;
+ } else {
+ mGnssInterface = (GnssInterface*)(*getter)();
+ }
+ }
+ return mGnssInterface;
+}
+
+Return<bool> Gnss::setCallback(const sp<V1_0::IGnssCallback>& callback) {
+ ENTRY_LOG_CALLFLOW();
+
+ // In case where previous call to setCallback_1_1/setCallback_2_0/setCallback_2_1, then
+ // we need to cleanup these interfaces/callbacks here since we no longer
+ // do so in cleanup() function to keep callbacks around after cleanup()
+ if (mApi != nullptr) {
+ mApi->gnssUpdateCallbacks_2_0(nullptr);
+ mApi->gnssUpdateCallbacks_2_1(nullptr);
+ }
+ if (mGnssCbIface_1_1 != nullptr) {
+ mGnssCbIface_1_1->unlinkToDeath(mGnssDeathRecipient);
+ mGnssCbIface_1_1 = nullptr;
+ }
+ if (mGnssCbIface_2_0 != nullptr) {
+ mGnssCbIface_2_0->unlinkToDeath(mGnssDeathRecipient);
+ mGnssCbIface_2_0 = nullptr;
+ }
+ if (mGnssCbIface_2_1 != nullptr) {
+ mGnssCbIface_2_1->unlinkToDeath(mGnssDeathRecipient);
+ mGnssCbIface_2_1 = nullptr;
+ }
+
+
+ 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.lppProfileMask = gnssConfig.lppProfileMask;
+ }
+ 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->gnssStop();
+ 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) {
+ return true;
+}
+
+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();
+ // deprecated function. Must return nullptr to pass VTS
+ return nullptr;
+}
+
+Return<sp<V1_0::IGnssNi>> Gnss::getExtensionGnssNi() {
+ ENTRY_LOG_CALLFLOW();
+ // deprecated function. Must return nullptr to pass VTS
+ return nullptr;
+}
+
+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();
+ if (mGnssConfig == nullptr) {
+ mGnssConfig = new GnssConfiguration(this);
+ }
+ return mGnssConfig;
+}
+
+Return<sp<V1_0::IGnssGeofencing>> Gnss::getExtensionGnssGeofencing() {
+ ENTRY_LOG_CALLFLOW();
+ if (mGnssGeofencingIface == nullptr) {
+ mGnssGeofencingIface = new GnssGeofencing();
+ }
+ return mGnssGeofencingIface;
+}
+
+Return<sp<V1_0::IGnssBatching>> Gnss::getExtensionGnssBatching() {
+ ENTRY_LOG_CALLFLOW();
+ if (mGnssBatching == nullptr) {
+ mGnssBatching = new GnssBatching();
+ }
+ return mGnssBatching;
+}
+
+Return<sp<V1_0::IGnssDebug>> Gnss::getExtensionGnssDebug() {
+ ENTRY_LOG_CALLFLOW();
+ if (mGnssDebug == nullptr) {
+ mGnssDebug = new GnssDebug(this);
+ }
+ return mGnssDebug;
+}
+
+Return<sp<V1_0::IAGnssRil>> Gnss::getExtensionAGnssRil() {
+ ENTRY_LOG_CALLFLOW();
+ if (mGnssRil == nullptr) {
+ 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();
+ auto r = callback->gnssNameCb(getVersionString());
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssNameCb description=%s",
+ __func__, r.description().c_str());
+ }
+
+ // In case where previous call to setCallback/setCallback_2_0/setCallback_2_1, then
+ // we need to cleanup these interfaces/callbacks here since we no longer
+ // do so in cleanup() function to keep callbacks around after cleanup()
+ if (mApi != nullptr) {
+ mApi->gnssUpdateCallbacks_2_0(nullptr);
+ mApi->gnssUpdateCallbacks_2_1(nullptr);
+ }
+ if (mGnssCbIface != nullptr) {
+ mGnssCbIface->unlinkToDeath(mGnssDeathRecipient);
+ mGnssCbIface = nullptr;
+ }
+ if (mGnssCbIface_2_0 != nullptr) {
+ mGnssCbIface_2_0->unlinkToDeath(mGnssDeathRecipient);
+ mGnssCbIface_2_0 = nullptr;
+ }
+ if (mGnssCbIface_2_1 != nullptr) {
+ mGnssCbIface_2_1->unlinkToDeath(mGnssDeathRecipient);
+ mGnssCbIface_2_1 = nullptr;
+ }
+
+
+ if (mGnssCbIface_1_1 != nullptr) {
+ mGnssCbIface_1_1->unlinkToDeath(mGnssDeathRecipient);
+ }
+ mGnssCbIface_1_1 = callback;
+ if (mGnssCbIface_1_1 != nullptr) {
+ mGnssCbIface_1_1->linkToDeath(mGnssDeathRecipient, 0 /*cookie*/);
+ }
+
+ const GnssInterface* gnssInterface = getGnssInterface();
+ if (nullptr != gnssInterface) {
+ OdcpiRequestCallback cb = [this](const OdcpiRequestInfo& odcpiRequest) {
+ odcpiRequestCb(odcpiRequest);
+ };
+ gnssInterface->odcpiInit(cb, OdcpiPrioritytype::ODCPI_HANDLER_PRIORITY_LOW);
+ }
+
+ GnssAPIClient* api = getApi();
+ if (api != nullptr) {
+ api->gnssUpdateCallbacks(mGnssCbIface_1_1, mGnssNiCbIface);
+ api->gnssEnable(LOCATION_TECHNOLOGY_TYPE_GNSS);
+ api->requestCapabilities();
+ }
+
+ return true;
+}
+
+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 (ODCPI_REQUEST_TYPE_STOP == request.type) {
+ return;
+ }
+ if (mGnssCbIface_2_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) {
+ LOC_LOGd("gnssRequestLocationCb_2_1 isUserEmergency = %d", request.isEmergencyMode);
+ auto r = mGnssCbIface_2_1->gnssRequestLocationCb_2_0(!request.isEmergencyMode,
+ request.isEmergencyMode);
+ if (!r.isOk()) {
+ LOC_LOGe("Error invoking gnssRequestLocationCb_2_0 %s", r.description().c_str());
+ }
+ } else {
+ LOC_LOGv("Unsupported ODCPI request type: %d", request.type);
+ }
+ } else if (mGnssCbIface_2_0 != nullptr) {
+ // For emergency mode, request DBH (Device based hybrid) location
+ // Mark Independent from GNSS flag to false.
+ if (ODCPI_REQUEST_TYPE_START == request.type) {
+ LOC_LOGd("gnssRequestLocationCb_2_0 isUserEmergency = %d", request.isEmergencyMode);
+ auto r = mGnssCbIface_2_0->gnssRequestLocationCb_2_0(!request.isEmergencyMode,
+ request.isEmergencyMode);
+ if (!r.isOk()) {
+ LOC_LOGe("Error invoking gnssRequestLocationCb_2_0 %s", r.description().c_str());
+ }
+ } else {
+ LOC_LOGv("Unsupported ODCPI request type: %d", request.type);
+ }
+ } else 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();
+ auto r = callback->gnssNameCb(getVersionString());
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssNameCb description=%s",
+ __func__, r.description().c_str());
+ }
+
+ // In case where previous call to setCallback/setCallback_1_1/setCallback_2_1, then
+ // we need to cleanup these interfaces/callbacks here since we no longer
+ // do so in cleanup() function to keep callbacks around after cleanup()
+ if (mApi != nullptr) {
+ mApi->gnssUpdateCallbacks(nullptr, nullptr);
+ mApi->gnssUpdateCallbacks_2_1(nullptr);
+ }
+ mGnssNiCbIface = nullptr;
+ if (mGnssCbIface != nullptr) {
+ mGnssCbIface->unlinkToDeath(mGnssDeathRecipient);
+ mGnssCbIface = nullptr;
+ }
+ if (mGnssCbIface_1_1 != nullptr) {
+ mGnssCbIface_1_1->unlinkToDeath(mGnssDeathRecipient);
+ mGnssCbIface_1_1 = nullptr;
+ }
+ if (mGnssCbIface_2_1 != nullptr) {
+ mGnssCbIface_2_1->unlinkToDeath(mGnssDeathRecipient);
+ mGnssCbIface_2_1 = nullptr;
+ }
+
+
+ if (mGnssCbIface_2_0 != nullptr) {
+ mGnssCbIface_2_0->unlinkToDeath(mGnssDeathRecipient);
+ }
+ mGnssCbIface_2_0 = callback;
+ if (mGnssCbIface_2_0 != nullptr) {
+ mGnssCbIface_2_0->linkToDeath(mGnssDeathRecipient, 0 /*cookie*/);
+ }
+
+ const GnssInterface* gnssInterface = getGnssInterface();
+ if (nullptr != gnssInterface) {
+ OdcpiRequestCallback cb = [this](const OdcpiRequestInfo& odcpiRequest) {
+ odcpiRequestCb(odcpiRequest);
+ };
+ gnssInterface->odcpiInit(cb, OdcpiPrioritytype::ODCPI_HANDLER_PRIORITY_LOW);
+ }
+
+ GnssAPIClient* api = getApi();
+ if (api != nullptr) {
+ api->gnssUpdateCallbacks_2_0(mGnssCbIface_2_0);
+ api->gnssEnable(LOCATION_TECHNOLOGY_TYPE_GNSS);
+ api->requestCapabilities();
+ }
+
+ return true;
+}
+
+Return<sp<V2_0::IAGnss>> Gnss::getExtensionAGnss_2_0() {
+ ENTRY_LOG_CALLFLOW();
+ if (mAGnssIface_2_0 == nullptr) {
+ mAGnssIface_2_0 = new AGnss(this);
+ }
+ return mAGnssIface_2_0;
+}
+Return<sp<V2_0::IAGnssRil>> Gnss::getExtensionAGnssRil_2_0() {
+
+ if (mGnssRil == nullptr) {
+ mGnssRil = new AGnssRil(this);
+ }
+ return mGnssRil;
+}
+
+Return<sp<V2_0::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration_2_0() {
+ ENTRY_LOG_CALLFLOW();
+ if (mGnssConfig == nullptr) {
+ 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<IMeasurementCorrectionsV1_0>>
+ Gnss::getExtensionMeasurementCorrections() {
+ ENTRY_LOG_CALLFLOW();
+ if (mGnssMeasCorr == nullptr) {
+ mGnssMeasCorr = new MeasurementCorrections(this);
+ }
+ return mGnssMeasCorr;
+}
+
+Return<sp<IMeasurementCorrectionsV1_1>>
+ Gnss::getExtensionMeasurementCorrections_1_1() {
+ ENTRY_LOG_CALLFLOW();
+ if (mGnssMeasCorr == nullptr) {
+ mGnssMeasCorr = new MeasurementCorrections(this);
+ }
+ 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 V2_0::GnssLocation& gnssLocation) {
+ ENTRY_LOG_CALLFLOW();
+ const GnssInterface* gnssInterface = getGnssInterface();
+ if (nullptr != gnssInterface) {
+ Location location = {};
+ convertGnssLocation(gnssLocation, location);
+ gnssInterface->odcpiInject(location);
+ }
+ return true;
+}
+
+Return<sp<V2_0::IGnssDebug>> Gnss::getExtensionGnssDebug_2_0() {
+ ENTRY_LOG_CALLFLOW();
+ if (mGnssDebug == nullptr) {
+ mGnssDebug = new GnssDebug(this);
+ }
+ return mGnssDebug;
+}
+
+Return<sp<V2_0::IGnssBatching>> Gnss::getExtensionGnssBatching_2_0() {
+ return nullptr;
+}
+
+// Methods from ::android::hardware::gnss::V2_1::IGnss follow.
+Return<bool> Gnss::setCallback_2_1(const sp<V2_1::IGnssCallback>& callback) {
+ ENTRY_LOG_CALLFLOW();
+ auto r = callback->gnssNameCb(getVersionString());
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssNameCb description=%s",
+ __func__, r.description().c_str());
+ }
+
+ // In case where previous call to setCallback/setCallback_1_1/setCallback_2_0, then
+ // we need to cleanup these interfaces/callbacks here since we no longer
+ // do so in cleanup() function to keep callbacks around after cleanup()
+ if (mApi != nullptr) {
+ mApi->gnssUpdateCallbacks(nullptr, nullptr);
+ mApi->gnssUpdateCallbacks_2_0(nullptr);
+ }
+ mGnssNiCbIface = nullptr;
+ if (mGnssCbIface != nullptr) {
+ mGnssCbIface->unlinkToDeath(mGnssDeathRecipient);
+ mGnssCbIface = nullptr;
+ }
+ if (mGnssCbIface_1_1 != nullptr) {
+ mGnssCbIface_1_1->unlinkToDeath(mGnssDeathRecipient);
+ mGnssCbIface_1_1 = nullptr;
+ }
+ if (mGnssCbIface_2_0 != nullptr) {
+ mGnssCbIface_2_0->unlinkToDeath(mGnssDeathRecipient);
+ mGnssCbIface_2_0 = nullptr;
+ }
+ if (mGnssCbIface_2_1 != nullptr) {
+ mGnssCbIface_2_1->unlinkToDeath(mGnssDeathRecipient);
+ }
+ mGnssCbIface_2_1 = callback;
+ if (mGnssCbIface_2_1 != nullptr) {
+ mGnssCbIface_2_1->linkToDeath(mGnssDeathRecipient, 0 /*cookie*/);
+ }
+
+ const GnssInterface* gnssInterface = getGnssInterface();
+ if (gnssInterface != nullptr) {
+ OdcpiRequestCallback cb = [this](const OdcpiRequestInfo& odcpiRequest) {
+ odcpiRequestCb(odcpiRequest);
+ };
+ gnssInterface->odcpiInit(cb, OdcpiPrioritytype::ODCPI_HANDLER_PRIORITY_LOW);
+ }
+
+ GnssAPIClient* api = getApi();
+ if (api != nullptr) {
+ api->gnssUpdateCallbacks_2_1(mGnssCbIface_2_1);
+ api->gnssEnable(LOCATION_TECHNOLOGY_TYPE_GNSS);
+ api->requestCapabilities();
+ }
+
+ return true;
+}
+Return<sp<V2_1::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement_2_1() {
+ ENTRY_LOG_CALLFLOW();
+ if (mGnssMeasurement == nullptr) {
+ mGnssMeasurement = new GnssMeasurement();
+ }
+ return mGnssMeasurement;
+}
+Return<sp<V2_1::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration_2_1() {
+ ENTRY_LOG_CALLFLOW();
+ if (mGnssConfig == nullptr) {
+ mGnssConfig = new GnssConfiguration(this);
+ }
+ return mGnssConfig;
+}
+
+Return<sp<V2_1::IGnssAntennaInfo>> Gnss::getExtensionGnssAntennaInfo() {
+ ENTRY_LOG_CALLFLOW();
+ if (mGnssAntennaInfo == nullptr) {
+ mGnssAntennaInfo = new GnssAntennaInfo(this);
+ }
+ return mGnssAntennaInfo;
+}
+
+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_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/android/2.1/Gnss.h b/android/2.1/Gnss.h
new file mode 100644
index 0000000..c383882
--- /dev/null
+++ b/android/2.1/Gnss.h
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2017-2020, 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_1_GNSS_H
+#define ANDROID_HARDWARE_GNSS_V2_1_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 <GnssAntennaInfo.h>
+
+#include <android/hardware/gnss/2.1/IGnss.h>
+#include <android/hardware/gnss/measurement_corrections/1.1/IMeasurementCorrections.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_1 {
+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 IMeasurementCorrectionsV1_0 =
+ ::android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrections;
+using IMeasurementCorrectionsV1_1 =
+ ::android::hardware::gnss::measurement_corrections::V1_1::IMeasurementCorrections;
+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<IMeasurementCorrectionsV1_0>> getExtensionMeasurementCorrections() override;
+ Return<sp<IMeasurementCorrectionsV1_1>> getExtensionMeasurementCorrections_1_1() 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;
+ Return<sp<::android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControl>>
+ getExtensionVisibilityControl() override;
+
+ // Methods from ::android::hardware::gnss::V2_1::IGnss follow.
+ Return<bool> setCallback_2_1(const sp<V2_1::IGnssCallback>& callback) override;
+ Return<sp<V2_1::IGnssMeasurement>> getExtensionGnssMeasurement_2_1() override;
+ Return<sp<V2_1::IGnssConfiguration>> getExtensionGnssConfiguration_2_1() override;
+ Return<sp<V2_1::IGnssAntennaInfo>> getExtensionGnssAntennaInfo() 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::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::IGnssBatching> mGnssBatching = nullptr;
+ sp<V2_0::IGnssDebug> mGnssDebug = nullptr;
+ sp<V2_0::IGnssCallback> mGnssCbIface_2_0 = nullptr;
+ sp<V2_1::IGnssCallback> mGnssCbIface_2_1 = nullptr;
+ sp<V2_1::IGnssMeasurement> mGnssMeasurement = nullptr;
+ sp<V2_1::IGnssConfiguration> mGnssConfig = nullptr;
+ sp<V2_1::IGnssAntennaInfo> mGnssAntennaInfo = nullptr;
+ sp<IMeasurementCorrectionsV1_1> 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_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V2_1_GNSS_H
diff --git a/android/2.1/GnssAntennaInfo.cpp b/android/2.1/GnssAntennaInfo.cpp
new file mode 100644
index 0000000..62c4cc7
--- /dev/null
+++ b/android/2.1/GnssAntennaInfo.cpp
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2020, 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_GnssAntennaInfoInterface"
+
+#include <log_util.h>
+#include "Gnss.h"
+#include "GnssAntennaInfo.h"
+#include <android/hardware/gnss/1.0/types.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_1 {
+namespace implementation {
+
+static GnssAntennaInfo* spGnssAntennaInfo = nullptr;
+
+static void convertGnssAntennaInfo(std::vector<GnssAntennaInformation>& in,
+ hidl_vec<IGnssAntennaInfoCallback::GnssAntennaInfo>& antennaInfos);
+
+void GnssAntennaInfo::GnssAntennaInfoDeathRecipient::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
+ // However, we need to inform the adapter that the service has died
+ if (nullptr == spGnssAntennaInfo) {
+ LOC_LOGE("%s]: spGnssAntennaInfo is nullptr", __FUNCTION__);
+ return;
+ }
+ if (nullptr == spGnssAntennaInfo->mGnss) {
+ LOC_LOGE("%s]: spGnssAntennaInfo->mGnss is nullptr", __FUNCTION__);
+ return;
+ }
+
+ spGnssAntennaInfo->mGnss->getGnssInterface()->antennaInfoClose();
+}
+
+static void convertGnssAntennaInfo(std::vector<GnssAntennaInformation>& in,
+ hidl_vec<IGnssAntennaInfoCallback::GnssAntennaInfo>& out) {
+
+ uint32_t vecSize, numberOfRows, numberOfColumns;
+ vecSize = in.size();
+ out.resize(vecSize);
+ for (uint32_t i = 0; i < vecSize; i++) {
+ out[i].carrierFrequencyMHz = in[i].carrierFrequencyMHz;
+ out[i].phaseCenterOffsetCoordinateMillimeters.x =
+ in[i].phaseCenterOffsetCoordinateMillimeters.x;
+ out[i].phaseCenterOffsetCoordinateMillimeters.xUncertainty =
+ in[i].phaseCenterOffsetCoordinateMillimeters.xUncertainty;
+ out[i].phaseCenterOffsetCoordinateMillimeters.y =
+ in[i].phaseCenterOffsetCoordinateMillimeters.y;
+ out[i].phaseCenterOffsetCoordinateMillimeters.yUncertainty =
+ in[i].phaseCenterOffsetCoordinateMillimeters.yUncertainty;
+ out[i].phaseCenterOffsetCoordinateMillimeters.z =
+ in[i].phaseCenterOffsetCoordinateMillimeters.z;
+ out[i].phaseCenterOffsetCoordinateMillimeters.zUncertainty =
+ in[i].phaseCenterOffsetCoordinateMillimeters.zUncertainty;
+
+ numberOfRows = in[i].phaseCenterVariationCorrectionMillimeters.size();
+ out[i].phaseCenterVariationCorrectionMillimeters.resize(numberOfRows);
+ for (uint32_t j = 0; j < numberOfRows; j++) {
+ numberOfColumns = in[i].phaseCenterVariationCorrectionMillimeters[j].size();
+ out[i].phaseCenterVariationCorrectionMillimeters[j].row.resize(numberOfColumns);
+ for (uint32_t k = 0; k < numberOfColumns; k++) {
+ out[i].phaseCenterVariationCorrectionMillimeters[j].row[k] =
+ in[i].phaseCenterVariationCorrectionMillimeters[j][k];
+ }
+ }
+
+ numberOfRows = in[i].phaseCenterVariationCorrectionUncertaintyMillimeters.size();
+ out[i].phaseCenterVariationCorrectionUncertaintyMillimeters.resize(numberOfRows);
+ for (uint32_t j = 0; j < numberOfRows; j++) {
+ numberOfColumns = in[i].phaseCenterVariationCorrectionUncertaintyMillimeters[j].size();
+ out[i].phaseCenterVariationCorrectionUncertaintyMillimeters[j].
+ row.resize(numberOfColumns);
+ for (uint32_t k = 0; k < numberOfColumns; k++) {
+ out[i].phaseCenterVariationCorrectionUncertaintyMillimeters[j].row[k] =
+ in[i].phaseCenterVariationCorrectionUncertaintyMillimeters[j][k];
+ }
+ }
+
+ numberOfRows = in[i].signalGainCorrectionDbi.size();
+ out[i].signalGainCorrectionDbi.resize(numberOfRows);
+ for (uint32_t j = 0; j < numberOfRows; j++) {
+ numberOfColumns = in[i].signalGainCorrectionDbi[j].size();
+ out[i].signalGainCorrectionDbi[j].row.resize(numberOfColumns);
+ for (uint32_t k = 0; k < numberOfColumns; k++) {
+ out[i].signalGainCorrectionDbi[j].row[k] = in[i].signalGainCorrectionDbi[j][k];
+ }
+ }
+
+ numberOfRows = in[i].signalGainCorrectionUncertaintyDbi.size();
+ out[i].signalGainCorrectionUncertaintyDbi.resize(numberOfRows);
+ for (uint32_t j = 0; j < numberOfRows; j++) {
+ numberOfColumns = in[i].signalGainCorrectionUncertaintyDbi[j].size();
+ out[i].signalGainCorrectionUncertaintyDbi[j].row.resize(numberOfColumns);
+ for (uint32_t k = 0; k < numberOfColumns; k++) {
+ out[i].signalGainCorrectionUncertaintyDbi[j].row[k] =
+ in[i].signalGainCorrectionUncertaintyDbi[j][k];
+ }
+ }
+ }
+}
+
+GnssAntennaInfo::GnssAntennaInfo(Gnss* gnss) : mGnss(gnss) {
+ mGnssAntennaInfoDeathRecipient = new GnssAntennaInfoDeathRecipient(this);
+ spGnssAntennaInfo = this;
+}
+
+GnssAntennaInfo::~GnssAntennaInfo() {
+ spGnssAntennaInfo = nullptr;
+}
+
+// Methods from ::android::hardware::gnss::V2_1::IGnssAntennaInfo follow.
+Return<GnssAntennaInfo::GnssAntennaInfoStatus>
+ GnssAntennaInfo::setCallback(const sp<IGnssAntennaInfoCallback>& callback) {
+ uint32_t retValue;
+ if (mGnss == nullptr) {
+ LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
+ return GnssAntennaInfoStatus::ERROR_GENERIC;
+ }
+
+ mGnssAntennaInfoCbIface = callback;
+ retValue = mGnss->getGnssInterface()->antennaInfoInit(aiGnssAntennaInfoCb);
+
+ switch (retValue) {
+ case ANTENNA_INFO_SUCCESS: return GnssAntennaInfoStatus::SUCCESS;
+ case ANTENNA_INFO_ERROR_ALREADY_INIT: return GnssAntennaInfoStatus::ERROR_ALREADY_INIT;
+ case ANTENNA_INFO_ERROR_GENERIC:
+ default: return GnssAntennaInfoStatus::ERROR_GENERIC;
+ }
+}
+
+Return<void> GnssAntennaInfo::close(void) {
+ if (mGnss == nullptr) {
+ LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
+ return Void();
+ }
+
+ mGnss->getGnssInterface()->antennaInfoClose();
+
+ return Void();
+}
+
+void GnssAntennaInfo::aiGnssAntennaInfoCb
+ (std::vector<GnssAntennaInformation> gnssAntennaInformations) {
+ if (nullptr != spGnssAntennaInfo) {
+ spGnssAntennaInfo->gnssAntennaInfoCb(gnssAntennaInformations);
+ }
+}
+
+void GnssAntennaInfo::gnssAntennaInfoCb
+ (std::vector<GnssAntennaInformation> gnssAntennaInformations) {
+
+ if (mGnssAntennaInfoCbIface != nullptr) {
+ hidl_vec<IGnssAntennaInfoCallback::GnssAntennaInfo> antennaInfos;
+
+ // Convert from one structure to another
+ convertGnssAntennaInfo(gnssAntennaInformations, antennaInfos);
+
+ auto r = mGnssAntennaInfoCbIface->gnssAntennaInfoCb(antennaInfos);
+ if (!r.isOk()) {
+ LOC_LOGw("Error antenna info cb %s", r.description().c_str());
+ }
+ } else {
+ LOC_LOGw("setCallback has not been called yet");
+ }
+}
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/android/2.1/GnssAntennaInfo.h b/android/2.1/GnssAntennaInfo.h
new file mode 100644
index 0000000..02ddd28
--- /dev/null
+++ b/android/2.1/GnssAntennaInfo.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2020, 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_V2_1_GNSSANTENNAINFO_H
+#define ANDROID_HARDWARE_GNSS_V2_1_GNSSANTENNAINFO_H
+
+#include <android/hardware/gnss/2.1/IGnssAntennaInfo.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_1 {
+namespace implementation {
+
+using ::android::hardware::gnss::V2_1::IGnssAntennaInfo;
+using ::android::hardware::gnss::V2_1::IGnssAntennaInfoCallback;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+struct Gnss;
+struct GnssAntennaInfo : public IGnssAntennaInfo {
+ GnssAntennaInfo(Gnss* gnss);
+ ~GnssAntennaInfo();
+
+ /*
+ * Methods from ::android::hardware::gnss::V1_1::IGnssAntennaInfo follow.
+ * These declarations were generated from IGnssAntennaInfo.hal.
+ */
+ Return<GnssAntennaInfoStatus>
+ setCallback(const sp<IGnssAntennaInfoCallback>& callback) override;
+ Return<void> close(void) override;
+
+ void gnssAntennaInfoCb(std::vector<GnssAntennaInformation> gnssAntennaInformations);
+
+ static void aiGnssAntennaInfoCb(std::vector<GnssAntennaInformation> gnssAntennaInformations);
+
+ private:
+ struct GnssAntennaInfoDeathRecipient : hidl_death_recipient {
+ GnssAntennaInfoDeathRecipient(sp<GnssAntennaInfo> gnssAntennaInfo) :
+ mGnssAntennaInfo(gnssAntennaInfo) {
+ }
+ ~GnssAntennaInfoDeathRecipient() = default;
+ virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override;
+ sp<GnssAntennaInfo> mGnssAntennaInfo;
+ };
+
+ private:
+ sp<GnssAntennaInfoDeathRecipient> mGnssAntennaInfoDeathRecipient = nullptr;
+ sp<IGnssAntennaInfoCallback> mGnssAntennaInfoCbIface = nullptr;
+ Gnss* mGnss = nullptr;
+};
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V2_1_GNSSANTENNAINFO_H
diff --git a/android/2.1/GnssBatching.cpp b/android/2.1/GnssBatching.cpp
new file mode 100644
index 0000000..73e3532
--- /dev/null
+++ b/android/2.1/GnssBatching.cpp
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2017-2020, 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_1 {
+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) {
+ mApi->destroy();
+ mApi = nullptr;
+ }
+}
+
+
+// Methods from ::android::hardware::gnss::V1_0::IGnssBatching follow.
+Return<bool> GnssBatching::init(const sp<V1_0::IGnssBatchingCallback>& callback) {
+ if (mApi != nullptr) {
+ LOC_LOGD("%s]: mApi is NOT nullptr, delete it first", __FUNCTION__);
+ mApi->destroy();
+ 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 (mApi != nullptr) {
+ mApi->stopSession();
+ }
+ if (mGnssBatchingCbIface != nullptr) {
+ mGnssBatchingCbIface->unlinkToDeath(mGnssBatchingDeathRecipient);
+ mGnssBatchingCbIface = nullptr;
+ }
+ if (mGnssBatchingCbIface_2_0 != nullptr) {
+ mGnssBatchingCbIface_2_0->unlinkToDeath(mGnssBatchingDeathRecipient);
+ mGnssBatchingCbIface_2_0 = nullptr;
+ }
+ return Void();
+}
+
+// Methods from ::android::hardware::gnss::V2_0::IGnssBatching follow.
+Return<bool> GnssBatching::init_2_0(const sp<V2_0::IGnssBatchingCallback>& callback) {
+ if (mApi != nullptr) {
+ LOC_LOGD("%s]: mApi is NOT nullptr, delete it first", __FUNCTION__);
+ mApi->destroy();
+ mApi = nullptr;
+ }
+
+ mApi = new BatchingAPIClient(callback);
+ if (mApi == nullptr) {
+ LOC_LOGE("%s]: failed to create mApi", __FUNCTION__);
+ return false;
+ }
+
+ if (mGnssBatchingCbIface_2_0 != nullptr) {
+ mGnssBatchingCbIface_2_0->unlinkToDeath(mGnssBatchingDeathRecipient);
+ }
+ mGnssBatchingCbIface_2_0 = callback;
+ if (mGnssBatchingCbIface_2_0 != nullptr) {
+ mGnssBatchingCbIface_2_0->linkToDeath(mGnssBatchingDeathRecipient, 0 /*cookie*/);
+ }
+
+ return true;
+}
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/android/2.1/GnssBatching.h b/android/2.1/GnssBatching.h
new file mode 100644
index 0000000..908748f
--- /dev/null
+++ b/android/2.1/GnssBatching.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2017-2020, 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/2.0/IGnssBatching.h>
+#include <hidl/Status.h>
+
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_1 {
+namespace implementation {
+
+using ::android::hardware::gnss::V2_0::IGnssBatching;
+using ::android::hardware::gnss::V2_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<V1_0::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;
+
+ // Methods from ::android::hardware::gnss::V2_0::IGnssBatching follow.
+ Return<bool> init_2_0(const sp<V2_0::IGnssBatchingCallback>& callback) 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<V1_0::IGnssBatchingCallback> mGnssBatchingCbIface = nullptr;
+ BatchingAPIClient* mApi = nullptr;
+ sp<V2_0::IGnssBatchingCallback> mGnssBatchingCbIface_2_0 = nullptr;
+};
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V2_0_GNSSBATCHING_H
diff --git a/android/2.1/GnssConfiguration.cpp b/android/2.1/GnssConfiguration.cpp
new file mode 100644
index 0000000..b6077ae
--- /dev/null
+++ b/android/2.1/GnssConfiguration.cpp
@@ -0,0 +1,408 @@
+/*
+ * Copyright (c) 2017-2020, 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 "ContextBase.h"
+#include <android/hardware/gnss/1.0/types.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_1 {
+namespace implementation {
+
+using ::android::hardware::gnss::V2_0::GnssConstellationType;
+using namespace loc_core;
+
+GnssConfiguration::GnssConfiguration(Gnss* gnss) : mGnss(gnss) {
+}
+
+// Methods from ::android::hardware::gps::V1_0::IGnssConfiguration follow.
+Return<bool> GnssConfiguration::setSuplEs(bool enabled) {
+ // deprecated function. Must return false to pass VTS
+ return false;
+}
+
+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 0x00020004:
+ config.suplVersion = GNSS_CONFIG_SUPL_VERSION_2_0_4;
+ break;
+ 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;
+ }
+
+ 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;
+ }
+
+ return mGnss->updateConfiguration(config);
+}
+
+Return<bool> GnssConfiguration::setLppProfile(uint8_t lppProfileMask) {
+ if (mGnss == nullptr) {
+ LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
+ return false;
+ }
+
+ GnssConfig config = {};
+ config.size = sizeof(GnssConfig);
+ config.flags = GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT;
+ config.lppProfileMask = GNSS_CONFIG_LPP_PROFILE_RRLP_ON_LTE; //default
+
+ if (lppProfileMask & (1<<0)) {
+ config.lppProfileMask |= GNSS_CONFIG_LPP_PROFILE_USER_PLANE_BIT;
+ }
+ if (lppProfileMask & (1<<1)) {
+ config.lppProfileMask |= GNSS_CONFIG_LPP_PROFILE_CONTROL_PLANE_BIT;
+ }
+ if (lppProfileMask & (1<<2)) {
+ config.lppProfileMask |= GNSS_CONFIG_LPP_PROFILE_USER_PLANE_OVER_NR5G_SA_BIT;
+ }
+ if (lppProfileMask & (1<<3)) {
+ config.lppProfileMask |= GNSS_CONFIG_LPP_PROFILE_CONTROL_PLANE_OVER_NR5G_SA_BIT;
+ }
+
+ 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) {
+
+ if (mGnss == nullptr) {
+ LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
+ return false;
+ }
+
+ GnssConfig config = {};
+ config.size = sizeof(GnssConfig);
+ config.flags = GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT;
+ switch (lock) {
+ case 0:
+ config.gpsLock = GNSS_CONFIG_GPS_LOCK_NONE;
+ break;
+ case 1:
+ config.gpsLock = GNSS_CONFIG_GPS_LOCK_MO;
+ break;
+ case 2:
+ config.gpsLock = GNSS_CONFIG_GPS_LOCK_NI;
+ break;
+ case 3:
+ config.gpsLock = GNSS_CONFIG_GPS_LOCK_MO_AND_NI;
+ break;
+ default:
+ LOC_LOGE("%s]: invalid lock: %d.", __FUNCTION__, lock);
+ return false;
+ }
+
+ mGnss->updateConfiguration(config);
+ // Must return false to pass VTS
+ return false;
+}
+
+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<V1_1::IGnssConfiguration::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, (GnssConstellationType)blacklist[idx].constellation,
+ blacklist[idx].svid) || 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 GnssConstellationType& constellation,
+ const int16_t svid) {
+
+ bool retVal = true;
+ uint16_t svIdOffset = 0;
+ copyToSource.size = sizeof(GnssSvIdSource);
+ copyToSource.svId = svid;
+
+ switch(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;
+ case GnssConstellationType::IRNSS:
+ copyToSource.constellation = GNSS_SV_TYPE_NAVIC;
+ svIdOffset = 0;
+ break;
+ default:
+ copyToSource.constellation = GNSS_SV_TYPE_UNKNOWN;
+ LOC_LOGe("Invalid constellation %hhu", constellation);
+ retVal = false;
+ break;
+ }
+
+ if (copyToSource.svId > 0 && svIdOffset > 0) {
+ copyToSource.svId += svIdOffset;
+ }
+
+ return retVal;
+}
+
+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 = GNSS_SV_CONFIG_QZSS_INITIAL_SV_ID - 1;
+ 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;
+ case GnssConstellationType::IRNSS:
+ copyToSource.constellation = GNSS_SV_TYPE_NAVIC;
+ svIdOffset = GNSS_SV_CONFIG_NAVIC_INITIAL_SV_ID - 1;
+ break;
+ default:
+ copyToSource.constellation = GNSS_SV_TYPE_UNKNOWN;
+ LOC_LOGe("Invalid constellation %hhu", 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);
+}
+
+// Methods from ::android::hardware::gnss::V2_1::IGnssConfiguration follow.
+Return<bool> GnssConfiguration::setBlacklist_2_1(
+ const hidl_vec<V2_1::IGnssConfiguration::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));
+}
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/android/2.1/GnssConfiguration.h b/android/2.1/GnssConfiguration.h
new file mode 100644
index 0000000..f000dbd
--- /dev/null
+++ b/android/2.1/GnssConfiguration.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2017-2020, 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_1_GNSSCONFIGURATION_H
+#define ANDROID_HARDWARE_GNSS_V2_1_GNSSCONFIGURATION_H
+
+#include <android/hardware/gnss/2.1/IGnssConfiguration.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_1 {
+namespace implementation {
+
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::hardware::gnss::V2_0::GnssConstellationType;
+using ::android::sp;
+
+/*
+ * Interface for passing GNSS configuration info from platform to HAL.
+ */
+struct Gnss;
+struct GnssConfiguration : public V2_1::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 lppProfileMask) 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<V1_1::IGnssConfiguration::BlacklistedSource>& blacklist) override;
+
+ // Methods from ::android::hardware::gnss::V2_0::IGnssConfiguration follow.
+ Return<bool> setEsExtensionSec(uint32_t emergencyExtensionSeconds) override;
+ // Methods from ::android::hardware::gnss::V2_1::IGnssConfiguration follow.
+ Return<bool> setBlacklist_2_1(
+ const hidl_vec<V2_1::IGnssConfiguration::BlacklistedSource>& blacklist) override;
+
+ private:
+ Gnss* mGnss = nullptr;
+ bool setBlacklistedSource(
+ GnssSvIdSource& copyToSource,
+ const GnssConfiguration::BlacklistedSource& copyFromSource);
+ bool setBlacklistedSource(
+ GnssSvIdSource& copyToSource, const GnssConstellationType& constellation,
+ const int16_t svid);
+};
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V2_1_GNSSCONFIGURATION_H
diff --git a/android/2.1/GnssDebug.cpp b/android/2.1/GnssDebug.cpp
new file mode 100644
index 0000000..27ff964
--- /dev/null
+++ b/android/2.1/GnssDebug.cpp
@@ -0,0 +1,299 @@
+/*
+ * Copyright (c) 2017-2020, 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_1 {
+namespace implementation {
+
+using ::android::hardware::hidl_vec;
+using ::android::hardware::gnss::V2_0::IGnssDebug;
+
+#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_MIN (999) // 999 ns
+#define GNSS_DEBUG_UNKNOWN_UTC_TIME_UNC_MAX (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__);
+
+ V1_0::IGnssDebug::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_MIN;
+ } else if (data.time.timeUncertaintyNs > GNSS_DEBUG_UNKNOWN_UTC_TIME_UNC_MAX) {
+ data.time.timeUncertaintyNs = (float)GNSS_DEBUG_UNKNOWN_UTC_TIME_UNC_MAX;
+ }
+ 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
+ V1_0::IGnssDebug::SatelliteData s = { };
+ std::vector<V1_0::IGnssDebug::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();
+}
+
+Return<void> GnssDebug::getDebugData_2_0(getDebugData_2_0_cb _hidl_cb)
+{
+ LOC_LOGD("%s]: ", __func__);
+
+ V2_0::IGnssDebug::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_MIN;
+ }
+ else if (data.time.timeUncertaintyNs > GNSS_DEBUG_UNKNOWN_UTC_TIME_UNC_MAX) {
+ data.time.timeUncertaintyNs = (float)GNSS_DEBUG_UNKNOWN_UTC_TIME_UNC_MAX;
+ }
+ 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
+ V2_0::IGnssDebug::SatelliteData s = { };
+ std::vector<V2_0::IGnssDebug::SatelliteData> s_array;
+
+ for (uint32_t i=0; i<reports.mSatelliteInfo.size(); i++) {
+ memset(&s, 0, sizeof(s));
+ s.v1_0.svid = reports.mSatelliteInfo[i].svid;
+ convertGnssConstellationType(
+ reports.mSatelliteInfo[i].constellation, s.constellation);
+ convertGnssEphemerisType(
+ reports.mSatelliteInfo[i].mEphemerisType, s.v1_0.ephemerisType);
+ convertGnssEphemerisSource(
+ reports.mSatelliteInfo[i].mEphemerisSource, s.v1_0.ephemerisSource);
+ convertGnssEphemerisHealth(
+ reports.mSatelliteInfo[i].mEphemerisHealth, s.v1_0.ephemerisHealth);
+
+ s.v1_0.ephemerisAgeSeconds =
+ reports.mSatelliteInfo[i].ephemerisAgeSeconds;
+ s.v1_0.serverPredictionIsAvailable =
+ reports.mSatelliteInfo[i].serverPredictionIsAvailable;
+ s.v1_0.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_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/android/2.1/GnssDebug.h b/android/2.1/GnssDebug.h
new file mode 100644
index 0000000..4eaf34a
--- /dev/null
+++ b/android/2.1/GnssDebug.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2017-2020, 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/2.0/IGnssDebug.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_1 {
+namespace implementation {
+
+using ::android::hardware::gnss::V2_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
+ Return<void> getDebugData(getDebugData_cb _hidl_cb) override;
+ // Methods from ::android::hardware::gnss::V2_0::IGnssDebug follow.
+ Return<void> getDebugData_2_0(getDebugData_2_0_cb _hidl_cb) override;
+
+private:
+ Gnss* mGnss = nullptr;
+};
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V2_0_GNSSDEBUG_H
diff --git a/android/2.1/GnssGeofencing.cpp b/android/2.1/GnssGeofencing.cpp
new file mode 100644
index 0000000..0ca3e6d
--- /dev/null
+++ b/android/2.1/GnssGeofencing.cpp
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2017-2020, 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_1 {
+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) {
+ mApi->destroy();
+ 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_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/android/2.1/GnssGeofencing.h b/android/2.1/GnssGeofencing.h
new file mode 100644
index 0000000..1cdca12
--- /dev/null
+++ b/android/2.1/GnssGeofencing.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2017-2020, 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_1 {
+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_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V2_0_GNSSGEOFENCING_H
diff --git a/android/2.1/GnssMeasurement.cpp b/android/2.1/GnssMeasurement.cpp
new file mode 100644
index 0000000..af75802
--- /dev/null
+++ b/android/2.1/GnssMeasurement.cpp
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2017-2020, 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_1 {
+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) {
+ mApi->destroy();
+ 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;
+ }
+
+ clearInterfaces();
+
+ mGnssMeasurementCbIface = callback;
+ mGnssMeasurementCbIface->linkToDeath(mGnssMeasurementDeathRecipient, 0);
+
+ return mApi->measurementSetCallback(callback);
+}
+
+void GnssMeasurement::clearInterfaces() {
+ 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;
+ }
+ if (mGnssMeasurementCbIface_2_1 != nullptr) {
+ mGnssMeasurementCbIface_2_1->unlinkToDeath(mGnssMeasurementDeathRecipient);
+ mGnssMeasurementCbIface_2_1 = nullptr;
+ }
+}
+
+Return<void> GnssMeasurement::close() {
+ if (mApi == nullptr) {
+ LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+ return Void();
+ }
+
+ clearInterfaces();
+ 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;
+ }
+
+ clearInterfaces();
+
+ 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;
+ }
+
+ clearInterfaces();
+
+ 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);
+}
+
+// Methods from ::android::hardware::gnss::V2_1::IGnssMeasurement follow.
+Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback_2_1(
+ const sp<::android::hardware::gnss::V2_1::IGnssMeasurementCallback>& callback,
+ bool enableFullTracking) {
+ Return<GnssMeasurement::GnssMeasurementStatus> ret =
+ IGnssMeasurement::GnssMeasurementStatus::ERROR_GENERIC;
+ if (mGnssMeasurementCbIface_2_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;
+ }
+
+ clearInterfaces();
+
+ mGnssMeasurementCbIface_2_1 = callback;
+ mGnssMeasurementCbIface_2_1->linkToDeath(mGnssMeasurementDeathRecipient, 0);
+
+ GnssPowerMode powerMode = enableFullTracking ?
+ GNSS_POWER_MODE_M1 : GNSS_POWER_MODE_M2;
+
+ return mApi->measurementSetCallback_2_1(callback, powerMode);
+
+}
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/android/2.1/GnssMeasurement.h b/android/2.1/GnssMeasurement.h
new file mode 100644
index 0000000..2ac45c6
--- /dev/null
+++ b/android/2.1/GnssMeasurement.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2017-2020, 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_1_GNSSMEASUREMENT_H
+#define ANDROID_HARDWARE_GNSS_V2_1_GNSSMEASUREMENT_H
+
+#include <android/hardware/gnss/2.1/IGnssMeasurement.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_1 {
+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_1::IGnssMeasurement {
+ GnssMeasurement();
+ ~GnssMeasurement();
+
+ /*
+ * Methods from ::android::hardware::gnss::V1_0::IGnssMeasurement follow.
+ * These declarations were generated from IGnssMeasurement.hal.
+ */
+ Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> setCallback(
+ const sp<V1_0::IGnssMeasurementCallback>& callback) override;
+ Return<void> close() override;
+
+ // Methods from ::android::hardware::gnss::V1_1::IGnssMeasurement follow.
+ Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> setCallback_1_1(
+ const sp<V1_1::IGnssMeasurementCallback>& callback,
+ bool enableFullTracking) override;
+
+ // Methods from ::android::hardware::gnss::V2_0::IGnssMeasurement follow.
+ Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> setCallback_2_0(
+ const sp<V2_0::IGnssMeasurementCallback>& callback,
+ bool enableFullTracking) override;
+ // Methods from ::android::hardware::gnss::V2_1::IGnssMeasurement follow.
+ Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> setCallback_2_1(
+ const sp<::android::hardware::gnss::V2_1::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;
+ sp<V2_1::IGnssMeasurementCallback> mGnssMeasurementCbIface_2_1 = nullptr;
+ MeasurementAPIClient* mApi;
+ void clearInterfaces();
+};
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V2_1_GNSSMEASUREMENT_H
diff --git a/android/2.1/GnssNi.cpp b/android/2.1/GnssNi.cpp
new file mode 100644
index 0000000..ba5e8d9
--- /dev/null
+++ b/android/2.1/GnssNi.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2017-2020, 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_1 {
+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_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/android/2.1/GnssNi.h b/android/2.1/GnssNi.h
new file mode 100644
index 0000000..9a8fb69
--- /dev/null
+++ b/android/2.1/GnssNi.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2017-2020, 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_1 {
+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_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V2_0_GNSSNI_H
diff --git a/android/visibility_control/1.0/GnssVisibilityControl.cpp b/android/2.1/GnssVisibilityControl.cpp
similarity index 100%
copy from android/visibility_control/1.0/GnssVisibilityControl.cpp
copy to android/2.1/GnssVisibilityControl.cpp
diff --git a/android/2.1/GnssVisibilityControl.h b/android/2.1/GnssVisibilityControl.h
new file mode 100644
index 0000000..6794a64
--- /dev/null
+++ b/android/2.1/GnssVisibilityControl.h
@@ -0,0 +1,90 @@
+/*
+ * 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_1::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);
+ bool isE911Session();
+
+ /* Data call setup callback passed down to GNSS HAL implementation */
+ static void nfwStatusCb(GnssNfwNotification notification);
+ static bool isInEmergencySession();
+
+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/android/2.1/MeasurementCorrections.cpp b/android/2.1/MeasurementCorrections.cpp
new file mode 100644
index 0000000..5159f2f
--- /dev/null
+++ b/android/2.1/MeasurementCorrections.cpp
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 2020-2021, 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_1 {
+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::measurement_corrections::V1_0::IMeasurementCorrectionsCallback;
+using ::android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrections;
+using MeasurementCorrectionsV1_0 =
+ ::android::hardware::gnss::measurement_corrections::V1_0::MeasurementCorrections;
+using MeasurementCorrectionsV1_1 =
+ ::android::hardware::gnss::measurement_corrections::V1_1::MeasurementCorrections;
+
+static MeasurementCorrections* spMeasurementCorrections = nullptr;
+
+void MeasurementCorrections::GnssMeasurementCorrectionsDeathRecipient::serviceDied(uint64_t cookie,
+ const wp<IBase>& who) {
+ LOC_LOGe("service died. cookie: %llu, who: %p", static_cast<unsigned long long>(cookie), &who);
+ // Gnss::GnssDeathrecipient will stop the session
+ // we inform the adapter that service has died
+ if (nullptr == spMeasurementCorrections) {
+ LOC_LOGe("spMeasurementCorrections is nullptr");
+ return;
+ }
+ if (nullptr == spMeasurementCorrections->mGnss ||
+ nullptr == spMeasurementCorrections->mGnss->getGnssInterface()) {
+ LOC_LOGe("Null GNSS interface");
+ return;
+ }
+ spMeasurementCorrections->mGnss->getGnssInterface()->measCorrClose();
+}
+
+MeasurementCorrections::MeasurementCorrections(Gnss* gnss) : mGnss(gnss) {
+ mGnssMeasurementCorrectionsDeathRecipient = new GnssMeasurementCorrectionsDeathRecipient(this);
+ spMeasurementCorrections = this;
+}
+
+MeasurementCorrections::~MeasurementCorrections() {
+ spMeasurementCorrections = nullptr;
+}
+
+void MeasurementCorrections::measCorrSetCapabilitiesCb(
+ GnssMeasurementCorrectionsCapabilitiesMask capabilities) {
+ if (nullptr != spMeasurementCorrections) {
+ spMeasurementCorrections->setCapabilitiesCb(capabilities);
+ }
+}
+
+void MeasurementCorrections::setCapabilitiesCb(
+ GnssMeasurementCorrectionsCapabilitiesMask capabilities) {
+
+ std::unique_lock<std::mutex> lock(mMutex);
+ auto measCorrCbIface(mMeasurementCorrectionsCbIface);
+ lock.unlock();
+ if (measCorrCbIface != nullptr) {
+ uint32_t measCorrCapabilities = 0;
+
+ // Convert from one enum to another
+ if (capabilities & GNSS_MEAS_CORR_LOS_SATS) {
+ measCorrCapabilities |=
+ IMeasurementCorrectionsCallback::Capabilities::LOS_SATS;
+ }
+ if (capabilities & GNSS_MEAS_CORR_EXCESS_PATH_LENGTH) {
+ measCorrCapabilities |=
+ IMeasurementCorrectionsCallback::Capabilities::EXCESS_PATH_LENGTH;
+ }
+ if (capabilities & GNSS_MEAS_CORR_REFLECTING_PLANE) {
+ measCorrCapabilities |=
+ IMeasurementCorrectionsCallback::Capabilities::REFLECTING_PLANE;
+ }
+
+ auto r = measCorrCbIface->setCapabilitiesCb(measCorrCapabilities);
+ if (!r.isOk()) {
+ LOC_LOGw("Error invoking setCapabilitiesCb %s", r.description().c_str());
+ }
+ } else {
+ LOC_LOGw("setCallback has not been called yet");
+ }
+}
+
+Return<bool> MeasurementCorrections::setCorrections(
+ const MeasurementCorrectionsV1_0& corrections) {
+
+ GnssMeasurementCorrections gnssMeasurementCorrections = {};
+
+ V2_1::implementation::convertMeasurementCorrections(corrections, gnssMeasurementCorrections);
+
+ return mGnss->getGnssInterface()->measCorrSetCorrections(gnssMeasurementCorrections);
+}
+
+Return<bool> MeasurementCorrections::setCorrections_1_1(
+ const MeasurementCorrectionsV1_1& corrections) {
+
+ GnssMeasurementCorrections gnssMeasurementCorrections = {};
+
+ V2_1::implementation::convertMeasurementCorrections(
+ corrections.v1_0, gnssMeasurementCorrections);
+
+ gnssMeasurementCorrections.hasEnvironmentBearing = corrections.hasEnvironmentBearing;
+ gnssMeasurementCorrections.environmentBearingDegrees =
+ corrections.environmentBearingDegrees;
+ gnssMeasurementCorrections.environmentBearingUncertaintyDegrees =
+ corrections.environmentBearingUncertaintyDegrees;
+
+ for (int i = 0; i < corrections.satCorrections.size(); i++) {
+ GnssSingleSatCorrection gnssSingleSatCorrection = {};
+
+ V2_1::implementation::convertSingleSatCorrections(
+ corrections.satCorrections[i].v1_0, gnssSingleSatCorrection);
+ switch (corrections.satCorrections[i].constellation) {
+ case (::android::hardware::gnss::V2_0::GnssConstellationType::GPS):
+ gnssSingleSatCorrection.svType = GNSS_SV_TYPE_GPS;
+ break;
+ case (::android::hardware::gnss::V2_0::GnssConstellationType::SBAS):
+ gnssSingleSatCorrection.svType = GNSS_SV_TYPE_SBAS;
+ break;
+ case (::android::hardware::gnss::V2_0::GnssConstellationType::GLONASS):
+ gnssSingleSatCorrection.svType = GNSS_SV_TYPE_GLONASS;
+ break;
+ case (::android::hardware::gnss::V2_0::GnssConstellationType::QZSS):
+ gnssSingleSatCorrection.svType = GNSS_SV_TYPE_QZSS;
+ break;
+ case (::android::hardware::gnss::V2_0::GnssConstellationType::BEIDOU):
+ gnssSingleSatCorrection.svType = GNSS_SV_TYPE_BEIDOU;
+ break;
+ case (::android::hardware::gnss::V2_0::GnssConstellationType::GALILEO):
+ gnssSingleSatCorrection.svType = GNSS_SV_TYPE_GALILEO;
+ break;
+ case (::android::hardware::gnss::V2_0::GnssConstellationType::IRNSS):
+ gnssSingleSatCorrection.svType = GNSS_SV_TYPE_NAVIC;
+ break;
+ case (::android::hardware::gnss::V2_0::GnssConstellationType::UNKNOWN):
+ default:
+ gnssSingleSatCorrection.svType = GNSS_SV_TYPE_UNKNOWN;
+ break;
+ }
+ gnssMeasurementCorrections.satCorrections.push_back(gnssSingleSatCorrection);
+ }
+
+ return mGnss->getGnssInterface()->measCorrSetCorrections(gnssMeasurementCorrections);
+}
+
+Return<bool> MeasurementCorrections::setCallback(
+ const sp<V1_0::IMeasurementCorrectionsCallback>& callback) {
+
+ if (nullptr == mGnss || nullptr == mGnss->getGnssInterface()) {
+ LOC_LOGe("Null GNSS interface");
+ return false;
+ }
+ std::unique_lock<std::mutex> lock(mMutex);
+ mMeasurementCorrectionsCbIface = callback;
+ lock.unlock();
+
+ return mGnss->getGnssInterface()->measCorrInit(measCorrSetCapabilitiesCb);
+}
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace measurement_corrections
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/android/2.1/MeasurementCorrections.h b/android/2.1/MeasurementCorrections.h
new file mode 100644
index 0000000..0247231
--- /dev/null
+++ b/android/2.1/MeasurementCorrections.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2020-2021, 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_1_MeasurementCorrections_H
+#define ANDROID_HARDWARE_GNSS_V1_1_MeasurementCorrections_H
+
+#include <android/hardware/gnss/measurement_corrections/1.1/IMeasurementCorrections.h>
+#include <android/hardware/gnss/measurement_corrections/1.0/IMeasurementCorrectionsCallback.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+#include <gps_extended_c.h>
+#include <location_interface.h>
+#include "Gnss.h"
+#include <LocationUtil.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace measurement_corrections {
+namespace V1_1 {
+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;
+using ::android::hardware::gnss::V2_1::implementation::Gnss;
+using MeasurementCorrectionsV1_0 =
+ ::android::hardware::gnss::measurement_corrections::V1_0::MeasurementCorrections;
+using MeasurementCorrectionsV1_1 =
+ ::android::hardware::gnss::measurement_corrections::V1_1::MeasurementCorrections;
+
+struct MeasurementCorrections : public V1_1::IMeasurementCorrections {
+ MeasurementCorrections(Gnss* gnss);
+ ~MeasurementCorrections();
+
+ Return<bool> setCorrections(const MeasurementCorrectionsV1_0& corrections) override;
+
+ // Methods from
+ // ::android::hardware::gnss::measurement_corrections::V1_1::IMeasurementCorrections follow.
+ Return<bool> setCorrections_1_1(const MeasurementCorrectionsV1_1& corrections);
+
+ Return<bool> setCallback(const sp<IMeasurementCorrectionsCallback>& callback) override;
+
+ void setCapabilitiesCb(GnssMeasurementCorrectionsCapabilitiesMask capabilities);
+
+ /* Data call setup callback passed down to GNSS HAL implementation */
+ static void measCorrSetCapabilitiesCb(GnssMeasurementCorrectionsCapabilitiesMask capabilities);
+
+private:
+ mutable std::mutex mMutex;
+ struct GnssMeasurementCorrectionsDeathRecipient : hidl_death_recipient {
+ GnssMeasurementCorrectionsDeathRecipient(
+ sp<MeasurementCorrections> gnssMeasurementCorrections) :
+ mGnssMeasurementCorrections(gnssMeasurementCorrections) {
+ }
+ ~GnssMeasurementCorrectionsDeathRecipient() = default;
+ virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override;
+ sp<MeasurementCorrections> mGnssMeasurementCorrections;
+ };
+ Gnss* mGnss = nullptr;
+ sp<GnssMeasurementCorrectionsDeathRecipient> mGnssMeasurementCorrectionsDeathRecipient =
+ nullptr;
+ sp<IMeasurementCorrectionsCallback> mMeasurementCorrectionsCbIface = nullptr;
+};
+
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace measurement_corrections
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V1_1_MeasurementCorrections_H
diff --git a/android/2.1/android.hardware.gnss@2.1-service-qti.rc b/android/2.1/android.hardware.gnss@2.1-service-qti.rc
new file mode 100644
index 0000000..71b43bc
--- /dev/null
+++ b/android/2.1/android.hardware.gnss@2.1-service-qti.rc
@@ -0,0 +1,4 @@
+service gnss_service /vendor/bin/hw/android.hardware.gnss@2.1-service-qti
+ class hal
+ user gps
+ group system gps radio
diff --git a/android/2.1/android.hardware.gnss@2.1-service-qti.xml b/android/2.1/android.hardware.gnss@2.1-service-qti.xml
new file mode 100755
index 0000000..842fb6e
--- /dev/null
+++ b/android/2.1/android.hardware.gnss@2.1-service-qti.xml
@@ -0,0 +1,36 @@
+<!-- Copyright (c) 2020, 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.
+-->
+<manifest version="1.0" type="device">
+ <hal format="hidl">
+ <name>android.hardware.gnss</name>
+ <transport>hwbinder</transport>
+ <fqname>@1.1::IGnss/default</fqname>
+ <fqname>@2.1::IGnss/default</fqname>
+ </hal>
+</manifest>
+
diff --git a/android/2.1/location_api/BatchingAPIClient.cpp b/android/2.1/location_api/BatchingAPIClient.cpp
new file mode 100644
index 0000000..0c871b7
--- /dev/null
+++ b/android/2.1/location_api/BatchingAPIClient.cpp
@@ -0,0 +1,292 @@
+/* Copyright (c) 2017-2021, 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 <inttypes.h>
+#include <log_util.h>
+#include <loc_cfg.h>
+#include <thread>
+#include "LocationUtil.h"
+#include "BatchingAPIClient.h"
+
+#include "limits.h"
+
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_1 {
+namespace implementation {
+
+using ::android::hardware::gnss::V2_0::IGnssBatching;
+using ::android::hardware::gnss::V2_0::IGnssBatchingCallback;
+using ::android::hardware::gnss::V2_0::GnssLocation;
+
+static void convertBatchOption(const IGnssBatching::Options& in, LocationOptions& out,
+ LocationCapabilitiesMask mask);
+
+BatchingAPIClient::BatchingAPIClient(const sp<V1_0::IGnssBatchingCallback>& callback) :
+ LocationAPIClientBase(),
+ mGnssBatchingCbIface(nullptr),
+ mDefaultId(UINT_MAX),
+ mLocationCapabilitiesMask(0),
+ mGnssBatchingCbIface_2_0(nullptr)
+{
+ LOC_LOGD("%s]: (%p)", __FUNCTION__, &callback);
+
+ gnssUpdateCallbacks(callback);
+}
+
+BatchingAPIClient::BatchingAPIClient(const sp<V2_0::IGnssBatchingCallback>& callback) :
+ LocationAPIClientBase(),
+ mGnssBatchingCbIface(nullptr),
+ mDefaultId(UINT_MAX),
+ mLocationCapabilitiesMask(0),
+ mGnssBatchingCbIface_2_0(nullptr)
+{
+ LOC_LOGD("%s]: (%p)", __FUNCTION__, &callback);
+
+ gnssUpdateCallbacks_2_0(callback);
+}
+
+BatchingAPIClient::~BatchingAPIClient()
+{
+ LOC_LOGD("%s]: ()", __FUNCTION__);
+}
+
+int BatchingAPIClient::getBatchSize() {
+ int batchSize = locAPIGetBatchSize();
+ LOC_LOGd("batchSize: %d", batchSize);
+ return batchSize;
+}
+
+void BatchingAPIClient::setCallbacks()
+{
+ LocationCallbacks locationCallbacks;
+ memset(&locationCallbacks, 0, sizeof(LocationCallbacks));
+ locationCallbacks.size = sizeof(LocationCallbacks);
+
+ locationCallbacks.trackingCb = nullptr;
+ locationCallbacks.batchingCb = 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);
+}
+
+void BatchingAPIClient::gnssUpdateCallbacks(const sp<V1_0::IGnssBatchingCallback>& callback)
+{
+ mMutex.lock();
+ mGnssBatchingCbIface = callback;
+ mMutex.unlock();
+
+ if (mGnssBatchingCbIface != nullptr) {
+ setCallbacks();
+ }
+}
+
+void BatchingAPIClient::gnssUpdateCallbacks_2_0(const sp<V2_0::IGnssBatchingCallback>& callback)
+{
+ mMutex.lock();
+ mGnssBatchingCbIface_2_0 = callback;
+ mMutex.unlock();
+
+ if (mGnssBatchingCbIface_2_0 != nullptr) {
+ setCallbacks();
+ }
+}
+
+int BatchingAPIClient::startSession(const IGnssBatching::Options& opts) {
+ mMutex.lock();
+ mState = STARTED;
+ mMutex.unlock();
+ 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() {
+ mMutex.lock();
+ mState = STOPPING;
+ mMutex.unlock();
+ LOC_LOGD("%s]: ", __FUNCTION__);
+ int retVal = -1;
+ locAPIGetBatchedLocations(mDefaultId, SIZE_MAX);
+ 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__);
+ uint32_t retVal = locAPIGetBatchedLocations(mDefaultId, SIZE_MAX);
+ // when flush a stopped session or one doesn't exist, just report an empty batch.
+ if (LOCATION_ERROR_ID_UNKNOWN == retVal) {
+ BatchingOptions opt = {};
+ ::std::thread thd(&BatchingAPIClient::onBatchingCb, this, 0, nullptr, opt);
+ thd.detach();
+ }
+}
+
+void BatchingAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)
+{
+ LOC_LOGD("%s]: (%" PRIu64 ")", __FUNCTION__, capabilitiesMask);
+ mLocationCapabilitiesMask = capabilitiesMask;
+}
+
+void BatchingAPIClient::onBatchingCb(size_t count, Location* location,
+ BatchingOptions /*batchOptions*/) {
+ bool processReport = false;
+ LOC_LOGd("(count: %zu)", count);
+ mMutex.lock();
+ // back to back stop() and flush() could bring twice onBatchingCb(). Each one might come first.
+ // Combine them both (the first goes to cache, the second in location*) before report to FW
+ switch (mState) {
+ case STOPPING:
+ mState = STOPPED;
+ for (size_t i = 0; i < count; i++) {
+ mBatchedLocationInCache.push_back(location[i]);
+ }
+ break;
+ case STARTED:
+ case STOPPED: // flush() always trigger report, even on a stopped session
+ processReport = true;
+ break;
+ default:
+ break;
+ }
+ // report location batch when in STARTED state or flush(), combined with cache in last stop()
+ if (processReport) {
+ auto gnssBatchingCbIface(mGnssBatchingCbIface);
+ auto gnssBatchingCbIface_2_0(mGnssBatchingCbIface_2_0);
+ size_t batchCacheCnt = mBatchedLocationInCache.size();
+ LOC_LOGd("(batchCacheCnt: %zu)", batchCacheCnt);
+ if (gnssBatchingCbIface_2_0 != nullptr) {
+ hidl_vec<V2_0::GnssLocation> locationVec;
+ if (count+batchCacheCnt > 0) {
+ locationVec.resize(count+batchCacheCnt);
+ for (size_t i = 0; i < batchCacheCnt; ++i) {
+ convertGnssLocation(mBatchedLocationInCache[i], locationVec[i]);
+ }
+ for (size_t i = 0; i < count; i++) {
+ convertGnssLocation(location[i], locationVec[i+batchCacheCnt]);
+ }
+ }
+ auto r = gnssBatchingCbIface_2_0->gnssLocationBatchCb(locationVec);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssLocationBatchCb 2_0 description=%s",
+ __func__, r.description().c_str());
+ }
+ } else if (gnssBatchingCbIface != nullptr) {
+ hidl_vec<V1_0::GnssLocation> locationVec;
+ if (count+batchCacheCnt > 0) {
+ locationVec.resize(count+batchCacheCnt);
+ for (size_t i = 0; i < batchCacheCnt; ++i) {
+ convertGnssLocation(mBatchedLocationInCache[i], locationVec[i]);
+ }
+ for (size_t i = 0; i < count; i++) {
+ convertGnssLocation(location[i], locationVec[i+batchCacheCnt]);
+ }
+ }
+ auto r = gnssBatchingCbIface->gnssLocationBatchCb(locationVec);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssLocationBatchCb 1.0 description=%s",
+ __func__, r.description().c_str());
+ }
+ }
+ mBatchedLocationInCache.clear();
+ }
+ mMutex.unlock();
+}
+
+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_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/android/2.1/location_api/BatchingAPIClient.h b/android/2.1/location_api/BatchingAPIClient.h
new file mode 100755
index 0000000..2d9ab74
--- /dev/null
+++ b/android/2.1/location_api/BatchingAPIClient.h
@@ -0,0 +1,88 @@
+/* Copyright (c) 2017-2020, 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 <mutex>
+#include <android/hardware/gnss/2.0/IGnssBatching.h>
+#include <android/hardware/gnss/2.0/IGnssBatchingCallback.h>
+#include <pthread.h>
+
+#include <LocationAPIClientBase.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_1 {
+namespace implementation {
+
+
+enum BATCHING_STATE { STARTED, STOPPING, STOPPED };
+
+class BatchingAPIClient : public LocationAPIClientBase
+{
+public:
+ BatchingAPIClient(const sp<V1_0::IGnssBatchingCallback>& callback);
+ BatchingAPIClient(const sp<V2_0::IGnssBatchingCallback>& callback);
+ void gnssUpdateCallbacks(const sp<V1_0::IGnssBatchingCallback>& callback);
+ void gnssUpdateCallbacks_2_0(const sp<V2_0::IGnssBatchingCallback>& callback);
+ 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:
+ ~BatchingAPIClient();
+
+ void setCallbacks();
+ std::mutex mMutex;
+ sp<V1_0::IGnssBatchingCallback> mGnssBatchingCbIface;
+ uint32_t mDefaultId;
+ LocationCapabilitiesMask mLocationCapabilitiesMask;
+ sp<V2_0::IGnssBatchingCallback> mGnssBatchingCbIface_2_0;
+ volatile BATCHING_STATE mState = STOPPED;
+
+ std::vector<Location> mBatchedLocationInCache;
+};
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+#endif // BATCHING_API_CLINET_H
diff --git a/android/2.1/location_api/GeofenceAPIClient.cpp b/android/2.1/location_api/GeofenceAPIClient.cpp
new file mode 100755
index 0000000..6e63465
--- /dev/null
+++ b/android/2.1/location_api/GeofenceAPIClient.cpp
@@ -0,0 +1,275 @@
+/* Copyright (c) 2017-2020, 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_1 {
+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]: (%d)", __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_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/android/2.1/location_api/GeofenceAPIClient.h b/android/2.1/location_api/GeofenceAPIClient.h
new file mode 100755
index 0000000..9ed289f
--- /dev/null
+++ b/android/2.1/location_api/GeofenceAPIClient.h
@@ -0,0 +1,77 @@
+/* Copyright (c) 2017-2020, 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_1 {
+namespace implementation {
+
+using ::android::sp;
+
+class GeofenceAPIClient : public LocationAPIClientBase
+{
+public:
+ GeofenceAPIClient(const sp<V1_0::IGnssGeofenceCallback>& callback);
+
+ 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:
+ virtual ~GeofenceAPIClient() = default;
+
+ sp<V1_0::IGnssGeofenceCallback> mGnssGeofencingCbIface;
+};
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+#endif // GEOFENCE_API_CLINET_H
diff --git a/android/2.1/location_api/GnssAPIClient.cpp b/android/2.1/location_api/GnssAPIClient.cpp
new file mode 100644
index 0000000..e1dc0d4
--- /dev/null
+++ b/android/2.1/location_api/GnssAPIClient.cpp
@@ -0,0 +1,864 @@
+/* Copyright (c) 2017-2020, 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 <inttypes.h>
+#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_1 {
+namespace implementation {
+
+using ::android::hardware::gnss::V2_1::IGnss;
+using ::android::hardware::gnss::V2_1::IGnssCallback;
+using ::android::hardware::gnss::V1_0::IGnssNiCallback;
+using ::android::hardware::gnss::V2_0::GnssLocation;
+
+static void convertGnssSvStatus(GnssSvNotification& in, V1_0::IGnssCallback::GnssSvStatus& out);
+static void convertGnssSvStatus(GnssSvNotification& in,
+ hidl_vec<V2_0::IGnssCallback::GnssSvInfo>& out);
+static void convertGnssSvStatus(GnssSvNotification& in,
+ hidl_vec<V2_1::IGnssCallback::GnssSvInfo>& out);
+
+GnssAPIClient::GnssAPIClient(const sp<V1_0::IGnssCallback>& gpsCb,
+ const sp<V1_0::IGnssNiCallback>& niCb) :
+ LocationAPIClientBase(),
+ mGnssCbIface(nullptr),
+ mGnssNiCbIface(nullptr),
+ mControlClient(new LocationAPIControlClient()),
+ mLocationCapabilitiesMask(0),
+ mLocationCapabilitiesCached(false),
+ mTracking(false),
+ mGnssCbIface_2_0(nullptr)
+{
+ LOC_LOGD("%s]: (%p %p)", __FUNCTION__, &gpsCb, &niCb);
+
+ initLocationOptions();
+ gnssUpdateCallbacks(gpsCb, niCb);
+}
+
+GnssAPIClient::GnssAPIClient(const sp<V2_0::IGnssCallback>& gpsCb) :
+ LocationAPIClientBase(),
+ mGnssCbIface(nullptr),
+ mGnssNiCbIface(nullptr),
+ mControlClient(new LocationAPIControlClient()),
+ mLocationCapabilitiesMask(0),
+ mLocationCapabilitiesCached(false),
+ mTracking(false),
+ mGnssCbIface_2_0(nullptr)
+{
+ LOC_LOGD("%s]: (%p)", __FUNCTION__, &gpsCb);
+
+ initLocationOptions();
+ gnssUpdateCallbacks_2_0(gpsCb);
+}
+
+GnssAPIClient::GnssAPIClient(const sp<V2_1::IGnssCallback>& gpsCb) :
+ LocationAPIClientBase(),
+ mGnssCbIface(nullptr),
+ mGnssNiCbIface(nullptr),
+ mControlClient(new LocationAPIControlClient()),
+ mLocationCapabilitiesMask(0),
+ mLocationCapabilitiesCached(false),
+ mTracking(false),
+ mGnssCbIface_2_1(nullptr)
+{
+ LOC_LOGD("%s]: (%p)", __FUNCTION__, &gpsCb);
+
+ initLocationOptions();
+ gnssUpdateCallbacks_2_1(gpsCb);
+}
+
+GnssAPIClient::~GnssAPIClient()
+{
+ LOC_LOGD("%s]: ()", __FUNCTION__);
+ if (mControlClient) {
+ delete mControlClient;
+ mControlClient = nullptr;
+ }
+}
+
+void GnssAPIClient::initLocationOptions()
+{
+ // set default LocationOptions.
+ memset(&mTrackingOptions, 0, sizeof(TrackingOptions));
+ mTrackingOptions.size = sizeof(TrackingOptions);
+ mTrackingOptions.minInterval = 1000;
+ mTrackingOptions.minDistance = 0;
+ mTrackingOptions.mode = GNSS_SUPL_MODE_STANDALONE;
+}
+
+void GnssAPIClient::setCallbacks()
+{
+ LocationCallbacks locationCallbacks;
+ memset(&locationCallbacks, 0, sizeof(LocationCallbacks));
+ locationCallbacks.size = sizeof(LocationCallbacks);
+
+ locationCallbacks.trackingCb = nullptr;
+ locationCallbacks.trackingCb = [this](Location location) {
+ onTrackingCb(location);
+ };
+
+ locationCallbacks.batchingCb = nullptr;
+ locationCallbacks.geofenceBreachCb = nullptr;
+ locationCallbacks.geofenceStatusCb = nullptr;
+ locationCallbacks.gnssLocationInfoCb = nullptr;
+ locationCallbacks.gnssNiCb = nullptr;
+ if (mGnssNiCbIface != nullptr) {
+ loc_core::ContextBase* context =
+ loc_core::LocContext::getLocContext(loc_core::LocContext::mLocationHalName);
+ if (!context->hasAgpsExtendedCapabilities()) {
+ LOC_LOGD("Registering NI CB");
+ locationCallbacks.gnssNiCb = [this](uint32_t id, GnssNiNotification gnssNiNotify) {
+ onGnssNiCb(id, gnssNiNotify);
+ };
+ }
+ }
+
+ locationCallbacks.gnssSvCb = nullptr;
+ locationCallbacks.gnssSvCb = [this](GnssSvNotification gnssSvNotification) {
+ onGnssSvCb(gnssSvNotification);
+ };
+
+ locationCallbacks.gnssNmeaCb = nullptr;
+ locationCallbacks.gnssNmeaCb = [this](GnssNmeaNotification gnssNmeaNotification) {
+ onGnssNmeaCb(gnssNmeaNotification);
+ };
+
+ locationCallbacks.gnssMeasurementsCb = nullptr;
+
+ locAPISetCallbacks(locationCallbacks);
+}
+
+// for GpsInterface
+void GnssAPIClient::gnssUpdateCallbacks(const sp<V1_0::IGnssCallback>& gpsCb,
+ const sp<IGnssNiCallback>& niCb)
+{
+ LOC_LOGD("%s]: (%p %p)", __FUNCTION__, &gpsCb, &niCb);
+
+ mMutex.lock();
+ mGnssCbIface = gpsCb;
+ mGnssNiCbIface = niCb;
+ mMutex.unlock();
+
+ if (mGnssCbIface != nullptr || mGnssNiCbIface != nullptr) {
+ setCallbacks();
+ }
+}
+
+void GnssAPIClient::gnssUpdateCallbacks_2_0(const sp<V2_0::IGnssCallback>& gpsCb)
+{
+ LOC_LOGD("%s]: (%p)", __FUNCTION__, &gpsCb);
+
+ mMutex.lock();
+ mGnssCbIface_2_0 = gpsCb;
+ mMutex.unlock();
+
+ if (mGnssCbIface_2_0 != nullptr) {
+ setCallbacks();
+ }
+}
+
+void GnssAPIClient::gnssUpdateCallbacks_2_1(const sp<V2_1::IGnssCallback>& gpsCb)
+{
+ LOC_LOGD("%s]: (%p)", __FUNCTION__, &gpsCb);
+
+ mMutex.lock();
+ mGnssCbIface_2_1 = gpsCb;
+ mMutex.unlock();
+
+ if (mGnssCbIface_2_1 != nullptr) {
+ setCallbacks();
+ }
+}
+
+bool GnssAPIClient::gnssStart()
+{
+ LOC_LOGD("%s]: ()", __FUNCTION__);
+
+ mMutex.lock();
+ mTracking = true;
+ mMutex.unlock();
+
+ bool retVal = true;
+ locAPIStartTracking(mTrackingOptions);
+ return retVal;
+}
+
+bool GnssAPIClient::gnssStop()
+{
+ LOC_LOGD("%s]: ()", __FUNCTION__);
+
+ mMutex.lock();
+ mTracking = false;
+ mMutex.unlock();
+
+ 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;
+ }
+ 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 |
+ GNSS_AIDING_DATA_SV_TYPE_NAVIC_BIT;
+ data.posEngineMask = STANDARD_POSITIONING_ENGINE;
+
+ 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]: (%" PRIu64 ")", __FUNCTION__, capabilitiesMask);
+ mLocationCapabilitiesMask = capabilitiesMask;
+ mLocationCapabilitiesCached = true;
+
+ mMutex.lock();
+ auto gnssCbIface(mGnssCbIface);
+ auto gnssCbIface_2_0(mGnssCbIface_2_0);
+ auto gnssCbIface_2_1(mGnssCbIface_2_1);
+ mMutex.unlock();
+
+ if (gnssCbIface_2_1 != nullptr ||gnssCbIface_2_0 != nullptr || gnssCbIface != nullptr) {
+
+ uint32_t antennaInfoVectorSize = 0;
+ uint32_t data = 0;
+ loc_param_s_type ant_info_vector_table[] =
+ {
+ { "ANTENNA_INFO_VECTOR_SIZE", &antennaInfoVectorSize, NULL, 'n' }
+ };
+ UTIL_READ_CONF(LOC_PATH_ANT_CORR, ant_info_vector_table);
+
+ if (0 != antennaInfoVectorSize) {
+ data |= V2_1::IGnssCallback::Capabilities::ANTENNA_INFO;
+ }
+
+ 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 |= V1_0::IGnssCallback::Capabilities::GEOFENCING;
+ if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT)
+ data |= V1_0::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;
+ if (capabilitiesMask & LOCATION_CAPABILITIES_AGPM_BIT)
+ data |= IGnssCallback::Capabilities::LOW_POWER_MODE;
+ if (capabilitiesMask & LOCATION_CAPABILITIES_CONSTELLATION_ENABLEMENT_BIT)
+ data |= IGnssCallback::Capabilities::SATELLITE_BLACKLIST;
+ if (capabilitiesMask & LOCATION_CAPABILITIES_MEASUREMENTS_CORRECTION_BIT)
+ data |= V2_0::IGnssCallback::Capabilities::MEASUREMENT_CORRECTIONS;
+
+ IGnssCallback::GnssSystemInfo gnssInfo = { .yearOfHw = 2015 };
+
+ if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT) {
+ gnssInfo.yearOfHw++; // 2016
+ if (capabilitiesMask & LOCATION_CAPABILITIES_DEBUG_NMEA_BIT) {
+ gnssInfo.yearOfHw++; // 2017
+ if (capabilitiesMask & LOCATION_CAPABILITIES_CONSTELLATION_ENABLEMENT_BIT ||
+ capabilitiesMask & LOCATION_CAPABILITIES_AGPM_BIT) {
+ gnssInfo.yearOfHw++; // 2018
+ if (capabilitiesMask & LOCATION_CAPABILITIES_PRIVACY_BIT) {
+ gnssInfo.yearOfHw++; // 2019
+ if (capabilitiesMask & LOCATION_CAPABILITIES_MEASUREMENTS_CORRECTION_BIT) {
+ gnssInfo.yearOfHw++; // 2020
+ }
+ }
+ }
+ }
+ }
+ LOC_LOGV("%s:%d] set_system_info_cb (%d)", __FUNCTION__, __LINE__, gnssInfo.yearOfHw);
+
+ if (gnssCbIface_2_1 != nullptr) {
+ auto r = gnssCbIface_2_1->gnssSetCapabilitiesCb_2_1(data);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssSetCapabilitiesCb_2_1 description=%s",
+ __func__, r.description().c_str());
+ }
+ r = gnssCbIface_2_1->gnssSetSystemInfoCb(gnssInfo);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssSetSystemInfoCb description=%s",
+ __func__, r.description().c_str());
+ }
+ } else if (gnssCbIface_2_0 != nullptr) {
+ auto r = gnssCbIface_2_0->gnssSetCapabilitiesCb_2_0(data);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssSetCapabilitiesCb_2_0 description=%s",
+ __func__, r.description().c_str());
+ }
+ r = gnssCbIface_2_0->gnssSetSystemInfoCb(gnssInfo);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssSetSystemInfoCb description=%s",
+ __func__, r.description().c_str());
+ }
+ } else if (gnssCbIface != nullptr) {
+ auto r = gnssCbIface->gnssSetCapabilitesCb(data);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssSetCapabilitesCb description=%s",
+ __func__, r.description().c_str());
+ }
+ 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)
+{
+ mMutex.lock();
+ auto gnssCbIface(mGnssCbIface);
+ auto gnssCbIface_2_0(mGnssCbIface_2_0);
+ auto gnssCbIface_2_1(mGnssCbIface_2_1);
+ bool isTracking = mTracking;
+ mMutex.unlock();
+
+ LOC_LOGD("%s]: (flags: %02x isTracking: %d)", __FUNCTION__, location.flags, isTracking);
+
+ if (!isTracking) {
+ return;
+ }
+
+ if (gnssCbIface_2_1 != nullptr) {
+ V2_0::GnssLocation gnssLocation;
+ convertGnssLocation(location, gnssLocation);
+ auto r = gnssCbIface_2_1->gnssLocationCb_2_0(gnssLocation);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssLocationCb_2_0 description=%s",
+ __func__, r.description().c_str());
+ }
+ } else if (gnssCbIface_2_0 != nullptr) {
+ V2_0::GnssLocation gnssLocation;
+ convertGnssLocation(location, gnssLocation);
+ auto r = gnssCbIface_2_0->gnssLocationCb_2_0(gnssLocation);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssLocationCb_2_0 description=%s",
+ __func__, r.description().c_str());
+ }
+ } else if (gnssCbIface != nullptr) {
+ V1_0::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());
+ }
+ } else {
+ LOC_LOGW("%s] No GNSS Interface ready for gnssLocationCb ", __FUNCTION__);
+ }
+
+}
+
+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: %u)", __FUNCTION__, gnssSvNotification.count);
+ mMutex.lock();
+ auto gnssCbIface(mGnssCbIface);
+ auto gnssCbIface_2_0(mGnssCbIface_2_0);
+ auto gnssCbIface_2_1(mGnssCbIface_2_1);
+ mMutex.unlock();
+
+ if (gnssCbIface_2_1 != nullptr) {
+ hidl_vec<V2_1::IGnssCallback::GnssSvInfo> svInfoList;
+ convertGnssSvStatus(gnssSvNotification, svInfoList);
+ auto r = gnssCbIface_2_1->gnssSvStatusCb_2_1(svInfoList);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssSvStatusCb_2_1 description=%s",
+ __func__, r.description().c_str());
+ }
+ } else if (gnssCbIface_2_0 != nullptr) {
+ hidl_vec<V2_0::IGnssCallback::GnssSvInfo> svInfoList;
+ convertGnssSvStatus(gnssSvNotification, svInfoList);
+ auto r = gnssCbIface_2_0->gnssSvStatusCb_2_0(svInfoList);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssSvStatusCb_2_0 description=%s",
+ __func__, r.description().c_str());
+ }
+ } else if (gnssCbIface != nullptr) {
+ V1_0::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);
+ auto gnssCbIface_2_0(mGnssCbIface_2_0);
+ auto gnssCbIface_2_1(mGnssCbIface_2_1);
+ mMutex.unlock();
+
+ if (gnssCbIface != nullptr || gnssCbIface_2_0 != nullptr || gnssCbIface_2_1 != 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());
+ if (gnssCbIface_2_1 != nullptr) {
+ auto r = gnssCbIface_2_1->gnssNmeaCb(
+ static_cast<V1_0::GnssUtcTime>(gnssNmeaNotification.timestamp), nmeaString);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssCbIface_2_1 nmea=%s length=%u description=%s",
+ __func__, gnssNmeaNotification.nmea, gnssNmeaNotification.length,
+ r.description().c_str());
+ }
+ } else if (gnssCbIface_2_0 != nullptr) {
+ auto r = gnssCbIface_2_0->gnssNmeaCb(
+ static_cast<V1_0::GnssUtcTime>(gnssNmeaNotification.timestamp), nmeaString);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssCbIface_2_0 nmea=%s length=%u description=%s",
+ __func__, gnssNmeaNotification.nmea, gnssNmeaNotification.length,
+ r.description().c_str());
+ }
+ } else if (gnssCbIface != nullptr) {
+ auto r = gnssCbIface->gnssNmeaCb(
+ static_cast<V1_0::GnssUtcTime>(gnssNmeaNotification.timestamp), nmeaString);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssNmeaCb nmea=%s length=%u 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);
+ auto gnssCbIface_2_0(mGnssCbIface_2_0);
+ auto gnssCbIface_2_1(mGnssCbIface_2_1);
+ mMutex.unlock();
+
+ if (error == LOCATION_ERROR_SUCCESS) {
+ if (gnssCbIface_2_1 != nullptr) {
+ auto r = gnssCbIface_2_1->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_ON);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssStatusCb 2_0 ENGINE_ON description=%s",
+ __func__, r.description().c_str());
+ }
+ r = gnssCbIface_2_1->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_BEGIN);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssStatusCb 2_0 SESSION_BEGIN description=%s",
+ __func__, r.description().c_str());
+ }
+ } else if (gnssCbIface_2_0 != nullptr) {
+ auto r = gnssCbIface_2_0->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_ON);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssStatusCb 2_0 ENGINE_ON description=%s",
+ __func__, r.description().c_str());
+ }
+ r = gnssCbIface_2_0->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_BEGIN);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssStatusCb 2_0 SESSION_BEGIN description=%s",
+ __func__, r.description().c_str());
+ }
+ } else if (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);
+ auto gnssCbIface_2_0(mGnssCbIface_2_0);
+ auto gnssCbIface_2_1(mGnssCbIface_2_1);
+ mMutex.unlock();
+
+ if (error == LOCATION_ERROR_SUCCESS) {
+ if (gnssCbIface_2_1 != nullptr) {
+ auto r = gnssCbIface_2_1->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_END);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssStatusCb 2_0 SESSION_END description=%s",
+ __func__, r.description().c_str());
+ }
+ r = gnssCbIface_2_1->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_OFF);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssStatusCb 2_0 ENGINE_OFF description=%s",
+ __func__, r.description().c_str());
+ }
+ } else if (gnssCbIface_2_0 != nullptr) {
+ auto r = gnssCbIface_2_0->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_END);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssStatusCb 2_0 SESSION_END description=%s",
+ __func__, r.description().c_str());
+ }
+ r = gnssCbIface_2_0->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_OFF);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssStatusCb 2_0 ENGINE_OFF description=%s",
+ __func__, r.description().c_str());
+ }
+
+ } else if (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, V1_0::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++) {
+ convertGnssSvid(in.gnssSvs[i], out.gnssSvList[i].svid);
+ convertGnssConstellationType(in.gnssSvs[i].type, out.gnssSvList[i].constellation);
+ out.gnssSvList[i].cN0Dbhz = in.gnssSvs[i].cN0Dbhz;
+ out.gnssSvList[i].elevationDegrees = in.gnssSvs[i].elevation;
+ out.gnssSvList[i].azimuthDegrees = in.gnssSvs[i].azimuth;
+ out.gnssSvList[i].carrierFrequencyHz = in.gnssSvs[i].carrierFrequencyHz;
+ out.gnssSvList[i].svFlag = static_cast<uint8_t>(IGnssCallback::GnssSvFlags::NONE);
+ if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_EPHEMER_BIT)
+ out.gnssSvList[i].svFlag |= IGnssCallback::GnssSvFlags::HAS_EPHEMERIS_DATA;
+ if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_ALMANAC_BIT)
+ out.gnssSvList[i].svFlag |= IGnssCallback::GnssSvFlags::HAS_ALMANAC_DATA;
+ if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_USED_IN_FIX_BIT)
+ out.gnssSvList[i].svFlag |= IGnssCallback::GnssSvFlags::USED_IN_FIX;
+ if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_CARRIER_FREQUENCY_BIT)
+ out.gnssSvList[i].svFlag |= IGnssCallback::GnssSvFlags::HAS_CARRIER_FREQUENCY;
+ }
+}
+
+static void convertGnssSvStatus(GnssSvNotification& in,
+ hidl_vec<V2_0::IGnssCallback::GnssSvInfo>& out)
+{
+ out.resize(in.count);
+ for (size_t i = 0; i < in.count; i++) {
+ convertGnssSvid(in.gnssSvs[i], out[i].v1_0.svid);
+ out[i].v1_0.cN0Dbhz = in.gnssSvs[i].cN0Dbhz;
+ out[i].v1_0.elevationDegrees = in.gnssSvs[i].elevation;
+ out[i].v1_0.azimuthDegrees = in.gnssSvs[i].azimuth;
+ out[i].v1_0.carrierFrequencyHz = in.gnssSvs[i].carrierFrequencyHz;
+ out[i].v1_0.svFlag = static_cast<uint8_t>(IGnssCallback::GnssSvFlags::NONE);
+ if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_EPHEMER_BIT)
+ out[i].v1_0.svFlag |= IGnssCallback::GnssSvFlags::HAS_EPHEMERIS_DATA;
+ if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_ALMANAC_BIT)
+ out[i].v1_0.svFlag |= IGnssCallback::GnssSvFlags::HAS_ALMANAC_DATA;
+ if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_USED_IN_FIX_BIT)
+ out[i].v1_0.svFlag |= IGnssCallback::GnssSvFlags::USED_IN_FIX;
+ if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_CARRIER_FREQUENCY_BIT)
+ out[i].v1_0.svFlag |= IGnssCallback::GnssSvFlags::HAS_CARRIER_FREQUENCY;
+
+ convertGnssConstellationType(in.gnssSvs[i].type, out[i].constellation);
+ }
+}
+
+static void convertGnssSvStatus(GnssSvNotification& in,
+ hidl_vec<V2_1::IGnssCallback::GnssSvInfo>& out)
+{
+ out.resize(in.count);
+ for (size_t i = 0; i < in.count; i++) {
+ convertGnssSvid(in.gnssSvs[i], out[i].v2_0.v1_0.svid);
+ out[i].v2_0.v1_0.cN0Dbhz = in.gnssSvs[i].cN0Dbhz;
+ out[i].v2_0.v1_0.elevationDegrees = in.gnssSvs[i].elevation;
+ out[i].v2_0.v1_0.azimuthDegrees = in.gnssSvs[i].azimuth;
+ out[i].v2_0.v1_0.carrierFrequencyHz = in.gnssSvs[i].carrierFrequencyHz;
+ out[i].v2_0.v1_0.svFlag = static_cast<uint8_t>(IGnssCallback::GnssSvFlags::NONE);
+ if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_EPHEMER_BIT)
+ out[i].v2_0.v1_0.svFlag |= IGnssCallback::GnssSvFlags::HAS_EPHEMERIS_DATA;
+ if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_ALMANAC_BIT)
+ out[i].v2_0.v1_0.svFlag |= IGnssCallback::GnssSvFlags::HAS_ALMANAC_DATA;
+ if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_USED_IN_FIX_BIT)
+ out[i].v2_0.v1_0.svFlag |= IGnssCallback::GnssSvFlags::USED_IN_FIX;
+ if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_CARRIER_FREQUENCY_BIT)
+ out[i].v2_0.v1_0.svFlag |= IGnssCallback::GnssSvFlags::HAS_CARRIER_FREQUENCY;
+
+ convertGnssConstellationType(in.gnssSvs[i].type, out[i].v2_0.constellation);
+ out[i].basebandCN0DbHz = in.gnssSvs[i].basebandCarrierToNoiseDbHz;
+ }
+}
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/android/2.1/location_api/GnssAPIClient.h b/android/2.1/location_api/GnssAPIClient.h
new file mode 100755
index 0000000..c4dbe9a
--- /dev/null
+++ b/android/2.1/location_api/GnssAPIClient.h
@@ -0,0 +1,118 @@
+/* Copyright (c) 2017-2020, 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.1/IGnss.h>
+#include <android/hardware/gnss/2.1/IGnssCallback.h>
+#include <LocationAPIClientBase.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_1 {
+namespace implementation {
+
+using ::android::sp;
+
+class GnssAPIClient : public LocationAPIClientBase
+{
+public:
+ GnssAPIClient(const sp<V1_0::IGnssCallback>& gpsCb,
+ const sp<V1_0::IGnssNiCallback>& niCb);
+ GnssAPIClient(const sp<V2_0::IGnssCallback>& gpsCb);
+ GnssAPIClient(const sp<V2_1::IGnssCallback>& gpsCb);
+ 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);
+ void gnssUpdateCallbacks_2_0(const sp<V2_0::IGnssCallback>& gpsCb);
+ void gnssUpdateCallbacks_2_1(const sp<V2_1::IGnssCallback>& gpsCb);
+ 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:
+ virtual ~GnssAPIClient();
+ void setCallbacks();
+ void initLocationOptions();
+
+ sp<V1_0::IGnssCallback> mGnssCbIface;
+ sp<V1_0::IGnssNiCallback> mGnssNiCbIface;
+ std::mutex mMutex;
+ LocationAPIControlClient* mControlClient;
+ LocationCapabilitiesMask mLocationCapabilitiesMask;
+ bool mLocationCapabilitiesCached;
+ TrackingOptions mTrackingOptions;
+ bool mTracking;
+ sp<V2_0::IGnssCallback> mGnssCbIface_2_0;
+ sp<V2_1::IGnssCallback> mGnssCbIface_2_1;
+};
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+#endif // GNSS_API_CLINET_H
diff --git a/android/2.1/location_api/LocationUtil.cpp b/android/2.1/location_api/LocationUtil.cpp
new file mode 100644
index 0000000..5154e70
--- /dev/null
+++ b/android/2.1/location_api/LocationUtil.cpp
@@ -0,0 +1,405 @@
+/* Copyright (c) 2017-2020, 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>
+#include <log_util.h>
+#include <inttypes.h>
+#include <loc_misc_utils.h>
+#include <gps_extended_c.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_1 {
+namespace implementation {
+
+using ::android::hardware::gnss::V2_0::GnssLocation;
+using ::android::hardware::gnss::V2_0::ElapsedRealtimeFlags;
+using ::android::hardware::gnss::V2_0::GnssConstellationType;
+using ::android::hardware::gnss::V1_0::GnssLocationFlags;
+using ::android::hardware::gnss::measurement_corrections::V1_0::GnssSingleSatCorrectionFlags;
+
+void convertGnssLocation(Location& in, V1_0::GnssLocation& out)
+{
+ memset(&out, 0, sizeof(V1_0::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(Location& in, V2_0::GnssLocation& out)
+{
+ memset(&out, 0, sizeof(V2_0::GnssLocation));
+ convertGnssLocation(in, out.v1_0);
+
+ if (in.flags & LOCATION_HAS_ELAPSED_REAL_TIME) {
+ out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIMESTAMP_NS;
+ out.elapsedRealtime.timestampNs = in.elapsedRealTime;
+ out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS;
+ out.elapsedRealtime.timeUncertaintyNs = in.elapsedRealTimeUnc;
+ LOC_LOGd("out.elapsedRealtime.timestampNs=%" PRIi64 ""
+ " out.elapsedRealtime.timeUncertaintyNs=%" PRIi64 ""
+ " out.elapsedRealtime.flags=0x%X",
+ out.elapsedRealtime.timestampNs,
+ out.elapsedRealtime.timeUncertaintyNs, out.elapsedRealtime.flags);
+ }
+}
+
+void convertGnssLocation(const V1_0::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 convertGnssLocation(const V2_0::GnssLocation& in, Location& out)
+{
+ memset(&out, 0, sizeof(out));
+ convertGnssLocation(in.v1_0, out);
+}
+
+void convertGnssConstellationType(GnssSvType& in, V1_0::GnssConstellationType& out)
+{
+ switch(in) {
+ case GNSS_SV_TYPE_GPS:
+ out = V1_0::GnssConstellationType::GPS;
+ break;
+ case GNSS_SV_TYPE_SBAS:
+ out = V1_0::GnssConstellationType::SBAS;
+ break;
+ case GNSS_SV_TYPE_GLONASS:
+ out = V1_0::GnssConstellationType::GLONASS;
+ break;
+ case GNSS_SV_TYPE_QZSS:
+ out = V1_0::GnssConstellationType::QZSS;
+ break;
+ case GNSS_SV_TYPE_BEIDOU:
+ out = V1_0::GnssConstellationType::BEIDOU;
+ break;
+ case GNSS_SV_TYPE_GALILEO:
+ out = V1_0::GnssConstellationType::GALILEO;
+ break;
+ case GNSS_SV_TYPE_UNKNOWN:
+ default:
+ out = V1_0::GnssConstellationType::UNKNOWN;
+ break;
+ }
+}
+
+void convertGnssConstellationType(GnssSvType& in, V2_0::GnssConstellationType& out)
+{
+ switch(in) {
+ case GNSS_SV_TYPE_GPS:
+ out = V2_0::GnssConstellationType::GPS;
+ break;
+ case GNSS_SV_TYPE_SBAS:
+ out = V2_0::GnssConstellationType::SBAS;
+ break;
+ case GNSS_SV_TYPE_GLONASS:
+ out = V2_0::GnssConstellationType::GLONASS;
+ break;
+ case GNSS_SV_TYPE_QZSS:
+ out = V2_0::GnssConstellationType::QZSS;
+ break;
+ case GNSS_SV_TYPE_BEIDOU:
+ out = V2_0::GnssConstellationType::BEIDOU;
+ break;
+ case GNSS_SV_TYPE_GALILEO:
+ out = V2_0::GnssConstellationType::GALILEO;
+ break;
+ case GNSS_SV_TYPE_NAVIC:
+ out = V2_0::GnssConstellationType::IRNSS;
+ break;
+ case GNSS_SV_TYPE_UNKNOWN:
+ default:
+ out = V2_0::GnssConstellationType::UNKNOWN;
+ break;
+ }
+}
+
+void convertGnssSvid(GnssSv& in, int16_t& out)
+{
+ switch (in.type) {
+ case GNSS_SV_TYPE_GPS:
+ out = in.svId;
+ break;
+ case GNSS_SV_TYPE_SBAS:
+ out = in.svId;
+ break;
+ case GNSS_SV_TYPE_GLONASS:
+ if (!isGloSlotUnknown(in.svId)) { // OSN is known
+ out = in.svId - GLO_SV_PRN_MIN + 1;
+ } else { // OSN is not known, report FCN
+ out = in.gloFrequency + 92;
+ }
+ break;
+ case GNSS_SV_TYPE_QZSS:
+ out = in.svId;
+ break;
+ case GNSS_SV_TYPE_BEIDOU:
+ out = in.svId - BDS_SV_PRN_MIN + 1;
+ break;
+ case GNSS_SV_TYPE_GALILEO:
+ out = in.svId - GAL_SV_PRN_MIN + 1;
+ break;
+ case GNSS_SV_TYPE_NAVIC:
+ out = in.svId - NAVIC_SV_PRN_MIN + 1;
+ break;
+ default:
+ out = in.svId;
+ break;
+ }
+}
+
+void convertGnssSvid(GnssMeasurementsData& in, int16_t& out)
+{
+ switch (in.svType) {
+ case GNSS_SV_TYPE_GPS:
+ out = in.svId;
+ break;
+ case GNSS_SV_TYPE_SBAS:
+ out = in.svId;
+ break;
+ case GNSS_SV_TYPE_GLONASS:
+ if (!isGloSlotUnknown(in.svId)) { // OSN is known
+ out = in.svId - GLO_SV_PRN_MIN + 1;
+ } else { // OSN is not known, report FCN
+ out = in.gloFrequency + 92;
+ }
+ break;
+ case GNSS_SV_TYPE_QZSS:
+ out = in.svId;
+ break;
+ case GNSS_SV_TYPE_BEIDOU:
+ out = in.svId - BDS_SV_PRN_MIN + 1;
+ break;
+ case GNSS_SV_TYPE_GALILEO:
+ out = in.svId - GAL_SV_PRN_MIN + 1;
+ break;
+ case GNSS_SV_TYPE_NAVIC:
+ out = in.svId - NAVIC_SV_PRN_MIN + 1;
+ break;
+ default:
+ out = in.svId;
+ 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;
+ }
+}
+
+void convertSingleSatCorrections(const SingleSatCorrection& in, GnssSingleSatCorrection& out)
+{
+ out.flags = GNSS_MEAS_CORR_UNKNOWN_BIT;
+ if (in.singleSatCorrectionFlags & (GnssSingleSatCorrectionFlags::HAS_SAT_IS_LOS_PROBABILITY)) {
+ out.flags |= GNSS_MEAS_CORR_HAS_SAT_IS_LOS_PROBABILITY_BIT;
+ }
+ if (in.singleSatCorrectionFlags & (GnssSingleSatCorrectionFlags::HAS_EXCESS_PATH_LENGTH)) {
+ out.flags |= GNSS_MEAS_CORR_HAS_EXCESS_PATH_LENGTH_BIT;
+ }
+ if (in.singleSatCorrectionFlags & (GnssSingleSatCorrectionFlags::HAS_EXCESS_PATH_LENGTH_UNC)) {
+ out.flags |= GNSS_MEAS_CORR_HAS_EXCESS_PATH_LENGTH_UNC_BIT;
+ }
+ if (in.singleSatCorrectionFlags & (GnssSingleSatCorrectionFlags::HAS_REFLECTING_PLANE)) {
+ out.flags |= GNSS_MEAS_CORR_HAS_REFLECTING_PLANE_BIT;
+ }
+ switch (in.constellation) {
+ case (::android::hardware::gnss::V1_0::GnssConstellationType::GPS):
+ out.svType = GNSS_SV_TYPE_GPS;
+ break;
+ case (::android::hardware::gnss::V1_0::GnssConstellationType::SBAS):
+ out.svType = GNSS_SV_TYPE_SBAS;
+ break;
+ case (::android::hardware::gnss::V1_0::GnssConstellationType::GLONASS):
+ out.svType = GNSS_SV_TYPE_GLONASS;
+ break;
+ case (::android::hardware::gnss::V1_0::GnssConstellationType::QZSS):
+ out.svType = GNSS_SV_TYPE_QZSS;
+ break;
+ case (::android::hardware::gnss::V1_0::GnssConstellationType::BEIDOU):
+ out.svType = GNSS_SV_TYPE_BEIDOU;
+ break;
+ case (::android::hardware::gnss::V1_0::GnssConstellationType::GALILEO):
+ out.svType = GNSS_SV_TYPE_GALILEO;
+ break;
+ case (::android::hardware::gnss::V1_0::GnssConstellationType::UNKNOWN):
+ default:
+ out.svType = GNSS_SV_TYPE_UNKNOWN;
+ break;
+ }
+ out.svId = in.svid;
+ out.carrierFrequencyHz = in.carrierFrequencyHz;
+ out.probSatIsLos = in.probSatIsLos;
+ out.excessPathLengthMeters = in.excessPathLengthMeters;
+ out.excessPathLengthUncertaintyMeters = in.excessPathLengthUncertaintyMeters;
+
+ out.reflectingPlane.latitudeDegrees = in.reflectingPlane.latitudeDegrees;
+ out.reflectingPlane.longitudeDegrees = in.reflectingPlane.longitudeDegrees;
+ out.reflectingPlane.altitudeMeters = in.reflectingPlane.altitudeMeters;
+ out.reflectingPlane.azimuthDegrees = in.reflectingPlane.azimuthDegrees;
+}
+
+void convertMeasurementCorrections(const MeasurementCorrectionsV1_0& in,
+ GnssMeasurementCorrections& out)
+{
+ memset(&out, 0, sizeof(GnssMeasurementCorrections));
+ out.latitudeDegrees = in.latitudeDegrees;
+ out.longitudeDegrees = in.longitudeDegrees;
+ out.altitudeMeters = in.altitudeMeters;
+ out.horizontalPositionUncertaintyMeters = in.horizontalPositionUncertaintyMeters;
+ out.verticalPositionUncertaintyMeters = in.verticalPositionUncertaintyMeters;
+ out.toaGpsNanosecondsOfWeek = in.toaGpsNanosecondsOfWeek;
+
+ for (int i = 0; i < in.satCorrections.size(); i++) {
+ GnssSingleSatCorrection gnssSingleSatCorrection = {};
+
+ convertSingleSatCorrections(in.satCorrections[i], gnssSingleSatCorrection);
+ out.satCorrections.push_back(gnssSingleSatCorrection);
+ }
+}
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/android/2.1/location_api/LocationUtil.h b/android/2.1/location_api/LocationUtil.h
new file mode 100644
index 0000000..2d95a2d
--- /dev/null
+++ b/android/2.1/location_api/LocationUtil.h
@@ -0,0 +1,68 @@
+/* Copyright (c) 2017-2020, 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/2.0/types.h>
+#include <android/hardware/gnss/measurement_corrections/1.0/IMeasurementCorrections.h>
+#include <LocationAPI.h>
+#include <GnssDebug.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_1 {
+namespace implementation {
+
+using MeasurementCorrectionsV1_0 =
+ ::android::hardware::gnss::measurement_corrections::V1_0::MeasurementCorrections;
+using ::android::hardware::gnss::measurement_corrections::V1_0::SingleSatCorrection;
+
+void convertGnssLocation(Location& in, V1_0::GnssLocation& out);
+void convertGnssLocation(Location& in, V2_0::GnssLocation& out);
+void convertGnssLocation(const V1_0::GnssLocation& in, Location& out);
+void convertGnssLocation(const V2_0::GnssLocation& in, Location& out);
+void convertGnssConstellationType(GnssSvType& in, V1_0::GnssConstellationType& out);
+void convertGnssConstellationType(GnssSvType& in, V2_0::GnssConstellationType& out);
+void convertGnssSvid(GnssSv& in, int16_t& out);
+void convertGnssSvid(GnssMeasurementsData& in, int16_t& out);
+void convertGnssEphemerisType(GnssEphemerisType& in, GnssDebug::SatelliteEphemerisType& out);
+void convertGnssEphemerisSource(GnssEphemerisSource& in, GnssDebug::SatelliteEphemerisSource& out);
+void convertGnssEphemerisHealth(GnssEphemerisHealth& in, GnssDebug::SatelliteEphemerisHealth& out);
+void convertSingleSatCorrections(const SingleSatCorrection& in, GnssSingleSatCorrection& out);
+void convertMeasurementCorrections(const MeasurementCorrectionsV1_0& in,
+ GnssMeasurementCorrections& out);
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+#endif // LOCATION_UTIL_H
diff --git a/android/2.1/location_api/MeasurementAPIClient.cpp b/android/2.1/location_api/MeasurementAPIClient.cpp
new file mode 100644
index 0000000..0028074
--- /dev/null
+++ b/android/2.1/location_api/MeasurementAPIClient.cpp
@@ -0,0 +1,642 @@
+/* Copyright (c) 2017-2020, 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 <inttypes.h>
+
+#include "LocationUtil.h"
+#include "MeasurementAPIClient.h"
+#include <loc_misc_utils.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_1 {
+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 convertGnssData_2_1(GnssMeasurementsNotification& in,
+ V2_1::IGnssMeasurementCallback::GnssData& out);
+static void convertGnssMeasurement(GnssMeasurementsData& in,
+ V1_0::IGnssMeasurementCallback::GnssMeasurement& out);
+static void convertGnssClock(GnssMeasurementsClock& in, IGnssMeasurementCallback::GnssClock& out);
+static void convertGnssClock_2_1(GnssMeasurementsClock& in,
+ V2_1::IGnssMeasurementCallback::GnssClock& out);
+static void convertGnssMeasurementsCodeType(GnssMeasurementsCodeType& inCodeType,
+ char* inOtherCodeTypeName,
+ ::android::hardware::hidl_string& out);
+static void convertGnssMeasurementsAccumulatedDeltaRangeState(GnssMeasurementsAdrStateMask& in,
+ ::android::hardware::hidl_bitfield
+ <V1_1::IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState>& out);
+static void convertGnssMeasurementsState(GnssMeasurementsStateMask& in,
+ ::android::hardware::hidl_bitfield
+ <V2_0::IGnssMeasurementCallback::GnssMeasurementState>& out);
+static void convertElapsedRealtimeNanos(GnssMeasurementsNotification& in,
+ ::android::hardware::gnss::V2_0::ElapsedRealtime& elapsedRealtimeNanos);
+
+MeasurementAPIClient::MeasurementAPIClient() :
+ mGnssMeasurementCbIface(nullptr),
+ mGnssMeasurementCbIface_1_1(nullptr),
+ mGnssMeasurementCbIface_2_0(nullptr),
+ mGnssMeasurementCbIface_2_1(nullptr),
+ mTracking(false)
+{
+ LOC_LOGD("%s]: ()", __FUNCTION__);
+}
+
+MeasurementAPIClient::~MeasurementAPIClient()
+{
+ LOC_LOGD("%s]: ()", __FUNCTION__);
+}
+
+void MeasurementAPIClient::clearInterfaces()
+{
+ mGnssMeasurementCbIface = nullptr;
+ mGnssMeasurementCbIface_1_1 = nullptr;
+ mGnssMeasurementCbIface_2_0 = nullptr;
+ mGnssMeasurementCbIface_2_1 = nullptr;
+}
+
+// for GpsInterface
+Return<IGnssMeasurement::GnssMeasurementStatus>
+MeasurementAPIClient::measurementSetCallback(const sp<V1_0::IGnssMeasurementCallback>& callback)
+{
+ LOC_LOGD("%s]: (%p)", __FUNCTION__, &callback);
+
+ mMutex.lock();
+ clearInterfaces();
+ 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();
+ clearInterfaces();
+ 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();
+ clearInterfaces();
+ mGnssMeasurementCbIface_2_0 = callback;
+ mMutex.unlock();
+
+ return startTracking(powerMode, timeBetweenMeasurement);
+}
+
+Return<IGnssMeasurement::GnssMeasurementStatus> MeasurementAPIClient::measurementSetCallback_2_1(
+ const sp<V2_1::IGnssMeasurementCallback>& callback,
+ GnssPowerMode powerMode, uint32_t timeBetweenMeasurement) {
+ LOC_LOGD("%s]: (%p) (powermode: %d) (tbm: %d)",
+ __FUNCTION__, &callback, (int)powerMode, timeBetweenMeasurement);
+
+ mMutex.lock();
+ clearInterfaces();
+ mGnssMeasurementCbIface_2_1 = 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_1 != nullptr ||
+ 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: %u 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;
+ sp<V2_1::IGnssMeasurementCallback> gnssMeasurementCbIface_2_1 = nullptr;
+ if (mGnssMeasurementCbIface_2_1 != nullptr) {
+ gnssMeasurementCbIface_2_1 = mGnssMeasurementCbIface_2_1;
+ } else 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_1 != nullptr) {
+ V2_1::IGnssMeasurementCallback::GnssData gnssData;
+ convertGnssData_2_1(gnssMeasurementsNotification, gnssData);
+ auto r = gnssMeasurementCbIface_2_1->gnssMeasurementCb_2_1(gnssData);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssMeasurementCb description=%s",
+ __func__, r.description().c_str());
+ }
+ } else 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(out));
+ 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;
+ convertGnssSvid(in, out.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(out));
+ 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 convertGnssClock_2_1(GnssMeasurementsClock& in,
+ V2_1::IGnssMeasurementCallback::GnssClock& out)
+{
+ memset(&out, 0, sizeof(out));
+ convertGnssClock(in, out.v1_0);
+ convertGnssConstellationType(in.referenceSignalTypeForIsb.svType,
+ out.referenceSignalTypeForIsb.constellation);
+ out.referenceSignalTypeForIsb.carrierFrequencyHz =
+ in.referenceSignalTypeForIsb.carrierFrequencyHz;
+ convertGnssMeasurementsCodeType(in.referenceSignalTypeForIsb.codeType,
+ in.referenceSignalTypeForIsb.otherCodeTypeName,
+ out.referenceSignalTypeForIsb.codeType);
+}
+
+static void convertGnssData(GnssMeasurementsNotification& in,
+ V1_0::IGnssMeasurementCallback::GnssData& out)
+{
+ memset(&out, 0, sizeof(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)
+{
+ memset(&out, 0, sizeof(out));
+ out.measurements.resize(in.count);
+ for (size_t i = 0; i < in.count; i++) {
+ convertGnssMeasurement(in.measurements[i], out.measurements[i].v1_0);
+ convertGnssMeasurementsAccumulatedDeltaRangeState(in.measurements[i].adrStateMask,
+ out.measurements[i].accumulatedDeltaRangeState);
+ }
+ convertGnssClock(in.clock, out.clock);
+}
+
+static void convertGnssData_2_0(GnssMeasurementsNotification& in,
+ V2_0::IGnssMeasurementCallback::GnssData& out)
+{
+ memset(&out, 0, sizeof(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);
+ convertGnssConstellationType(in.measurements[i].svType, out.measurements[i].constellation);
+ convertGnssMeasurementsCodeType(in.measurements[i].codeType,
+ in.measurements[i].otherCodeTypeName,
+ out.measurements[i].codeType);
+ convertGnssMeasurementsAccumulatedDeltaRangeState(in.measurements[i].adrStateMask,
+ out.measurements[i].v1_1.accumulatedDeltaRangeState);
+ convertGnssMeasurementsState(in.measurements[i].stateMask, out.measurements[i].state);
+ }
+ convertGnssClock(in.clock, out.clock);
+ convertElapsedRealtimeNanos(in, out.elapsedRealtime);
+}
+
+static void convertGnssMeasurementsCodeType(GnssMeasurementsCodeType& inCodeType,
+ char* inOtherCodeTypeName, ::android::hardware::hidl_string& out)
+{
+ memset(&out, 0, sizeof(out));
+ switch(inCodeType) {
+ case GNSS_MEASUREMENTS_CODE_TYPE_A:
+ out = "A";
+ break;
+ case GNSS_MEASUREMENTS_CODE_TYPE_B:
+ out = "B";
+ break;
+ case GNSS_MEASUREMENTS_CODE_TYPE_C:
+ out = "C";
+ break;
+ case GNSS_MEASUREMENTS_CODE_TYPE_I:
+ out = "I";
+ break;
+ case GNSS_MEASUREMENTS_CODE_TYPE_L:
+ out = "L";
+ break;
+ case GNSS_MEASUREMENTS_CODE_TYPE_M:
+ out = "M";
+ break;
+ case GNSS_MEASUREMENTS_CODE_TYPE_P:
+ out = "P";
+ break;
+ case GNSS_MEASUREMENTS_CODE_TYPE_Q:
+ out = "Q";
+ break;
+ case GNSS_MEASUREMENTS_CODE_TYPE_S:
+ out = "S";
+ break;
+ case GNSS_MEASUREMENTS_CODE_TYPE_W:
+ out = "W";
+ break;
+ case GNSS_MEASUREMENTS_CODE_TYPE_X:
+ out = "X";
+ break;
+ case GNSS_MEASUREMENTS_CODE_TYPE_Y:
+ out = "Y";
+ break;
+ case GNSS_MEASUREMENTS_CODE_TYPE_Z:
+ out = "Z";
+ break;
+ case GNSS_MEASUREMENTS_CODE_TYPE_N:
+ out = "N";
+ break;
+ case GNSS_MEASUREMENTS_CODE_TYPE_OTHER:
+ default:
+ out = inOtherCodeTypeName;
+ break;
+ }
+}
+
+static void convertGnssMeasurementsAccumulatedDeltaRangeState(GnssMeasurementsAdrStateMask& in,
+ ::android::hardware::hidl_bitfield
+ <V1_1::IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState>& out)
+{
+ memset(&out, 0, sizeof(out));
+ if (in & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_VALID_BIT)
+ out |= IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_VALID;
+ if (in & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_RESET_BIT)
+ out |= IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_RESET;
+ if (in & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_CYCLE_SLIP_BIT)
+ out |= IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_CYCLE_SLIP;
+ if (in & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_HALF_CYCLE_RESOLVED_BIT)
+ out |= IGnssMeasurementCallback::
+ GnssAccumulatedDeltaRangeState::ADR_STATE_HALF_CYCLE_RESOLVED;
+}
+
+static void convertGnssMeasurementsState(GnssMeasurementsStateMask& in,
+ ::android::hardware::hidl_bitfield
+ <V2_0::IGnssMeasurementCallback::GnssMeasurementState>& out)
+{
+ memset(&out, 0, sizeof(out));
+ if (in & GNSS_MEASUREMENTS_STATE_CODE_LOCK_BIT)
+ out |= IGnssMeasurementCallback::GnssMeasurementState::STATE_CODE_LOCK;
+ if (in & GNSS_MEASUREMENTS_STATE_BIT_SYNC_BIT)
+ out |= IGnssMeasurementCallback::GnssMeasurementState::STATE_BIT_SYNC;
+ if (in & GNSS_MEASUREMENTS_STATE_SUBFRAME_SYNC_BIT)
+ out |= IGnssMeasurementCallback::GnssMeasurementState::STATE_SUBFRAME_SYNC;
+ if (in & GNSS_MEASUREMENTS_STATE_TOW_DECODED_BIT)
+ out |= IGnssMeasurementCallback::GnssMeasurementState::STATE_TOW_DECODED;
+ if (in & GNSS_MEASUREMENTS_STATE_MSEC_AMBIGUOUS_BIT)
+ out |= IGnssMeasurementCallback::GnssMeasurementState::STATE_MSEC_AMBIGUOUS;
+ if (in & GNSS_MEASUREMENTS_STATE_SYMBOL_SYNC_BIT)
+ out |= IGnssMeasurementCallback::GnssMeasurementState::STATE_SYMBOL_SYNC;
+ if (in & GNSS_MEASUREMENTS_STATE_GLO_STRING_SYNC_BIT)
+ out |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GLO_STRING_SYNC;
+ if (in & GNSS_MEASUREMENTS_STATE_GLO_TOD_DECODED_BIT)
+ out |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GLO_TOD_DECODED;
+ if (in & GNSS_MEASUREMENTS_STATE_BDS_D2_BIT_SYNC_BIT)
+ out |= IGnssMeasurementCallback::GnssMeasurementState::STATE_BDS_D2_BIT_SYNC;
+ if (in & GNSS_MEASUREMENTS_STATE_BDS_D2_SUBFRAME_SYNC_BIT)
+ out |= IGnssMeasurementCallback::GnssMeasurementState::STATE_BDS_D2_SUBFRAME_SYNC;
+ if (in & GNSS_MEASUREMENTS_STATE_GAL_E1BC_CODE_LOCK_BIT)
+ out |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GAL_E1BC_CODE_LOCK;
+ if (in & GNSS_MEASUREMENTS_STATE_GAL_E1C_2ND_CODE_LOCK_BIT)
+ out |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GAL_E1C_2ND_CODE_LOCK;
+ if (in & GNSS_MEASUREMENTS_STATE_GAL_E1B_PAGE_SYNC_BIT)
+ out |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GAL_E1B_PAGE_SYNC;
+ if (in & GNSS_MEASUREMENTS_STATE_SBAS_SYNC_BIT)
+ out |= IGnssMeasurementCallback::GnssMeasurementState::STATE_SBAS_SYNC;
+ if (in & GNSS_MEASUREMENTS_STATE_TOW_KNOWN_BIT)
+ out |= IGnssMeasurementCallback::GnssMeasurementState::STATE_TOW_KNOWN;
+ if (in & GNSS_MEASUREMENTS_STATE_GLO_TOD_KNOWN_BIT)
+ out |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GLO_TOD_KNOWN;
+ if (in & GNSS_MEASUREMENTS_STATE_2ND_CODE_LOCK_BIT)
+ out |= IGnssMeasurementCallback::GnssMeasurementState::STATE_2ND_CODE_LOCK;
+}
+
+static void convertGnssData_2_1(GnssMeasurementsNotification& in,
+ V2_1::IGnssMeasurementCallback::GnssData& out)
+{
+ memset(&out, 0, sizeof(out));
+ out.measurements.resize(in.count);
+ for (size_t i = 0; i < in.count; i++) {
+ out.measurements[i].flags = 0;
+ convertGnssMeasurement(in.measurements[i], out.measurements[i].v2_0.v1_1.v1_0);
+ convertGnssConstellationType(in.measurements[i].svType,
+ out.measurements[i].v2_0.constellation);
+ convertGnssMeasurementsCodeType(in.measurements[i].codeType,
+ in.measurements[i].otherCodeTypeName,
+ out.measurements[i].v2_0.codeType);
+ convertGnssMeasurementsAccumulatedDeltaRangeState(in.measurements[i].adrStateMask,
+ out.measurements[i].v2_0.v1_1.accumulatedDeltaRangeState);
+ convertGnssMeasurementsState(in.measurements[i].stateMask,
+ out.measurements[i].v2_0.state);
+ out.measurements[i].basebandCN0DbHz = in.measurements[i].basebandCarrierToNoiseDbHz;
+
+ if (in.measurements[i].flags & GNSS_MEASUREMENTS_DATA_SIGNAL_TO_NOISE_RATIO_BIT) {
+ out.measurements[i].flags |=
+ V2_1::IGnssMeasurementCallback::GnssMeasurementFlags::HAS_SNR;
+ }
+ if (in.measurements[i].flags & GNSS_MEASUREMENTS_DATA_CARRIER_FREQUENCY_BIT) {
+ out.measurements[i].flags |=
+ V2_1::IGnssMeasurementCallback::GnssMeasurementFlags::HAS_CARRIER_FREQUENCY;
+ }
+ if (in.measurements[i].flags & GNSS_MEASUREMENTS_DATA_CARRIER_CYCLES_BIT) {
+ out.measurements[i].flags |=
+ V2_1::IGnssMeasurementCallback::GnssMeasurementFlags::HAS_CARRIER_CYCLES;
+ }
+ if (in.measurements[i].flags & GNSS_MEASUREMENTS_DATA_CARRIER_PHASE_BIT) {
+ out.measurements[i].flags |=
+ V2_1::IGnssMeasurementCallback::GnssMeasurementFlags::HAS_CARRIER_PHASE;
+ }
+ if (in.measurements[i].flags & GNSS_MEASUREMENTS_DATA_CARRIER_PHASE_UNCERTAINTY_BIT) {
+ out.measurements[i].flags |=
+ V2_1::IGnssMeasurementCallback::
+ GnssMeasurementFlags::HAS_CARRIER_PHASE_UNCERTAINTY;
+ }
+ if (in.measurements[i].flags & GNSS_MEASUREMENTS_DATA_AUTOMATIC_GAIN_CONTROL_BIT) {
+ out.measurements[i].flags |=
+ V2_1::IGnssMeasurementCallback::GnssMeasurementFlags::HAS_AUTOMATIC_GAIN_CONTROL;
+ }
+ if (in.measurements[i].flags & GNSS_MEASUREMENTS_DATA_FULL_ISB_BIT) {
+ out.measurements[i].fullInterSignalBiasNs = in.measurements[i].fullInterSignalBiasNs;
+ out.measurements[i].flags |=
+ V2_1::IGnssMeasurementCallback::GnssMeasurementFlags::HAS_FULL_ISB;
+ }
+ if (in.measurements[i].flags & GNSS_MEASUREMENTS_DATA_FULL_ISB_UNCERTAINTY_BIT) {
+ out.measurements[i].fullInterSignalBiasUncertaintyNs =
+ in.measurements[i].fullInterSignalBiasUncertaintyNs;
+ out.measurements[i].flags |=
+ V2_1::IGnssMeasurementCallback::
+ GnssMeasurementFlags::HAS_FULL_ISB_UNCERTAINTY;
+ }
+ if (in.measurements[i].flags & GNSS_MEASUREMENTS_DATA_SATELLITE_ISB_BIT) {
+ out.measurements[i].satelliteInterSignalBiasNs =
+ in.measurements[i].satelliteInterSignalBiasNs;
+ out.measurements[i].flags |=
+ V2_1::IGnssMeasurementCallback::GnssMeasurementFlags::HAS_SATELLITE_ISB;
+ }
+ if (in.measurements[i].flags & GNSS_MEASUREMENTS_DATA_SATELLITE_ISB_UNCERTAINTY_BIT) {
+ out.measurements[i].satelliteInterSignalBiasUncertaintyNs =
+ in.measurements[i].satelliteInterSignalBiasUncertaintyNs;
+ out.measurements[i].flags |=
+ V2_1::IGnssMeasurementCallback::
+ GnssMeasurementFlags::HAS_SATELLITE_ISB_UNCERTAINTY;
+ }
+ }
+ convertGnssClock_2_1(in.clock, out.clock);
+ convertElapsedRealtimeNanos(in, out.elapsedRealtime);
+}
+
+static void convertElapsedRealtimeNanos(GnssMeasurementsNotification& in,
+ ::android::hardware::gnss::V2_0::ElapsedRealtime& elapsedRealtime)
+{
+ if (in.clock.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_ELAPSED_REAL_TIME_BIT) {
+ elapsedRealtime.flags |= V2_0::ElapsedRealtimeFlags::HAS_TIMESTAMP_NS;
+ elapsedRealtime.timestampNs = in.clock.elapsedRealTime;
+ elapsedRealtime.flags |= V2_0::ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS;
+ elapsedRealtime.timeUncertaintyNs = in.clock.elapsedRealTimeUnc;
+ LOC_LOGd("elapsedRealtime.timestampNs=%" PRIi64 ""
+ " elapsedRealtime.timeUncertaintyNs=%" PRIi64 " elapsedRealtime.flags=0x%X",
+ elapsedRealtime.timestampNs,
+ elapsedRealtime.timeUncertaintyNs, elapsedRealtime.flags);
+ }
+}
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/android/2.1/location_api/MeasurementAPIClient.h b/android/2.1/location_api/MeasurementAPIClient.h
new file mode 100644
index 0000000..3e8805b
--- /dev/null
+++ b/android/2.1/location_api/MeasurementAPIClient.h
@@ -0,0 +1,96 @@
+/* Copyright (c) 2017-2020, 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.1/IGnssMeasurement.h>
+//#include <android/hardware/gnss/1.1/IGnssMeasurementCallback.h>
+#include <android/hardware/gnss/2.1/IGnssMeasurementCallback.h>
+#include <LocationAPIClientBase.h>
+#include <hidl/Status.h>
+#include <gps_extended_c.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_1 {
+namespace implementation {
+
+using ::android::sp;
+
+class MeasurementAPIClient : public LocationAPIClientBase
+{
+public:
+ 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);
+ Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> measurementSetCallback_2_1(
+ const sp<V2_1::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:
+ virtual ~MeasurementAPIClient();
+
+ std::mutex mMutex;
+ sp<V1_0::IGnssMeasurementCallback> mGnssMeasurementCbIface;
+ sp<V1_1::IGnssMeasurementCallback> mGnssMeasurementCbIface_1_1;
+ sp<V2_0::IGnssMeasurementCallback> mGnssMeasurementCbIface_2_0;
+ sp<V2_1::IGnssMeasurementCallback> mGnssMeasurementCbIface_2_1;
+ bool mTracking;
+ void clearInterfaces();
+};
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+#endif // MEASUREMENT_API_CLINET_H
diff --git a/android/2.1/service.cpp b/android/2.1/service.cpp
new file mode 100755
index 0000000..2788484
--- /dev/null
+++ b/android/2.1/service.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2017-2020, 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.1-service-qti"
+
+#include <android/hardware/gnss/2.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::V2_1::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__);
+
+ int vendorInfo = getVendorEnhancedInfo();
+ bool vendorEnhanced = ( 1 == vendorInfo || 3 == vendorInfo );
+ 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) {
+ #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
+ ALOGI("LOC_HIDL_VERSION not defined.");
+ #endif
+
+ joinRpcThreadpool();
+
+ } else {
+ ALOGE("Error while registering IGnss 2.1 service: %d", status);
+ }
+
+ return 0;
+}
diff --git a/android/Android.mk b/android/Android.mk
index 3b5c01f..aa2f4b5 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -1,15 +1,2 @@
LOCAL_PATH := $(call my-dir)
-ifneq ($(BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE),)
-include $(CLEAR_VARS)
-DIR_LIST := $(LOCAL_PATH)
-include $(DIR_LIST)/utils/Android.mk
-ifeq ($(GNSS_HIDL_VERSION),2.0)
-include $(DIR_LIST)/2.0/Android.mk
-else
-ifeq ($(GNSS_HIDL_VERSION),1.1)
-include $(DIR_LIST)/1.1/Android.mk
-else
-include $(DIR_LIST)/1.0/Android.mk
-endif #GNSS HIDL 1.1
-endif #GNSS HIDL 2.0
-endif #BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE
+include $(call all-subdir-makefiles)
diff --git a/android/utils/Android.bp b/android/utils/Android.bp
new file mode 100644
index 0000000..dcbff22
--- /dev/null
+++ b/android/utils/Android.bp
@@ -0,0 +1,46 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_qcom_sm7250_gps_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-BSD
+ default_applicable_licenses: ["hardware_qcom_sm7250_gps_license"],
+}
+
+cc_library_static {
+
+ name: "liblocbatterylistener",
+ vendor: true,
+
+
+
+ cflags: GNSS_CFLAGS + ["-DBATTERY_LISTENER_ENABLED"],
+ local_include_dirs: ["."],
+
+ srcs: ["battery_listener.cpp"],
+
+ shared_libs: [
+ "liblog",
+ "libhidlbase",
+ "libcutils",
+ "libutils",
+ "android.hardware.health@1.0",
+ "android.hardware.health@2.0",
+ "android.hardware.health@2.1",
+ "android.hardware.power@1.2",
+ "libbase",
+ ],
+
+ static_libs: ["libhealthhalutils"],
+
+ header_libs: [
+ "libgps.utils_headers",
+ "libloc_pla_headers",
+ ],
+}
+
+cc_library_headers {
+
+ name: "liblocbatterylistener_headers",
+ export_include_dirs: ["."],
+}
diff --git a/android/utils/Android.mk b/android/utils/Android.mk
deleted file mode 100644
index 9cb6f7b..0000000
--- a/android/utils/Android.mk
+++ /dev/null
@@ -1,41 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := liblocbatterylistener
-LOCAL_SANITIZE += $(GNSS_SANITIZE)
-# activate the following line for debug purposes only, comment out for production
-#LOCAL_SANITIZE_DIAG += $(GNSS_SANITIZE_DIAG)
-LOCAL_VENDOR_MODULE := true
-
-LOCAL_CFLAGS += $(GNSS_CFLAGS)
-
-LOCAL_C_INCLUDES += \
- $(LOCAL_PATH) \
-
-LOCAL_SRC_FILES:= \
- battery_listener.cpp
-LOCAL_SHARED_LIBRARIES := \
- liblog \
- libhidlbase \
- libcutils \
- libutils \
- android.hardware.health@1.0 \
- android.hardware.health@2.0 \
- android.hardware.power@1.2 \
- libbase
-
-LOCAL_HEADER_LIBRARIES := \
- libgps.utils_headers \
-
-LOCAL_STATIC_LIBRARIES := libhealthhalutils
-LOCAL_CFLAGS += -DBATTERY_LISTENER_ENABLED
-
-include $(BUILD_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := liblocbatterylistener_headers
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
-
-include $(BUILD_HEADER_LIBRARY)
-
-
diff --git a/android/utils/battery_listener.cpp b/android/utils/battery_listener.cpp
index 8547e41..9cbfabd 100644
--- a/android/utils/battery_listener.cpp
+++ b/android/utils/battery_listener.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2019, The Linux Foundation. All rights reserved.
+* Copyright (c) 2019-2020, 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,7 +34,8 @@
#define LOG_NDEBUG 0
#include <android/hidl/manager/1.0/IServiceManager.h>
-#include <android/hardware/health/2.0/IHealth.h>
+#include <android/hardware/health/2.1/IHealth.h>
+#include <android/hardware/health/2.1/IHealthInfoCallback.h>
#include <healthhalutils/HealthHalUtils.h>
#include <hidl/HidlTransportSupport.h>
#include <thread>
@@ -44,10 +45,9 @@
using android::hardware::Return;
using android::hardware::Void;
using android::hardware::health::V1_0::BatteryStatus;
-using android::hardware::health::V1_0::toString;
-using android::hardware::health::V2_0::get_health_service;
-using android::hardware::health::V2_0::HealthInfo;
-using android::hardware::health::V2_0::IHealth;
+using android::hardware::health::V2_1::HealthInfo;
+using android::hardware::health::V2_1::IHealthInfoCallback;
+using android::hardware::health::V2_1::IHealth;
using android::hardware::health::V2_0::Result;
using android::hidl::manager::V1_0::IServiceManager;
using namespace std::literals::chrono_literals;
@@ -58,13 +58,15 @@
#define GET_HEALTH_SVC_RETRY_CNT 5
#define GET_HEALTH_SVC_WAIT_TIME_MS 500
-struct BatteryListenerImpl : public hardware::health::V2_0::IHealthInfoCallback,
+struct BatteryListenerImpl : public hardware::health::V2_1::IHealthInfoCallback,
public hardware::hidl_death_recipient {
typedef std::function<void(bool)> cb_fn_t;
BatteryListenerImpl(cb_fn_t cb);
virtual ~BatteryListenerImpl ();
virtual hardware::Return<void> healthInfoChanged(
- const hardware::health::V2_0::HealthInfo& info);
+ const hardware::health::V2_0::HealthInfo& info);
+ virtual hardware::Return<void> healthInfoChanged_2_1(
+ const hardware::health::V2_1::HealthInfo& info);
virtual void serviceDied(uint64_t cookie,
const wp<hidl::base::V1_0::IBase>& who);
bool isCharging() {
@@ -72,7 +74,7 @@
return statusToBool(mStatus);
}
private:
- sp<hardware::health::V2_0::IHealth> mHealth;
+ sp<hardware::health::V2_1::IHealth> mHealth;
status_t init();
BatteryStatus mStatus;
cb_fn_t mCb;
@@ -94,7 +96,7 @@
return INVALID_OPERATION;
do {
- mHealth = hardware::health::V2_0::get_health_service();
+ mHealth = IHealth::getService();
if (mHealth != NULL)
break;
usleep(GET_HEALTH_SVC_WAIT_TIME_MS * 1000);
@@ -183,7 +185,7 @@
{
std::lock_guard<std::mutex> _l(mLock);
if (mHealth != NULL)
- mHealth->unlinkToDeath(this);
+ mHealth->unregisterCallback(this);
auto r = mHealth->unlinkToDeath(this);
if (!r.isOk() || r == false) {
LOC_LOGe("Transaction error in unregister to HealthHAL death: %s",
@@ -206,6 +208,8 @@
LOC_LOGi("health service died, reinit");
mDone = true;
}
+ mHealth = NULL;
+ mCond.notify_one();
mThread->join();
std::lock_guard<std::mutex> _l(mLock);
init();
@@ -227,6 +231,13 @@
return Void();
}
+Return<void> BatteryListenerImpl::healthInfoChanged_2_1(
+ const hardware::health::V2_1::HealthInfo& info) {
+ LOC_LOGv("healthInfoChanged_2_1: %d", info.legacy.legacy.batteryStatus);
+ healthInfoChanged(info.legacy);
+ return Void();
+}
+
static sp<BatteryListenerImpl> batteryListener;
bool batteryPropertiesListenerIsCharging() {
@@ -251,6 +262,7 @@
} // namespace android
void loc_extn_battery_properties_listener_init(battery_status_change_fn_t fn) {
+ LOC_LOGv("loc_extn_battery_properties_listener_init entry");
if (!sIsBatteryListened) {
std::thread t1(android::batteryPropertiesListenerInit,
[=](bool charging) { fn(charging); });
diff --git a/batching/Android.bp b/batching/Android.bp
new file mode 100644
index 0000000..7b1f8ba
--- /dev/null
+++ b/batching/Android.bp
@@ -0,0 +1,40 @@
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_qcom_sm7250_gps_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-BSD
+ default_applicable_licenses: ["hardware_qcom_sm7250_gps_license"],
+}
+
+cc_library_shared {
+
+ name: "libbatching",
+ vendor: true,
+
+
+
+ shared_libs: [
+ "libutils",
+ "libcutils",
+ "liblog",
+ "libloc_core",
+ "libgps.utils",
+ "libdl",
+ ],
+
+ srcs: [
+ "location_batching.cpp",
+ "BatchingAdapter.cpp",
+ ],
+
+ header_libs: [
+ "libgps.utils_headers",
+ "libloc_core_headers",
+ "libloc_pla_headers",
+ "liblocation_api_headers",
+ ],
+
+ cflags: GNSS_CFLAGS,
+}
diff --git a/batching/Android.mk b/batching/Android.mk
deleted file mode 100644
index f3e8fe4..0000000
--- a/batching/Android.mk
+++ /dev/null
@@ -1,39 +0,0 @@
-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_SANITIZE += $(GNSS_SANITIZE)
-# activate the following line for debug purposes only, comment out for production
-#LOCAL_SANITIZE_DIAG += $(GNSS_SANITIZE_DIAG)
-LOCAL_VENDOR_MODULE := true
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SHARED_LIBRARIES := \
- libutils \
- libcutils \
- liblog \
- libloc_core \
- libgps.utils \
- libdl
-
-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
index 135f0ed..4f1a43c 100644
--- a/batching/BatchingAdapter.cpp
+++ b/batching/BatchingAdapter.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2020, 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,11 +38,8 @@
BatchingAdapter::BatchingAdapter() :
LocAdapterBase(0,
- LocContext::getLocContext(
- NULL,
- NULL,
- LocContext::mLocationHalName,
- false)),
+ LocContext::getLocContext(LocContext::mLocationHalName),
+ false, nullptr, true),
mOngoingTripDistance(0),
mOngoingTripTBFInterval(0),
mTripWithOngoingTBFDropped(false),
@@ -55,6 +52,10 @@
LOC_LOGD("%s]: Constructor", __func__);
readConfigCommand();
setConfigCommand();
+
+ // at last step, let us inform adapater base that we are done
+ // with initialization, e.g.: ready to process handleEngineUpEvent
+ doneInit();
}
void
diff --git a/batching/Makefile.am b/batching/Makefile.am
index ef8011e..d5cba39 100644
--- a/batching/Makefile.am
+++ b/batching/Makefile.am
@@ -22,8 +22,7 @@
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_LDFLAGS = -lstdc++ -g -Wl,-z,defs -lpthread $(requiredlibs) @GLIB_LIBS@ -shared -version-info 1:0:0
libbatching_la_CPPFLAGS = -DUSE_GLIB $(AM_CFLAGS) $(AM_CPPFLAGS) @GLIB_CFLAGS@
else
libbatching_la_CFLAGS = $(AM_CFLAGS)
diff --git a/batching/configure.ac b/batching/configure.ac
index 27435c6..4ca4998 100644
--- a/batching/configure.ac
+++ b/batching/configure.ac
@@ -7,7 +7,7 @@
# 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])
+AM_INIT_AUTOMAKE([foreign subdir-objects])
# Disables auto rebuilding of configure, Makefile.ins
AM_MAINTAINER_MODE
# Verifies the --srcdir is correct by checking for the path
@@ -37,10 +37,6 @@
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]),
diff --git a/build/target_specific_features.mk b/build/target_specific_features.mk
deleted file mode 100644
index bdccbbf..0000000
--- a/build/target_specific_features.mk
+++ /dev/null
@@ -1,73 +0,0 @@
-GNSS_CFLAGS := \
- -Werror \
- -Wno-error=unused-parameter \
- -Wno-error=macro-redefined \
- -Wno-error=reorder \
- -Wno-error=missing-braces \
- -Wno-error=self-assign \
- -Wno-error=enum-conversion \
- -Wno-error=logical-op-parentheses \
- -Wno-error=null-arithmetic \
- -Wno-error=null-conversion \
- -Wno-error=parentheses-equality \
- -Wno-error=undefined-bool-conversion \
- -Wno-error=tautological-compare \
- -Wno-error=switch \
- -Wno-error=date-time
-
-# GPS-HIDL
-GNSS_HIDL_1_0_TARGET_LIST := msm8960
-GNSS_HIDL_1_0_TARGET_LIST += msm8974
-GNSS_HIDL_1_0_TARGET_LIST += msm8226
-GNSS_HIDL_1_0_TARGET_LIST += msm8610
-GNSS_HIDL_1_0_TARGET_LIST += apq8084
-GNSS_HIDL_1_0_TARGET_LIST += msm8916
-GNSS_HIDL_1_0_TARGET_LIST += msm8994
-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_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 += sdmshrike
-GNSS_HIDL_2_0_TARGET_LIST += $(MSMSTEPPE)
-GNSS_HIDL_2_0_TARGET_LIST += $(TRINKET)
-GNSS_HIDL_2_0_TARGET_LIST += kona
-GNSS_HIDL_2_0_TARGET_LIST += atoll
-GNSS_HIDL_2_0_TARGET_LIST += lito
-GNSS_HIDL_2_0_TARGET_LIST += bengal
-GNSS_HIDL_2_0_TARGET_LIST += lahaina
-
-ifneq (,$(filter $(GNSS_HIDL_2_0_TARGET_LIST),$(TARGET_BOARD_PLATFORM)))
-GNSS_HIDL_VERSION = 2.0
-else ifneq (,$(filter $(GNSS_HIDL_1_0_TARGET_LIST),$(TARGET_BOARD_PLATFORM)))
-GNSS_HIDL_VERSION = 1.0
-else ifneq (,$(filter $(GNSS_HIDL_1_1_TARGET_LIST),$(TARGET_BOARD_PLATFORM)))
-GNSS_HIDL_VERSION = 1.1
-else # default to 2.0
-GNSS_HIDL_VERSION = 2.0
-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
-
-# Activate the following two lines for regression testing
-#GNSS_SANITIZE := address cfi alignment bounds null unreachable integer
-#GNSS_SANITIZE_DIAG := address cfi alignment bounds null unreachable integer
diff --git a/core/Android.bp b/core/Android.bp
new file mode 100644
index 0000000..2d9a804
--- /dev/null
+++ b/core/Android.bp
@@ -0,0 +1,65 @@
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_qcom_sm7250_gps_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-BSD
+ default_applicable_licenses: ["hardware_qcom_sm7250_gps_license"],
+}
+
+cc_library_shared {
+
+ name: "libloc_core",
+ vendor: true,
+
+
+
+ shared_libs: [
+ "liblog",
+ "libutils",
+ "libcutils",
+ "libgps.utils",
+ "libdl",
+ "liblog",
+ ],
+
+ srcs: [
+ "LocApiBase.cpp",
+ "LocAdapterBase.cpp",
+ "ContextBase.cpp",
+ "LocContext.cpp",
+ "loc_core_log.cpp",
+ "data-items/DataItemsFactoryProxy.cpp",
+ "SystemStatusOsObserver.cpp",
+ "SystemStatus.cpp",
+ ],
+
+ cflags: [
+ "-fno-short-enums",
+ "-D_ANDROID_",
+ ] + GNSS_CFLAGS,
+
+ local_include_dirs: [
+ "data-items",
+ "observer",
+ ],
+
+ header_libs: [
+ "libutils_headers",
+ "libgps.utils_headers",
+ "libloc_pla_headers",
+ "liblocation_api_headers",
+ ],
+
+}
+
+cc_library_headers {
+
+ name: "libloc_core_headers",
+ vendor: true,
+ export_include_dirs: ["."] + [
+ "data-items",
+ "observer",
+ ],
+}
diff --git a/core/Android.mk b/core/Android.mk
deleted file mode 100644
index ce5d6a8..0000000
--- a/core/Android.mk
+++ /dev/null
@@ -1,62 +0,0 @@
-ifneq ($(BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE),)
-ifneq ($(BUILD_TINY_ANDROID),true)
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libloc_core
-LOCAL_SANITIZE += $(GNSS_SANITIZE)
-# activate the following line for debug purposes only, comment out for production
-#LOCAL_SANITIZE_DIAG += $(GNSS_SANITIZE_DIAG)
-LOCAL_VENDOR_MODULE := true
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SHARED_LIBRARIES := \
- liblog \
- libutils \
- libcutils \
- libgps.utils \
- libdl \
- liblog
-
-LOCAL_SRC_FILES += \
- LocApiBase.cpp \
- LocAdapterBase.cpp \
- ContextBase.cpp \
- LocContext.cpp \
- loc_core_log.cpp \
- data-items/DataItemsFactoryProxy.cpp \
- SystemStatusOsObserver.cpp \
- SystemStatus.cpp
-
-LOCAL_CFLAGS += \
- -fno-short-enums \
- -D_ANDROID_
-
-LOCAL_C_INCLUDES:= \
- $(LOCAL_PATH)/data-items \
- $(LOCAL_PATH)/data-items/common \
- $(LOCAL_PATH)/observer \
-
-LOCAL_HEADER_LIBRARIES := \
- libutils_headers \
- libgps.utils_headers \
- libloc_pla_headers \
- liblocation_api_headers
-
-LOCAL_CFLAGS += $(GNSS_CFLAGS)
-
-include $(BUILD_SHARED_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := libloc_core_headers
-LOCAL_EXPORT_C_INCLUDE_DIRS := \
- $(LOCAL_PATH) \
- $(LOCAL_PATH)/data-items \
- $(LOCAL_PATH)/data-items/common \
- $(LOCAL_PATH)/observer
-include $(BUILD_HEADER_LIBRARY)
-
-endif # not BUILD_TINY_ANDROID
-endif # BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE
diff --git a/core/ContextBase.cpp b/core/ContextBase.cpp
index 3eb4973..87e98dc 100644
--- a/core/ContextBase.cpp
+++ b/core/ContextBase.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2014,2016-2017 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2014,2016-2017,2020 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,7 +30,6 @@
#define LOG_TAG "LocSvc_CtxBase"
#include <dlfcn.h>
-#include <cutils/sched_policy.h>
#include <unistd.h>
#include <ContextBase.h>
#include <msg_q.h>
@@ -50,6 +49,8 @@
uint64_t ContextBase::sSupportedMsgMask = 0;
bool ContextBase::sGnssMeasurementSupported = false;
uint8_t ContextBase::sFeaturesSupported[MAX_FEATURE_LENGTH];
+GnssNMEARptRate ContextBase::sNmeaReportRate = GNSS_NMEA_REPORT_RATE_NHZ;
+LocationCapabilitiesMask ContextBase::sQwesFeatureMask = 0;
const loc_param_s_type ContextBase::mGps_conf_table[] =
{
@@ -65,8 +66,8 @@
{"INTERMEDIATE_POS", &mGps_conf.INTERMEDIATE_POS, NULL, 'n'},
{"ACCURACY_THRES", &mGps_conf.ACCURACY_THRES, NULL, 'n'},
{"NMEA_PROVIDER", &mGps_conf.NMEA_PROVIDER, NULL, 'n'},
+ {"NMEA_REPORT_RATE", &mGps_conf.NMEA_REPORT_RATE, NULL, 's'},
{"CAPABILITIES", &mGps_conf.CAPABILITIES, NULL, 'n'},
- {"XTRA_VERSION_CHECK", &mGps_conf.XTRA_VERSION_CHECK, NULL, 'n'},
{"XTRA_SERVER_1", &mGps_conf.XTRA_SERVER_1, NULL, 's'},
{"XTRA_SERVER_2", &mGps_conf.XTRA_SERVER_2, NULL, 's'},
{"XTRA_SERVER_3", &mGps_conf.XTRA_SERVER_3, NULL, 's'},
@@ -92,7 +93,9 @@
{"GNSS_DEPLOYMENT", &mGps_conf.GNSS_DEPLOYMENT, NULL, 'n'},
{"CUSTOM_NMEA_GGA_FIX_QUALITY_ENABLED",
&mGps_conf.CUSTOM_NMEA_GGA_FIX_QUALITY_ENABLED, NULL, 'n'},
+ {"NMEA_TAG_BLOCK_GROUPING_ENABLED", &mGps_conf.NMEA_TAG_BLOCK_GROUPING_ENABLED, NULL, 'n'},
{"NI_SUPL_DENY_ON_NFW_LOCKED", &mGps_conf.NI_SUPL_DENY_ON_NFW_LOCKED, NULL, 'n'},
+ {"ENABLE_NMEA_PRINT", &mGps_conf.ENABLE_NMEA_PRINT, NULL, 'n'}
};
const loc_param_s_type ContextBase::mSap_conf_table[] =
@@ -135,8 +138,6 @@
mGps_conf.LPP_PROFILE = 0;
/*By default no positioning protocol is selected on A-GLONASS system*/
mGps_conf.A_GLONASS_POS_PROTOCOL_SELECT = 0;
- /*XTRA version check is disabled by default*/
- mGps_conf.XTRA_VERSION_CHECK=0;
/*Use emergency PDN by default*/
mGps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL = 1;
/* By default no LPPe CP technology is enabled*/
@@ -192,12 +193,22 @@
/* default configuration QTI GNSS H/W */
mGps_conf.GNSS_DEPLOYMENT = 0;
mGps_conf.CUSTOM_NMEA_GGA_FIX_QUALITY_ENABLED = 0;
+ /* default NMEA Tag Block Grouping is disabled */
+ mGps_conf.NMEA_TAG_BLOCK_GROUPING_ENABLED = 0;
/* default configuration for NI_SUPL_DENY_ON_NFW_LOCKED */
mGps_conf.NI_SUPL_DENY_ON_NFW_LOCKED = 1;
+ /* By default NMEA Printing is disabled */
+ mGps_conf.ENABLE_NMEA_PRINT = 0;
UTIL_READ_CONF(LOC_PATH_GPS_CONF, mGps_conf_table);
UTIL_READ_CONF(LOC_PATH_SAP_CONF, mSap_conf_table);
+ if (strncmp(mGps_conf.NMEA_REPORT_RATE, "1HZ", sizeof(mGps_conf.NMEA_REPORT_RATE)) == 0) {
+ /* NMEA reporting is configured at 1Hz*/
+ sNmeaReportRate = GNSS_NMEA_REPORT_RATE_1HZ;
+ } else {
+ sNmeaReportRate = GNSS_NMEA_REPORT_RATE_NHZ;
+ }
LOC_LOGI("%s] GNSS Deployment: %s", __FUNCTION__,
((mGps_conf.GNSS_DEPLOYMENT == 1) ? "SS5" :
((mGps_conf.GNSS_DEPLOYMENT == 2) ? "QFUSION" : "QGNSS")));
@@ -326,6 +337,32 @@
(void *)featureList, sizeof(ContextBase::sFeaturesSupported));
}
+ /* */
+ if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_MEASUREMENTS_CORRECTION)) {
+ static uint8_t isSapModeKnown = 0;
+
+ if (!isSapModeKnown) {
+ /* Check if SAP is PREMIUM_ENV_AIDING in izat.conf */
+ char conf_feature_sap[LOC_MAX_PARAM_STRING];
+ loc_param_s_type izat_conf_feature_table[] =
+ {
+ { "SAP", &conf_feature_sap, &isSapModeKnown, 's' }
+ };
+ UTIL_READ_CONF(LOC_PATH_IZAT_CONF, izat_conf_feature_table);
+
+ /* Disable this feature if SAP is not PREMIUM_ENV_AIDING in izat.conf */
+ if (strcmp(conf_feature_sap, "PREMIUM_ENV_AIDING") != 0) {
+ uint8_t arrayIndex = LOC_SUPPORTED_FEATURE_MEASUREMENTS_CORRECTION >> 3;
+ uint8_t bitPos = LOC_SUPPORTED_FEATURE_MEASUREMENTS_CORRECTION & 7;
+
+ if (arrayIndex < MAX_FEATURE_LENGTH) {
+ /* To disable the feature we need to reset the bit on the "bitPos"
+ position, so shift a "1" to the left by "bitPos" */
+ ContextBase::sFeaturesSupported[arrayIndex] &= ~(1 << bitPos);
+ }
+ }
+ }
+ }
ContextBase::sIsEngineCapabilitiesKnown = true;
}
}
diff --git a/core/ContextBase.h b/core/ContextBase.h
index e63450f..34cad60 100644
--- a/core/ContextBase.h
+++ b/core/ContextBase.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2017, 2020, 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
@@ -35,6 +35,11 @@
#include <LocApiBase.h>
#include <LBSProxyBase.h>
#include <loc_cfg.h>
+#ifdef NO_UNORDERED_SET_OR_MAP
+ #include <map>
+#else
+ #include <unordered_map>
+#endif
/* GPS.conf support */
/* NOTE: the implementaiton of the parser casts number
@@ -49,12 +54,12 @@
uint32_t SUPL_ES;
uint32_t CAPABILITIES;
uint32_t LPP_PROFILE;
- uint32_t XTRA_VERSION_CHECK;
char XTRA_SERVER_1[LOC_MAX_PARAM_STRING];
char XTRA_SERVER_2[LOC_MAX_PARAM_STRING];
char XTRA_SERVER_3[LOC_MAX_PARAM_STRING];
uint32_t USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL;
uint32_t NMEA_PROVIDER;
+ char NMEA_REPORT_RATE[LOC_MAX_PARAM_NAME];
GnssConfigGpsLock GPS_LOCK;
uint32_t A_GLONASS_POS_PROTOCOL_SELECT;
uint32_t AGPS_CERT_WRITABLE_MASK;
@@ -76,15 +81,17 @@
uint32_t GNSS_DEPLOYMENT;
uint32_t CUSTOM_NMEA_GGA_FIX_QUALITY_ENABLED;
uint32_t NI_SUPL_DENY_ON_NFW_LOCKED;
+ uint32_t ENABLE_NMEA_PRINT;
+ uint32_t NMEA_TAG_BLOCK_GROUPING_ENABLED;
} loc_gps_cfg_s_type;
-/* NOTE: the implementaiton of the parser casts number
+/* NOTE: the implementation of the parser casts number
fields to 32 bit. To ensure all 'n' fields working,
they must all be 32 bit fields. */
/* Meanwhile, *_valid fields are 8 bit fields, and 'f'
fields are double. Rigid as they are, it is the
the status quo, until the parsing mechanism is
- change, that is. */
+ changed, that is. */
typedef struct
{
uint8_t GYRO_BIAS_RANDOM_WALK_VALID;
@@ -109,6 +116,8 @@
double VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY;
} loc_sap_cfg_s_type;
+using namespace loc_util;
+
namespace loc_core {
class LocAdapterBase;
@@ -156,6 +165,8 @@
static uint64_t sSupportedMsgMask;
static uint8_t sFeaturesSupported[MAX_FEATURE_LENGTH];
static bool sGnssMeasurementSupported;
+ static GnssNMEARptRate sNmeaReportRate;
+ static LocationCapabilitiesMask sQwesFeatureMask;
void readConfig();
static uint32_t getCarrierCapabilities();
@@ -188,6 +199,118 @@
*/
static bool gnssConstellationConfig();
+ /*
+ set QWES feature status info
+ */
+ static inline void setQwesFeatureStatus(
+ const std::unordered_map<LocationQwesFeatureType, bool> &featureMap) {
+ std::unordered_map<LocationQwesFeatureType, bool>::const_iterator itr;
+ static LocationQwesFeatureType locQwesFeatType[LOCATION_QWES_FEATURE_TYPE_MAX];
+ for (itr = featureMap.begin(); itr != featureMap.end(); ++itr) {
+ LOC_LOGi("Feature : %d isValid: %d", itr->first, itr->second);
+ locQwesFeatType[itr->first] = itr->second;
+ switch (itr->first) {
+ case LOCATION_QWES_FEATURE_TYPE_CARRIER_PHASE:
+ if (itr->second) {
+ sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_CARRIER_PHASE_BIT;
+ } else {
+ sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_CARRIER_PHASE_BIT;
+ }
+ break;
+ case LOCATION_QWES_FEATURE_TYPE_SV_POLYNOMIAL:
+ if (itr->second) {
+ sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_SV_POLYNOMIAL_BIT;
+ } else {
+ sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_SV_POLYNOMIAL_BIT;
+ }
+ break;
+ case LOCATION_QWES_FEATURE_TYPE_GNSS_SINGLE_FREQUENCY:
+ if (itr->second) {
+ sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_GNSS_SINGLE_FREQUENCY;
+ } else {
+ sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_GNSS_SINGLE_FREQUENCY;
+ }
+ break;
+ case LOCATION_QWES_FEATURE_TYPE_SV_EPH:
+ if (itr->second) {
+ sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_SV_EPHEMERIS_BIT;
+ } else {
+ sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_SV_EPHEMERIS_BIT;
+ }
+ break;
+ case LOCATION_QWES_FEATURE_TYPE_GNSS_MULTI_FREQUENCY:
+ if (itr->second) {
+ sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_GNSS_MULTI_FREQUENCY;
+ } else {
+ sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_GNSS_MULTI_FREQUENCY;
+ }
+ break;
+ case LOCATION_QWES_FEATURE_TYPE_PPE:
+ if (itr->second) {
+ sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_PPE;
+ } else {
+ sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_PPE;
+ }
+ break;
+ case LOCATION_QWES_FEATURE_TYPE_QDR2:
+ if (itr->second) {
+ sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_QDR2;
+ } else {
+ sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_QDR2;
+ }
+ break;
+ case LOCATION_QWES_FEATURE_TYPE_QDR3:
+ if (itr->second) {
+ sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_QDR3;
+ } else {
+ sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_QDR3;
+ }
+ break;
+ case LOCATION_QWES_FEATURE_TYPE_VPE:
+ if (itr->second) {
+ sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_VPE;
+ } else {
+ sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_VPE;
+ }
+ break;
+ }
+ }
+
+ // Set CV2X basic when time freq and tunc is set
+ // CV2X_BASIC = LOCATION_QWES_FEATURE_TYPE_TIME_FREQUENCY &
+ // LOCATION_QWES_FEATURE_TYPE_TIME_UNCERTAINTY
+
+ // Set CV2X premium when time freq and tunc is set
+ // CV2X_PREMIUM = CV2X_BASIC & LOCATION_QWES_FEATURE_TYPE_QDR3 &
+ // LOCATION_QWES_FEATURE_TYPE_CLOCK_ESTIMATE
+
+ bool cv2xBasicEnabled = (1 == locQwesFeatType[LOCATION_QWES_FEATURE_TYPE_TIME_FREQUENCY]) &&
+ (1 == locQwesFeatType[LOCATION_QWES_FEATURE_TYPE_TIME_UNCERTAINTY]);
+ bool cv2xPremiumEnabled = cv2xBasicEnabled &&
+ (1 == locQwesFeatType[LOCATION_QWES_FEATURE_TYPE_QDR3]) &&
+ (1 == locQwesFeatType[LOCATION_QWES_FEATURE_TYPE_CLOCK_ESTIMATE]);
+
+ LOC_LOGd("CV2X_BASIC:%d, CV2X_PREMIUM:%d", cv2xBasicEnabled, cv2xPremiumEnabled);
+ if (cv2xBasicEnabled) {
+ sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_CV2X_LOCATION_BASIC;
+ } else {
+ sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_CV2X_LOCATION_BASIC;
+ }
+ if (cv2xPremiumEnabled) {
+ sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_CV2X_LOCATION_PREMIUM;
+ } else {
+ sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_CV2X_LOCATION_PREMIUM;
+ }
+ }
+
+ /*
+ get QWES feature status info
+ */
+ static inline LocationCapabilitiesMask getQwesFeatureStatus() {
+ return (ContextBase::sQwesFeatureMask);
+ }
+
+
};
struct LocApiResponse: LocMsg {
diff --git a/core/EngineHubProxyBase.h b/core/EngineHubProxyBase.h
index d46bca2..468a8f0 100644
--- a/core/EngineHubProxyBase.h
+++ b/core/EngineHubProxyBase.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2018-2020 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
@@ -28,9 +28,16 @@
*/
#ifndef ENGINE_HUB_PROXY_BASE_H
#define ENGINE_HUB_PROXY_BASE_H
+#ifdef NO_UNORDERED_SET_OR_MAP
+ #include <map>
+#else
+ #include <unordered_map>
+#endif
namespace loc_core {
+using namespace loc_util;
+
class EngineHubProxyBase {
public:
inline EngineHubProxyBase() {
@@ -106,6 +113,19 @@
(void) configInfo;
return false;
}
+
+ inline virtual bool configDeadReckoningEngineParams(
+ const DeadReckoningEngineConfig& dreConfig) {
+ (void) dreConfig;
+ return false;
+ }
+
+ inline virtual bool configEngineRunState(
+ PositioningEngineMask engType, LocEngineRunState engState) {
+ (void) engType;
+ (void) engState;
+ return false;
+ }
};
typedef std::function<void(int count, EngineLocationInfo* locationArr)>
@@ -121,6 +141,9 @@
typedef std::function<void(bool nHzNeeded, bool nHzMeasNeeded)>
GnssAdapterUpdateNHzRequirementCb;
+typedef std::function<void(const std::unordered_map<LocationQwesFeatureType, bool> &featureMap)>
+ GnssAdapterUpdateQwesFeatureStatusCb;
+
// potential parameters: message queue: MsgTask * msgTask;
// callback function to report back dr and ppe position and sv report
typedef EngineHubProxyBase* (getEngHubProxyFn)(
@@ -129,7 +152,8 @@
GnssAdapterReportEnginePositionsEventCb positionEventCb,
GnssAdapterReportSvEventCb svEventCb,
GnssAdapterReqAidingDataCb reqAidingDataCb,
- GnssAdapterUpdateNHzRequirementCb updateNHzRequirementCb);
+ GnssAdapterUpdateNHzRequirementCb updateNHzRequirementCb,
+ GnssAdapterUpdateQwesFeatureStatusCb updateQwesFeatureStatusCb);
} // namespace loc_core
diff --git a/core/LocAdapterBase.cpp b/core/LocAdapterBase.cpp
index 1e91cf8..95f2728 100644
--- a/core/LocAdapterBase.cpp
+++ b/core/LocAdapterBase.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2014, 2016-2019 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2014, 2016-2020 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
@@ -185,6 +185,10 @@
void LocAdapterBase::reportGnssSvTypeConfigEvent(const GnssSvTypeConfig& /*config*/)
DEFAULT_IMPL()
+void LocAdapterBase::reportGnssConfigEvent(uint32_t, /* session id*/
+ const GnssConfig& /*gnssConfig*/)
+DEFAULT_IMPL()
+
bool LocAdapterBase::
requestOdcpiEvent(OdcpiRequestInfo& /*request*/)
DEFAULT_IMPL(false)
@@ -309,6 +313,15 @@
if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_LOCATION_PRIVACY)) {
mask |= LOCATION_CAPABILITIES_PRIVACY_BIT;
}
+ if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_MEASUREMENTS_CORRECTION)) {
+ mask |= LOCATION_CAPABILITIES_MEASUREMENTS_CORRECTION_BIT;
+ }
+ if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_ROBUST_LOCATION)) {
+ mask |= LOCATION_CAPABILITIES_CONFORMITY_INDEX_BIT;
+ }
+ if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_EDGNSS)) {
+ mask |= LOCATION_CAPABILITIES_EDGNSS_BIT;
+ }
} else {
LOC_LOGE("%s]: attempt to get capabilities before they are known.", __func__);
}
@@ -415,4 +428,12 @@
sendMsg(new MsgRequestCapabilities(*this, client));
}
+void
+LocAdapterBase::reportLatencyInfoEvent(const GnssLatencyInfo& /*gnssLatencyInfo*/)
+DEFAULT_IMPL()
+
+bool LocAdapterBase::
+ reportQwesCapabilities(const std::unordered_map<LocationQwesFeatureType, bool> &featureMap)
+DEFAULT_IMPL(false)
+
} // namespace loc_core
diff --git a/core/LocAdapterBase.h b/core/LocAdapterBase.h
index 7ca3ecd..51b2306 100644
--- a/core/LocAdapterBase.h
+++ b/core/LocAdapterBase.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2014, 2016-2019 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2014, 2016-2020 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
@@ -156,7 +156,7 @@
return ContextBase::isFeatureSupported(featureVal);
}
- uint32_t generateSessionId();
+ static uint32_t generateSessionId();
inline bool isAdapterMaster() {
return mIsMaster;
@@ -206,6 +206,7 @@
GpsLocationExtended &location_extended, LocPosTechMask tech_mask);
virtual void reportGnssSvIdConfigEvent(const GnssSvIdConfig& config);
virtual void reportGnssSvTypeConfigEvent(const GnssSvTypeConfig& config);
+ virtual void reportGnssConfigEvent(uint32_t sessionId, const GnssConfig& gnssConfig);
virtual bool requestOdcpiEvent(OdcpiRequestInfo& request);
virtual bool reportGnssEngEnergyConsumedEvent(uint64_t energyConsumedSinceFirstBoot);
virtual bool reportDeleteAidingDataEvent(GnssAidingData &aidingData);
@@ -235,6 +236,9 @@
removeClientCompleteCallback rmClientCb);
void requestCapabilitiesCommand(LocationAPI* client);
+ virtual void reportLatencyInfoEvent(const GnssLatencyInfo& gnssLatencyInfo);
+ virtual bool reportQwesCapabilities(
+ const std::unordered_map<LocationQwesFeatureType, bool> &featureMap);
};
} // namespace loc_core
diff --git a/core/LocApiBase.cpp b/core/LocApiBase.cpp
index 71abdf9..860da2e 100644
--- a/core/LocApiBase.cpp
+++ b/core/LocApiBase.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2014, 2016-2019 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2014, 2016-2021 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,6 +36,7 @@
#include <LocAdapterBase.h>
#include <log_util.h>
#include <LocContext.h>
+#include <loc_misc_utils.h>
namespace loc_core {
@@ -160,7 +161,7 @@
android_atomic_inc(&mMsgTaskRefCount);
if (nullptr == mMsgTask) {
- mMsgTask = new MsgTask("LocApiMsgTask", false);
+ mMsgTask = new MsgTask("LocApiMsgTask");
}
}
@@ -330,7 +331,7 @@
"timestamp: %" PRId64 "\n"
"Session status: %d\n Technology mask: %u\n "
"SV used in fix (gps/glo/bds/gal/qzss) : \
- (0x%" PRIx64 "/0x%" PRIx64 "/0x%" PRIx64 "/0x%" PRIx64 "/0x%" PRIx64 ")",
+ (0x%" PRIx64 "/0x%" PRIx64 "/0x%" PRIx64 "/0x%" PRIx64 "/0x%" PRIx64 "/0x%" PRIx64 ")",
location.gpsLocation.flags, location.position_source,
location.gpsLocation.latitude, location.gpsLocation.longitude,
location.gpsLocation.altitude, location.gpsLocation.speed,
@@ -340,7 +341,8 @@
locationExtended.gnss_sv_used_ids.glo_sv_used_ids_mask,
locationExtended.gnss_sv_used_ids.bds_sv_used_ids_mask,
locationExtended.gnss_sv_used_ids.gal_sv_used_ids_mask,
- locationExtended.gnss_sv_used_ids.qzss_sv_used_ids_mask);
+ locationExtended.gnss_sv_used_ids.qzss_sv_used_ids_mask,
+ locationExtended.gnss_sv_used_ids.navic_sv_used_ids_mask);
// loop through adapters, and deliver to all adapters.
TO_ALL_LOCADAPTERS(
mLocAdapters[i]->reportPositionEvent(location, locationExtended,
@@ -406,28 +408,27 @@
// print the SV info before delivering
LOC_LOGV("num sv: %u\n"
- " sv: constellation svid cN0"
+ " sv: constellation svid cN0 basebandCN0"
" elevation azimuth flags",
svNotify.count);
- for (size_t i = 0; i < svNotify.count && i < LOC_GNSS_MAX_SVS; i++) {
+ for (size_t i = 0; i < svNotify.count && i < GNSS_SV_MAX; i++) {
if (svNotify.gnssSvs[i].type >
sizeof(constellationString) / sizeof(constellationString[0]) - 1) {
svNotify.gnssSvs[i].type = GNSS_SV_TYPE_UNKNOWN;
}
// Display what we report to clients
- uint16_t displaySvId = GNSS_SV_TYPE_QZSS == svNotify.gnssSvs[i].type ?
- svNotify.gnssSvs[i].svId + QZSS_SV_PRN_MIN - 1 :
- svNotify.gnssSvs[i].svId;
- LOC_LOGV(" %03zu: %*s %02d %f %f %f %f 0x%02X",
+ LOC_LOGV(" %03zu: %*s %02d %f %f %f %f %f 0x%02X 0x%2X",
i,
13,
constellationString[svNotify.gnssSvs[i].type],
- displaySvId,
+ svNotify.gnssSvs[i].svId,
svNotify.gnssSvs[i].cN0Dbhz,
+ svNotify.gnssSvs[i].basebandCarrierToNoiseDbHz,
svNotify.gnssSvs[i].elevation,
svNotify.gnssSvs[i].azimuth,
svNotify.gnssSvs[i].carrierFrequencyHz,
- svNotify.gnssSvs[i].gnssSvOptionsMask);
+ svNotify.gnssSvs[i].gnssSvOptionsMask,
+ svNotify.gnssSvs[i].gnssSignalTypeMask);
}
// loop through adapters, and deliver to all adapters.
TO_ALL_LOCADAPTERS(
@@ -483,6 +484,14 @@
TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportLocationSystemInfoEvent(locationSystemInfo));
}
+void LocApiBase::reportQwesCapabilities
+(
+ const std::unordered_map<LocationQwesFeatureType, bool> &featureMap
+)
+{
+ // loop through adapters, and deliver to all adapters.
+ TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportQwesCapabilities(featureMap));
+}
void LocApiBase::requestXtraData()
{
// loop through adapters, and deliver to the first handling adapter.
@@ -541,9 +550,10 @@
{
// Print the config
LOC_LOGv("gloBlacklistSvMask: %" PRIu64 ", bdsBlacklistSvMask: %" PRIu64 ",\n"
- "qzssBlacklistSvMask: %" PRIu64 ", galBlacklistSvMask: %" PRIu64,
+ "qzssBlacklistSvMask: %" PRIu64 ", galBlacklistSvMask: %" PRIu64 ",\n"
+ "navicBlacklistSvMask: %" PRIu64,
config.gloBlacklistSvMask, config.bdsBlacklistSvMask,
- config.qzssBlacklistSvMask, config.galBlacklistSvMask);
+ config.qzssBlacklistSvMask, config.galBlacklistSvMask, config.navicBlacklistSvMask);
// Loop through adapters, and deliver to all adapters.
TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportGnssSvIdConfigEvent(config));
@@ -593,6 +603,17 @@
TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportBatchStatusChangeEvent(batchStatus));
}
+void LocApiBase::reportGnssConfig(uint32_t sessionId, const GnssConfig& gnssConfig)
+{
+ // loop through adapters, and deliver to the first handling adapter.
+ TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportGnssConfigEvent(sessionId, gnssConfig));
+}
+
+void LocApiBase::reportLatencyInfo(GnssLatencyInfo& gnssLatencyInfo)
+{
+ // loop through adapters, and deliver to the first handling adapter.
+ TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportLatencyInfoEvent(gnssLatencyInfo));
+}
enum loc_api_adapter_err LocApiBase::
open(LOC_API_ADAPTER_EVENT_MASK_T /*mask*/)
@@ -613,7 +634,8 @@
DEFAULT_IMPL()
void LocApiBase::
- injectPosition(double /*latitude*/, double /*longitude*/, float /*accuracy*/)
+ injectPosition(double /*latitude*/, double /*longitude*/, float /*accuracy*/,
+ bool /*onDemandCpi*/)
DEFAULT_IMPL()
void LocApiBase::
@@ -628,10 +650,6 @@
setTime(LocGpsUtcTime /*time*/, int64_t /*timeReference*/, int /*uncertainty*/)
DEFAULT_IMPL()
-enum loc_api_adapter_err LocApiBase::
- setXtraData(char* /*data*/, int /*length*/)
-DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS)
-
void LocApiBase::
atlOpenStatus(int /*handle*/, int /*is_succ*/, char* /*apn*/, uint32_t /*apnLen*/,
AGpsBearerType /*bear*/, LocAGpsType /*agpsType*/,
@@ -663,7 +681,7 @@
DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS)
LocationError LocApiBase::
- setLPPConfigSync(GnssConfigLppProfile /*profile*/)
+ setLPPConfigSync(GnssConfigLppProfileMask /*profileMask*/)
DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
@@ -708,9 +726,6 @@
GnssConfigSuplVersion LocApiBase::convertSuplVersion(const uint32_t /*suplVersion*/)
DEFAULT_IMPL(GNSS_CONFIG_SUPL_VERSION_1_0_0)
-GnssConfigLppProfile LocApiBase::convertLppProfile(const uint32_t /*lppProfile*/)
-DEFAULT_IMPL(GNSS_CONFIG_LPP_PROFILE_RRLP_ON_LTE)
-
GnssConfigLppeControlPlaneMask LocApiBase::convertLppeCp(const uint32_t /*lppeControlPlaneMask*/)
DEFAULT_IMPL(0)
@@ -721,6 +736,10 @@
const uint32_t /*emergencyExtensionSeconds*/)
DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
+void LocApiBase::setMeasurementCorrections(
+ const GnssMeasurementCorrections& /*gnssMeasurementCorrections*/)
+DEFAULT_IMPL()
+
void LocApiBase::
getWwanZppFix()
DEFAULT_IMPL()
@@ -737,12 +756,6 @@
requestForAidingData(GnssAidingDataSvMask /*svDataMask*/)
DEFAULT_IMPL()
-void LocApiBase::
- installAGpsCert(const LocDerEncodedCertificate* /*pData*/,
- size_t /*length*/,
- uint32_t /*slotBitMask*/)
-DEFAULT_IMPL()
-
LocationError LocApiBase::
setXtraVersionCheckSync(uint32_t /*check*/)
DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
@@ -750,7 +763,8 @@
LocationError LocApiBase::setBlacklistSvSync(const GnssSvIdConfig& /*config*/)
DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
-void LocApiBase::setBlacklistSv(const GnssSvIdConfig& /*config*/)
+void LocApiBase::setBlacklistSv(const GnssSvIdConfig& /*config*/,
+ LocApiResponse* /*adapterResponse*/)
DEFAULT_IMPL()
void LocApiBase::getBlacklistSv()
@@ -778,8 +792,8 @@
LocApiResponse* /*adapterResponse*/)
DEFAULT_IMPL()
-LocationError LocApiBase::getGnssEnergyConsumed()
-DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
+void LocApiBase::getGnssEnergyConsumed()
+DEFAULT_IMPL()
void LocApiBase::addGeofence(uint32_t /*clientId*/, const GeofenceOption& /*options*/,
@@ -879,4 +893,177 @@
void LocApiBase::updateSystemPowerState(PowerStateType /*powerState*/)
DEFAULT_IMPL()
+void LocApiBase::
+ configRobustLocation(bool /*enabled*/,
+ bool /*enableForE911*/,
+ LocApiResponse* /*adapterResponse*/)
+DEFAULT_IMPL()
+
+void LocApiBase::
+ getRobustLocationConfig(uint32_t sessionId, LocApiResponse* /*adapterResponse*/)
+DEFAULT_IMPL()
+
+void LocApiBase::
+ configMinGpsWeek(uint16_t minGpsWeek,
+ LocApiResponse* /*adapterResponse*/)
+DEFAULT_IMPL()
+
+void LocApiBase::
+ getMinGpsWeek(uint32_t sessionId, LocApiResponse* /*adapterResponse*/)
+DEFAULT_IMPL()
+
+LocationError LocApiBase::
+ setParameterSync(const GnssConfig& gnssConfig)
+DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
+
+void LocApiBase::
+ getParameter(uint32_t sessionId, GnssConfigFlagsMask flags, LocApiResponse* /*adapterResponse*/)
+DEFAULT_IMPL()
+
+void LocApiBase::
+ configConstellationMultiBand(const GnssSvTypeConfig& secondaryBandConfig,
+ LocApiResponse* /*adapterResponse*/)
+DEFAULT_IMPL()
+
+void LocApiBase::
+ getConstellationMultiBandConfig(uint32_t sessionId, LocApiResponse* /*adapterResponse*/)
+DEFAULT_IMPL()
+
+int64_t ElapsedRealtimeEstimator::getElapsedRealtimeEstimateNanos(int64_t curDataTimeNanos,
+ bool isCurDataTimeTrustable, int64_t tbf) {
+ //The algorithm works follow below steps:
+ //When isCurDataTimeTrustable is meet (means Modem timestamp is already stable),
+ //1, Wait for mFixTimeStablizationThreshold fixes; While waiting for modem time
+ // stable, we set the traveltime to a default value;
+ //2, When the mFixTimeStablizationThreshold fix comes, we think now the mode time
+ // is already stable, calculate the initial AP-Modem clock diff(mCurrentClockDiff)
+ // using formula:
+ // mCurrentClockDiff = currentTimeNanos - locationTimeNanos - currentTravelTimeNanos
+ //3, since then, when the nth fix comes,
+ // 3.1 First update mCurrentClockDiff using below formula:
+ // mCurrentClockDiff = mCurrentClockDiff + (currentTimeNanos - sinceBootTimeNanos)
+ // - (mPrevUtcTimeNanos - mPrevBootTimeNanos)
+ // 3.2 Calculate currentTravelTimeNanos:
+ // currentTravelTimeNanos = currentTimeNanos - locationTimeNanos - mCurrentClockDiff
+ //4, It is possible that locationTimeNanos will jump,
+ // reset mFixTimeStablizationThreshold to default value, jump to step 2 to continue.
+
+ int64_t currentTravelTimeNanos = mInitialTravelTime;
+ struct timespec currentTime;
+ int64_t sinceBootTimeNanos;
+ if (getCurrentTime(currentTime, sinceBootTimeNanos)) {
+ if (isCurDataTimeTrustable) {
+ if (tbf > 0 && tbf != curDataTimeNanos - mPrevDataTimeNanos) {
+ mFixTimeStablizationThreshold = 5;
+ }
+ int64_t currentTimeNanos = (int64_t)currentTime.tv_sec*1000000000 + currentTime.tv_nsec;
+ LOC_LOGd("sinceBootTimeNanos:%" PRIi64 " currentTimeNanos:%" PRIi64 ""
+ " locationTimeNanos:%" PRIi64 "",
+ sinceBootTimeNanos, currentTimeNanos, curDataTimeNanos);
+ if (mFixTimeStablizationThreshold == 0) {
+ currentTravelTimeNanos = mInitialTravelTime;
+ mCurrentClockDiff = currentTimeNanos - curDataTimeNanos - currentTravelTimeNanos;
+ } else if (mFixTimeStablizationThreshold < 0) {
+ mCurrentClockDiff = mCurrentClockDiff + (currentTimeNanos - sinceBootTimeNanos)
+ - (mPrevUtcTimeNanos - mPrevBootTimeNanos);
+ currentTravelTimeNanos = currentTimeNanos - curDataTimeNanos - mCurrentClockDiff;
+ }
+
+ mPrevUtcTimeNanos = currentTimeNanos;
+ mPrevBootTimeNanos = sinceBootTimeNanos;
+ mPrevDataTimeNanos = curDataTimeNanos;
+ mFixTimeStablizationThreshold--;
+ }
+ } else {
+ return -1;
+ }
+ LOC_LOGd("Estimated travel time: %" PRIi64 "", currentTravelTimeNanos);
+ return (sinceBootTimeNanos - currentTravelTimeNanos);
+}
+
+void ElapsedRealtimeEstimator::reset() {
+ mCurrentClockDiff = 0;
+ mPrevDataTimeNanos = 0;
+ mPrevUtcTimeNanos = 0;
+ mPrevBootTimeNanos = 0;
+ mFixTimeStablizationThreshold = 5;
+}
+
+int64_t ElapsedRealtimeEstimator::getElapsedRealtimeQtimer(int64_t qtimerTicksAtOrigin) {
+ struct timespec currentTime;
+ int64_t sinceBootTimeNanos;
+ int64_t elapsedRealTimeNanos;
+
+ if (getCurrentTime(currentTime, sinceBootTimeNanos)) {
+ uint64_t qtimerDiff = 0;
+ uint64_t qTimerTickCount = getQTimerTickCount();
+ if (qTimerTickCount >= qtimerTicksAtOrigin) {
+ qtimerDiff = qTimerTickCount - qtimerTicksAtOrigin;
+ }
+ LOC_LOGd("sinceBootTimeNanos:%" PRIi64 " qtimerTicksAtOrigin=%" PRIi64 ""
+ " qTimerTickCount=%" PRIi64 " qtimerDiff=%" PRIi64 "",
+ sinceBootTimeNanos, qtimerTicksAtOrigin, qTimerTickCount, qtimerDiff);
+ uint64_t qTimerDiffNanos = qTimerTicksToNanos(double(qtimerDiff));
+
+ /* If the time difference between Qtimer on modem side and Qtimer on AP side
+ is greater than one second we assume this is a dual-SoC device such as
+ Kona and will try to get Qtimer on modem side and on AP side and
+ will adjust our difference accordingly */
+ if (qTimerDiffNanos > 1000000000) {
+ uint64_t qtimerDelta = getQTimerDeltaNanos();
+ if (qTimerDiffNanos >= qtimerDelta) {
+ qTimerDiffNanos -= qtimerDelta;
+ }
+ }
+
+ LOC_LOGd("Qtimer travel time: %" PRIi64 "", qTimerDiffNanos);
+ if (sinceBootTimeNanos >= qTimerDiffNanos) {
+ elapsedRealTimeNanos = sinceBootTimeNanos - qTimerDiffNanos;
+ } else {
+ elapsedRealTimeNanos = -1;
+ }
+ } else {
+ elapsedRealTimeNanos = -1;
+ }
+ return elapsedRealTimeNanos;
+}
+
+bool ElapsedRealtimeEstimator::getCurrentTime(
+ struct timespec& currentTime, int64_t& sinceBootTimeNanos)
+{
+ struct timespec sinceBootTime;
+ struct timespec sinceBootTimeTest;
+ bool clockGetTimeSuccess = false;
+ const uint32_t MAX_TIME_DELTA_VALUE_NANOS = 15000;
+ const uint32_t MAX_GET_TIME_COUNT = 20;
+ /* Attempt to get CLOCK_REALTIME and CLOCK_BOOTIME in succession without an interruption
+ or context switch (for up to MAX_GET_TIME_COUNT times) to avoid errors in the calculation */
+ for (uint32_t i = 0; i < MAX_GET_TIME_COUNT; i++) {
+ if (clock_gettime(CLOCK_BOOTTIME, &sinceBootTime) != 0) {
+ break;
+ };
+ if (clock_gettime(CLOCK_REALTIME, ¤tTime) != 0) {
+ break;
+ }
+ if (clock_gettime(CLOCK_BOOTTIME, &sinceBootTimeTest) != 0) {
+ break;
+ };
+ sinceBootTimeNanos = (int64_t)sinceBootTime.tv_sec * 1000000000 + sinceBootTime.tv_nsec;
+ int64_t sinceBootTimeTestNanos =
+ (int64_t)sinceBootTimeTest.tv_sec * 1000000000 + sinceBootTimeTest.tv_nsec;
+ int64_t sinceBootTimeDeltaNanos = sinceBootTimeTestNanos - sinceBootTimeNanos;
+
+ /* sinceBootTime and sinceBootTimeTest should have a close value if there was no
+ interruption or context switch between clock_gettime for CLOCK_BOOTIME and
+ clock_gettime for CLOCK_REALTIME */
+ if (sinceBootTimeDeltaNanos < MAX_TIME_DELTA_VALUE_NANOS) {
+ clockGetTimeSuccess = true;
+ break;
+ } else {
+ LOC_LOGd("Delta:%" PRIi64 "ns time too large, retry number #%u...",
+ sinceBootTimeDeltaNanos, i + 1);
+ }
+ }
+ return clockGetTimeSuccess;
+}
} // namespace loc_core
diff --git a/core/LocApiBase.h b/core/LocApiBase.h
index 9c76bab..cbe5f9f 100644
--- a/core/LocApiBase.h
+++ b/core/LocApiBase.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2014, 2016-2019 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2014, 2016-2020 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,6 +36,15 @@
#include <MsgTask.h>
#include <LocSharedLock.h>
#include <log_util.h>
+#ifdef NO_UNORDERED_SET_OR_MAP
+ #include <map>
+#else
+ #include <unordered_map>
+#endif
+#include <inttypes.h>
+#include <functional>
+
+using namespace loc_util;
namespace loc_core {
@@ -59,13 +68,6 @@
#define TO_1ST_HANDLING_ADAPTER(adapters, call) \
for (int i = 0; i <MAX_ADAPTERS && NULL != (adapters)[i] && !(call); i++);
-enum xtra_version_check {
- DISABLED,
- AUTO,
- XTRA2,
- XTRA3
-};
-
class LocAdapterBase;
struct LocSsrMsg;
struct LocOpenMsg;
@@ -97,6 +99,9 @@
inline LocApiProxyBase() {}
inline virtual ~LocApiProxyBase() {}
inline virtual void* getSibling2() { return NULL; }
+ inline virtual double getGloRfLoss(uint32_t left,
+ uint32_t center, uint32_t right, uint8_t gloFrequency) { return 0.0; }
+ inline virtual float getGeoidalSeparation(double latitude, double longitude) { return 0.0; }
};
class LocApiBase {
@@ -125,7 +130,7 @@
inline virtual ~LocApiBase() {
android_atomic_dec(&mMsgTaskRefCount);
if (nullptr != mMsgTask && 0 == mMsgTaskRefCount) {
- mMsgTask->destroy();
+ delete mMsgTask;
mMsgTask = nullptr;
}
}
@@ -196,6 +201,12 @@
void reportKlobucharIonoModel(GnssKlobucharIonoModel& ionoModel);
void reportGnssAdditionalSystemInfo(GnssAdditionalSystemInfo& additionalSystemInfo);
void sendNfwNotification(GnssNfwNotification& notification);
+ void reportGnssConfig(uint32_t sessionId, const GnssConfig& gnssConfig);
+ void reportLatencyInfo(GnssLatencyInfo& gnssLatencyInfo);
+ void reportQwesCapabilities
+ (
+ const std::unordered_map<LocationQwesFeatureType, bool> &featureMap
+ );
void geofenceBreach(size_t count, uint32_t* hwIds, Location& location,
GeofenceBreachType breachType, uint64_t timestamp);
@@ -214,12 +225,12 @@
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(double latitude, double longitude, float accuracy,
+ bool onDemandCpi);
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);
@@ -228,7 +239,7 @@
virtual void informNiResponse(GnssNiResponse userResponse, const void* passThroughData);
virtual LocationError setSUPLVersionSync(GnssConfigSuplVersion version);
virtual enum loc_api_adapter_err setNMEATypesSync(uint32_t typesMask);
- virtual LocationError setLPPConfigSync(GnssConfigLppProfile profile);
+ virtual LocationError setLPPConfigSync(GnssConfigLppProfileMask profileMask);
virtual enum loc_api_adapter_err setSensorPropertiesSync(
bool gyroBiasVarianceRandomWalk_valid, float gyroBiasVarianceRandomWalk,
bool accelBiasVarianceRandomWalk_valid, float accelBiasVarianceRandomWalk,
@@ -244,21 +255,21 @@
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 setMeasurementCorrections(
+ const GnssMeasurementCorrections& gnssMeasurementCorrections);
virtual void getWwanZppFix();
virtual void getBestAvailableZppFix();
- 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);
+ virtual void setBlacklistSv(const GnssSvIdConfig& config,
+ LocApiResponse *adapterResponse=nullptr);
virtual void getBlacklistSv();
virtual void setConstellationControl(const GnssSvTypeConfig& config,
LocApiResponse *adapterResponse=nullptr);
@@ -271,7 +282,7 @@
LocApiResponse* adapterResponse=nullptr);
virtual void setPositionAssistedClockEstimatorMode(bool enabled,
LocApiResponse* adapterResponse=nullptr);
- virtual LocationError getGnssEnergyConsumed();
+ virtual void getGnssEnergyConsumed();
virtual void addGeofence(uint32_t clientId, const GeofenceOption& options,
const GeofenceInfo& info, LocApiResponseData<LocApiGeofenceData>* adapterResponseData);
@@ -318,6 +329,43 @@
void updateNmeaMask(uint32_t mask);
virtual void updateSystemPowerState(PowerStateType systemPowerState);
+
+ virtual void configRobustLocation(bool enable, bool enableForE911,
+ LocApiResponse* adapterResponse=nullptr);
+ virtual void getRobustLocationConfig(uint32_t sessionId, LocApiResponse* adapterResponse);
+ virtual void configMinGpsWeek(uint16_t minGpsWeek,
+ LocApiResponse* adapterResponse=nullptr);
+ virtual void getMinGpsWeek(uint32_t sessionId, LocApiResponse* adapterResponse);
+
+ virtual LocationError setParameterSync(const GnssConfig & gnssConfig);
+ virtual void getParameter(uint32_t sessionId, GnssConfigFlagsMask flags,
+ LocApiResponse* adapterResponse=nullptr);
+
+ virtual void configConstellationMultiBand(const GnssSvTypeConfig& secondaryBandConfig,
+ LocApiResponse* adapterResponse=nullptr);
+ virtual void getConstellationMultiBandConfig(uint32_t sessionId,
+ LocApiResponse* adapterResponse=nullptr);
+};
+
+class ElapsedRealtimeEstimator {
+private:
+ int64_t mCurrentClockDiff;
+ int64_t mPrevUtcTimeNanos;
+ int64_t mPrevBootTimeNanos;
+ int64_t mFixTimeStablizationThreshold;
+ int64_t mInitialTravelTime;
+ int64_t mPrevDataTimeNanos;
+public:
+
+ ElapsedRealtimeEstimator(int64_t travelTimeNanosEstimate):
+ mInitialTravelTime(travelTimeNanosEstimate) {reset();}
+ int64_t getElapsedRealtimeEstimateNanos(int64_t curDataTimeNanos,
+ bool isCurDataTimeTrustable, int64_t tbf);
+ inline int64_t getElapsedRealtimeUncNanos() { return 5000000;}
+ void reset();
+
+ static int64_t getElapsedRealtimeQtimer(int64_t qtimerTicksAtOrigin);
+ static bool getCurrentTime(struct timespec& currentTime, int64_t& sinceBootTimeNanos);
};
typedef LocApiBase* (getLocApi_t)(LOC_API_ADAPTER_EVENT_MASK_T exMask,
diff --git a/core/LocContext.cpp b/core/LocContext.cpp
index 18d3f2d..272c08c 100644
--- a/core/LocContext.cpp
+++ b/core/LocContext.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2014, 2016-2019 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2014, 2016-2020 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,36 +50,25 @@
pthread_mutex_t LocContext::mGetLocContextMutex = PTHREAD_MUTEX_INITIALIZER;
-const MsgTask* LocContext::getMsgTask(LocThread::tCreate tCreator,
- const char* name, bool joinable)
+const MsgTask* LocContext::getMsgTask(const char* name)
{
if (NULL == mMsgTask) {
- mMsgTask = new MsgTask(tCreator, name, joinable);
+ mMsgTask = new MsgTask(name);
}
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)
+ContextBase* LocContext::getLocContext(const char* name)
{
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);
+ const MsgTask* msgTask = getMsgTask(name);
mContext = new LocContext(msgTask);
}
pthread_mutex_unlock(&LocContext::mGetLocContextMutex);
- if (firstMsg) {
- mContext->sendMsg(firstMsg);
- }
-
return mContext;
}
diff --git a/core/LocContext.h b/core/LocContext.h
index fb7d009..628ed93 100644
--- a/core/LocContext.h
+++ b/core/LocContext.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2014, 2017-2019 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2014, 2017-2020 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
@@ -39,9 +39,7 @@
class LocContext : public ContextBase {
static const MsgTask* mMsgTask;
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 const MsgTask* getMsgTask(const char* name);
static pthread_mutex_t mGetLocContextMutex;
protected:
@@ -52,11 +50,7 @@
static const char* mLBSLibName;
static const char* mLocationHalName;
- static ContextBase* getLocContext(LocThread::tCreate tCreator, LocMsg* firstMsg,
- const char* name, bool joinable = true);
- inline static ContextBase* getLocContext(const char* name, bool joinable = true) {
- return getLocContext(NULL, NULL, name, joinable);
- }
+ static ContextBase* getLocContext(const char* name);
static void injectFeatureConfig(ContextBase *context);
};
diff --git a/core/Makefile.am b/core/Makefile.am
index 1199a52..291dbb5 100644
--- a/core/Makefile.am
+++ b/core/Makefile.am
@@ -40,6 +40,10 @@
SystemStatusOsObserver.cpp \
SystemStatus.cpp
+if USE_EXTERNAL_AP
+AM_CFLAGS += -DFEATURE_EXTERNAL_AP
+endif
+
library_includedir = $(pkgincludedir)
library_include_HEADERS = $(libloc_core_la_h_sources)
diff --git a/core/SystemStatus.cpp b/core/SystemStatus.cpp
index 393eead..fe11de0 100644
--- a/core/SystemStatus.cpp
+++ b/core/SystemStatus.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, 2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2021, 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
@@ -1287,6 +1287,14 @@
mInstance = NULL;
}
+void SystemStatus::resetNetworkInfo() {
+ for (int i=0; i<mCache.mNetworkInfo.size(); ++i) {
+ // Reset all the cached NetworkInfo Items as disconnected
+ eventConnectionStatus(false, mCache.mNetworkInfo[i].mType, mCache.mNetworkInfo[i].mRoaming,
+ mCache.mNetworkInfo[i].mNetworkHandle, mCache.mNetworkInfo[i].mApn);
+ }
+}
+
IOsObserver* SystemStatus::getOsObserver()
{
return &mSysStatusObsvr;
@@ -1578,6 +1586,7 @@
break;
}
pthread_mutex_unlock(&mMutexSystemStatus);
+ LOC_LOGv("DataItemId: %d, whether to record dateitem in cache: %d", dataitem->getId(), ret);
return ret;
}
@@ -1724,11 +1733,12 @@
@return true when successfully done
******************************************************************************/
bool SystemStatus::eventConnectionStatus(bool connected, int8_t type,
- bool roaming, NetworkHandle networkHandle)
+ bool roaming, NetworkHandle networkHandle,
+ string& apn)
{
// send networkinof dataitem to systemstatus observer clients
SystemStatusNetworkInfo s(type, "", "", connected, roaming,
- (uint64_t) networkHandle);
+ (uint64_t) networkHandle, apn);
mSysStatusObsvr.notify({&s});
return true;
diff --git a/core/SystemStatus.h b/core/SystemStatus.h
index 8ec85fa..21036cd 100644
--- a/core/SystemStatus.h
+++ b/core/SystemStatus.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2021, 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
@@ -482,12 +482,13 @@
NetworkInfoDataItemBase* mSrcObjPtr;
public:
inline SystemStatusNetworkInfo(
- int32_t type=0,
- std::string typeName="",
- string subTypeName="",
- bool connected=false,
- bool roaming=false,
- uint64_t networkHandle=NETWORK_HANDLE_UNKNOWN) :
+ int32_t type = 0,
+ std::string typeName = "",
+ string subTypeName = "",
+ bool connected = false,
+ bool roaming = false,
+ uint64_t networkHandle = NETWORK_HANDLE_UNKNOWN,
+ string apn = "") :
NetworkInfoDataItemBase(
(NetworkType)type,
type,
@@ -496,33 +497,39 @@
connected && (!roaming),
connected,
roaming,
- networkHandle),
+ networkHandle, apn),
mSrcObjPtr(nullptr) {}
inline SystemStatusNetworkInfo(const NetworkInfoDataItemBase& itemBase) :
NetworkInfoDataItemBase(itemBase),
mSrcObjPtr((NetworkInfoDataItemBase*)&itemBase) {
- mType = itemBase.getType();
+ mType = (int32_t)itemBase.getType();
}
inline bool equals(const SystemStatusNetworkInfo& peer) {
- for (uint8_t i = 0; i < MAX_NETWORK_HANDLES; ++i) {
- if (!(mAllNetworkHandles[i] == peer.mAllNetworkHandles[i])) {
- return false;
- }
- }
- return true;
+ bool rtv = (peer.mConnected == mConnected);
+ for (uint8_t i = 0; rtv && i < MAX_NETWORK_HANDLES; ++i) {
+ rtv &= (mAllNetworkHandles[i] == peer.mAllNetworkHandles[i]);
+ }
+ return rtv && !peer.mApn.compare(mApn);
}
inline virtual SystemStatusItemBase& collate(SystemStatusItemBase& curInfo) {
+ LOC_LOGv("NetworkInfo: mAllTypes=%" PRIx64 " connected=%u mType=%x mApn=%s",
+ mAllTypes, mConnected, mType, mApn.c_str());
uint64_t allTypes = (static_cast<SystemStatusNetworkInfo&>(curInfo)).mAllTypes;
- uint64_t networkHandle =
- (static_cast<SystemStatusNetworkInfo&>(curInfo)).mNetworkHandle;
- int32_t type = (static_cast<SystemStatusNetworkInfo&>(curInfo)).mType;
+ string& apn = (static_cast<SystemStatusNetworkInfo&>(curInfo)).mApn;
// Replace current with cached table for now and then update
memcpy(mAllNetworkHandles,
(static_cast<SystemStatusNetworkInfo&>(curInfo)).getNetworkHandle(),
sizeof(mAllNetworkHandles));
+ LOC_LOGd("NetworkInfo: allTypes=%" PRIx64 " mType=%x mConnected=%u mNetworkHandle=%" PRIx64 , allTypes, mType, mConnected, mNetworkHandle);
+ // Update the apn for non-mobile type connections.
+ if (TYPE_MOBILE != mType && apn.compare("") != 0) {
+ mApn = apn;
+ }
if (mConnected) {
mAllTypes |= allTypes;
for (uint8_t i = 0; i < MAX_NETWORK_HANDLES; ++i) {
+ LOC_LOGd("NetworkInfo: mNetworkHandle[%u]: networkHandle %" PRIx64 ", networkType %x", i, mAllNetworkHandles[i].networkHandle,
+ mAllNetworkHandles[i].networkType);
if (mNetworkHandle == mAllNetworkHandles[i].networkHandle) {
LOC_LOGD("collate duplicate detected, not updating");
break;
@@ -542,18 +549,21 @@
++lastValidIndex) {
// Maintain count for number of network handles still
// connected for given type
- if (mType == mAllNetworkHandles[lastValidIndex].networkType) {
- typeCount++;
+ if (mType == (int32_t)mAllNetworkHandles[lastValidIndex].networkType) {
+ if (mNetworkHandle == mAllNetworkHandles[lastValidIndex].networkHandle) {
+ deletedIndex = lastValidIndex;
+ } else {
+ typeCount++;
+ }
}
- if (mNetworkHandle == mAllNetworkHandles[lastValidIndex].networkHandle) {
- deletedIndex = lastValidIndex;
- typeCount--;
- }
+ }
+ if (lastValidIndex > 0) {
+ --lastValidIndex;
}
if (MAX_NETWORK_HANDLES != deletedIndex) {
- LOC_LOGD("deletedIndex:%u, lastValidIndex:%u, typeCount:%u",
+ LOC_LOGd("deletedIndex:%u, lastValidIndex:%u, typeCount:%u",
deletedIndex, lastValidIndex, typeCount);
mAllNetworkHandles[deletedIndex] = mAllNetworkHandles[lastValidIndex];
mAllNetworkHandles[lastValidIndex].networkHandle = NETWORK_HANDLE_UNKNOWN;
@@ -578,8 +588,8 @@
return *this;
}
inline void dump(void) override {
- LOC_LOGD("NetworkInfo: mAllTypes=%" PRIx64 " connected=%u mType=%x",
- mAllTypes, mConnected, mType);
+ LOC_LOGD("NetworkInfo: mAllTypes=%" PRIx64 " connected=%u mType=%x mApn=%s",
+ mAllTypes, mConnected, mType, mApn.c_str());
}
};
@@ -908,8 +918,9 @@
bool getReport(SystemStatusReports& reports, bool isLatestonly = false) const;
bool setDefaultGnssEngineStates(void);
bool eventConnectionStatus(bool connected, int8_t type,
- bool roaming, NetworkHandle networkHandle);
+ bool roaming, NetworkHandle networkHandle, string& apn);
bool updatePowerConnectState(bool charging);
+ void resetNetworkInfo();
};
} // namespace loc_core
diff --git a/core/SystemStatusOsObserver.cpp b/core/SystemStatusOsObserver.cpp
index 0427380..8fd9564 100644
--- a/core/SystemStatusOsObserver.cpp
+++ b/core/SystemStatusOsObserver.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2020, 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 @@
{
template <typename CINT, typename COUT>
COUT SystemStatusOsObserver::containerTransfer(CINT& inContainer) {
- COUT outContainer(0);
+ COUT outContainer = {};
for (auto item : inContainer) {
outContainer.insert(outContainer.begin(), item);
}
@@ -67,6 +67,7 @@
inline SetSubsObj(ObserverContext& context, IDataItemSubscription* subscriptionObj) :
mContext(context), mSubsObj(subscriptionObj) {}
void proc() const {
+ LOC_LOGi("SetSubsObj::enter");
mContext.mSubscriptionObj = mSubsObj;
if (!mContext.mSSObserver->mDataItemToClients.empty()) {
@@ -76,6 +77,7 @@
mContext.mSubscriptionObj->subscribe(dis, mContext.mSSObserver);
mContext.mSubscriptionObj->requestData(dis, mContext.mSSObserver);
}
+ LOC_LOGi("SetSubsObj::exit");
}
};
@@ -101,7 +103,7 @@
mToRequestData(requestData) {}
void proc() const {
- unordered_set<DataItemId> dataItemsToSubscribe(0);
+ unordered_set<DataItemId> dataItemsToSubscribe = {};
mParent->mDataItemToClients.add(mDataItemSet, {mClient}, &dataItemsToSubscribe);
mParent->mClientToDataItems.add(mClient, mDataItemSet);
@@ -147,8 +149,8 @@
mDataItemSet(containerTransfer<list<DataItemId>, unordered_set<DataItemId>>(l)) {}
void proc() const {
- unordered_set<DataItemId> dataItemsToSubscribe(0);
- unordered_set<DataItemId> dataItemsToUnsubscribe(0);
+ unordered_set<DataItemId> dataItemsToSubscribe = {};
+ unordered_set<DataItemId> dataItemsToUnsubscribe = {};
unordered_set<IDataItemObserver*> clients({mClient});
// below removes clients from all entries keyed with the return of the
// mClientToDataItems.update() call. If leaving an empty set of clients as the
@@ -219,11 +221,11 @@
mDataItemSet(containerTransfer<list<DataItemId>, unordered_set<DataItemId>>(l)) {}
void proc() const {
- unordered_set<DataItemId> dataItemsUnusedByClient(0);
- unordered_set<IDataItemObserver*> clientToRemove(0);
+ unordered_set<DataItemId> dataItemsUnusedByClient = {};
+ unordered_set<IDataItemObserver*> clientToRemove = {};
+ unordered_set<DataItemId> dataItemsToUnsubscribe = {};
mParent->mClientToDataItems.trimOrRemove({mClient}, mDataItemSet, &clientToRemove,
&dataItemsUnusedByClient);
- unordered_set<DataItemId> dataItemsToUnsubscribe(0);
mParent->mDataItemToClients.trimOrRemove(dataItemsUnusedByClient, {mClient},
&dataItemsToUnsubscribe, nullptr);
@@ -259,6 +261,7 @@
void proc() const {
unordered_set<DataItemId> diByClient = mParent->mClientToDataItems.getValSet(mClient);
+
if (!diByClient.empty()) {
unordered_set<DataItemId> dataItemsToUnsubscribe;
mParent->mClientToDataItems.remove(mClient);
@@ -308,7 +311,7 @@
void proc() const {
// Update Cache with received data items and prepare
// list of data items to be sent.
- unordered_set<DataItemId> dataItemIdsToBeSent(0);
+ unordered_set<DataItemId> dataItemIdsToBeSent = {};
for (auto item : mDiVec) {
if (mParent->updateCache(item)) {
dataItemIdsToBeSent.insert(item->getId());
@@ -316,7 +319,7 @@
}
// Send data item to all subscribed clients
- unordered_set<IDataItemObserver*> clientSet(0);
+ unordered_set<IDataItemObserver*> clientSet = {};
for (auto each : dataItemIdsToBeSent) {
auto clients = mParent->mDataItemToClients.getValSetPtr(each);
if (nullptr != clients) {
@@ -347,11 +350,6 @@
vector<IDataItemCore*> dataItemVec(dlist.size());
for (auto each : dlist) {
- IF_LOC_LOGD {
- string dv;
- each->stringify(dv);
- LOC_LOGD("notify: DataItem In Value:%s", dv.c_str());
- }
IDataItemCore* di = DataItemsFactoryProxy::createNewDataItem(each->getId());
if (nullptr == di) {
@@ -364,6 +362,11 @@
// add this dataitem if updated from last one
dataItemVec.push_back(di);
+ IF_LOC_LOGD {
+ string dv;
+ di->stringify(dv);
+ LOC_LOGd("notify: DataItem In Value:%s", dv.c_str());
+ }
}
if (!dataItemVec.empty()) {
@@ -449,59 +452,73 @@
}
#ifdef USE_GLIB
-bool SystemStatusOsObserver::connectBackhaul()
+bool SystemStatusOsObserver::connectBackhaul(const string& clientName)
{
bool result = false;
if (mContext.mFrameworkActionReqObj != NULL) {
struct HandleConnectBackhaul : public LocMsg {
- HandleConnectBackhaul(IFrameworkActionReq* fwkActReq) :
- mFwkActionReqObj(fwkActReq) {}
+ HandleConnectBackhaul(IFrameworkActionReq* fwkActReq, const string& clientName) :
+ mClientName(clientName), mFwkActionReqObj(fwkActReq) {}
virtual ~HandleConnectBackhaul() {}
void proc() const {
- LOC_LOGD("HandleConnectBackhaul");
- mFwkActionReqObj->connectBackhaul();
+ LOC_LOGi("HandleConnectBackhaul::enter");
+ mFwkActionReqObj->connectBackhaul(mClientName);
+ LOC_LOGi("HandleConnectBackhaul::exit");
}
IFrameworkActionReq* mFwkActionReqObj;
+ string mClientName;
};
mContext.mMsgTask->sendMsg(
- new (nothrow) HandleConnectBackhaul(mContext.mFrameworkActionReqObj));
+ new (nothrow) HandleConnectBackhaul(mContext.mFrameworkActionReqObj, clientName));
result = true;
}
else {
- ++mBackHaulConnectReqCount;
- LOC_LOGE("Framework action request object is NULL.Caching connect request: %d",
- mBackHaulConnectReqCount);
+ LOC_LOGe("Framework action request object is NULL.Caching connect request: %s",
+ clientName.c_str());
+ ClientBackhaulReqCache::const_iterator iter = mBackHaulConnReqCache.find(clientName);
+ if (iter == mBackHaulConnReqCache.end()) {
+ // not found in set. first time receiving from request from client
+ LOC_LOGe("Adding client to BackHaulConnReqCache list");
+ mBackHaulConnReqCache.insert(clientName);
+ }
result = false;
}
return result;
}
-bool SystemStatusOsObserver::disconnectBackhaul()
+bool SystemStatusOsObserver::disconnectBackhaul(const string& clientName)
{
bool result = false;
if (mContext.mFrameworkActionReqObj != NULL) {
struct HandleDisconnectBackhaul : public LocMsg {
- HandleDisconnectBackhaul(IFrameworkActionReq* fwkActReq) :
- mFwkActionReqObj(fwkActReq) {}
+ HandleDisconnectBackhaul(IFrameworkActionReq* fwkActReq, const string& clientName) :
+ mClientName(clientName), mFwkActionReqObj(fwkActReq) {}
virtual ~HandleDisconnectBackhaul() {}
void proc() const {
- LOC_LOGD("HandleDisconnectBackhaul");
- mFwkActionReqObj->disconnectBackhaul();
+ LOC_LOGi("HandleDisconnectBackhaul::enter");
+ mFwkActionReqObj->disconnectBackhaul(mClientName);
+ LOC_LOGi("HandleDisconnectBackhaul::exit");
}
IFrameworkActionReq* mFwkActionReqObj;
+ string mClientName;
};
mContext.mMsgTask->sendMsg(
- new (nothrow) HandleDisconnectBackhaul(mContext.mFrameworkActionReqObj));
+ new (nothrow) HandleDisconnectBackhaul(mContext.mFrameworkActionReqObj,
+ clientName));
}
else {
- if (mBackHaulConnectReqCount > 0) {
- --mBackHaulConnectReqCount;
+ LOC_LOGe("Framework action request object is NULL.Caching disconnect request: %s",
+ clientName.c_str());
+ // Check if client has requested for backhaul connection.
+ ClientBackhaulReqCache::const_iterator iter = mBackHaulConnReqCache.find(clientName);
+ if (iter != mBackHaulConnReqCache.end()) {
+ // client found, remove from set.
+ LOC_LOGd("Removing client from BackHaulConnReqCache list");
+ mBackHaulConnReqCache.erase(iter);
}
- LOC_LOGE("Framework action request object is NULL.Caching disconnect request: %d",
- mBackHaulConnectReqCount);
result = false;
}
return result;
@@ -518,7 +535,7 @@
} else {
string clientName;
to->getName(clientName);
- list<IDataItemCore*> dataItems(0);
+ list<IDataItemCore*> dataItems = {};
for (auto each : s) {
auto citer = mDataItemCache.find(each);
diff --git a/core/SystemStatusOsObserver.h b/core/SystemStatusOsObserver.h
index fd60606..c0f56d8 100644
--- a/core/SystemStatusOsObserver.h
+++ b/core/SystemStatusOsObserver.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2017, 2020 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
@@ -60,6 +60,10 @@
typedef LocUnorderedSetMap<DataItemId, IDataItemObserver*> DataItemToClients;
typedef unordered_map<DataItemId, IDataItemCore*> DataItemIdToCore;
typedef unordered_map<DataItemId, int> DataItemIdToInt;
+#ifdef USE_GLIB
+// Cache details of backhaul client requests
+typedef unordered_set<string> ClientBackhaulReqCache;
+#endif
struct ObserverContext {
IDataItemSubscription* mSubscriptionObj;
@@ -83,12 +87,7 @@
inline SystemStatusOsObserver(SystemStatus* systemstatus, const MsgTask* msgTask) :
mSystemStatus(systemstatus), mContext(msgTask, this),
mAddress("SystemStatusOsObserver"),
- mClientToDataItems(MAX_DATA_ITEM_ID), mDataItemToClients(MAX_DATA_ITEM_ID)
-#ifdef USE_GLIB
- , mBackHaulConnectReqCount(0)
-#endif
- {
- }
+ mClientToDataItems(MAX_DATA_ITEM_ID), mDataItemToClients(MAX_DATA_ITEM_ID) {}
// dtor
~SystemStatusOsObserver();
@@ -107,9 +106,15 @@
inline void setFrameworkActionReqObj(IFrameworkActionReq* frameworkActionReqObj) {
mContext.mFrameworkActionReqObj = frameworkActionReqObj;
#ifdef USE_GLIB
- if (mBackHaulConnectReqCount > 0) {
- connectBackhaul();
- mBackHaulConnectReqCount = 0;
+ uint32_t numBackHaulClients = mBackHaulConnReqCache.size();
+ if (numBackHaulClients > 0) {
+ // For each client, invoke connectbackhaul.
+ for (auto clientName : mBackHaulConnReqCache) {
+ LOC_LOGd("Invoke connectBackhaul for client: %s", clientName.c_str());
+ connectBackhaul(clientName);
+ }
+ // Clear the set
+ mBackHaulConnReqCache.clear();
}
#endif
}
@@ -135,8 +140,8 @@
virtual void turnOn(DataItemId dit, int timeOut = 0) override;
virtual void turnOff(DataItemId dit) override;
#ifdef USE_GLIB
- virtual bool connectBackhaul() override;
- virtual bool disconnectBackhaul();
+ virtual bool connectBackhaul(const string& clientName) override;
+ virtual bool disconnectBackhaul(const string& clientName) override;
#endif
private:
@@ -153,7 +158,7 @@
const list<DataItemId>& l, IDataItemObserver* client);
#ifdef USE_GLIB
// Cache the framework action request for connect/disconnect
- int mBackHaulConnectReqCount;
+ ClientBackhaulReqCache mBackHaulConnReqCache;
#endif
void subscribe(const list<DataItemId>& l, IDataItemObserver* client, bool toRequestData);
diff --git a/core/configure.ac b/core/configure.ac
index 548c5e5..19db9cf 100644
--- a/core/configure.ac
+++ b/core/configure.ac
@@ -86,6 +86,19 @@
AM_CONDITIONAL(USE_FEATURE_AUTOMOTIVE, test "x${with_auto_feature}" = "xyes")
+# External AP
+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"
+fi
+
+AM_CONDITIONAL(USE_EXTERNAL_AP, test "x${with_external_ap}" = "xyes")
+
AC_CONFIG_FILES([ \
Makefile \
loc-core.pc \
diff --git a/core/data-items/DataItemConcreteTypesBase.h b/core/data-items/DataItemConcreteTypesBase.h
index c32d65d..11a3cce 100644
--- a/core/data-items/DataItemConcreteTypesBase.h
+++ b/core/data-items/DataItemConcreteTypesBase.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2017, 2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2017, 2020, 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
@@ -284,7 +284,7 @@
public:
NetworkInfoDataItemBase(
NetworkType initialType, int32_t type, string typeName, string subTypeName,
- bool available, bool connected, bool roaming, uint64_t networkHandle ):
+ bool available, bool connected, bool roaming, uint64_t networkHandle, string apn):
mAllTypes(typeToAllTypes(initialType)),
mType(type),
mTypeName(typeName),
@@ -293,7 +293,7 @@
mConnected(connected),
mRoaming(roaming),
mNetworkHandle(networkHandle),
- mId(NETWORKINFO_DATA_ITEM_ID) {
+ mId(NETWORKINFO_DATA_ITEM_ID), mApn(apn) {
mAllNetworkHandles[0].networkHandle = networkHandle;
mAllNetworkHandles[0].networkType = initialType;
}
@@ -318,6 +318,7 @@
bool mRoaming;
NetworkInfoType mAllNetworkHandles[MAX_NETWORK_HANDLES];
uint64_t mNetworkHandle;
+ string mApn;
protected:
DataItemId mId;
inline uint64_t typeToAllTypes(NetworkType type) {
diff --git a/core/data-items/DataItemsFactoryProxy.cpp b/core/data-items/DataItemsFactoryProxy.cpp
index f8a5e03..10f73f4 100644
--- a/core/data-items/DataItemsFactoryProxy.cpp
+++ b/core/data-items/DataItemsFactoryProxy.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2020, 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 <DataItemsFactoryProxy.h>
#include <loc_pla.h>
#include <log_util.h>
+#include "loc_misc_utils.h"
namespace loc_core
{
@@ -48,40 +49,21 @@
mydi = (*getConcreteDIFunc)(id);
}
else {
- // first call to this function, symbol not yet loaded
- if (NULL == dataItemLibHandle) {
- LOC_LOGD("Loaded library %s",DATA_ITEMS_LIB_NAME);
- dataItemLibHandle = dlopen(DATA_ITEMS_LIB_NAME, RTLD_NOW);
- if (NULL == dataItemLibHandle) {
- // dlopen failed.
- const char * err = dlerror();
- if (NULL == err)
- {
- err = "Unknown";
- }
- LOC_LOGE("%s:%d]: failed to load library %s; error=%s",
- __func__, __LINE__, DATA_ITEMS_LIB_NAME, err);
- }
- }
+ getConcreteDIFunc = (get_concrete_data_item_fn * )
+ dlGetSymFromLib(dataItemLibHandle, DATA_ITEMS_LIB_NAME, DATA_ITEMS_GET_CONCRETE_DI);
- // load sym - if dlopen handle is obtained and symbol is not yet obtained
- if (NULL != dataItemLibHandle) {
- getConcreteDIFunc = (get_concrete_data_item_fn * )
- dlsym(dataItemLibHandle, DATA_ITEMS_GET_CONCRETE_DI);
- if (NULL != getConcreteDIFunc) {
- LOC_LOGD("Loaded function %s : %p",DATA_ITEMS_GET_CONCRETE_DI,getConcreteDIFunc);
- mydi = (*getConcreteDIFunc)(id);
+ if (NULL != getConcreteDIFunc) {
+ LOC_LOGd("Loaded function %s : %p", DATA_ITEMS_GET_CONCRETE_DI, getConcreteDIFunc);
+ mydi = (*getConcreteDIFunc)(id);
+ }
+ else {
+ // dlysm failed.
+ const char * err = dlerror();
+ if (NULL == err)
+ {
+ err = "Unknown";
}
- else {
- // dlysm failed.
- const char * err = dlerror();
- if (NULL == err)
- {
- err = "Unknown";
- }
- LOC_LOGE("%s:%d]: failed to find symbol %s; error=%s",
- __func__, __LINE__, DATA_ITEMS_GET_CONCRETE_DI, err);
- }
+ LOC_LOGe("failed to find symbol %s; error=%s", DATA_ITEMS_GET_CONCRETE_DI, err);
}
}
return mydi;
diff --git a/core/loc_core_log.cpp b/core/loc_core_log.cpp
index ddf18ec..904f94b 100644
--- a/core/loc_core_log.cpp
+++ b/core/loc_core_log.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2015, 2020 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
@@ -53,7 +53,7 @@
}
/* GPS status names */
-static const loc_name_val_s_type gps_status_name[] =
+DECLARE_TBL(gps_status_name) =
{
NAME_VAL( LOC_GPS_STATUS_NONE ),
NAME_VAL( LOC_GPS_STATUS_SESSION_BEGIN ),
@@ -61,18 +61,16 @@
NAME_VAL( LOC_GPS_STATUS_ENGINE_ON ),
NAME_VAL( LOC_GPS_STATUS_ENGINE_OFF ),
};
-static const int gps_status_num = sizeof(gps_status_name) / sizeof(loc_name_val_s_type);
/* Find Android GPS status name */
const char* loc_get_gps_status_name(LocGpsStatusValue gps_status)
{
- return loc_get_name_from_val(gps_status_name, gps_status_num,
- (long) gps_status);
+ return loc_get_name_from_val(gps_status_name_tbl, (int64_t) gps_status);
}
-static const loc_name_val_s_type loc_eng_position_modes[] =
+DECLARE_TBL(loc_eng_position_modes) =
{
NAME_VAL( LOC_POSITION_MODE_STANDALONE ),
NAME_VAL( LOC_POSITION_MODE_MS_BASED ),
@@ -83,25 +81,23 @@
NAME_VAL( LOC_POSITION_MODE_RESERVED_4 ),
NAME_VAL( LOC_POSITION_MODE_RESERVED_5 )
};
-static const int loc_eng_position_mode_num = sizeof(loc_eng_position_modes) / sizeof(loc_name_val_s_type);
const char* loc_get_position_mode_name(LocGpsPositionMode mode)
{
- return loc_get_name_from_val(loc_eng_position_modes, loc_eng_position_mode_num, (long) mode);
+ return loc_get_name_from_val(loc_eng_position_modes_tbl, (int64_t) mode);
}
-static const loc_name_val_s_type loc_eng_position_recurrences[] =
+DECLARE_TBL(loc_eng_position_recurrences) =
{
NAME_VAL( LOC_GPS_POSITION_RECURRENCE_PERIODIC ),
NAME_VAL( LOC_GPS_POSITION_RECURRENCE_SINGLE )
};
-static const int loc_eng_position_recurrence_num = sizeof(loc_eng_position_recurrences) / sizeof(loc_name_val_s_type);
const char* loc_get_position_recurrence_name(LocGpsPositionRecurrence recur)
{
- return loc_get_name_from_val(loc_eng_position_recurrences, loc_eng_position_recurrence_num, (long) recur);
+ return loc_get_name_from_val(loc_eng_position_recurrences_tbl, (int64_t) recur);
}
const char* loc_get_aiding_data_mask_names(LocGpsAidingData /*data*/)
@@ -110,7 +106,7 @@
}
-static const loc_name_val_s_type loc_eng_agps_types[] =
+DECLARE_TBL(loc_eng_agps_types) =
{
NAME_VAL( LOC_AGPS_TYPE_INVALID ),
NAME_VAL( LOC_AGPS_TYPE_ANY ),
@@ -118,44 +114,41 @@
NAME_VAL( LOC_AGPS_TYPE_C2K ),
NAME_VAL( LOC_AGPS_TYPE_WWAN_ANY )
};
-static const int loc_eng_agps_type_num = sizeof(loc_eng_agps_types) / sizeof(loc_name_val_s_type);
const char* loc_get_agps_type_name(LocAGpsType type)
{
- return loc_get_name_from_val(loc_eng_agps_types, loc_eng_agps_type_num, (long) type);
+ return loc_get_name_from_val(loc_eng_agps_types_tbl, (int64_t) type);
}
-static const loc_name_val_s_type loc_eng_ni_types[] =
+DECLARE_TBL(loc_eng_ni_types) =
{
NAME_VAL( LOC_GPS_NI_TYPE_VOICE ),
NAME_VAL( LOC_GPS_NI_TYPE_UMTS_SUPL ),
NAME_VAL( LOC_GPS_NI_TYPE_UMTS_CTRL_PLANE ),
NAME_VAL( LOC_GPS_NI_TYPE_EMERGENCY_SUPL )
};
-static const int loc_eng_ni_type_num = sizeof(loc_eng_ni_types) / sizeof(loc_name_val_s_type);
const char* loc_get_ni_type_name(LocGpsNiType type)
{
- return loc_get_name_from_val(loc_eng_ni_types, loc_eng_ni_type_num, (long) type);
+ return loc_get_name_from_val(loc_eng_ni_types_tbl, (int64_t) type);
}
-static const loc_name_val_s_type loc_eng_ni_responses[] =
+DECLARE_TBL(loc_eng_ni_responses) =
{
NAME_VAL( LOC_GPS_NI_RESPONSE_ACCEPT ),
NAME_VAL( LOC_GPS_NI_RESPONSE_DENY ),
NAME_VAL( LOC_GPS_NI_RESPONSE_DENY )
};
-static const int loc_eng_ni_reponse_num = sizeof(loc_eng_ni_responses) / sizeof(loc_name_val_s_type);
const char* loc_get_ni_response_name(LocGpsUserResponseType response)
{
- return loc_get_name_from_val(loc_eng_ni_responses, loc_eng_ni_reponse_num, (long) response);
+ return loc_get_name_from_val(loc_eng_ni_responses_tbl, (int64_t) response);
}
-static const loc_name_val_s_type loc_eng_ni_encodings[] =
+DECLARE_TBL(loc_eng_ni_encodings) =
{
NAME_VAL( LOC_GPS_ENC_NONE ),
NAME_VAL( LOC_GPS_ENC_SUPL_GSM_DEFAULT ),
@@ -163,55 +156,51 @@
NAME_VAL( LOC_GPS_ENC_SUPL_UCS2 ),
NAME_VAL( LOC_GPS_ENC_UNKNOWN )
};
-static const int loc_eng_ni_encoding_num = sizeof(loc_eng_ni_encodings) / sizeof(loc_name_val_s_type);
const char* loc_get_ni_encoding_name(LocGpsNiEncodingType encoding)
{
- return loc_get_name_from_val(loc_eng_ni_encodings, loc_eng_ni_encoding_num, (long) encoding);
+ return loc_get_name_from_val(loc_eng_ni_encodings_tbl, (int64_t) encoding);
}
-static const loc_name_val_s_type loc_eng_agps_bears[] =
+DECLARE_TBL(loc_eng_agps_bears) =
{
NAME_VAL( AGPS_APN_BEARER_INVALID ),
NAME_VAL( AGPS_APN_BEARER_IPV4 ),
NAME_VAL( AGPS_APN_BEARER_IPV6 ),
NAME_VAL( AGPS_APN_BEARER_IPV4V6 )
};
-static const int loc_eng_agps_bears_num = sizeof(loc_eng_agps_bears) / sizeof(loc_name_val_s_type);
const char* loc_get_agps_bear_name(AGpsBearerType bearer)
{
- return loc_get_name_from_val(loc_eng_agps_bears, loc_eng_agps_bears_num, (long) bearer);
+ return loc_get_name_from_val(loc_eng_agps_bears_tbl, (int64_t) bearer);
}
-static const loc_name_val_s_type loc_eng_server_types[] =
+DECLARE_TBL(loc_eng_server_types) =
{
NAME_VAL( LOC_AGPS_CDMA_PDE_SERVER ),
NAME_VAL( LOC_AGPS_CUSTOM_PDE_SERVER ),
NAME_VAL( LOC_AGPS_MPC_SERVER ),
NAME_VAL( LOC_AGPS_SUPL_SERVER )
};
-static const int loc_eng_server_types_num = sizeof(loc_eng_server_types) / sizeof(loc_name_val_s_type);
const char* loc_get_server_type_name(LocServerType type)
{
- return loc_get_name_from_val(loc_eng_server_types, loc_eng_server_types_num, (long) type);
+ return loc_get_name_from_val(loc_eng_server_types_tbl, (int64_t) type);
}
-static const loc_name_val_s_type loc_eng_position_sess_status_types[] =
+DECLARE_TBL(loc_eng_position_sess_status_types) =
{
NAME_VAL( LOC_SESS_SUCCESS ),
NAME_VAL( LOC_SESS_INTERMEDIATE ),
NAME_VAL( LOC_SESS_FAILURE )
};
-static const int loc_eng_position_sess_status_num = sizeof(loc_eng_position_sess_status_types) / sizeof(loc_name_val_s_type);
const char* loc_get_position_sess_status_name(enum loc_sess_status status)
{
- return loc_get_name_from_val(loc_eng_position_sess_status_types, loc_eng_position_sess_status_num, (long) status);
+ return loc_get_name_from_val(loc_eng_position_sess_status_types_tbl, (int64_t) status);
}
-static const loc_name_val_s_type loc_eng_agps_status_names[] =
+DECLARE_TBL(loc_eng_agps_status_names) =
{
NAME_VAL( LOC_GPS_REQUEST_AGPS_DATA_CONN ),
NAME_VAL( LOC_GPS_RELEASE_AGPS_DATA_CONN ),
@@ -219,9 +208,8 @@
NAME_VAL( LOC_GPS_AGPS_DATA_CONN_DONE ),
NAME_VAL( LOC_GPS_AGPS_DATA_CONN_FAILED )
};
-static const int loc_eng_agps_status_num = sizeof(loc_eng_agps_status_names) / sizeof(loc_name_val_s_type);
const char* loc_get_agps_status_name(LocAGpsStatusValue status)
{
- return loc_get_name_from_val(loc_eng_agps_status_names, loc_eng_agps_status_num, (long) status);
+ return loc_get_name_from_val(loc_eng_agps_status_names_tbl, (int64_t) status);
}
diff --git a/core/observer/IFrameworkActionReq.h b/core/observer/IFrameworkActionReq.h
index 4be947f..138508c 100644
--- a/core/observer/IFrameworkActionReq.h
+++ b/core/observer/IFrameworkActionReq.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017, 2020 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,8 +30,11 @@
#ifndef __IFRAMEWORKACTIONREQ_H__
#define __IFRAMEWORKACTIONREQ_H__
+#include <string>
#include <DataItemId.h>
+using namespace std;
+
namespace loc_core
{
@@ -77,7 +80,7 @@
*
* @param None
*/
- virtual bool connectBackhaul() = 0;
+ virtual bool connectBackhaul(const string& clientName) = 0;
/**
* @brief Disconnects the WWANbackhaul
@@ -85,7 +88,7 @@
*
* @param None
*/
- virtual bool disconnectBackhaul() = 0;
+ virtual bool disconnectBackhaul(const string& clientName) = 0;
#endif
/**
diff --git a/core/observer/IOsObserver.h b/core/observer/IOsObserver.h
index f661828..a25bb9f 100644
--- a/core/observer/IOsObserver.h
+++ b/core/observer/IOsObserver.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017, 2020 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
@@ -91,8 +91,8 @@
inline virtual void turnOn (DataItemId /*dit*/, int /*timeOut*/){}
inline virtual void turnOff (DataItemId /*dit*/) {}
#ifdef USE_GLIB
- inline virtual bool connectBackhaul() { return false; }
- inline virtual bool disconnectBackhaul() { return false; }
+ inline virtual bool connectBackhaul(const string& clientName) { return false; }
+ inline virtual bool disconnectBackhaul(const string& clientName) { return false; }
#endif
/**
diff --git a/etc/Android.bp b/etc/Android.bp
new file mode 100644
index 0000000..05ecd90
--- /dev/null
+++ b/etc/Android.bp
@@ -0,0 +1,58 @@
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_qcom_sm7250_gps_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-BSD
+ default_applicable_licenses: ["hardware_qcom_sm7250_gps_license"],
+}
+
+prebuilt_etc {
+
+ name: "gps.conf",
+ vendor: true,
+ src: "gps.conf",
+}
+
+prebuilt_etc {
+
+ name: "flp.conf",
+ vendor: true,
+ src: "flp.conf",
+}
+
+prebuilt_etc {
+
+ name: "gnss_antenna_info.conf",
+ vendor: true,
+ src: "gnss_antenna_info.conf",
+}
+
+prebuilt_etc {
+ name: "gnss@2.0-base.policy",
+ vendor: true,
+ sub_dir: "seccomp_policy",
+ src: "seccomp_policy/gnss@2.0-base.policy",
+}
+
+prebuilt_etc {
+ name: "gnss@2.0-xtra-daemon.policy",
+ vendor: true,
+ sub_dir: "seccomp_policy",
+ src: "seccomp_policy/gnss@2.0-xtra-daemon.policy",
+}
+
+prebuilt_etc {
+ name: "gnss@2.0-xtwifi-client.policy",
+ vendor: true,
+ sub_dir: "seccomp_policy",
+ src: "seccomp_policy/gnss@2.0-xtwifi-client.policy",
+}
+
+prebuilt_etc {
+ name: "gnss@2.0-xtwifi-inet-agent.policy",
+ vendor: true,
+ sub_dir: "seccomp_policy",
+ src: "seccomp_policy/gnss@2.0-xtwifi-inet-agent.policy",
+}
diff --git a/etc/Android.mk b/etc/Android.mk
deleted file mode 100644
index 6746876..0000000
--- a/etc/Android.mk
+++ /dev/null
@@ -1,21 +0,0 @@
-ifneq ($(BOARD_VENDOR_QCOM_LOC_PDK_FEATURE_SET),true)
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := gps.conf
-LOCAL_VENDOR_MODULE := true
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := 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/gnss_antenna_info.conf b/etc/gnss_antenna_info.conf
new file mode 100644
index 0000000..e037daa
--- /dev/null
+++ b/etc/gnss_antenna_info.conf
@@ -0,0 +1,135 @@
+###################################
+##### ANTENNA INFORMATION #####
+###################################
+
+###################################
+# ANTENNA INFO VECTOR SIZE
+###################################
+# The number of antenna info
+# structures in the vector. Each
+# entry in this vector is a structure
+# with the following elements:
+#
+# - CARRIER_FREQUENCY
+# - PC_OFFSET
+# - PC_VARIATION_CORRECTION
+# - PC_VARIATION_CORRECTION_UNC
+# - SIGNAL_GAIN_CORRECTION
+# - SIGNAL_GAIN_CORRECTION_UNC
+#
+# Notes:
+# CARRIER_FREQUENCY
+# The carrier frequency in MHz.
+#
+# PC = PHASE CENTER
+# PC_OFFSET is a structure with six
+# elements: x, y, z and their associated uncertainties
+# Phase center offset (PCO) is defined with
+# respect to the origin of the Android sensor coordinate system, e.g.,
+# center of primary screen for mobiles
+#
+# PC_VARIATION_CORRECTION
+# 2D vectors representing the phase center variation (PCV) corrections,
+# in millimeters, at regularly spaced azimuthal angle (theta) and zenith angle
+# (phi). The PCV correction is added to the phase measurement to obtain the
+# corrected value.
+# The azimuthal angle, theta, is defined with respect to the X axis of the
+# Android sensor coordinate system, increasing toward the Y axis. The zenith
+# angle, phi, is defined with respect to the Z axis of the Android Sensor
+# coordinate system, increasing toward the X-Y plane.
+# Each row vector (outer vectors) represents a fixed theta. The first row
+# corresponds to a theta angle of 0 degrees. The last row corresponds to a
+# theta angle of (360 - deltaTheta) degrees, where deltaTheta is the regular
+# spacing between azimuthal angles, i.e., deltaTheta = 360 / (number of rows).
+# The columns (inner vectors) represent fixed zenith angles, beginning at 0
+# degrees and ending at 180 degrees. They are separated by deltaPhi, the regular
+# spacing between zenith angles, i.e., deltaPhi = 180 / (number of columns - 1).
+#
+# PC_VARIATION_CORRECTION_UNC
+# 2D vectors of 1-sigma uncertainty in millimeters associated with the PCV
+# correction values.
+#
+# SIGNAL_GAIN_CORRECTION
+# 2D vectors representing the signal gain corrections at regularly spaced
+# azimuthal angle (theta) and zenith angle (phi). The values are calculated or
+# measured at the antenna feed point without considering the radio and receiver
+# noise figure and path loss contribution, in dBi, i.e., decibel over isotropic
+# antenna with the same total power. The signal gain correction is added the
+# signal gain measurement to obtain the corrected value.
+# The azimuthal angle, theta, is defined with respect to the X axis of the
+# Android sensor coordinate system, increasing toward the Y axis. The zenith
+# angle, phi, is defined with respect to the Z axis of the Android Sensor
+# coordinate system, increasing toward the X-Y plane.
+# Each row vector (outer vectors) represents a fixed theta. The first row
+# corresponds to a theta angle of 0 degrees. The last row corresponds to a
+# theta angle of (360 - deltaTheta) degrees, where deltaTheta is the regular
+# spacing between azimuthal angles, i.e., deltaTheta = 360 / (number of rows).
+# The columns (inner vectors) represent fixed zenith angles, beginning at 0
+# degrees and ending at 180 degrees. They are separated by deltaPhi, the regular
+# spacing between zenith angles, i.e., deltaPhi = 180 / (number of columns - 1).
+#
+# SIGNAL_GAIN_CORRECTION_UNC
+# 2D vectors of 1-sigma uncertainty in dBi associated with the signal
+# gain correction values.
+#
+# The number of rows and columns could be the same for PC variation correction
+# and signal gain corrections, or could be different
+# If the former then NUMBER_OF_ROWS_ and NUMBER_OF_COLUMNS_ are specified once
+# only, if the latter then NUMBER_OF_ROWS_ and NUMBER_OF_COLUMNS_ represent
+# the number of rows/columns for PC variation correction and
+# NUMBER_OF_ROWS_SGC_ and NUMBER_OF_COLUMNS_SGC_ represent the number of
+# rows/columns for signal gain corrections
+
+# ANTENNA_INFO_VECTOR_SIZE must be non zero if antenna corrections are sent
+# ANTENNA_INFO_VECTOR_SIZE = 2
+
+CARRIER_FREQUENCY_0 = 1575.42
+
+PC_OFFSET_0 = 1.2 0.1 3.4 0.2 5.6 0.3
+
+NUMBER_OF_ROWS_0 = 3
+NUMBER_OF_COLUMNS_0 = 4
+
+PC_VARIATION_CORRECTION_0_ROW_0 = 11.22 33.44 55.66 77.88
+PC_VARIATION_CORRECTION_0_ROW_1 = 10.2 30.4 50.6 70.8
+PC_VARIATION_CORRECTION_0_ROW_2 = 12.2 34.4 56.6 78.8
+
+PC_VARIATION_CORRECTION_UNC_0_ROW_0 = 0.1 0.2 0.3 0.4
+PC_VARIATION_CORRECTION_UNC_0_ROW_1 = 1.1 1.2 1.3 1.4
+PC_VARIATION_CORRECTION_UNC_0_ROW_2 = 2.1 2.2 2.3 2.4
+
+SIGNAL_GAIN_CORRECTION_0_ROW_0 = 9.8 8.7 7.6 6.5
+SIGNAL_GAIN_CORRECTION_0_ROW_1 = 5.4 4.3 3.2 2.1
+SIGNAL_GAIN_CORRECTION_0_ROW_2 = 1.3 2.4 3.5 4.6
+
+SIGNAL_GAIN_CORRECTION_UNC_0_ROW_0 = 0.11 0.22 0.33 0.44
+SIGNAL_GAIN_CORRECTION_UNC_0_ROW_1 = 0.55 0.66 0.77 0.88
+SIGNAL_GAIN_CORRECTION_UNC_0_ROW_2 = 0.91 0.92 0.93 0.94
+
+
+CARRIER_FREQUENCY_1 = 1227.6
+
+PC_OFFSET_1 = 3.4 0.2 5.6 0.3 1.2 0.1
+
+NUMBER_OF_ROWS_1 = 4
+NUMBER_OF_COLUMNS_1 = 2
+NUMBER_OF_ROWS_SGC_1 = 3
+NUMBER_OF_COLUMNS_SGC_1 = 4
+
+PC_VARIATION_CORRECTION_1_ROW_0 = 55.66 77.88
+PC_VARIATION_CORRECTION_1_ROW_1 = 11.22 33.44
+PC_VARIATION_CORRECTION_1_ROW_2 = 56.6 78.8
+PC_VARIATION_CORRECTION_1_ROW_3 = 12.2 34.4
+
+PC_VARIATION_CORRECTION_UNC_1_ROW_0 = 0.3 0.4
+PC_VARIATION_CORRECTION_UNC_1_ROW_1 = 1.1 1.2
+PC_VARIATION_CORRECTION_UNC_1_ROW_2 = 2.1 2.2
+PC_VARIATION_CORRECTION_UNC_1_ROW_3 = 0.1 0.2
+
+SIGNAL_GAIN_CORRECTION_1_ROW_0 = 7.6 6.5 5.4 4.3
+SIGNAL_GAIN_CORRECTION_1_ROW_1 = 1.3 2.4 9.8 8.7
+SIGNAL_GAIN_CORRECTION_1_ROW_2 = 1.4 2.5 3.6 4.7
+
+SIGNAL_GAIN_CORRECTION_UNC_1_ROW_0 = 0.91 0.92 0.55 0.66
+SIGNAL_GAIN_CORRECTION_UNC_1_ROW_1 = 0.11 0.22 0.93 0.94
+SIGNAL_GAIN_CORRECTION_UNC_1_ROW_2 = 0.95 0.96 0.33 0.44
diff --git a/etc/gps.conf b/etc/gps.conf
index 1d4e233..75f12f2 100644
--- a/etc/gps.conf
+++ b/etc/gps.conf
@@ -1,17 +1,10 @@
-#Version check for XTRA
-#DISABLE = 0
-#AUTO = 1
-#XTRA2 = 2
-#XTRA3 = 3
-XTRA_VERSION_CHECK=0
-
# Error Estimate
# _SET = 1
# _CLEAR = 0
ERR_ESTIMATE=0
#NTP server
-NTP_SERVER=time.izatcloud.net
+NTP_SERVER=time.xtracloud.net
#XTRA CA path
XTRA_CA_PATH=/usr/lib/ssl-1.1/certs
@@ -81,10 +74,12 @@
####################################
# LTE Positioning Profile Settings
####################################
+# LPP_PROFILE is a bit mask
# 0: Enable RRLP on LTE(Default)
-# 1: Enable LPP_User_Plane on LTE
-# 2: Enable LPP_Control_Plane
-# 3: Enable both LPP_User_Plane and LPP_Control_Plane
+# 0x1: LPP User Plane
+# 0x2: LPP Control Plane
+# 0x4: LPP User Plane for NR5G
+# 0x8: LPP Control Plane for NR5G
LPP_PROFILE = 2
####################################
@@ -100,6 +95,15 @@
# NMEA provider (1=Modem Processor, 0=Application Processor)
NMEA_PROVIDER=0
+################################
+# NMEA TAG BLOCK GROUPING
+################################
+# NMEA tag block grouping is only applicable to GSA
+# Default is disabled
+# 0 - disabled
+# 1 - enabled
+NMEA_TAG_BLOCK_GROUPING_ENABLED = 0
+
# Customized NMEA GGA fix quality that can be used to tell
# whether SENSOR contributed to the fix.
#
@@ -124,6 +128,15 @@
# 1 - enabled
CUSTOM_NMEA_GGA_FIX_QUALITY_ENABLED = 0
+################################
+# NMEA Reporting Rate Config, valid only when NMEA_PROVIDER is set to "0"
+################################
+# NMEA Reporting Rate
+# Set it to "1HZ" for 1Hz NMEA Reporting
+# Set it to "NHZ" for NHz NMEA Reporting
+#Default : NHZ (overridden by position update rate if set to lower rates)
+NMEA_REPORT_RATE=NHZ
+
# Mark if it is a SGLTE target (1=SGLTE, 0=nonSGLTE)
SGLTE_TARGET=0
@@ -184,16 +197,6 @@
# is able to acquire better timing information
AP_TIMESTAMP_UNCERTAINTY = 10
-##################################################
-# QDR engine availability status
-##################################################
-# 0 : NO QDR (default)
-# 1 : QDR enabled
-# This settings enables QDR Configuration for
-# automotive use case, if enabled then
-# DR_AP_Service needs to be enabled in izat.conf
-#EXTERNAL_DR_ENABLED = 0
-
#####################################
# DR_SYNC Pulse Availability
#####################################
@@ -318,8 +321,9 @@
##################################################
# 0 : Enable QTI GNSS (default)
# 1 : Enable QCSR SS5
-# This setting use to select between QTI GNSS
-# and QCSR SS5 hardware receiver.
+# 2 : Enable PDS API
+# This setting use to select between QTI GNSS,
+# QCSR SS5 hardware receiver, and PDS API.
# By default QTI GNSS receiver is enabled.
# GNSS_DEPLOYMENT = 0
@@ -343,3 +347,45 @@
V_LEVEL_TIME_DEPTH = 200
V_LEVEL_MAX_CAPACITY = 400
+##################################################
+# Allow buffer diag log packets when diag memory allocation
+# fails during boot up time.
+##################################################
+BUFFER_DIAG_LOGGING = 1
+
+#######################################
+# NTRIP CLIENT LIBRARY NAME
+#######################################
+# NTRIP_CLIENT_LIB_NAME =
+
+##################################################
+# Correction Data Framework settings
+# Default values:
+# CDFW_SOURCE_PRIORITY_1 = INTERNAL_1 RTCM
+# CDFW_INJECT_DATA_INTERVAL = 600000 //10 mins
+# CDFW_RTCM_MESSAGE_INTERVAL = 1000 //1 second
+#
+# If multiple sources coexist on a PL,
+# the prorioty sequence can be set by the integer number.
+# PRIORITY_1 is higher than PRIORITY_2, for example,
+# CDFW_SOURCE_PRIORITY_1 = INTERNAL_1 RTCM
+# CDFW_SOURCE_PRIORITY_2 = CV2X RTCM
+##################################################
+
+##################################################
+# RF LOSS
+# The loss in 0.1 dbHz from the C/N0 at the antenna port
+# These values must be configured by OEM if not
+# supported in QMI LOC message
+# There is one entry for each signal type
+##################################################
+RF_LOSS_GPS = 0
+RF_LOSS_GPS_L5 = 0
+RF_LOSS_GLO_LEFT = 0
+RF_LOSS_GLO_CENTER = 0
+RF_LOSS_GLO_RIGHT = 0
+RF_LOSS_BDS = 0
+RF_LOSS_BDS_B2A = 0
+RF_LOSS_GAL = 0
+RF_LOSS_GAL_E5 = 0
+RF_LOSS_NAVIC = 0
diff --git a/etc/seccomp_policy/gnss@2.0-base.policy b/etc/seccomp_policy/gnss@2.0-base.policy
new file mode 100644
index 0000000..0a2e17b
--- /dev/null
+++ b/etc/seccomp_policy/gnss@2.0-base.policy
@@ -0,0 +1,119 @@
+#*******************************************************************************
+# Copyright (c) 2020 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.
+#
+#******************************************************************************
+
+clone: 1
+close: 1
+connect: 1
+execve: 1
+exit_group: 1
+exit: 1
+faccessat: 1
+fcntl: 1
+fstat: 1
+fstatfs: 1
+futex: 1
+getpid: 1
+getuid: 1
+getgid: 1
+getegid: 1
+getgroups: 1
+geteuid: 1
+umask: 1
+getrandom: 1
+mmap: arg2 in ~PROT_EXEC || arg2 in ~PROT_WRITE
+mprotect: arg2 in ~PROT_EXEC || arg2 in ~PROT_WRITE
+mremap: 1
+munmap: 1
+newfstatat: 1
+openat: 1
+#prctl: arg0 == PR_SET_VMA || arg0 == PR_SET_NO_NEW_PRIVS || arg0 == PR_GET_DUMPABLE || arg0 == PR_SET_SECCOMP || arg0 == 0x37 /* PR_??? */
+prctl: 1
+pread64: 1
+read: 1
+pwrite64: 1
+write: 1
+writev: 1
+readlinkat: 1
+restart_syscall: 1
+rt_sigaction: 1
+rt_sigprocmask: 1
+rt_sigreturn: 1
+sched_getscheduler: 1
+set_tid_address: 1
+sigaltstack: 1
+unlinkat: 1
+lseek: 1
+##ioctl: arg1 == _IOC(_IOC_NONE || arg1 == _IOC(_IOC_READ || arg1 == VSOC_MAYBE_SEND_INTERRUPT_TO_HOST
+ioctl: 1
+clock_gettime: 1
+
+
+socket: arg0 == AF_INET6 || arg0 == AF_UNIX || arg0 == AF_QIPCRTR
+connect: 1
+setsockopt: 1
+getsockname: 1
+socketpair: 1
+ppoll: 1
+pselect6: 1
+accept4: 1
+listen: 1
+bind: 1
+pipe2: 1
+
+recvmsg: 1
+sendmsg: 1
+
+sendto: 1
+recvfrom: 1
+
+getsockname: 1
+nanosleep: 1
+clone: 1
+setsockopt: 1
+getsockopt: 1
+madvise: 1
+
+getitimer: 1
+setitimer: 1
+getpid: 1
+bind: 1
+listen: 1
+getpeername: 1
+socketpair: 1
+wait4: 1
+chown: 1
+fchown: 1
+lchown: 1
+umask: 1
+mmap2: 1
+fstat64: 1
+fstatat64: 1
+_llseek: 1
+geteuid: 1
diff --git a/etc/seccomp_policy/gnss@2.0-xtra-daemon.policy b/etc/seccomp_policy/gnss@2.0-xtra-daemon.policy
new file mode 100644
index 0000000..19b67bb
--- /dev/null
+++ b/etc/seccomp_policy/gnss@2.0-xtra-daemon.policy
@@ -0,0 +1,48 @@
+#*******************************************************************************
+# Copyright (c) 2020 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.
+#
+#******************************************************************************
+bind: 1
+getrlimit: 1
+
+pipe2: 1
+
+sched_getaffinity: 1
+timerfd_create: 1
+unlinkat: 1
+setpriority: 1
+
+epoll_create1: 1
+epoll_ctl: 1
+epoll_pwait: 1
+timerfd_settime: 1
+
+fdatasync: 1
+madvise: 1
+ftruncate: 1
+
diff --git a/etc/seccomp_policy/gnss@2.0-xtwifi-client.policy b/etc/seccomp_policy/gnss@2.0-xtwifi-client.policy
new file mode 100644
index 0000000..38a41f9
--- /dev/null
+++ b/etc/seccomp_policy/gnss@2.0-xtwifi-client.policy
@@ -0,0 +1,73 @@
+
+#*******************************************************************************
+# Copyright (c) 2020 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.
+#
+#******************************************************************************
+
+fdatasync: 1
+getdents64: 1
+gettimeofday: 1
+ioctl: 1
+lseek: 1
+madvise: 1
+mkdirat: 1
+pwrite64: 1
+
+timerfd_create: 1
+timerfd_settime: 1
+epoll_create1: 1
+epoll_pwait: 1
+epoll_ctl: 1
+
+sched_getaffinity: 1
+gettid: 1
+fchown: 1
+fchmod: 1
+fchmodat: 1
+getsockopt: 1
+fchownat: 1
+fstat: 1
+fstatfs: 1
+newfstatat: 1
+sendmsg: 1
+recvmsg: 1
+gettimeofday: 1
+setsockopt: 1
+rt_tgsigqueueinfo: 1
+ioctl: 1
+mmap: 1
+getuid32: 1
+getuid: 1
+fstat64: 1
+fstatat64: 1
+mkdir: 1
+rmdir: 1
+creat: 1
+chmod: 1
+lseek: 1
+geteuid32: 1
diff --git a/etc/seccomp_policy/gnss@2.0-xtwifi-inet-agent.policy b/etc/seccomp_policy/gnss@2.0-xtwifi-inet-agent.policy
new file mode 100644
index 0000000..024600a
--- /dev/null
+++ b/etc/seccomp_policy/gnss@2.0-xtwifi-inet-agent.policy
@@ -0,0 +1,43 @@
+
+#*******************************************************************************
+# Copyright (c) 2020 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.
+#
+#******************************************************************************
+
+unlinkat: 1
+sched_getaffinity: 1
+newfstatat: 1
+fchmodat: 1
+madvise: 1
+mmap: 1
+getuid: 1
+getuid32: 1
+fstat64: 1
+fstatat64: 1
+gettimeofday: 1
+getdents64: 1
diff --git a/geofence/Android.bp b/geofence/Android.bp
new file mode 100644
index 0000000..1c57f24
--- /dev/null
+++ b/geofence/Android.bp
@@ -0,0 +1,40 @@
+
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_qcom_sm7250_gps_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-BSD
+ default_applicable_licenses: ["hardware_qcom_sm7250_gps_license"],
+}
+
+cc_library_shared {
+
+ name: "libgeofencing",
+ vendor: true,
+
+
+
+ srcs: [
+ "GeofenceAdapter.cpp",
+ "location_geofence.cpp",
+ ],
+
+ shared_libs: [
+ "libutils",
+ "libcutils",
+ "libgps.utils",
+ "liblog",
+ "libloc_core",
+ ],
+
+ header_libs: [
+ "libgps.utils_headers",
+ "libloc_core_headers",
+ "libloc_pla_headers",
+ "liblocation_api_headers",
+ ],
+
+ cflags: GNSS_CFLAGS,
+}
diff --git a/geofence/Android.mk b/geofence/Android.mk
deleted file mode 100644
index 133d408..0000000
--- a/geofence/Android.mk
+++ /dev/null
@@ -1,38 +0,0 @@
-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_SANITIZE += $(GNSS_SANITIZE)
-# activate the following line for debug purposes only, comment out for production
-#LOCAL_SANITIZE_DIAG += $(GNSS_SANITIZE_DIAG)
-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
-
-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
index e299589..1aeea0a 100644
--- a/geofence/GeofenceAdapter.cpp
+++ b/geofence/GeofenceAdapter.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2021, 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
@@ -37,14 +37,14 @@
GeofenceAdapter::GeofenceAdapter() :
LocAdapterBase(0,
- LocContext::getLocContext(
- NULL,
- NULL,
- LocContext::mLocationHalName,
- false),
- true /*isMaster*/)
+ LocContext::getLocContext(LocContext::mLocationHalName),
+ true /*isMaster*/, nullptr, true)
{
LOC_LOGD("%s]: Constructor", __func__);
+
+ // at last step, let us inform adapater base that we are done
+ // with initialization, e.g.: ready to process handleEngineUpEvent
+ doneInit();
}
void
diff --git a/geofence/configure.ac b/geofence/configure.ac
index 8e3cd81..74eae7a 100644
--- a/geofence/configure.ac
+++ b/geofence/configure.ac
@@ -1,6 +1,6 @@
AC_PREREQ(2.61)
AC_INIT([location-geofence], 1.0.0)
-AM_INIT_AUTOMAKE([foreign])
+AM_INIT_AUTOMAKE([foreign subdir-objects])
AC_CONFIG_SRCDIR([Makefile.am])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4])
diff --git a/gnss/Agps.cpp b/gnss/Agps.cpp
index 9255f88..0b95f99 100644
--- a/gnss/Agps.cpp
+++ b/gnss/Agps.cpp
@@ -448,7 +448,7 @@
mAPN = NULL;
}
- if (NULL == apn || len <= 0 || len > MAX_APN_LEN || strlen(apn) != len) {
+ if (NULL == apn || len > MAX_APN_LEN || strlen(apn) != len) {
LOC_LOGD("Invalid apn len (%d) or null apn", len);
mAPN = NULL;
mAPNLen = 0;
@@ -590,7 +590,7 @@
sm->setApnTypeMask(apnTypeMask);
/* Invoke AGPS SM processing */
- AgpsSubscriber subscriber(connHandle, false, false, apnTypeMask);
+ AgpsSubscriber subscriber(connHandle, true, false, apnTypeMask);
sm->setCurrentSubscriber(&subscriber);
/* Send subscriber event */
sm->processAgpsEvent(AGPS_EVENT_SUBSCRIBE);
diff --git a/gnss/Agps.h b/gnss/Agps.h
index d559377..8a27cd9 100644
--- a/gnss/Agps.h
+++ b/gnss/Agps.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2018, 2020 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
@@ -37,6 +37,8 @@
#include <loc_pla.h>
#include <log_util.h>
+using namespace loc_util;
+
/* ATL callback function pointers
* Passed in by Adapter to AgpsManager */
typedef std::function<void(
@@ -165,7 +167,7 @@
/* Getter/Setter methods */
void setAPN(char* apn, unsigned int len);
- inline char* getAPN() const { return (char*)mAPN; }
+ inline char* getAPN() const { return mAPN; }
inline uint32_t getAPNLen() const { return mAPNLen; }
inline void setBearer(AGpsBearerType bearer) { mBearer = bearer; }
inline LocApnTypeMask getApnTypeMask() const { return mApnTypeMask; }
diff --git a/gnss/Android.bp b/gnss/Android.bp
new file mode 100644
index 0000000..97c0efe
--- /dev/null
+++ b/gnss/Android.bp
@@ -0,0 +1,44 @@
+
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_qcom_sm7250_gps_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-BSD
+ default_applicable_licenses: ["hardware_qcom_sm7250_gps_license"],
+}
+
+cc_library_shared {
+
+ name: "libgnss",
+ vendor: true,
+
+
+
+ shared_libs: [
+ "libutils",
+ "libcutils",
+ "libdl",
+ "liblog",
+ "libloc_core",
+ "libgps.utils",
+ ],
+
+ srcs: [
+ "location_gnss.cpp",
+ "GnssAdapter.cpp",
+ "Agps.cpp",
+ "XtraSystemStatusObserver.cpp",
+ "NativeAgpsHandler.cpp",
+ ],
+
+ cflags: ["-fno-short-enums"] + GNSS_CFLAGS,
+ header_libs: [
+ "libgps.utils_headers",
+ "libloc_core_headers",
+ "libloc_pla_headers",
+ "liblocation_api_headers",
+ ],
+
+}
diff --git a/gnss/Android.mk b/gnss/Android.mk
deleted file mode 100644
index c1b5944..0000000
--- a/gnss/Android.mk
+++ /dev/null
@@ -1,49 +0,0 @@
-ifneq ($(BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE),)
-ifneq ($(BUILD_TINY_ANDROID),true)
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libgnss
-LOCAL_SANITIZE += $(GNSS_SANITIZE)
-# activate the following line for debug purposes only, comment out for production
-#LOCAL_SANITIZE_DIAG += $(GNSS_SANITIZE_DIAG)
-LOCAL_VENDOR_MODULE := true
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SHARED_LIBRARIES := \
- libutils \
- libcutils \
- libdl \
- liblog \
- libloc_core \
- libgps.utils
-
-LOCAL_SRC_FILES += \
- location_gnss.cpp \
- GnssAdapter.cpp \
- Agps.cpp \
- XtraSystemStatusObserver.cpp
-
-LOCAL_CFLAGS += \
- -fno-short-enums \
-
-ifeq ($(TARGET_BUILD_VARIANT),user)
- LOCAL_CFLAGS += -DTARGET_BUILD_VARIANT_USER
-endif
-
-LOCAL_HEADER_LIBRARIES := \
- libgps.utils_headers \
- libloc_core_headers \
- libloc_pla_headers \
- liblocation_api_headers
-
-LOCAL_CFLAGS += $(GNSS_CFLAGS)
-
-LOCAL_PRELINK_MODULE := false
-
-include $(BUILD_SHARED_LIBRARY)
-
-endif # not BUILD_TINY_ANDROID
-endif # BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE
diff --git a/gnss/GnssAdapter.cpp b/gnss/GnssAdapter.cpp
index f954488..c9ea7ca 100644
--- a/gnss/GnssAdapter.cpp
+++ b/gnss/GnssAdapter.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2021 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,13 +46,27 @@
#include <Agps.h>
#include <SystemStatus.h>
#include <vector>
+#include <loc_misc_utils.h>
+#include <gps_extended_c.h>
#define RAD2DEG (180.0 / M_PI)
+#define DEG2RAD (M_PI / 180.0)
#define PROCESS_NAME_ENGINE_SERVICE "engine-service"
#define MIN_TRACKING_INTERVAL (100) // 100 msec
+#define BILLION_NSEC (1000000000ULL)
+#define NMEA_MIN_THRESHOLD_MSEC (99)
+#define NMEA_MAX_THRESHOLD_MSEC (975)
+
+#define DGNSS_RANGE_UPDATE_TIME_10MIN_IN_MILLI 600000
+
using namespace loc_core;
+static int loadEngHubForExternalEngine = 0;
+static loc_param_s_type izatConfParamTable[] = {
+ {"LOAD_ENGHUB_FOR_EXTERNAL_ENGINE", &loadEngHubForExternalEngine, nullptr,'n'}
+};
+
/* Method to fetch status cb from loc_net_iface library */
typedef AgpsCbInfo& (*LocAgpsGetAgpsCbInfo)(LocAgpsOpenResultCb openResultCb,
LocAgpsCloseResultCb closeResultCb, void* userDataPtr);
@@ -61,14 +75,29 @@
AGpsBearerType bearerType, void* userDataPtr);
static void agpsCloseResultCb (bool isSuccess, AGpsExtType agpsType, void* userDataPtr);
+typedef const CdfwInterface* (*getCdfwInterface)();
+
+typedef void getPdnTypeFromWds(const std::string& apnName, std::function<void(int)> pdnCb);
+
+inline bool GnssReportLoggerUtil::isLogEnabled() {
+ return (mLogLatency != nullptr);
+}
+
+inline void GnssReportLoggerUtil::log(const GnssLatencyInfo& gnssLatencyMeasInfo) {
+ if (mLogLatency != nullptr) {
+ mLogLatency(gnssLatencyMeasInfo);
+ }
+}
+
GnssAdapter::GnssAdapter() :
LocAdapterBase(0,
- LocContext::getLocContext(NULL,
- NULL,
- LocContext::mLocationHalName,
- false),
+ LocContext::getLocContext(LocContext::mLocationHalName),
true, nullptr, true),
mEngHubProxy(new EngineHubProxyBase()),
+ mQDgnssListenerHDL(nullptr),
+ mCdfwInterface(nullptr),
+ mDGnssNeedReport(false),
+ mDGnssDataUsage(false),
mLocPositionMode(),
mNHzNeeded(false),
mSPEAlreadyRunningAtHighestInterval(false),
@@ -78,6 +107,7 @@
mAfwControlId(0),
mNmeaMask(0),
mGnssSvIdConfig(),
+ mGnssSeconaryBandConfig(),
mGnssSvTypeConfig(),
mGnssSvTypeConfigCb(nullptr),
mLocConfigInfo{},
@@ -87,11 +117,13 @@
mOdcpiRequestActive(false),
mOdcpiTimer(this),
mOdcpiRequest(),
+ mCallbackPriority(OdcpiPrioritytype::ODCPI_HANDLER_PRIORITY_LOW),
mSystemStatus(SystemStatus::getInstance(mMsgTask)),
mServerUrl(":"),
mXtraObserver(mSystemStatus->getOsObserver(), mMsgTask),
- mLocSystemInfo{},
mBlockCPIInfo{},
+ mDreIntEnabled(false),
+ mLocSystemInfo{},
mNfwCb(NULL),
mPowerOn(false),
mAllowFlpNetworkFixes(0),
@@ -101,7 +133,14 @@
mGnssMbSvIdUsedInPosition{},
mGnssMbSvIdUsedInPosAvail(false),
mSupportNfwControl(true),
- mSystemPowerState(POWER_STATE_UNKNOWN)
+ mSystemPowerState(POWER_STATE_UNKNOWN),
+ mIsMeasCorrInterfaceOpen(false),
+ mIsAntennaInfoInterfaceOpened(false),
+ mLastDeleteAidingDataTime(0),
+ mDgnssState(0),
+ mSendNmeaConsent(false),
+ mDgnssLastNmeaBootTimeMilli(0),
+ mNativeAgpsHandler(mSystemStatus->getOsObserver(), *this)
{
LOC_LOGD("%s]: Constructor %p", __func__, this);
mLocPositionMode.mode = LOC_POSITION_MODE_INVALID;
@@ -178,6 +217,7 @@
bool
GnssAdapter::checkAndSetSPEToRunforNHz(TrackingOptions & out) {
+
// first check if NHz meas is needed at all, if not, just return false
// if a NHz capable engine is subscribed for NHz measurement or NHz positions,
// always run the SPE only session at 100ms TBF.
@@ -202,8 +242,7 @@
void
GnssAdapter::convertLocation(Location& out, const UlpLocation& ulpLocation,
- const GpsLocationExtended& locationExtended,
- const LocPosTechMask techMask)
+ const GpsLocationExtended& locationExtended)
{
memset(&out, 0, sizeof(Location));
out.size = sizeof(Location);
@@ -240,24 +279,57 @@
out.flags |= LOCATION_HAS_BEARING_ACCURACY_BIT;
out.bearingAccuracy = locationExtended.bearing_unc;
}
+ if (GPS_LOCATION_EXTENDED_HAS_CONFORMITY_INDEX & locationExtended.flags) {
+ out.flags |= LOCATION_HAS_CONFORMITY_INDEX_BIT;
+ out.conformityIndex = locationExtended.conformityIndex;
+ }
out.timestamp = ulpLocation.gpsLocation.timestamp;
- if (LOC_POS_TECH_MASK_SATELLITE & techMask) {
+ if (LOC_POS_TECH_MASK_SATELLITE & locationExtended.tech_mask) {
out.techMask |= LOCATION_TECHNOLOGY_GNSS_BIT;
}
- if (LOC_POS_TECH_MASK_CELLID & techMask) {
+ if (LOC_POS_TECH_MASK_CELLID & locationExtended.tech_mask) {
out.techMask |= LOCATION_TECHNOLOGY_CELL_BIT;
}
- if (LOC_POS_TECH_MASK_WIFI & techMask) {
+ if (LOC_POS_TECH_MASK_WIFI & locationExtended.tech_mask) {
out.techMask |= LOCATION_TECHNOLOGY_WIFI_BIT;
}
- if (LOC_POS_TECH_MASK_SENSORS & techMask) {
+ if (LOC_POS_TECH_MASK_SENSORS & locationExtended.tech_mask) {
out.techMask |= LOCATION_TECHNOLOGY_SENSORS_BIT;
}
+ if (LOC_POS_TECH_MASK_REFERENCE_LOCATION & locationExtended.tech_mask) {
+ out.techMask |= LOCATION_TECHNOLOGY_REFERENCE_LOCATION_BIT;
+ }
+ if (LOC_POS_TECH_MASK_INJECTED_COARSE_POSITION & locationExtended.tech_mask) {
+ out.techMask |= LOCATION_TECHNOLOGY_INJECTED_COARSE_POSITION_BIT;
+ }
+ if (LOC_POS_TECH_MASK_AFLT & locationExtended.tech_mask) {
+ out.techMask |= LOCATION_TECHNOLOGY_AFLT_BIT;
+ }
+ if (LOC_POS_TECH_MASK_HYBRID & locationExtended.tech_mask) {
+ out.techMask |= LOCATION_TECHNOLOGY_HYBRID_BIT;
+ }
+ if (LOC_POS_TECH_MASK_PPE & locationExtended.tech_mask) {
+ out.techMask |= LOCATION_TECHNOLOGY_PPE_BIT;
+ }
+ if (LOC_POS_TECH_MASK_VEH & locationExtended.tech_mask) {
+ out.techMask |= LOCATION_TECHNOLOGY_VEH_BIT;
+ }
+ if (LOC_POS_TECH_MASK_VIS & locationExtended.tech_mask) {
+ out.techMask |= LOCATION_TECHNOLOGY_VIS_BIT;
+ }
+ if (LOC_NAV_MASK_DGNSS_CORRECTION & locationExtended.navSolutionMask) {
+ out.techMask |= LOCATION_TECHNOLOGY_DGNSS_BIT;
+ }
if (LOC_GPS_LOCATION_HAS_SPOOF_MASK & ulpLocation.gpsLocation.flags) {
out.flags |= LOCATION_HAS_SPOOF_MASK;
out.spoofMask = ulpLocation.gpsLocation.spoof_mask;
}
+ if (LOC_GPS_LOCATION_HAS_ELAPSED_REAL_TIME & ulpLocation.gpsLocation.flags) {
+ out.flags |= LOCATION_HAS_ELAPSED_REAL_TIME;
+ out.elapsedRealTime = ulpLocation.gpsLocation.elapsedRealTime;
+ out.elapsedRealTimeUnc = ulpLocation.gpsLocation.elapsedRealTimeUnc;
+ }
}
/* This is utility routine that computes number of SV used
@@ -287,7 +359,8 @@
void
GnssAdapter::convertLocationInfo(GnssLocationInfoNotification& out,
- const GpsLocationExtended& locationExtended)
+ const GpsLocationExtended& locationExtended,
+ enum loc_sess_status status)
{
out.size = sizeof(GnssLocationInfoNotification);
if (GPS_LOCATION_EXTENDED_HAS_ALTITUDE_MEAN_SEA_LEVEL & locationExtended.flags) {
@@ -407,6 +480,8 @@
locationExtended.gnss_sv_used_ids.bds_sv_used_ids_mask;
out.svUsedInPosition.qzssSvUsedIdsMask =
locationExtended.gnss_sv_used_ids.qzss_sv_used_ids_mask;
+ out.svUsedInPosition.navicSvUsedIdsMask =
+ locationExtended.gnss_sv_used_ids.navic_sv_used_ids_mask;
out.flags |= GNSS_LOCATION_INFO_NUM_SV_USED_IN_POSITION_BIT;
out.numSvUsedInPosition = getNumSvUsed(out.svUsedInPosition.gpsSvUsedIdsMask,
@@ -419,6 +494,8 @@
BDS_SV_PRN_MAX - BDS_SV_PRN_MIN + 1);
out.numSvUsedInPosition += getNumSvUsed(out.svUsedInPosition.galSvUsedIdsMask,
GAL_SV_PRN_MAX - GAL_SV_PRN_MIN + 1);
+ out.numSvUsedInPosition += getNumSvUsed(out.svUsedInPosition.navicSvUsedIdsMask,
+ NAVIC_SV_PRN_MAX - NAVIC_SV_PRN_MIN + 1);
out.numOfMeasReceived = locationExtended.numOfMeasReceived;
for (int idx =0; idx < locationExtended.numOfMeasReceived; idx++) {
@@ -434,10 +511,6 @@
out.flags |= GNSS_LOCATION_INFO_NAV_SOLUTION_MASK_BIT;
out.navSolutionMask = locationExtended.navSolutionMask;
}
- if (GPS_LOCATION_EXTENDED_HAS_POS_TECH_MASK & locationExtended.flags) {
- out.flags |= GNSS_LOCATION_INFO_POS_TECH_MASK_BIT;
- out.posTechMask = locationExtended.tech_mask;
- }
if (GPS_LOCATION_EXTENDED_HAS_POS_DYNAMICS_DATA & locationExtended.flags) {
out.flags |= GPS_LOCATION_EXTENDED_HAS_POS_DYNAMICS_DATA;
if (locationExtended.bodyFrameData.bodyFrameDataMask &
@@ -452,46 +525,88 @@
LOCATION_NAV_DATA_HAS_VERT_ACCEL_BIT) {
out.bodyFrameData.bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_VERT_ACCEL_BIT;
}
- if (locationExtended.bodyFrameData.bodyFrameDataMask & LOCATION_NAV_DATA_HAS_YAW_RATE_BIT) {
+ if (locationExtended.bodyFrameData.bodyFrameDataMask &
+ LOCATION_NAV_DATA_HAS_YAW_RATE_BIT) {
out.bodyFrameData.bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_YAW_RATE_BIT;
}
- if (locationExtended.bodyFrameData.bodyFrameDataMask & LOCATION_NAV_DATA_HAS_PITCH_BIT) {
+ if (locationExtended.bodyFrameData.bodyFrameDataMask &
+ LOCATION_NAV_DATA_HAS_PITCH_BIT) {
out.bodyFrameData.bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_PITCH_BIT;
}
+
+ if (locationExtended.bodyFrameData.bodyFrameDataMask &
+ LOCATION_NAV_DATA_HAS_LONG_ACCEL_UNC_BIT) {
+ out.bodyFrameData.bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_LONG_ACCEL_UNC_BIT;
+ }
+ if (locationExtended.bodyFrameData.bodyFrameDataMask &
+ LOCATION_NAV_DATA_HAS_LAT_ACCEL_UNC_BIT) {
+ out.bodyFrameData.bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_LAT_ACCEL_UNC_BIT;
+ }
+ if (locationExtended.bodyFrameData.bodyFrameDataMask &
+ LOCATION_NAV_DATA_HAS_VERT_ACCEL_UNC_BIT) {
+ out.bodyFrameData.bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_VERT_ACCEL_UNC_BIT;
+ }
+ if (locationExtended.bodyFrameData.bodyFrameDataMask &
+ LOCATION_NAV_DATA_HAS_YAW_RATE_UNC_BIT) {
+ out.bodyFrameData.bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_YAW_RATE_UNC_BIT;
+ }
+ if (locationExtended.bodyFrameData.bodyFrameDataMask &
+ LOCATION_NAV_DATA_HAS_PITCH_UNC_BIT) {
+ out.bodyFrameData.bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_PITCH_UNC_BIT;
+ }
+
+ if (locationExtended.bodyFrameDataExt.bodyFrameDataMask &
+ LOCATION_NAV_DATA_HAS_PITCH_RATE_BIT) {
+ out.bodyFrameDataExt.bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_PITCH_RATE_BIT;
+ }
+ if (locationExtended.bodyFrameDataExt.bodyFrameDataMask &
+ LOCATION_NAV_DATA_HAS_PITCH_RATE_UNC_BIT) {
+ out.bodyFrameDataExt.bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_PITCH_RATE_UNC_BIT;
+ }
+ if (locationExtended.bodyFrameDataExt.bodyFrameDataMask &
+ LOCATION_NAV_DATA_HAS_ROLL_BIT) {
+ out.bodyFrameDataExt.bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_ROLL_BIT;
+ }
+ if (locationExtended.bodyFrameDataExt.bodyFrameDataMask &
+ LOCATION_NAV_DATA_HAS_ROLL_UNC_BIT) {
+ out.bodyFrameDataExt.bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_ROLL_UNC_BIT;
+ }
+ if (locationExtended.bodyFrameDataExt.bodyFrameDataMask &
+ LOCATION_NAV_DATA_HAS_ROLL_RATE_BIT) {
+ out.bodyFrameDataExt.bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_ROLL_RATE_BIT;
+ }
+ if (locationExtended.bodyFrameDataExt.bodyFrameDataMask &
+ LOCATION_NAV_DATA_HAS_ROLL_RATE_UNC_BIT) {
+ out.bodyFrameDataExt.bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_ROLL_RATE_UNC_BIT;
+ }
+ if (locationExtended.bodyFrameDataExt.bodyFrameDataMask &
+ LOCATION_NAV_DATA_HAS_YAW_BIT) {
+ out.bodyFrameDataExt.bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_YAW_BIT;
+ }
+ if (locationExtended.bodyFrameDataExt.bodyFrameDataMask &
+ LOCATION_NAV_DATA_HAS_YAW_UNC_BIT) {
+ out.bodyFrameDataExt.bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_YAW_UNC_BIT;
+ }
+
out.bodyFrameData.longAccel = locationExtended.bodyFrameData.longAccel;
out.bodyFrameData.latAccel = locationExtended.bodyFrameData.latAccel;
out.bodyFrameData.vertAccel = locationExtended.bodyFrameData.vertAccel;
out.bodyFrameData.yawRate = locationExtended.bodyFrameData.yawRate;
out.bodyFrameData.pitch = locationExtended.bodyFrameData.pitch;
- }
- if (GPS_LOCATION_EXTENDED_HAS_GPS_TIME & locationExtended.flags) {
- out.flags |= GPS_LOCATION_EXTENDED_HAS_GPS_TIME;
- out.gnssSystemTime.gnssSystemTimeSrc = locationExtended.gnssSystemTime.gnssSystemTimeSrc;
- out.gnssSystemTime.u = locationExtended.gnssSystemTime.u;
- }
- if (GPS_LOCATION_EXTENDED_HAS_NORTH_VEL & locationExtended.flags) {
- out.flags |= GPS_LOCATION_EXTENDED_HAS_NORTH_VEL;
- out.northVelocity = locationExtended.northVelocity;
- }
- if (GPS_LOCATION_EXTENDED_HAS_EAST_VEL & locationExtended.flags) {
- out.flags |= GPS_LOCATION_EXTENDED_HAS_EAST_VEL;
- out.eastVelocity = locationExtended.eastVelocity;
- }
- if (GPS_LOCATION_EXTENDED_HAS_UP_VEL & locationExtended.flags) {
- out.flags |= GPS_LOCATION_EXTENDED_HAS_UP_VEL;
- out.upVelocity = locationExtended.upVelocity;
- }
- if (GPS_LOCATION_EXTENDED_HAS_NORTH_VEL_UNC & locationExtended.flags) {
- out.flags |= GPS_LOCATION_EXTENDED_HAS_NORTH_VEL_UNC;
- out.northVelocityStdDeviation = locationExtended.northVelocityStdDeviation;
- }
- if (GPS_LOCATION_EXTENDED_HAS_EAST_VEL_UNC & locationExtended.flags) {
- out.flags |= GPS_LOCATION_EXTENDED_HAS_EAST_VEL_UNC;
- out.eastVelocityStdDeviation = locationExtended.eastVelocityStdDeviation;
- }
- if (GPS_LOCATION_EXTENDED_HAS_UP_VEL_UNC & locationExtended.flags) {
- out.flags |= GPS_LOCATION_EXTENDED_HAS_UP_VEL_UNC;
- out.upVelocityStdDeviation = locationExtended.upVelocityStdDeviation;
+ out.bodyFrameData.longAccelUnc = locationExtended.bodyFrameData.longAccelUnc;
+ out.bodyFrameData.latAccelUnc = locationExtended.bodyFrameData.latAccelUnc;
+ out.bodyFrameData.vertAccelUnc = locationExtended.bodyFrameData.vertAccelUnc;
+ out.bodyFrameData.yawRateUnc = locationExtended.bodyFrameData.yawRateUnc;
+ out.bodyFrameData.pitchUnc = locationExtended.bodyFrameData.pitchUnc;
+
+ out.bodyFrameDataExt.pitchRate = locationExtended.bodyFrameDataExt.pitchRate;
+ out.bodyFrameDataExt.pitchRateUnc = locationExtended.bodyFrameDataExt.pitchRateUnc;
+ out.bodyFrameDataExt.roll = locationExtended.bodyFrameDataExt.roll;
+ out.bodyFrameDataExt.rollUnc = locationExtended.bodyFrameDataExt.rollUnc;
+ out.bodyFrameDataExt.rollRate = locationExtended.bodyFrameDataExt.rollRate;
+ out.bodyFrameDataExt.rollRateUnc = locationExtended.bodyFrameDataExt.rollRateUnc;
+ out.bodyFrameDataExt.yaw = locationExtended.bodyFrameDataExt.yaw;
+ out.bodyFrameDataExt.yawUnc = locationExtended.bodyFrameDataExt.yawUnc;
}
// Validity of this structure is established from the timeSrc of the GnssSystemTime structure.
@@ -526,10 +641,39 @@
out.flags |= GNSS_LOCATION_INFO_OUTPUT_ENG_MASK_BIT;
out.locOutputEngMask = locationExtended.locOutputEngMask;
}
+
+ if (GPS_LOCATION_EXTENDED_HAS_CONFORMITY_INDEX & locationExtended.flags) {
+ out.flags |= GNSS_LOCATION_INFO_CONFORMITY_INDEX_BIT;
+ out.conformityIndex = locationExtended.conformityIndex;
+ }
+
+ if (GPS_LOCATION_EXTENDED_HAS_LLA_VRP_BASED & locationExtended.flags) {
+ out.flags |= GNSS_LOCATION_INFO_LLA_VRP_BASED_BIT;
+ out.llaVRPBased = locationExtended.llaVRPBased;
+ }
+
+ if (GPS_LOCATION_EXTENDED_HAS_ENU_VELOCITY_LLA_VRP_BASED & locationExtended.flags) {
+ out.flags |= GNSS_LOCATION_INFO_ENU_VELOCITY_VRP_BASED_BIT;
+ // copy over east, north and up vrp based velocity
+ out.enuVelocityVRPBased[0] = locationExtended.enuVelocityVRPBased[0];
+ out.enuVelocityVRPBased[1] = locationExtended.enuVelocityVRPBased[1];
+ out.enuVelocityVRPBased[2] = locationExtended.enuVelocityVRPBased[2];
+ }
+
+ if (GPS_LOCATION_EXTENDED_HAS_DR_SOLUTION_STATUS_MASK & locationExtended.flags) {
+ out.flags |= GNSS_LOCATION_INFO_DR_SOLUTION_STATUS_MASK_BIT;
+ out.drSolutionStatusMask = locationExtended.drSolutionStatusMask;
+ }
+
+ if (GPS_LOCATION_EXTENDED_HAS_ALTITUDE_ASSUMED & locationExtended.flags) {
+ out.flags |= GNSS_LOCATION_INFO_ALTITUDE_ASSUMED_BIT;
+ out.altitudeAssumed = locationExtended.altitudeAssumed;
+ }
+
+ out.flags |= GNSS_LOCATION_INFO_SESSION_STATUS_BIT;
+ out.sessionStatus = status;
}
-
-
inline uint32_t
GnssAdapter::convertSuplVersion(const GnssConfigSuplVersion suplVersion)
{
@@ -546,22 +690,6 @@
}
}
-inline uint32_t
-GnssAdapter::convertLppProfile(const GnssConfigLppProfile lppProfile)
-{
- switch (lppProfile) {
- case GNSS_CONFIG_LPP_PROFILE_USER_PLANE:
- return 1;
- case GNSS_CONFIG_LPP_PROFILE_CONTROL_PLANE:
- return 2;
- case GNSS_CONFIG_LPP_PROFILE_USER_PLANE_AND_CONTROL_PLANE:
- return 3;
- case GNSS_CONFIG_LPP_PROFILE_RRLP_ON_LTE:
- default:
- return 0;
- }
-}
-
uint32_t
GnssAdapter::convertLppeCp(const GnssConfigLppeControlPlaneMask lppeControlPlaneMask)
{
@@ -713,7 +841,9 @@
} else if (length >= 0) {
if (LOC_AGPS_SUPL_SERVER == type) {
getServerUrl().assign(serverUrl);
- strlcpy(ContextBase::mGps_conf.SUPL_HOST, server, LOC_MAX_PARAM_STRING);
+ strlcpy(ContextBase::mGps_conf.SUPL_HOST,
+ (nullptr == server) ? serverUrl : server,
+ LOC_MAX_PARAM_STRING);
ContextBase::mGps_conf.SUPL_PORT = port;
} else {
if (strncasecmp(getMoServerUrl().c_str(), serverUrl, sizeof(serverUrl)) != 0) {
@@ -733,6 +863,9 @@
uint32_t mask = 0;
if (NMEA_PROVIDER_MP == ContextBase::mGps_conf.NMEA_PROVIDER) {
mask |= LOC_NMEA_ALL_GENERAL_SUPPORTED_MASK;
+ if (ContextBase::mGps_conf.NMEA_TAG_BLOCK_GROUPING_ENABLED) {
+ mask |= LOC_NMEA_MASK_TAGBLOCK_V02;
+ }
}
if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_DEBUG_NMEA_V02)) {
mask |= LOC_NMEA_MASK_DEBUG_V02;
@@ -758,6 +891,8 @@
ContextBase::mGps_conf.MO_SUPL_PORT,
LOC_AGPS_MO_SUPL_SERVER);
+ std::string moServerUrl = getMoServerUrl();
+ std::string serverUrl = getServerUrl();
// inject the configurations into modem
loc_gps_cfg_s gpsConf = ContextBase::mGps_conf;
loc_sap_cfg_s_type sapConf = ContextBase::mSap_conf;
@@ -788,12 +923,9 @@
GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT |
GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT |
GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT;
- gnssConfigRequested.suplVersion =
- mLocApi->convertSuplVersion(gpsConf.SUPL_VER);
- gnssConfigRequested.lppProfile =
- mLocApi->convertLppProfile(gpsConf.LPP_PROFILE);
- gnssConfigRequested.aGlonassPositionProtocolMask =
- gpsConf.A_GLONASS_POS_PROTOCOL_SELECT;
+ gnssConfigRequested.suplVersion = mLocApi->convertSuplVersion(gpsConf.SUPL_VER);
+ gnssConfigRequested.lppProfileMask = gpsConf.LPP_PROFILE;
+ gnssConfigRequested.aGlonassPositionProtocolMask = gpsConf.A_GLONASS_POS_PROTOCOL_SELECT;
if (gpsConf.LPPE_CP_TECHNOLOGY) {
gnssConfigRequested.flags |= GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT;
gnssConfigRequested.lppeControlPlaneMask =
@@ -808,13 +940,18 @@
gnssConfigRequested.blacklistedSvIds.assign(mBlacklistedSvIds.begin(),
mBlacklistedSvIds.end());
mLocApi->sendMsg(new LocApiMsg(
- [this, gpsConf, sapConf, oldMoServerUrl, gnssConfigRequested] () mutable {
- gnssUpdateConfig(oldMoServerUrl, gnssConfigRequested, gnssConfigRequested);
+ [this, gpsConf, sapConf, oldMoServerUrl, moServerUrl,
+ serverUrl, gnssConfigRequested] () mutable {
+ gnssUpdateConfig(oldMoServerUrl, moServerUrl, serverUrl,
+ gnssConfigRequested, gnssConfigRequested);
// set nmea mask type
uint32_t mask = 0;
if (NMEA_PROVIDER_MP == gpsConf.NMEA_PROVIDER) {
mask |= LOC_NMEA_ALL_GENERAL_SUPPORTED_MASK;
+ if (gpsConf.NMEA_TAG_BLOCK_GROUPING_ENABLED) {
+ mask |= LOC_NMEA_MASK_TAGBLOCK_V02;
+ }
}
if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_DEBUG_NMEA_V02)) {
mask |= LOC_NMEA_MASK_DEBUG_V02;
@@ -824,8 +961,6 @@
mLocApi->setNMEATypesSync(mask);
}
- mLocApi->setXtraVersionCheckSync(gpsConf.XTRA_VERSION_CHECK);
-
// load tunc configuration from config file on first boot-up,
// e.g.: adapter.mLocConfigInfo.tuncConfigInfo.isValid is false
if (mLocConfigInfo.tuncConfigInfo.isValid == false) {
@@ -853,6 +988,13 @@
mLocApi->setPositionAssistedClockEstimatorMode(
mLocConfigInfo.paceConfigInfo.enable);
+ // we do not support control robust location from gps.conf
+ if (mLocConfigInfo.robustLocationConfigInfo.isValid == true) {
+ mLocApi->configRobustLocation(
+ mLocConfigInfo.robustLocationConfigInfo.enable,
+ mLocConfigInfo.robustLocationConfigInfo.enableFor911);
+ }
+
if (sapConf.GYRO_BIAS_RANDOM_WALK_VALID ||
sapConf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY_VALID ||
sapConf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY_VALID ||
@@ -882,10 +1024,14 @@
sapConf.SENSOR_GYRO_BATCHES_PER_SEC_HIGH,
sapConf.SENSOR_ALGORITHM_CONFIG_MASK);
} ));
-
+ // deal with Measurement Corrections
+ if (true == mIsMeasCorrInterfaceOpen) {
+ initMeasCorr(true);
+ }
}
std::vector<LocationError> GnssAdapter::gnssUpdateConfig(const std::string& oldMoServerUrl,
+ const std::string& moServerUrl, const std::string& serverUrl,
GnssConfig& gnssConfigRequested, GnssConfig& gnssConfigNeedEngineUpdate, size_t count) {
loc_gps_cfg_s gpsConf = ContextBase::mGps_conf;
size_t index = 0;
@@ -895,9 +1041,6 @@
errsList.insert(errsList.begin(), count, LOCATION_ERROR_SUCCESS);
}
- std::string serverUrl = getServerUrl();
- std::string moServerUrl = getMoServerUrl();
-
int serverUrlLen = serverUrl.length();
int moServerUrlLen = moServerUrl.length();
@@ -996,7 +1139,7 @@
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);
+ err = mLocApi->setLPPConfigSync(gnssConfigRequested.lppProfileMask);
if (index < count) {
errsList[index] = err;
}
@@ -1075,11 +1218,23 @@
}
index++;
}
+
+ if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_MIN_SV_ELEVATION_BIT) {
+ GnssConfig gnssConfig = {};
+ gnssConfig.flags = GNSS_CONFIG_FLAGS_MIN_SV_ELEVATION_BIT;
+ gnssConfig.minSvElevation = gnssConfigRequested.minSvElevation;
+ err = mLocApi->setParameterSync(gnssConfig);
+ if (index < count) {
+ errsList[index] = err;
+ }
+ index++;
+ }
+
return errsList;
}
uint32_t*
-GnssAdapter::gnssUpdateConfigCommand(GnssConfig config)
+GnssAdapter::gnssUpdateConfigCommand(const GnssConfig& config)
{
// count the number of bits set
GnssConfigFlagsMask flagsCopy = config.flags;
@@ -1125,19 +1280,26 @@
mApi(api),
mConfig(config),
mCount(count),
- mIds(ids) {}
+ mIds(nullptr) {
+ if (mCount > 0) {
+ mIds = new uint32_t[count];
+ if (mIds) {
+ for (uint32_t index = 0; index < count; index++) {
+ mIds[index] = ids[index];
+ }
+ } else {
+ LOC_LOGe("memory allocation for mIds failed");
+ }
+ }
+ }
+
inline MsgGnssUpdateConfig(const MsgGnssUpdateConfig& obj) :
MsgGnssUpdateConfig(obj.mAdapter, obj.mApi, obj.mConfig,
- new uint32_t[obj.mCount], obj.mCount) {
- if (mIds != nullptr) {
- for (int i = 0; i < mCount; ++i) {
- mIds[i] = obj.mIds[i];
- }
- }
- }
+ obj.mIds, obj.mCount) {}
+
inline virtual ~MsgGnssUpdateConfig()
{
- delete[] mIds;
+ if (nullptr != mIds) delete[] mIds;
}
inline virtual void proc() const {
@@ -1154,6 +1316,7 @@
sessionIds.assign(mIds, mIds + mCount);
std::vector<LocationError> errs(mCount, LOCATION_ERROR_SUCCESS);
int index = 0;
+ bool needSuspendResume = false;
if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT) {
GnssConfigGpsLock newGpsLock = gnssConfigRequested.gpsLock;
@@ -1207,8 +1370,8 @@
index++;
}
if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT) {
- uint32_t newLppProfile = mAdapter.convertLppProfile(gnssConfigRequested.lppProfile);
- ContextBase::mGps_conf.LPP_PROFILE = newLppProfile;
+ uint32_t newLppProfileMask = gnssConfigRequested.lppProfileMask;
+ ContextBase::mGps_conf.LPP_PROFILE = newLppProfileMask;
index++;
}
if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT) {
@@ -1253,6 +1416,14 @@
index++;
}
+ if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_MIN_SV_ELEVATION_BIT) {
+ needSuspendResume = true;
+ index++;
+ }
+
+ if (needSuspendResume == true) {
+ mAdapter.suspendSessions();
+ }
LocApiCollectiveResponse *configCollectiveResponse = new LocApiCollectiveResponse(
*adapter.getContext(),
[&adapter, sessionIds, countOfConfigs] (std::vector<LocationError> errs) {
@@ -1261,14 +1432,22 @@
adapter.reportResponse(countOfConfigs, errs.data(), ids.data());
});
+ std::string moServerUrl = adapter.getMoServerUrl();
+ std::string serverUrl = adapter.getServerUrl();
mApi.sendMsg(new LocApiMsg(
[&adapter, gnssConfigRequested, gnssConfigNeedEngineUpdate,
- countOfConfigs, configCollectiveResponse, errs] () mutable {
+ moServerUrl, serverUrl, countOfConfigs, configCollectiveResponse,
+ errs] () mutable {
std::vector<LocationError> errsList = adapter.gnssUpdateConfig("",
+ moServerUrl, serverUrl,
gnssConfigRequested, gnssConfigNeedEngineUpdate, countOfConfigs);
configCollectiveResponse->returnToSender(errsList);
}));
+
+ if (needSuspendResume == true) {
+ mAdapter.restartSessions();
+ }
}
};
@@ -1302,10 +1481,10 @@
GnssAdapter::gnssSvIdConfigUpdate()
{
LOC_LOGd("blacklist bds 0x%" PRIx64 ", glo 0x%" PRIx64
- ", qzss 0x%" PRIx64 ", gal 0x%" PRIx64,
+ ", qzss 0x%" PRIx64 ", gal 0x%" PRIx64 ", sbas 0x%" PRIx64 ", navic 0x%" PRIx64,
mGnssSvIdConfig.bdsBlacklistSvMask, mGnssSvIdConfig.gloBlacklistSvMask,
- mGnssSvIdConfig.qzssBlacklistSvMask, mGnssSvIdConfig.galBlacklistSvMask);
-
+ mGnssSvIdConfig.qzssBlacklistSvMask, mGnssSvIdConfig.galBlacklistSvMask,
+ mGnssSvIdConfig.sbasBlacklistSvMask, mGnssSvIdConfig.navicBlacklistSvMask);
// Now set required blacklisted SVs
mLocApi->setBlacklistSv(mGnssSvIdConfig);
}
@@ -1327,14 +1506,28 @@
GnssAdapter::gnssSvIdConfigUpdateSync()
{
LOC_LOGd("blacklist bds 0x%" PRIx64 ", glo 0x%" PRIx64
- ", qzss 0x%" PRIx64 ", gal 0x%" PRIx64,
+ ", qzss 0x%" PRIx64 ", gal 0x%" PRIx64 ", sbas 0x%" PRIx64 ", navic 0x%" PRIx64,
mGnssSvIdConfig.bdsBlacklistSvMask, mGnssSvIdConfig.gloBlacklistSvMask,
- mGnssSvIdConfig.qzssBlacklistSvMask, mGnssSvIdConfig.galBlacklistSvMask);
+ mGnssSvIdConfig.qzssBlacklistSvMask, mGnssSvIdConfig.galBlacklistSvMask,
+ mGnssSvIdConfig.sbasBlacklistSvMask, mGnssSvIdConfig.navicBlacklistSvMask);
// Now set required blacklisted SVs
return mLocApi->setBlacklistSvSync(mGnssSvIdConfig);
}
+void
+GnssAdapter::gnssSecondaryBandConfigUpdate(LocApiResponse* locApiResponse)
+{
+ LOC_LOGd("secondary band config, size %d, enabled constellation 0x%" PRIx64 ","
+ "disabled constellation 0x%" PRIx64 "", mGnssSeconaryBandConfig.size,
+ mGnssSeconaryBandConfig.enabledSvTypesMask,
+ mGnssSeconaryBandConfig.blacklistedSvTypesMask);
+ if (mGnssSeconaryBandConfig.size == sizeof(mGnssSeconaryBandConfig)) {
+ // Now set required secondary band config
+ mLocApi->configConstellationMultiBand(mGnssSeconaryBandConfig, locApiResponse);
+ }
+}
+
uint32_t*
GnssAdapter::gnssGetConfigCommand(GnssConfigFlagsMask configMask) {
@@ -1381,21 +1574,27 @@
mAdapter(adapter),
mApi(api),
mConfigMask(configMask),
- mIds(ids),
- mCount(count) {}
+ mCount(count),
+ mIds(nullptr) {
+ if (mCount > 0) {
+ mIds = new uint32_t[count];
+ if (mIds) {
+ for (uint32_t index = 0; index < count; index++) {
+ mIds[index] = ids[index];
+ }
+ } else {
+ LOC_LOGe("memory allocation for mIds failed");
+ }
+ }
+ }
inline MsgGnssGetConfig(const MsgGnssGetConfig& obj) :
MsgGnssGetConfig(obj.mAdapter, obj.mApi, obj.mConfigMask,
- new uint32_t[obj.mCount], obj.mCount) {
- if (mIds != nullptr) {
- for (int i = 0; i < mCount; ++i) {
- mIds[i] = obj.mIds[i];
- }
- }
- }
+ obj.mIds, obj.mCount) {}
+
inline virtual ~MsgGnssGetConfig()
{
- delete[] mIds;
+ if (nullptr != mIds) delete[] mIds;
}
inline virtual void proc() const {
if (!mAdapter.isEngineCapabilitiesKnown()) {
@@ -1483,6 +1682,48 @@
errs[index++] = LOCATION_ERROR_NOT_SUPPORTED;
}
}
+ if (mConfigMask & GNSS_CONFIG_FLAGS_ROBUST_LOCATION_BIT) {
+ uint32_t sessionId = *(mIds+index);
+ LocApiResponse* locApiResponse =
+ new LocApiResponse(*mAdapter.getContext(),
+ [this, sessionId] (LocationError err) {
+ mAdapter.reportResponse(err, sessionId);});
+ if (!locApiResponse) {
+ LOC_LOGe("memory alloc failed");
+ mAdapter.reportResponse(LOCATION_ERROR_GENERAL_FAILURE, sessionId);
+ } else {
+ mApi.getRobustLocationConfig(sessionId, locApiResponse);
+ }
+ }
+
+ if (mConfigMask & GNSS_CONFIG_FLAGS_MIN_GPS_WEEK_BIT) {
+ uint32_t sessionId = *(mIds+index);
+ LocApiResponse* locApiResponse =
+ new LocApiResponse(*mAdapter.getContext(),
+ [this, sessionId] (LocationError err) {
+ mAdapter.reportResponse(err, sessionId);});
+ if (!locApiResponse) {
+ LOC_LOGe("memory alloc failed");
+ mAdapter.reportResponse(LOCATION_ERROR_GENERAL_FAILURE, sessionId);
+ } else {
+ mApi.getMinGpsWeek(sessionId, locApiResponse);
+ }
+ }
+
+ if (mConfigMask & GNSS_CONFIG_FLAGS_MIN_SV_ELEVATION_BIT) {
+ uint32_t sessionId = *(mIds+index);
+ LocApiResponse* locApiResponse =
+ new LocApiResponse(*mAdapter.getContext(),
+ [this, sessionId] (LocationError err) {
+ mAdapter.reportResponse(err, sessionId);});
+ if (!locApiResponse) {
+ LOC_LOGe("memory alloc failed");
+ mAdapter.reportResponse(LOCATION_ERROR_GENERAL_FAILURE, sessionId);
+ } else {
+ mApi.getParameter(sessionId, GNSS_CONFIG_FLAGS_MIN_SV_ELEVATION_BIT,
+ locApiResponse);
+ }
+ }
mAdapter.reportResponse(index, errs, mIds);
delete[] errs;
@@ -1512,12 +1753,15 @@
config.bdsBlacklistSvMask = 0;
config.qzssBlacklistSvMask = 0;
config.galBlacklistSvMask = 0;
+ config.sbasBlacklistSvMask = 0;
+ config.navicBlacklistSvMask = 0;
retVal = true;
} else {
// Parse the vector and convert SV IDs to mask values
for (GnssSvIdSource source : blacklistedSvIds) {
uint64_t* svMaskPtr = NULL;
GnssSvId initialSvId = 0;
+ uint16_t svIndexOffset = 0;
switch(source.constellation) {
case GNSS_SV_TYPE_GLONASS:
svMaskPtr = &config.gloBlacklistSvMask;
@@ -1535,6 +1779,31 @@
svMaskPtr = &config.galBlacklistSvMask;
initialSvId = GNSS_SV_CONFIG_GAL_INITIAL_SV_ID;
break;
+ case GNSS_SV_TYPE_SBAS:
+ // SBAS does not support enable/disable whole constellation
+ // so do not set up svTypeMask for SBAS
+ svMaskPtr = &config.sbasBlacklistSvMask;
+ // SBAS currently has two ranges, [120, 158] and [183, 191]
+ if (0 == source.svId) {
+ LOC_LOGd("blacklist all SBAS SV");
+ } else if (source.svId >= GNSS_SV_CONFIG_SBAS_INITIAL2_SV_ID) {
+ // handle SV id in range [183, 191]
+ initialSvId = GNSS_SV_CONFIG_SBAS_INITIAL2_SV_ID;
+ svIndexOffset = GNSS_SV_CONFIG_SBAS_INITIAL_SV_LENGTH;
+ } else if ((source.svId >= GNSS_SV_CONFIG_SBAS_INITIAL_SV_ID) &&
+ (source.svId < (GNSS_SV_CONFIG_SBAS_INITIAL_SV_ID +
+ GNSS_SV_CONFIG_SBAS_INITIAL_SV_LENGTH))){
+ // handle SV id in range of [120, 158]
+ initialSvId = GNSS_SV_CONFIG_SBAS_INITIAL_SV_ID;
+ } else {
+ LOC_LOGe("invalid SBAS sv id %d", source.svId);
+ svMaskPtr = nullptr;
+ }
+ break;
+ case GNSS_SV_TYPE_NAVIC:
+ svMaskPtr = &config.navicBlacklistSvMask;
+ initialSvId = GNSS_SV_CONFIG_NAVIC_INITIAL_SV_ID;
+ break;
default:
break;
}
@@ -1549,7 +1818,8 @@
LOC_LOGe("Invalid sv id %d for sv type %d",
source.svId, source.constellation);
} else {
- *svMaskPtr |= (1ULL << (source.svId - initialSvId));
+ uint32_t shiftCnt = source.svId + svIndexOffset - initialSvId;
+ *svMaskPtr |= (1ULL << shiftCnt);
}
}
}
@@ -1558,41 +1828,67 @@
if (0 != config.gloBlacklistSvMask ||
0 != config.bdsBlacklistSvMask ||
0 != config.galBlacklistSvMask ||
- 0 != config.qzssBlacklistSvMask) {
+ 0 != config.qzssBlacklistSvMask ||
+ 0 != config.sbasBlacklistSvMask ||
+ 0 != config.navicBlacklistSvMask) {
retVal = true;
}
}
+ LOC_LOGd("blacklist bds 0x%" PRIx64 ", glo 0x%" PRIx64
+ ", qzss 0x%" PRIx64 ", gal 0x%" PRIx64 ", sbas 0x%" PRIx64 ", navic 0x%" PRIx64,
+ config.bdsBlacklistSvMask, config.gloBlacklistSvMask,
+ config.qzssBlacklistSvMask, config.galBlacklistSvMask,
+ config.sbasBlacklistSvMask, config.navicBlacklistSvMask);
+
return retVal;
}
void GnssAdapter::convertFromGnssSvIdConfig(
- const GnssSvIdConfig& svConfig, GnssConfig& config)
+ const GnssSvIdConfig& svConfig, std::vector<GnssSvIdSource>& blacklistedSvIds)
{
// Convert blacklisted SV mask values to vectors
if (svConfig.bdsBlacklistSvMask) {
convertGnssSvIdMaskToList(
- svConfig.bdsBlacklistSvMask, config.blacklistedSvIds,
+ svConfig.bdsBlacklistSvMask, blacklistedSvIds,
GNSS_SV_CONFIG_BDS_INITIAL_SV_ID, GNSS_SV_TYPE_BEIDOU);
- config.flags |= GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT;
}
if (svConfig.galBlacklistSvMask) {
convertGnssSvIdMaskToList(
- svConfig.galBlacklistSvMask, config.blacklistedSvIds,
+ svConfig.galBlacklistSvMask, blacklistedSvIds,
GNSS_SV_CONFIG_GAL_INITIAL_SV_ID, GNSS_SV_TYPE_GALILEO);
- config.flags |= GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT;
}
if (svConfig.gloBlacklistSvMask) {
convertGnssSvIdMaskToList(
- svConfig.gloBlacklistSvMask, config.blacklistedSvIds,
+ svConfig.gloBlacklistSvMask, blacklistedSvIds,
GNSS_SV_CONFIG_GLO_INITIAL_SV_ID, GNSS_SV_TYPE_GLONASS);
- config.flags |= GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT;
}
if (svConfig.qzssBlacklistSvMask) {
convertGnssSvIdMaskToList(
- svConfig.qzssBlacklistSvMask, config.blacklistedSvIds,
+ svConfig.qzssBlacklistSvMask, blacklistedSvIds,
GNSS_SV_CONFIG_QZSS_INITIAL_SV_ID, GNSS_SV_TYPE_QZSS);
- config.flags |= GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT;
+ }
+ if (svConfig.sbasBlacklistSvMask) {
+ // SBAS - SV 120 to 158, maps to 0 to 38
+ // SV 183 to 191, maps to 39 to 47
+ uint64_t sbasBlacklistSvMask = svConfig.sbasBlacklistSvMask;
+ // operate on 120 and 158 first
+ sbasBlacklistSvMask <<= (64 - GNSS_SV_CONFIG_SBAS_INITIAL_SV_LENGTH);
+ sbasBlacklistSvMask >>= (64 - GNSS_SV_CONFIG_SBAS_INITIAL_SV_LENGTH);
+ convertGnssSvIdMaskToList(
+ sbasBlacklistSvMask, blacklistedSvIds,
+ GNSS_SV_CONFIG_SBAS_INITIAL_SV_ID, GNSS_SV_TYPE_SBAS);
+ // operate on the second range
+ sbasBlacklistSvMask = svConfig.sbasBlacklistSvMask;
+ sbasBlacklistSvMask >>= GNSS_SV_CONFIG_SBAS_INITIAL_SV_LENGTH;
+ convertGnssSvIdMaskToList(
+ sbasBlacklistSvMask, blacklistedSvIds,
+ GNSS_SV_CONFIG_SBAS_INITIAL2_SV_ID, GNSS_SV_TYPE_SBAS);
+ }
+ if (svConfig.navicBlacklistSvMask) {
+ convertGnssSvIdMaskToList(
+ svConfig.navicBlacklistSvMask, blacklistedSvIds,
+ GNSS_SV_CONFIG_NAVIC_INITIAL_SV_ID, GNSS_SV_TYPE_NAVIC);
}
}
@@ -1606,6 +1902,7 @@
// SV ID 0 => All SV IDs in mask
if (GNSS_SV_CONFIG_ALL_BITS_ENABLED_MASK == svIdMask) {
+ LOC_LOGd("blacklist all SVs in constellation %d", source.constellation);
source.svId = 0;
svIds.push_back(source);
return;
@@ -1616,6 +1913,18 @@
while (svIdMask > 0) {
if (svIdMask & 0x1) {
source.svId = bitNumber + initialSvId;
+ // SBAS has two ranges:
+ // SBAS - SV 120 to 158, maps to 0 to 38
+ // SV 183 to 191, maps to 39 to 47
+ // #define GNSS_SV_CONFIG_SBAS_INITIAL_SV_ID 120
+ // #define GNSS_SV_CONFIG_SBAS_INITIAL_SV_LENGTH 39
+ // #define GNSS_SV_CONFIG_SBAS_INITIAL2_SV_ID 183
+ if (svType == GNSS_SV_TYPE_SBAS) {
+ if (bitNumber >= GNSS_SV_CONFIG_SBAS_INITIAL_SV_LENGTH) {
+ source.svId = bitNumber - GNSS_SV_CONFIG_SBAS_INITIAL_SV_LENGTH +
+ GNSS_SV_CONFIG_SBAS_INITIAL2_SV_ID;
+ }
+ }
svIds.push_back(source);
}
bitNumber++;
@@ -1649,12 +1958,18 @@
// Invoke control clients config callback
if (nullptr != mControlCallbacks.gnssConfigCb &&
svIdConfig.size == sizeof(GnssSvIdConfig)) {
- convertFromGnssSvIdConfig(svIdConfig, config);
- LOC_LOGd("blacklist bds 0x%" PRIx64 ", glo 0x%" PRIx64
- ", qzss 0x%" PRIx64 ", gal 0x%" PRIx64,
- svIdConfig.bdsBlacklistSvMask, svIdConfig.gloBlacklistSvMask,
- svIdConfig.qzssBlacklistSvMask, svIdConfig.galBlacklistSvMask);
- mControlCallbacks.gnssConfigCb(config);
+
+ convertFromGnssSvIdConfig(svIdConfig, config.blacklistedSvIds);
+ if (config.blacklistedSvIds.size() > 0) {
+ config.flags |= GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT;
+ }
+ LOC_LOGd("blacklist bds 0x%" PRIx64 ", glo 0x%" PRIx64 ", "
+ "qzss 0x%" PRIx64 ", gal 0x%" PRIx64 ", sbas 0x%" PRIx64 ", navic 0x%" PRIx64,
+ svIdConfig.bdsBlacklistSvMask, svIdConfig.gloBlacklistSvMask,
+ svIdConfig.qzssBlacklistSvMask, svIdConfig.galBlacklistSvMask,
+ svIdConfig.sbasBlacklistSvMask, svIdConfig.navicBlacklistSvMask);
+ // use 0 session id to indicate that receiver does not yet care about session id
+ mControlCallbacks.gnssConfigCb(0, config);
} else {
LOC_LOGe("Failed to report, size %d", (uint32_t)config.size);
}
@@ -1715,6 +2030,18 @@
mGnssSvTypeConfig.size, mGnssSvTypeConfig.blacklistedSvTypesMask,
mGnssSvTypeConfig.enabledSvTypesMask, sendReset);
+ LOC_LOGd("blacklist bds 0x%" PRIx64 ", glo 0x%" PRIx64
+ ", qzss 0x%" PRIx64 ", gal 0x%" PRIx64 ", sbas 0x%" PRIx64 ", Navic 0x%" PRIx64,
+ mGnssSvIdConfig.bdsBlacklistSvMask, mGnssSvIdConfig.gloBlacklistSvMask,
+ mGnssSvIdConfig.qzssBlacklistSvMask, mGnssSvIdConfig.galBlacklistSvMask,
+ mGnssSvIdConfig.sbasBlacklistSvMask, mGnssSvIdConfig.navicBlacklistSvMask);
+
+ LOC_LOGd("blacklist bds 0x%" PRIx64 ", glo 0x%" PRIx64
+ ", qzss 0x%" PRIx64 ", gal 0x%" PRIx64 ", sbas 0x%" PRIx64 ", Navic 0x%" PRIx64,
+ mGnssSvIdConfig.bdsBlacklistSvMask, mGnssSvIdConfig.gloBlacklistSvMask,
+ mGnssSvIdConfig.qzssBlacklistSvMask, mGnssSvIdConfig.galBlacklistSvMask,
+ mGnssSvIdConfig.sbasBlacklistSvMask, mGnssSvIdConfig.navicBlacklistSvMask);
+
if (mGnssSvTypeConfig.size == sizeof(mGnssSvTypeConfig)) {
if (sendReset) {
@@ -1738,6 +2065,9 @@
if (mGnssSvTypeConfig.blacklistedSvTypesMask & GNSS_SV_TYPES_MASK_GAL_BIT) {
blacklistConfig.galBlacklistSvMask = GNSS_SV_CONFIG_ALL_BITS_ENABLED_MASK;
}
+ if (mGnssSvTypeConfig.blacklistedSvTypesMask & GNSS_SV_TYPES_MASK_NAVIC_BIT) {
+ blacklistConfig.navicBlacklistSvMask = GNSS_SV_CONFIG_ALL_BITS_ENABLED_MASK;
+ }
}
// Send blacklist info
@@ -1853,10 +2183,19 @@
}
void GnssAdapter::deleteAidingData(const GnssAidingData &data, uint32_t sessionId) {
- mLocApi->deleteAidingData(data, new LocApiResponse(*getContext(),
- [this, sessionId] (LocationError err) {
- reportResponse(err, sessionId);
- }));
+ struct timespec bootDeleteAidingDataTime;
+ int64_t bootDeleteTimeMs;
+ if (clock_gettime(CLOCK_BOOTTIME, &bootDeleteAidingDataTime) == 0) {
+ bootDeleteTimeMs = bootDeleteAidingDataTime.tv_sec * 1000000;
+ int64_t diffTimeBFirSecDelete = bootDeleteTimeMs - mLastDeleteAidingDataTime;
+ if (diffTimeBFirSecDelete > DELETE_AIDING_DATA_EXPECTED_TIME_MS) {
+ mLocApi->deleteAidingData(data, new LocApiResponse(*getContext(),
+ [this, sessionId] (LocationError err) {
+ reportResponse(err, sessionId);
+ }));
+ mLastDeleteAidingDataTime = bootDeleteTimeMs;
+ }
+ }
}
uint32_t
@@ -1879,14 +2218,23 @@
inline virtual void proc() const {
if ((mData.posEngineMask & STANDARD_POSITIONING_ENGINE) != 0) {
mAdapter.deleteAidingData(mData, mSessionId);
-
SystemStatus* s = mAdapter.getSystemStatus();
if ((nullptr != s) && (mData.deleteAll)) {
s->setDefaultGnssEngineStates();
}
}
- mAdapter.mEngHubProxy->gnssDeleteAidingData(mData);
+ bool retVal = mAdapter.mEngHubProxy->gnssDeleteAidingData(mData);
+ // When SPE engine is invoked, responseCb will be invoked
+ // from QMI Loc API call.
+ // When SPE engine is not invoked, we also need to deliver responseCb
+ if ((mData.posEngineMask & STANDARD_POSITIONING_ENGINE) == 0) {
+ LocationError err = LOCATION_ERROR_NOT_SUPPORTED;
+ if (retVal == true) {
+ err = LOCATION_ERROR_SUCCESS;
+ }
+ mAdapter.reportResponse(err, mSessionId);
+ }
}
};
@@ -1927,35 +2275,38 @@
double mLatitude;
double mLongitude;
float mAccuracy;
+ bool mOnDemandCpi;
inline MsgInjectLocation(LocApiBase& api,
ContextBase& context,
BlockCPIInfo& blockCPIInfo,
double latitude,
double longitude,
- float accuracy) :
+ float accuracy,
+ bool onDemandCpi) :
LocMsg(),
mApi(api),
mContext(context),
mBlockCPI(blockCPIInfo),
mLatitude(latitude),
mLongitude(longitude),
- mAccuracy(accuracy) {}
+ mAccuracy(accuracy),
+ mOnDemandCpi(onDemandCpi) {}
inline virtual void proc() const {
if ((uptimeMillis() <= mBlockCPI.blockedTillTsMs) &&
(fabs(mLatitude-mBlockCPI.latitude) <= mBlockCPI.latLonDiffThreshold) &&
(fabs(mLongitude-mBlockCPI.longitude) <= mBlockCPI.latLonDiffThreshold)) {
- LOC_LOGD("%s]: positon injeciton blocked: lat: %f, lon: %f, accuracy: %f",
+ LOC_LOGD("%s]: positon injection blocked: lat: %f, lon: %f, accuracy: %f",
__func__, mLatitude, mLongitude, mAccuracy);
} else {
- mApi.injectPosition(mLatitude, mLongitude, mAccuracy);
+ mApi.injectPosition(mLatitude, mLongitude, mAccuracy, mOnDemandCpi);
}
}
};
sendMsg(new MsgInjectLocation(*mLocApi, *mContext, mBlockCPIInfo,
- latitude, longitude, accuracy));
+ latitude, longitude, accuracy, mOdcpiRequestActive));
}
void
@@ -2145,7 +2496,10 @@
void
GnssAdapter::updateClientsEventMask()
{
- LOC_API_ADAPTER_EVENT_MASK_T mask = 0;
+ // need to register for leap second info
+ // for proper nmea generation
+ LOC_API_ADAPTER_EVENT_MASK_T mask = LOC_API_ADAPTER_BIT_LOC_SYSTEM_INFO |
+ LOC_API_ADAPTER_BIT_EVENT_REPORT_INFO;
for (auto it=mClientData.begin(); it != mClientData.end(); ++it) {
if (it->second.trackingCb != nullptr ||
it->second.gnssLocationInfoCb != nullptr ||
@@ -2180,8 +2534,6 @@
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;
// Nhz measurement bit is set based on callback from loc eng hub
// for Nhz engines.
@@ -2206,6 +2558,13 @@
// always register for NI NOTIFY VERIFY to handle internally in HAL
mask |= LOC_API_ADAPTER_BIT_NI_NOTIFY_VERIFY_REQUEST;
+ // Enable the latency report
+ if (mask & LOC_API_ADAPTER_BIT_GNSS_MEASUREMENT) {
+ if (mLogger.isLogEnabled()) {
+ mask |= LOC_API_ADAPTER_BIT_LATENCY_INFORMATION;
+ }
+ }
+
updateEvtMask(mask, LOC_REGISTRATION_MASK_SET);
}
@@ -2227,7 +2586,11 @@
mAdapter.gnssSvIdConfigUpdate();
mAdapter.gnssSvTypeConfigUpdate();
mAdapter.updateSystemPowerState(mAdapter.getSystemPowerState());
- mAdapter.restartSessions();
+ mAdapter.gnssSecondaryBandConfigUpdate();
+ // start CDFW service
+ mAdapter.initCDFWService();
+ // restart sessions
+ mAdapter.restartSessions(true);
for (auto msg: mAdapter.mPendingMsgs) {
mAdapter.sendMsg(msg);
}
@@ -2240,13 +2603,32 @@
}
void
-GnssAdapter::restartSessions()
+GnssAdapter::restartSessions(bool modemSSR)
+{
+ LOC_LOGi(":enter");
+
+ if (modemSSR) {
+ // odcpi session is no longer active after restart
+ mOdcpiRequestActive = false;
+ }
+
+ // SPE will be restarted now, so set this variable to false.
+ mSPEAlreadyRunningAtHighestInterval = false;
+
+ if (false == mTimeBasedTrackingSessions.empty()) {
+ // inform engine hub that GNSS session is about to start
+ mEngHubProxy->gnssSetFixMode(mLocPositionMode);
+ mEngHubProxy->gnssStartFix();
+ checkUpdateDgnssNtrip(false);
+ }
+
+ checkAndRestartSPESession();
+}
+
+void GnssAdapter::checkAndRestartSPESession()
{
LOC_LOGD("%s]: ", __func__);
- // odcpi session is no longer active after restart
- mOdcpiRequestActive = false;
-
// SPE will be restarted now, so set this variable to false.
mSPEAlreadyRunningAtHighestInterval = false;
@@ -2260,6 +2642,24 @@
}
}
+// suspend all on-going sessions
+void
+GnssAdapter::suspendSessions()
+{
+ LOC_LOGi(":enter");
+
+ if (!mTimeBasedTrackingSessions.empty()) {
+ // inform engine hub that GNSS session has stopped
+ mEngHubProxy->gnssStopFix();
+ mLocApi->stopFix(nullptr);
+ if (isDgnssNmeaRequired()) {
+ mDgnssState &= ~DGNSS_STATE_NO_NMEA_PENDING;
+ }
+ stopDgnssNtrip();
+ mSPEAlreadyRunningAtHighestInterval = false;
+ }
+}
+
void GnssAdapter::checkAndRestartTimeBasedSession()
{
LOC_LOGD("%s]: ", __func__);
@@ -2294,6 +2694,48 @@
}
}
+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;
+ }
+ //Get QWES feature status mask
+ mask |= ContextBase::getQwesFeatureStatus();
+ return mask;
+}
+
void
GnssAdapter::notifyClientOfCachedLocationSystemInfo(
LocationAPI* client, const LocationCallbacks& callbacks) {
@@ -2344,7 +2786,8 @@
auto it = mClientData.find(client);
if (it != mClientData.end()) {
if (it->second.trackingCb || it->second.gnssLocationInfoCb ||
- it->second.engineLocationsInfoCb || it->second.gnssMeasurementsCb) {
+ it->second.engineLocationsInfoCb || it->second.gnssMeasurementsCb ||
+ it->second.gnssDataCb || it->second.gnssSvCb || it->second.gnssNmeaCb) {
allowed = true;
} else {
LOC_LOGi("missing right callback to start tracking")
@@ -2376,15 +2819,15 @@
}
void
-GnssAdapter::getPowerStateChangesCommand(void* powerStateCb)
+GnssAdapter::getPowerStateChangesCommand(std::function<void(bool)> powerStateCb)
{
LOC_LOGD("%s]: ", __func__);
struct MsgReportLocation : public LocMsg {
GnssAdapter& mAdapter;
- powerStateCallback mPowerStateCb;
+ std::function<void(bool)> mPowerStateCb;
inline MsgReportLocation(GnssAdapter& adapter,
- powerStateCallback powerStateCb) :
+ std::function<void(bool)> powerStateCb) :
LocMsg(),
mAdapter(adapter),
mPowerStateCb(powerStateCb) {}
@@ -2394,7 +2837,7 @@
}
};
- sendMsg(new MsgReportLocation(*this, (powerStateCallback)powerStateCb));
+ sendMsg(new MsgReportLocation(*this, powerStateCb));
}
void
@@ -2427,7 +2870,6 @@
reportPowerStateIfChanged();
}
-
bool GnssAdapter::setLocPositionMode(const LocPosMode& mode) {
if (!mLocPositionMode.equals(mode)) {
mLocPositionMode = mode;
@@ -2573,6 +3015,8 @@
bool reportToClientWithNoWait = true;
if (mTimeBasedTrackingSessions.empty()) {
+ /*Reset previous NMEA reported time stamp */
+ mPrevNmeaRptTimeNsec = 0;
startTimeBasedTracking(client, sessionId, options);
// need to wait for QMI callback
reportToClientWithNoWait = false;
@@ -2626,12 +3070,12 @@
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);
-
+ // save position mode parameters
+ setLocPositionMode(locPosMode);
// inform engine hub that GNSS session is about to start
- mEngHubProxy->gnssSetFixMode(locPosMode);
+ mEngHubProxy->gnssSetFixMode(mLocPositionMode);
mEngHubProxy->gnssStartFix();
// want to run SPE session at a fixed min interval in some automotive scenarios
@@ -2643,6 +3087,8 @@
[this, client, sessionId] (LocationError err) {
if (LOCATION_ERROR_SUCCESS != err) {
eraseTrackingSession(client, sessionId);
+ } else {
+ checkUpdateDgnssNtrip(false);
}
reportResponse(client, err, sessionId);
@@ -2660,9 +3106,11 @@
{
LocPosMode locPosMode = {};
convertOptions(locPosMode, updatedOptions);
+ // save position mode parameters
+ setLocPositionMode(locPosMode);
// inform engine hub that GNSS session is about to start
- mEngHubProxy->gnssSetFixMode(locPosMode);
+ mEngHubProxy->gnssSetFixMode(mLocPositionMode);
mEngHubProxy->gnssStartFix();
// want to run SPE session at a fixed min interval in some automotive scenarios
@@ -2968,7 +3416,6 @@
// else part: no QMI call is made, need to report back to client right away
}
}
-
return reportToClientWithNoWait;
}
@@ -2983,6 +3430,11 @@
reportResponse(client, err, id);
}));
+ if (isDgnssNmeaRequired()) {
+ mDgnssState &= ~DGNSS_STATE_NO_NMEA_PENDING;
+ }
+ stopDgnssNtrip();
+
mSPEAlreadyRunningAtHighestInterval = false;
}
@@ -3195,6 +3647,63 @@
}
+// This function computes the VRP based latitude, longitude and alittude, and
+// north, east and up velocity and save the result into EHubTechReport.
+void
+GnssAdapter::computeVRPBasedLla(const UlpLocation& loc, GpsLocationExtended& locExt,
+ const LeverArmConfigInfo& leverArmConfigInfo) {
+
+ float leverArm[3];
+ float rollPitchYaw[3];
+ double lla[3];
+
+ uint16_t locFlags = loc.gpsLocation.flags;
+ uint64_t locExtFlags = locExt.flags;
+
+ // check for SPE fix
+ if (!((locExtFlags & GPS_LOCATION_EXTENDED_HAS_OUTPUT_ENG_TYPE) &&
+ (locExt.locOutputEngType == LOC_OUTPUT_ENGINE_SPE))){
+ LOC_LOGv("not SPE fix, return");
+ return;
+ }
+
+ // we can only do translation if we have VRP based lever ARM info
+ LeverArmTypeMask leverArmFlags = leverArmConfigInfo.leverArmValidMask;
+ if (!(leverArmFlags & LEVER_ARM_TYPE_GNSS_TO_VRP_BIT)) {
+ LOC_LOGd("no VRP based lever ARM info");
+ return;
+ }
+
+ leverArm[0] = leverArmConfigInfo.gnssToVRP.forwardOffsetMeters;
+ leverArm[1] = leverArmConfigInfo.gnssToVRP.sidewaysOffsetMeters;
+ leverArm[2] = leverArmConfigInfo.gnssToVRP.upOffsetMeters;
+
+ if ((locFlags & LOC_GPS_LOCATION_HAS_LAT_LONG) &&
+ (locFlags & LOC_GPS_LOCATION_HAS_ALTITUDE) &&
+ (locFlags & LOCATION_HAS_BEARING_BIT)) {
+
+ lla[0] = loc.gpsLocation.latitude * DEG2RAD;
+ lla[1] = loc.gpsLocation.longitude * DEG2RAD;
+ lla[2] = loc.gpsLocation.altitude;
+
+ rollPitchYaw[0] = 0.0f;
+ rollPitchYaw[1] = 0.0f;
+ rollPitchYaw[2] = loc.gpsLocation.bearing * DEG2RAD;
+
+ loc_convert_lla_gnss_to_vrp(lla, rollPitchYaw, leverArm);
+
+ // assign the converted value into position report and
+ // set up valid mask
+ locExt.llaVRPBased.latitude = lla[0] * RAD2DEG;
+ locExt.llaVRPBased.longitude = lla[1] * RAD2DEG;
+ locExt.llaVRPBased.altitude = lla[2];
+ locExt.flags |= GPS_LOCATION_EXTENDED_HAS_LLA_VRP_BASED;
+ } else {
+ LOC_LOGd("SPE fix missing latitude/longitude/alitutde");
+ return;
+ }
+}
+
void
GnssAdapter::reportPositionEvent(const UlpLocation& ulpLocation,
const GpsLocationExtended& locationExtended,
@@ -3206,85 +3715,94 @@
// this position is from QMI LOC API, then send report to engine hub
// also, send out SPE fix promptly to the clients that have registered
// with SPE report
- LOC_LOGd("reportPositionEvent, eng type: %d, unpro %d, sess status %d",
- locationExtended.locOutputEngType, ulpLocation.unpropagatedPosition,
- status);
+ LOC_LOGd("reportPositionEvent, eng type: %d, unpro %d, sess status %d msInWeek %d",
+ locationExtended.locOutputEngType,
+ ulpLocation.unpropagatedPosition, status, msInWeek);
- if (true == initEngHubProxy()){
- // send the SPE fix to engine hub
- mEngHubProxy->gnssReportPosition(ulpLocation, locationExtended, status);
- // report out all SPE fix if it is not propagated, even for failed fix
- if (false == ulpLocation.unpropagatedPosition) {
- EngineLocationInfo engLocationInfo = {};
- engLocationInfo.location = ulpLocation;
- engLocationInfo.locationExtended = locationExtended;
- engLocationInfo.sessionStatus = status;
- reportEnginePositionsEvent(1, &engLocationInfo);
- }
- return;
- }
-
- // unpropagated report: is only for engine hub to consume and no need
- // to send out to the clients
- if (true == ulpLocation.unpropagatedPosition) {
- return;
- }
-
- // Fix is from QMI, and it is not an unpropagated position and engine hub
- // is not loaded, queue the message when message is processed, the position
- // can be dispatched to requesting client that registers for SPE report
- struct MsgReportPosition : public LocMsg {
+ struct MsgReportSPEPosition : public LocMsg {
GnssAdapter& mAdapter;
- const UlpLocation mUlpLocation;
- const GpsLocationExtended mLocationExtended;
- loc_sess_status mStatus;
+ mutable UlpLocation mUlpLocation;
+ mutable GpsLocationExtended mLocationExtended;
+ enum loc_sess_status mStatus;
LocPosTechMask mTechMask;
- GnssDataNotification mDataNotify;
+ mutable GnssDataNotification mDataNotify;
int mMsInWeek;
- bool mbIsDataValid;
- inline MsgReportPosition(GnssAdapter& adapter,
- const UlpLocation& ulpLocation,
- const GpsLocationExtended& locationExtended,
- loc_sess_status status,
- LocPosTechMask techMask,
- GnssDataNotification* pDataNotify,
- int msInWeek) :
+
+ inline MsgReportSPEPosition(GnssAdapter& adapter,
+ const UlpLocation& ulpLocation,
+ const GpsLocationExtended& locationExtended,
+ enum loc_sess_status status,
+ LocPosTechMask techMask,
+ GnssDataNotification dataNotify,
+ int msInWeek) :
LocMsg(),
mAdapter(adapter),
mUlpLocation(ulpLocation),
mLocationExtended(locationExtended),
mStatus(status),
mTechMask(techMask),
- mMsInWeek(msInWeek) {
- memset(&mDataNotify, 0, sizeof(mDataNotify));
- if (pDataNotify != nullptr) {
- mDataNotify = *pDataNotify;
- mbIsDataValid = true;
- } else {
- mbIsDataValid = false;
- }
- }
+ mDataNotify(dataNotify),
+ mMsInWeek(msInWeek) {}
inline virtual void proc() const {
+ if (mAdapter.mTimeBasedTrackingSessions.empty() &&
+ mAdapter.mDistanceBasedTrackingSessions.empty()) {
+ LOC_LOGd("reportPositionEvent, no session on-going, throw away the SPE reports");
+ return;
+ }
+
+ if (false == mUlpLocation.unpropagatedPosition && mDataNotify.size != 0) {
+ if (mMsInWeek >= 0) {
+ mAdapter.getDataInformation((GnssDataNotification&)mDataNotify,
+ mMsInWeek);
+ }
+ mAdapter.reportData(mDataNotify);
+ }
+
+ if (true == mAdapter.initEngHubProxy()){
+ // send the SPE fix to engine hub
+ mAdapter.mEngHubProxy->gnssReportPosition(mUlpLocation, mLocationExtended, mStatus);
+ // report out all SPE fix if it is not propagated, even for failed fix
+ if (false == mUlpLocation.unpropagatedPosition) {
+ EngineLocationInfo engLocationInfo = {};
+ engLocationInfo.location = mUlpLocation;
+ engLocationInfo.locationExtended = mLocationExtended;
+ engLocationInfo.sessionStatus = mStatus;
+
+ // obtain the VRP based latitude/longitude/altitude for SPE fix
+ computeVRPBasedLla(engLocationInfo.location,
+ engLocationInfo.locationExtended,
+ mAdapter.mLocConfigInfo.leverArmConfigInfo);
+ mAdapter.reportEnginePositions(1, &engLocationInfo);
+ }
+ return;
+ }
+
+ // unpropagated report: is only for engine hub to consume and no need
+ // to send out to the clients
+ if (true == mUlpLocation.unpropagatedPosition) {
+ return;
+ }
+
// extract bug report info - this returns true if consumed by systemstatus
SystemStatus* s = mAdapter.getSystemStatus();
if ((nullptr != s) &&
((LOC_SESS_SUCCESS == mStatus) || (LOC_SESS_INTERMEDIATE == mStatus))){
s->eventPosition(mUlpLocation, mLocationExtended);
}
+
mAdapter.reportPosition(mUlpLocation, mLocationExtended, mStatus, mTechMask);
- if (true == mbIsDataValid) {
- if (-1 != mMsInWeek) {
- mAdapter.getDataInformation((GnssDataNotification&)mDataNotify,
- mMsInWeek);
- }
- mAdapter.reportData((GnssDataNotification&)mDataNotify);
- }
}
};
- sendMsg(new MsgReportPosition(*this, ulpLocation, locationExtended,
- status, techMask,
- pDataNotify, msInWeek));
+ if (mContext != NULL) {
+ GnssDataNotification dataNotifyCopy = {};
+ if (pDataNotify) {
+ dataNotifyCopy = *pDataNotify;
+ dataNotifyCopy.size = sizeof(dataNotifyCopy);
+ }
+ sendMsg(new MsgReportSPEPosition(*this, ulpLocation, locationExtended,
+ status, techMask, dataNotifyCopy, msInWeek));
+ }
}
void
@@ -3335,9 +3853,9 @@
bool
GnssAdapter::needReportForFlpClient(enum loc_sess_status status,
LocPosTechMask techMask) {
- if ((status == LOC_SESS_INTERMEDIATE) &&
- !(techMask & LOC_POS_TECH_MASK_SENSORS) &&
- (!getAllowFlpNetworkFixes())) {
+ if (((LOC_SESS_INTERMEDIATE == status) && !(techMask & LOC_POS_TECH_MASK_SENSORS) &&
+ (!getAllowFlpNetworkFixes())) ||
+ (LOC_SESS_FAILURE == status)) {
return false;
} else {
return true;
@@ -3354,6 +3872,97 @@
locationCallbacks.gnssMeasurementsCb == nullptr);
}
+bool GnssAdapter::needToGenerateNmeaReport(const uint32_t &gpsTimeOfWeekMs,
+ const struct timespec32_t &apTimeStamp)
+{
+ bool retVal = false;
+ uint64_t currentTimeNsec = 0;
+
+ if (NMEA_PROVIDER_AP == ContextBase::mGps_conf.NMEA_PROVIDER && !mTimeBasedTrackingSessions.empty()) {
+ currentTimeNsec = (apTimeStamp.tv_sec * BILLION_NSEC + apTimeStamp.tv_nsec);
+ if ((GNSS_NMEA_REPORT_RATE_NHZ == ContextBase::sNmeaReportRate) ||
+ (GPS_DEFAULT_FIX_INTERVAL_MS <= mLocPositionMode.min_interval)) {
+ retVal = true;
+ } else { /*tbf is less than 1000 milli-seconds and NMEA reporting rate is set to 1Hz */
+ /* Always send NMEA string for first position report
+ * Send when gpsTimeOfWeekMs is closely aligned with integer boundary
+ */
+ if ((0 == mPrevNmeaRptTimeNsec) ||
+ (0 != gpsTimeOfWeekMs) && (NMEA_MIN_THRESHOLD_MSEC >= (gpsTimeOfWeekMs % 1000))) {
+ retVal = true;
+ } else {
+ uint64_t timeDiffMsec = ((currentTimeNsec - mPrevNmeaRptTimeNsec) / 1000000);
+ // Send when the delta time becomes >= 1 sec
+ if (NMEA_MAX_THRESHOLD_MSEC <= timeDiffMsec) {
+ retVal = true;
+ }
+ }
+ }
+ if (true == retVal) {
+ mPrevNmeaRptTimeNsec = currentTimeNsec;
+ }
+ }
+ return retVal;
+}
+
+void
+GnssAdapter::logLatencyInfo()
+{
+ if (0 == mGnssLatencyInfoQueue.size()) {
+ LOC_LOGv("mGnssLatencyInfoQueue.size is 0");
+ return;
+ }
+ mGnssLatencyInfoQueue.front().hlosQtimer5 = getQTimerTickCount();
+ if (0 == mGnssLatencyInfoQueue.front().hlosQtimer3) {
+ /* if SPE from engine hub is not reported then hlosQtimer3 = 0, set it
+ equal to hlosQtimer2 to make sense */
+ LOC_LOGv("hlosQtimer3 is 0, setting it to hlosQtimer2");
+ mGnssLatencyInfoQueue.front().hlosQtimer3 = mGnssLatencyInfoQueue.front().hlosQtimer2;
+ }
+ if (0 == mGnssLatencyInfoQueue.front().hlosQtimer4) {
+ /* if PPE from engine hub is not reported then hlosQtimer4 = 0, set it
+ equal to hlosQtimer3 to make sense */
+ LOC_LOGv("hlosQtimer4 is 0, setting it to hlosQtimer3");
+ mGnssLatencyInfoQueue.front().hlosQtimer4 = mGnssLatencyInfoQueue.front().hlosQtimer3;
+ }
+ if (mGnssLatencyInfoQueue.front().hlosQtimer4 < mGnssLatencyInfoQueue.front().hlosQtimer3) {
+ /* hlosQtimer3 is timestamped when SPE from engine hub is reported,
+ and hlosQtimer4 is timestamped when PPE from engine hub is reported.
+ The order is random though, hence making sure the timestamps are sorted */
+ LOC_LOGv("hlosQtimer4 is < hlosQtimer3, swapping them");
+ std::swap(mGnssLatencyInfoQueue.front().hlosQtimer3,
+ mGnssLatencyInfoQueue.front().hlosQtimer4);
+ }
+ LOC_LOGv("meQtimer1=%" PRIi64 " "
+ "meQtimer2=%" PRIi64 " "
+ "meQtimer3=%" PRIi64 " "
+ "peQtimer1=%" PRIi64 " "
+ "peQtimer2=%" PRIi64 " "
+ "peQtimer3=%" PRIi64 " "
+ "smQtimer1=%" PRIi64 " "
+ "smQtimer2=%" PRIi64 " "
+ "smQtimer3=%" PRIi64 " "
+ "locMwQtimer=%" PRIi64 " "
+ "hlosQtimer1=%" PRIi64 " "
+ "hlosQtimer2=%" PRIi64 " "
+ "hlosQtimer3=%" PRIi64 " "
+ "hlosQtimer4=%" PRIi64 " "
+ "hlosQtimer5=%" PRIi64 " ",
+ mGnssLatencyInfoQueue.front().meQtimer1, mGnssLatencyInfoQueue.front().meQtimer2,
+ mGnssLatencyInfoQueue.front().meQtimer3, mGnssLatencyInfoQueue.front().peQtimer1,
+ mGnssLatencyInfoQueue.front().peQtimer2, mGnssLatencyInfoQueue.front().peQtimer3,
+ mGnssLatencyInfoQueue.front().smQtimer1, mGnssLatencyInfoQueue.front().smQtimer2,
+ mGnssLatencyInfoQueue.front().smQtimer3, mGnssLatencyInfoQueue.front().locMwQtimer,
+ mGnssLatencyInfoQueue.front().hlosQtimer1, mGnssLatencyInfoQueue.front().hlosQtimer2,
+ mGnssLatencyInfoQueue.front().hlosQtimer3, mGnssLatencyInfoQueue.front().hlosQtimer4,
+ mGnssLatencyInfoQueue.front().hlosQtimer5);
+ mLogger.log(mGnssLatencyInfoQueue.front());
+ mGnssLatencyInfoQueue.pop();
+ LOC_LOGv("mGnssLatencyInfoQueue.size after pop=%zu", mGnssLatencyInfoQueue.size());
+}
+
+// only fused report (when engine hub is enabled) or
+// SPE report (when engine hub is disabled) will reach this function
void
GnssAdapter::reportPosition(const UlpLocation& ulpLocation,
const GpsLocationExtended& locationExtended,
@@ -3365,16 +3974,16 @@
if (reportToGnssClient || reportToFlpClient) {
GnssLocationInfoNotification locationInfo = {};
- convertLocationInfo(locationInfo, locationExtended);
- convertLocation(locationInfo.location, ulpLocation, locationExtended, techMask);
-
+ convertLocationInfo(locationInfo, locationExtended, status);
+ convertLocation(locationInfo.location, ulpLocation, locationExtended);
+ logLatencyInfo();
for (auto it=mClientData.begin(); it != mClientData.end(); ++it) {
if ((reportToFlpClient && isFlpClient(it->second)) ||
(reportToGnssClient && !isFlpClient(it->second))) {
if (nullptr != it->second.gnssLocationInfoCb) {
it->second.gnssLocationInfoCb(locationInfo);
} else if ((nullptr != it->second.engineLocationsInfoCb) &&
- (false == initEngHubProxy())) {
+ (false == initEngHubProxy())) {
// if engine hub is disabled, this is SPE fix from modem
// we need to mark one copy marked as fused and one copy marked as PPE
// and dispatch it to the engineLocationsInfoCb
@@ -3402,18 +4011,24 @@
}
}
- // if PACE is enabled and engine hub is running and the fix is from sensor,
- // e.g.: DRE, inject DRE fix to modem
- if ((true == mLocConfigInfo.paceConfigInfo.isValid &&
- true == mLocConfigInfo.paceConfigInfo.enable) &&
- (true == initEngHubProxy()) && (LOC_POS_TECH_MASK_SENSORS & techMask)) {
- mLocApi->injectPosition(locationInfo, false);
+ // if PACE is enabled
+ if ((true == mLocConfigInfo.paceConfigInfo.isValid) &&
+ (true == mLocConfigInfo.paceConfigInfo.enable)) {
+ // If fix has sensor contribution, and it is fused fix with DRE engine
+ // contributing to the fix, inject to modem
+ if ((LOC_POS_TECH_MASK_SENSORS & techMask) &&
+ (locationInfo.flags & GNSS_LOCATION_INFO_OUTPUT_ENG_TYPE_BIT) &&
+ (locationInfo.locOutputEngType == LOC_OUTPUT_ENGINE_FUSED) &&
+ (locationInfo.flags & GNSS_LOCATION_INFO_OUTPUT_ENG_MASK_BIT) &&
+ (locationInfo.locOutputEngMask & DEAD_RECKONING_ENGINE)) {
+ mLocApi->injectPosition(locationInfo, false);
+ }
}
}
}
- if (NMEA_PROVIDER_AP == ContextBase::mGps_conf.NMEA_PROVIDER &&
- !mTimeBasedTrackingSessions.empty()) {
+ if (needToGenerateNmeaReport(locationExtended.gpsTime.gpsTimeOfWeekMs,
+ locationExtended.timeStamp.apTimeStamp)) {
/*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) &&
@@ -3421,19 +4036,50 @@
(LOC_RELIABILITY_NOT_SET == locationExtended.horizontal_reliability));
uint8_t generate_nmea = (reportToGnssClient && status != LOC_SESS_FAILURE && !blank_fix);
bool custom_nmea_gga = (1 == ContextBase::mGps_conf.CUSTOM_NMEA_GGA_FIX_QUALITY_ENABLED);
+ bool isTagBlockGroupingEnabled =
+ (1 == ContextBase::mGps_conf.NMEA_TAG_BLOCK_GROUPING_ENABLED);
std::vector<std::string> nmeaArraystr;
- loc_nmea_generate_pos(ulpLocation, locationExtended, mLocSystemInfo,
- generate_nmea, custom_nmea_gga, nmeaArraystr);
+ int indexOfGGA = -1;
+ loc_nmea_generate_pos(ulpLocation, locationExtended, mLocSystemInfo, generate_nmea,
+ custom_nmea_gga, nmeaArraystr, indexOfGGA, isTagBlockGroupingEnabled);
stringstream ss;
for (auto itor = nmeaArraystr.begin(); itor != nmeaArraystr.end(); ++itor) {
ss << *itor;
}
string s = ss.str();
reportNmea(s.c_str(), s.length());
+
+ /* DgnssNtrip */
+ if (-1 != indexOfGGA && isDgnssNmeaRequired()) {
+ mDgnssState |= DGNSS_STATE_NO_NMEA_PENDING;
+ mStartDgnssNtripParams.nmea = std::move(nmeaArraystr[indexOfGGA]);
+ bool isLocationValid = (0 != ulpLocation.gpsLocation.latitude) ||
+ (0 != ulpLocation.gpsLocation.longitude);
+ checkUpdateDgnssNtrip(isLocationValid);
+ }
}
}
void
+GnssAdapter::reportLatencyInfoEvent(const GnssLatencyInfo& gnssLatencyInfo)
+{
+ struct MsgReportLatencyInfo : public LocMsg {
+ GnssAdapter& mAdapter;
+ GnssLatencyInfo mGnssLatencyInfo;
+ inline MsgReportLatencyInfo(GnssAdapter& adapter,
+ const GnssLatencyInfo& gnssLatencyInfo) :
+ mGnssLatencyInfo(gnssLatencyInfo),
+ mAdapter(adapter) {}
+ inline virtual void proc() const {
+ mAdapter.mGnssLatencyInfoQueue.push(mGnssLatencyInfo);
+ LOC_LOGv("mGnssLatencyInfoQueue.size after push=%zu",
+ mAdapter.mGnssLatencyInfoQueue.size());
+ }
+ };
+ sendMsg(new MsgReportLatencyInfo(*this, gnssLatencyInfo));
+}
+
+void
GnssAdapter::reportEnginePositions(unsigned int count,
const EngineLocationInfo* locationArr)
{
@@ -3458,14 +4104,30 @@
}
if (needReportEnginePositions) {
- convertLocationInfo(locationInfo[i], engLocation->locationExtended);
+ convertLocationInfo(locationInfo[i], engLocation->locationExtended,
+ engLocation->sessionStatus);
convertLocation(locationInfo[i].location,
engLocation->location,
- engLocation->locationExtended,
- engLocation->location.tech_mask);
+ engLocation->locationExtended);
}
}
+ const EngineLocationInfo* engLocation = locationArr;
+ LOC_LOGv("engLocation->locationExtended.locOutputEngType=%d",
+ engLocation->locationExtended.locOutputEngType);
+
+ if (0 != mGnssLatencyInfoQueue.size()) {
+ if ((GPS_LOCATION_EXTENDED_HAS_OUTPUT_ENG_TYPE & engLocation->locationExtended.flags) &&
+ (LOC_OUTPUT_ENGINE_SPE == engLocation->locationExtended.locOutputEngType)) {
+ mGnssLatencyInfoQueue.front().hlosQtimer3 = getQTimerTickCount();
+ LOC_LOGv("SPE hlosQtimer3=%" PRIi64 " ", mGnssLatencyInfoQueue.front().hlosQtimer3);
+ }
+ if ((GPS_LOCATION_EXTENDED_HAS_OUTPUT_ENG_TYPE & engLocation->locationExtended.flags) &&
+ (LOC_OUTPUT_ENGINE_PPE == engLocation->locationExtended.locOutputEngType)) {
+ mGnssLatencyInfoQueue.front().hlosQtimer4 = getQTimerTickCount();
+ LOC_LOGv("PPE hlosQtimer4=%" PRIi64 " ", mGnssLatencyInfoQueue.front().hlosQtimer4);
+ }
+ }
if (needReportEnginePositions) {
for (auto it=mClientData.begin(); it != mClientData.end(); ++it) {
if (nullptr != it->second.engineLocationsInfoCb) {
@@ -3506,7 +4168,7 @@
GnssAdapter::reportSv(GnssSvNotification& svNotify)
{
int numSv = svNotify.count;
- int16_t gnssSvId = 0;
+ uint16_t gnssSvId = 0;
uint64_t svUsedIdMask = 0;
for (int i=0; i < numSv; i++) {
svUsedIdMask = 0;
@@ -3550,6 +4212,9 @@
svUsedIdMask = mGnssSvIdUsedInPosition.glo_sv_used_ids_mask;
}
}
+ // map the svid to respective constellation range 1..xx
+ // then repective constellation svUsedIdMask map correctly to svid
+ gnssSvId = gnssSvId - GLO_SV_PRN_MIN + 1;
break;
case GNSS_SV_TYPE_BEIDOU:
if (mGnssSvIdUsedInPosAvail) {
@@ -3575,6 +4240,7 @@
svUsedIdMask = mGnssSvIdUsedInPosition.bds_sv_used_ids_mask;
}
}
+ gnssSvId = gnssSvId - BDS_SV_PRN_MIN + 1;
break;
case GNSS_SV_TYPE_GALILEO:
if (mGnssSvIdUsedInPosAvail) {
@@ -3594,6 +4260,7 @@
svUsedIdMask = mGnssSvIdUsedInPosition.gal_sv_used_ids_mask;
}
}
+ gnssSvId = gnssSvId - GAL_SV_PRN_MIN + 1;
break;
case GNSS_SV_TYPE_QZSS:
if (mGnssSvIdUsedInPosAvail) {
@@ -3616,15 +4283,13 @@
svUsedIdMask = mGnssSvIdUsedInPosition.qzss_sv_used_ids_mask;
}
}
- // QZSS SV id's need to reported as it is to framework, since
- // framework expects it as it is. See GnssStatus.java.
- // SV id passed to here by LocApi is 1-based.
- svNotify.gnssSvs[i].svId += (QZSS_SV_PRN_MIN - 1);
+ gnssSvId = gnssSvId - QZSS_SV_PRN_MIN + 1;
break;
case GNSS_SV_TYPE_NAVIC:
if (mGnssSvIdUsedInPosAvail) {
svUsedIdMask = mGnssSvIdUsedInPosition.navic_sv_used_ids_mask;
}
+ gnssSvId = gnssSvId - NAVIC_SV_PRN_MIN + 1;
break;
default:
svUsedIdMask = 0;
@@ -3633,7 +4298,7 @@
// If SV ID was used in previous position fix, then set USED_IN_FIX
// flag, else clear the USED_IN_FIX flag.
- if ((gnssSvId < 64) && (svUsedIdMask & (1ULL << (gnssSvId - 1)))) {
+ if (svFitsMask(svUsedIdMask, gnssSvId) && (svUsedIdMask & (1ULL << (gnssSvId - 1)))) {
svNotify.gnssSvs[i].gnssSvOptionsMask |= GNSS_SV_OPTIONS_USED_IN_FIX_BIT;
}
}
@@ -3657,6 +4322,7 @@
}
mGnssSvIdUsedInPosAvail = false;
+ mGnssMbSvIdUsedInPosAvail = false;
}
void
@@ -3698,6 +4364,8 @@
if (false == ret) {
// forward NMEA message to upper layer
mAdapter.reportNmea(mNmea, mLength);
+ // DgnssNtrip
+ mAdapter.reportGGAToNtrip(mNmea);
}
}
};
@@ -3723,6 +4391,10 @@
it->second.gnssNmeaCb(nmeaNotification);
}
}
+
+ if (isNMEAPrintEnabled()) {
+ LOC_LOGd("[%" PRId64 ", %zu] %s", now, length, nmea);
+ }
}
void
@@ -3734,15 +4406,15 @@
GnssDataNotification mDataNotify;
int mMsInWeek;
inline MsgReportData(GnssAdapter& adapter,
- const GnssDataNotification& dataNotify,
- int msInWeek) :
+ const GnssDataNotification& dataNotify,
+ int msInWeek) :
LocMsg(),
mAdapter(adapter),
mDataNotify(dataNotify),
mMsInWeek(msInWeek) {
}
inline virtual void proc() const {
- if (-1 != mMsInWeek) {
+ if (mMsInWeek >= 0) {
mAdapter.getDataInformation((GnssDataNotification&)mDataNotify,
mMsInWeek);
}
@@ -4081,6 +4753,9 @@
sendMsg(new MsgReportGnssMeasurementData(*this, gnssMeasurements, msInWeek));
}
mEngHubProxy->gnssReportSvMeasurement(gnssMeasurements.gnssSvMeasurementSet);
+ if (mDGnssNeedReport) {
+ reportDGnssDataUsable(gnssMeasurements.gnssSvMeasurementSet);
+ }
}
void
@@ -4094,6 +4769,27 @@
}
void
+GnssAdapter::reportDGnssDataUsable(const GnssSvMeasurementSet &svMeasurementSet)
+{
+ uint32_t i;
+ bool preDGnssDataUsage = mDGnssDataUsage;
+
+ mDGnssDataUsage = false;
+ for (i = 0; i < svMeasurementSet.svMeasCount; i++) {
+ const Gnss_SVMeasurementStructType& svMeas = svMeasurementSet.svMeas[i];
+ if (svMeas.dgnssSvMeas.dgnssMeasStatus) {
+ mDGnssDataUsage = true;
+ break;
+ }
+ }
+ if (mDGnssDataUsage != preDGnssDataUsage) {
+ if (mCdfwInterface) {
+ mCdfwInterface->reportUsable(mQDgnssListenerHDL, mDGnssDataUsage);
+ }
+ }
+}
+
+void
GnssAdapter::reportSvPolynomialEvent(GnssSvPolynomial &svPolynomial)
{
LOC_LOGD("%s]: ", __func__);
@@ -4164,8 +4860,12 @@
// the request is being stopped, but allow timer to expire first
// before stopping the timer just in case more ODCPI requests come
// to avoid spamming more odcpi requests to the framework
- } else {
+ } else if (ODCPI_REQUEST_TYPE_STOP == request.type) {
+ LOC_LOGd("request: type %d, isEmergency %d", request.type, request.isEmergencyMode);
+ mOdcpiRequestCb(request);
mOdcpiRequestActive = false;
+ } else {
+ LOC_LOGE("Invalid ODCPI request type..");
}
} else {
LOC_LOGw("ODCPI request not supported");
@@ -4194,31 +4894,63 @@
return true;
}
-void GnssAdapter::initOdcpiCommand(const OdcpiRequestCallback& callback)
+bool GnssAdapter::reportQwesCapabilities(
+ const std::unordered_map<LocationQwesFeatureType, bool> &featureMap)
+{
+ struct MsgReportQwesFeatureStatus : public LocMsg {
+ GnssAdapter& mAdapter;
+ const std::unordered_map<LocationQwesFeatureType, bool> mFeatureMap;
+ inline MsgReportQwesFeatureStatus(GnssAdapter& adapter,
+ const std::unordered_map<LocationQwesFeatureType, bool> &featureMap) :
+ LocMsg(),
+ mAdapter(adapter),
+ mFeatureMap(std::move(featureMap)) {}
+ inline virtual void proc() const {
+ LOC_LOGi("ReportQwesFeatureStatus before caps %" PRIx64 " ",
+ mAdapter.getCapabilities());
+ ContextBase::setQwesFeatureStatus(mFeatureMap);
+ LOC_LOGi("ReportQwesFeatureStatus After caps %" PRIx64 " ",
+ mAdapter.getCapabilities());
+ mAdapter.broadcastCapabilities(mAdapter.getCapabilities());
+ }
+ };
+
+ sendMsg(new MsgReportQwesFeatureStatus(*this, featureMap));
+ return true;
+}
+
+void GnssAdapter::initOdcpiCommand(const OdcpiRequestCallback& callback,
+ OdcpiPrioritytype priority)
{
struct MsgInitOdcpi : public LocMsg {
GnssAdapter& mAdapter;
OdcpiRequestCallback mOdcpiCb;
+ OdcpiPrioritytype mPriority;
inline MsgInitOdcpi(GnssAdapter& adapter,
- const OdcpiRequestCallback& callback) :
+ const OdcpiRequestCallback& callback,
+ OdcpiPrioritytype priority) :
LocMsg(),
mAdapter(adapter),
- mOdcpiCb(callback) {}
+ mOdcpiCb(callback), mPriority(priority){}
inline virtual void proc() const {
- mAdapter.initOdcpi(mOdcpiCb);
+ mAdapter.initOdcpi(mOdcpiCb, mPriority);
}
};
- sendMsg(new MsgInitOdcpi(*this, callback));
+ sendMsg(new MsgInitOdcpi(*this, callback, priority));
}
-void GnssAdapter::initOdcpi(const OdcpiRequestCallback& callback)
+void GnssAdapter::initOdcpi(const OdcpiRequestCallback& callback,
+ OdcpiPrioritytype priority)
{
- mOdcpiRequestCb = callback;
-
- /* Register for WIFI request */
- updateEvtMask(LOC_API_ADAPTER_BIT_REQUEST_WIFI,
- LOC_REGISTRATION_MASK_ENABLED);
+ LOC_LOGd("In priority: %d, Curr priority: %d", priority, mCallbackPriority);
+ if (priority >= mCallbackPriority) {
+ mOdcpiRequestCb = callback;
+ mCallbackPriority = priority;
+ /* Register for WIFI request */
+ updateEvtMask(LOC_API_ADAPTER_BIT_REQUEST_WIFI,
+ LOC_REGISTRATION_MASK_ENABLED);
+ }
}
void GnssAdapter::injectOdcpiCommand(const Location& location)
@@ -4316,23 +5048,20 @@
void GnssAdapter::initDefaultAgps() {
LOC_LOGD("%s]: ", __func__);
-
void *handle = nullptr;
- if ((handle = dlopen("libloc_net_iface.so", RTLD_NOW)) == nullptr) {
- LOC_LOGD("%s]: libloc_net_iface.so not found !", __func__);
- return;
- }
- LocAgpsGetAgpsCbInfo getAgpsCbInfo = (LocAgpsGetAgpsCbInfo)
- dlsym(handle, "LocNetIfaceAgps_getAgpsCbInfo");
- if (getAgpsCbInfo == nullptr) {
- LOC_LOGE("%s]: Failed to get method LocNetIfaceAgps_getStatusCb", __func__);
- dlclose(handle);
- return;
+ LocAgpsGetAgpsCbInfo getAgpsCbInfo =
+ (LocAgpsGetAgpsCbInfo)dlGetSymFromLib(handle, "libloc_net_iface.so",
+ "LocNetIfaceAgps_getAgpsCbInfo");
+ // Below step is to make sure we init nativeAgpsHandler
+ // for Android platforms only
+ AgpsCbInfo cbInfo = {};
+ if (nullptr != getAgpsCbInfo) {
+ cbInfo = getAgpsCbInfo(agpsOpenResultCb, agpsCloseResultCb, this);
+ } else {
+ cbInfo = mNativeAgpsHandler.getAgpsCbInfo();
}
- AgpsCbInfo& cbInfo = getAgpsCbInfo(agpsOpenResultCb, agpsCloseResultCb, this);
-
if (cbInfo.statusV4Cb == nullptr) {
LOC_LOGE("%s]: statusV4Cb is nullptr!", __func__);
dlclose(handle);
@@ -4497,6 +5226,38 @@
return true;
}
+void GnssAdapter::reportPdnTypeFromWds(int pdnType, AGpsExtType agpsType, std::string apnName,
+ AGpsBearerType bearerType) {
+ LOC_LOGd("pdnType from WDS QMI: %d, agpsType: %d, apnName: %s, bearerType: %d",
+ pdnType, agpsType, apnName.c_str(), bearerType);
+
+ struct MsgReportAtlPdn : public LocMsg {
+ GnssAdapter& mAdapter;
+ int mPdnType;
+ AgpsManager* mAgpsManager;
+ AGpsExtType mAgpsType;
+ string mApnName;
+ AGpsBearerType mBearerType;
+
+ inline MsgReportAtlPdn(GnssAdapter& adapter, int pdnType,
+ AgpsManager* agpsManager, AGpsExtType agpsType,
+ const string& apnName, AGpsBearerType bearerType) :
+ LocMsg(), mAgpsManager(agpsManager), mAgpsType(agpsType),
+ mApnName(apnName), mBearerType(bearerType),
+ mAdapter(adapter), mPdnType(pdnType) {}
+ inline virtual void proc() const {
+ mAgpsManager->reportAtlOpenSuccess(mAgpsType,
+ const_cast<char*>(mApnName.c_str()),
+ mApnName.length(), mPdnType<=0? mBearerType:mPdnType);
+ }
+ };
+
+ AGpsBearerType atlPdnType = (pdnType+1) & 3; // convert WDS QMI pdn type to AgpsBearerType
+ sendMsg(new MsgReportAtlPdn(*this, atlPdnType, &mAgpsManager,
+ agpsType, apnName, bearerType));
+}
+
+
void GnssAdapter::dataConnOpenCommand(
AGpsExtType agpsType,
const char* apnName, int apnLen, AGpsBearerType bearerType){
@@ -4504,17 +5265,16 @@
LOC_LOGI("GnssAdapter::frameworkDataConnOpen");
struct AgpsMsgAtlOpenSuccess: public LocMsg {
-
+ GnssAdapter& mAdapter;
AgpsManager* mAgpsManager;
AGpsExtType mAgpsType;
char* mApnName;
- int mApnLen;
AGpsBearerType mBearerType;
- inline AgpsMsgAtlOpenSuccess(AgpsManager* agpsManager, AGpsExtType agpsType,
- const char* apnName, int apnLen, AGpsBearerType bearerType) :
+ inline AgpsMsgAtlOpenSuccess(GnssAdapter& adapter, AgpsManager* agpsManager,
+ AGpsExtType agpsType, const char* apnName, int apnLen, AGpsBearerType bearerType) :
LocMsg(), mAgpsManager(agpsManager), mAgpsType(agpsType), mApnName(
- new char[apnLen + 1]), mApnLen(apnLen), mBearerType(bearerType) {
+ new char[apnLen + 1]), mBearerType(bearerType), mAdapter(adapter) {
LOC_LOGV("AgpsMsgAtlOpenSuccess");
if (mApnName == nullptr) {
@@ -4532,18 +5292,36 @@
}
inline virtual void proc() const {
+ LOC_LOGv("AgpsMsgAtlOpenSuccess::proc()");
+ string apn(mApnName);
+ //Use QMI WDS API to query IP Protocol from modem profile
+ void* libHandle = nullptr;
+ getPdnTypeFromWds* getPdnTypeFunc = (getPdnTypeFromWds*)dlGetSymFromLib(libHandle,
+ #ifdef USE_GLIB
+ "libloc_api_wds.so", "_Z10getPdnTypeRKNSt7__cxx1112basic_string"\
+ "IcSt11char_traitsIcESaIcEEESt8functionIFviEE");
+ #else
+ "libloc_api_wds.so", "_Z10getPdnTypeRKNSt3__112basic_stringIcNS_11char_traits"\
+ "IcEENS_9allocatorIcEEEENS_8functionIFviEEE");
+ #endif
- LOC_LOGV("AgpsMsgAtlOpenSuccess::proc()");
- mAgpsManager->reportAtlOpenSuccess(mAgpsType, mApnName, mApnLen, mBearerType);
+ std::function<void(int)> wdsPdnTypeCb = std::bind(&GnssAdapter::reportPdnTypeFromWds,
+ &mAdapter, std::placeholders::_1, mAgpsType, apn, mBearerType);
+ if (getPdnTypeFunc != nullptr) {
+ LOC_LOGv("dlGetSymFromLib success");
+ (*getPdnTypeFunc)(apn, wdsPdnTypeCb);
+ } else {
+ mAgpsManager->reportAtlOpenSuccess(mAgpsType, mApnName, apn.length(), mBearerType);
+ }
}
};
// 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)) {
+ if (NULL == apnName || apnLen > MAX_APN_LEN || (strlen(apnName) != (unsigned)apnLen)) {
LOC_LOGe("%s]: incorrect apnlen length or incorrect apnName", __func__);
mAgpsManager.reportAtlClosed(agpsType);
} else {
- sendMsg( new AgpsMsgAtlOpenSuccess(
+ sendMsg( new AgpsMsgAtlOpenSuccess(*this,
&mAgpsManager, agpsType, apnName, apnLen, bearerType));
}
}
@@ -4873,28 +5651,28 @@
case GNSS_SV_TYPE_GPS:
case GNSS_SV_TYPE_QZSS:
measurements.measurements[i].agcLevelDb =
- reports.mRfAndParams.back().mAgcGps;
+ (double)-reports.mRfAndParams.back().mJammerGps;
measurements.measurements[i].flags |=
GNSS_MEASUREMENTS_DATA_AUTOMATIC_GAIN_CONTROL_BIT;
break;
case GNSS_SV_TYPE_GALILEO:
measurements.measurements[i].agcLevelDb =
- reports.mRfAndParams.back().mAgcGal;
+ (double)-reports.mRfAndParams.back().mJammerGal;
measurements.measurements[i].flags |=
GNSS_MEASUREMENTS_DATA_AUTOMATIC_GAIN_CONTROL_BIT;
break;
case GNSS_SV_TYPE_GLONASS:
measurements.measurements[i].agcLevelDb =
- reports.mRfAndParams.back().mAgcGlo;
+ (double)-reports.mRfAndParams.back().mJammerGlo;
measurements.measurements[i].flags |=
GNSS_MEASUREMENTS_DATA_AUTOMATIC_GAIN_CONTROL_BIT;
break;
case GNSS_SV_TYPE_BEIDOU:
measurements.measurements[i].agcLevelDb =
- reports.mRfAndParams.back().mAgcBds;
+ (double)-reports.mRfAndParams.back().mJammerBds;
measurements.measurements[i].flags |=
GNSS_MEASUREMENTS_DATA_AUTOMATIC_GAIN_CONTROL_BIT;
break;
@@ -4929,67 +5707,47 @@
data.jammerInd[sig] = 0.0;
data.agc[sig] = 0.0;
}
- if (GNSS_INVALID_JAMMER_IND != reports.mRfAndParams.back().mAgcGps) {
- data.gnssDataMask[GNSS_LOC_SIGNAL_TYPE_GPS_L1CA] |=
- GNSS_LOC_DATA_AGC_BIT;
- data.agc[GNSS_LOC_SIGNAL_TYPE_GPS_L1CA] =
- reports.mRfAndParams.back().mAgcGps;
- data.gnssDataMask[GNSS_LOC_SIGNAL_TYPE_QZSS_L1CA] |=
- GNSS_LOC_DATA_AGC_BIT;
- data.agc[GNSS_LOC_SIGNAL_TYPE_QZSS_L1CA] =
- reports.mRfAndParams.back().mAgcGps;
- data.gnssDataMask[GNSS_LOC_SIGNAL_TYPE_SBAS_L1_CA] |=
- GNSS_LOC_DATA_AGC_BIT;
- data.agc[GNSS_LOC_SIGNAL_TYPE_SBAS_L1_CA] =
- reports.mRfAndParams.back().mAgcGps;
- }
if (GNSS_INVALID_JAMMER_IND != reports.mRfAndParams.back().mJammerGps) {
data.gnssDataMask[GNSS_LOC_SIGNAL_TYPE_GPS_L1CA] |=
- GNSS_LOC_DATA_JAMMER_IND_BIT;
+ GNSS_LOC_DATA_AGC_BIT | GNSS_LOC_DATA_JAMMER_IND_BIT;
+ data.agc[GNSS_LOC_SIGNAL_TYPE_GPS_L1CA] =
+ (double)-reports.mRfAndParams.back().mJammerGps;
data.jammerInd[GNSS_LOC_SIGNAL_TYPE_GPS_L1CA] =
(double)reports.mRfAndParams.back().mJammerGps;
data.gnssDataMask[GNSS_LOC_SIGNAL_TYPE_QZSS_L1CA] |=
- GNSS_LOC_DATA_JAMMER_IND_BIT;
+ GNSS_LOC_DATA_AGC_BIT | GNSS_LOC_DATA_JAMMER_IND_BIT;
+ data.agc[GNSS_LOC_SIGNAL_TYPE_QZSS_L1CA] =
+ (double)-reports.mRfAndParams.back().mJammerGps;
data.jammerInd[GNSS_LOC_SIGNAL_TYPE_QZSS_L1CA] =
(double)reports.mRfAndParams.back().mJammerGps;
data.gnssDataMask[GNSS_LOC_SIGNAL_TYPE_SBAS_L1_CA] |=
- GNSS_LOC_DATA_JAMMER_IND_BIT;
+ GNSS_LOC_DATA_AGC_BIT | GNSS_LOC_DATA_JAMMER_IND_BIT;
+ data.agc[GNSS_LOC_SIGNAL_TYPE_SBAS_L1_CA] =
+ (double)-reports.mRfAndParams.back().mJammerGps;
data.jammerInd[GNSS_LOC_SIGNAL_TYPE_SBAS_L1_CA] =
- (double)reports.mRfAndParams.back().mJammerGps;
- }
- if (GNSS_INVALID_JAMMER_IND != reports.mRfAndParams.back().mAgcGlo) {
- data.gnssDataMask[GNSS_LOC_SIGNAL_TYPE_GLONASS_G1] |=
- GNSS_LOC_DATA_AGC_BIT;
- data.agc[GNSS_LOC_SIGNAL_TYPE_GLONASS_G1] =
- reports.mRfAndParams.back().mAgcGlo;
+ (double)reports.mRfAndParams.back().mJammerGps;
}
if (GNSS_INVALID_JAMMER_IND != reports.mRfAndParams.back().mJammerGlo) {
data.gnssDataMask[GNSS_LOC_SIGNAL_TYPE_GLONASS_G1] |=
- GNSS_LOC_DATA_JAMMER_IND_BIT;
+ GNSS_LOC_DATA_AGC_BIT | GNSS_LOC_DATA_JAMMER_IND_BIT;
+ data.agc[GNSS_LOC_SIGNAL_TYPE_GLONASS_G1] =
+ (double)-reports.mRfAndParams.back().mJammerGlo;
data.jammerInd[GNSS_LOC_SIGNAL_TYPE_GLONASS_G1] =
(double)reports.mRfAndParams.back().mJammerGlo;
}
- if (GNSS_INVALID_JAMMER_IND != reports.mRfAndParams.back().mAgcBds) {
- data.gnssDataMask[GNSS_LOC_SIGNAL_TYPE_BEIDOU_B1_I] |=
- GNSS_LOC_DATA_AGC_BIT;
- data.agc[GNSS_LOC_SIGNAL_TYPE_BEIDOU_B1_I] =
- reports.mRfAndParams.back().mAgcBds;
- }
if (GNSS_INVALID_JAMMER_IND != reports.mRfAndParams.back().mJammerBds) {
data.gnssDataMask[GNSS_LOC_SIGNAL_TYPE_BEIDOU_B1_I] |=
- GNSS_LOC_DATA_JAMMER_IND_BIT;
+ GNSS_LOC_DATA_AGC_BIT | GNSS_LOC_DATA_JAMMER_IND_BIT;
+ data.agc[GNSS_LOC_SIGNAL_TYPE_BEIDOU_B1_I] =
+ (double)-reports.mRfAndParams.back().mJammerBds;
data.jammerInd[GNSS_LOC_SIGNAL_TYPE_BEIDOU_B1_I] =
(double)reports.mRfAndParams.back().mJammerBds;
}
- if (GNSS_INVALID_JAMMER_IND != reports.mRfAndParams.back().mAgcGal) {
- data.gnssDataMask[GNSS_LOC_SIGNAL_TYPE_GALILEO_E1_C] |=
- GNSS_LOC_DATA_AGC_BIT;
- data.agc[GNSS_LOC_SIGNAL_TYPE_GALILEO_E1_C] =
- reports.mRfAndParams.back().mAgcGal;
- }
if (GNSS_INVALID_JAMMER_IND != reports.mRfAndParams.back().mJammerGal) {
data.gnssDataMask[GNSS_LOC_SIGNAL_TYPE_GALILEO_E1_C] |=
- GNSS_LOC_DATA_JAMMER_IND_BIT;
+ GNSS_LOC_DATA_AGC_BIT | GNSS_LOC_DATA_JAMMER_IND_BIT;
+ data.agc[GNSS_LOC_SIGNAL_TYPE_GALILEO_E1_C] =
+ (double)-reports.mRfAndParams.back().mJammerGal;
data.jammerInd[GNSS_LOC_SIGNAL_TYPE_GALILEO_E1_C] =
(double)reports.mRfAndParams.back().mJammerGal;
}
@@ -5204,40 +5962,54 @@
return sessionId;
}
-void
-GnssAdapter::updateSvConfig(uint32_t sessionId,
- const GnssSvTypeConfig& svTypeConfig,
- const GnssSvIdConfig& svIdConfig) {
+void GnssAdapter::gnssUpdateSvConfig(
+ uint32_t sessionId, const GnssSvTypeConfig& constellationEnablementConfig,
+ const GnssSvIdConfig& blacklistSvConfig) {
- // check whether if any constellation is removed from the new config
- GnssSvTypesMask enabledRemoved = mGnssSvTypeConfig.enabledSvTypesMask &
- (mGnssSvTypeConfig.enabledSvTypesMask ^ svTypeConfig.enabledSvTypesMask);
- // Send reset if any constellation is removed from the enabled list
- if (enabledRemoved != 0) {
+ // suspend all tracking sessions to apply the constellation config
+ suspendSessions();
+ if (constellationEnablementConfig.size == sizeof(constellationEnablementConfig)) {
+ // check whether if any constellation is removed from the new config
+ GnssSvTypesMask currentEnabledMask = mGnssSvTypeConfig.enabledSvTypesMask;
+ GnssSvTypesMask newEnabledMask = constellationEnablementConfig.enabledSvTypesMask;
+ GnssSvTypesMask enabledRemoved = currentEnabledMask & (currentEnabledMask ^ newEnabledMask);
+ // Send reset if any constellation is removed from the enabled list
+ if (enabledRemoved != 0) {
+ mLocApi->resetConstellationControl();
+ }
+
+ // if the constellation config is valid, issue request to modem
+ // to enable/disable constellation
+ mLocApi->setConstellationControl(mGnssSvTypeConfig);
+ } else if (constellationEnablementConfig.size == 0) {
+ // when the size is not set, meaning reset to modem default
mLocApi->resetConstellationControl();
}
+ // save the constellation settings to be used for modem SSR
+ mGnssSvTypeConfig = constellationEnablementConfig;
- mGnssSvTypeConfig = svTypeConfig;
- mGnssSvIdConfig = svIdConfig;
-
- // Send blacklist info
- mLocApi->setBlacklistSv(mGnssSvIdConfig);
-
- // Send only enabled constellation config
- GnssSvTypeConfig svTypeConfigCopy = {sizeof(GnssSvTypeConfig), 0, 0};
- svTypeConfigCopy.enabledSvTypesMask = mGnssSvTypeConfig.enabledSvTypesMask;
+ // handle blacklisted SV settings
+ mGnssSvIdConfig = blacklistSvConfig;
+ // process blacklist svs info
+ mBlacklistedSvIds.clear();
+ // need to save the balcklisted sv info into mBlacklistedSvIds as well
+ convertFromGnssSvIdConfig(blacklistSvConfig, mBlacklistedSvIds);
LocApiResponse* locApiResponse = new LocApiResponse(*getContext(),
[this, sessionId] (LocationError err) {
reportResponse(err, sessionId);});
if (!locApiResponse) {
LOC_LOGe("memory alloc failed");
}
- mLocApi->setConstellationControl(svTypeConfigCopy, locApiResponse);
+ mLocApi->setBlacklistSv(mGnssSvIdConfig, locApiResponse);
+
+ // resume all tracking sessions after the constellation config has been applied
+ restartSessions(false);
}
-uint32_t GnssAdapter::gnssUpdateSvConfigCommand(
- const GnssSvTypeConfig& svTypeConfig,
- const GnssSvIdConfig& svIdConfig) {
+uint32_t
+GnssAdapter::gnssUpdateSvConfigCommand(
+ const GnssSvTypeConfig& constellationEnablementConfig,
+ const GnssSvIdConfig& blacklistSvConfig) {
// generated session id will be none-zero
uint32_t sessionId = generateSessionId();
@@ -5246,67 +6018,115 @@
struct MsgUpdateSvConfig : public LocMsg {
GnssAdapter& mAdapter;
uint32_t mSessionId;
- GnssSvTypeConfig mSvTypeConfig;
- GnssSvIdConfig mSvIdConfig;
+ GnssSvTypeConfig mConstellationEnablementConfig;
+ GnssSvIdConfig mBlacklistSvIdConfig;
inline MsgUpdateSvConfig(GnssAdapter& adapter,
uint32_t sessionId,
- const GnssSvTypeConfig& svTypeConfig,
- const GnssSvIdConfig& svIdConfig) :
+ const GnssSvTypeConfig& constellationEnablementConfig,
+ const GnssSvIdConfig& blacklistSvConfig) :
LocMsg(),
mAdapter(adapter),
mSessionId(sessionId),
- mSvTypeConfig(svTypeConfig),
- mSvIdConfig(svIdConfig) {}
+ mConstellationEnablementConfig(constellationEnablementConfig),
+ mBlacklistSvIdConfig(blacklistSvConfig) {}
inline virtual void proc() const {
- mAdapter.updateSvConfig(mSessionId, mSvTypeConfig, mSvIdConfig);
+ mAdapter.gnssUpdateSvConfig(mSessionId, mConstellationEnablementConfig,
+ mBlacklistSvIdConfig);
}
};
if (sessionId != 0) {
- sendMsg(new MsgUpdateSvConfig(*this, sessionId,
- svTypeConfig, svIdConfig));
+ sendMsg(new MsgUpdateSvConfig(*this, sessionId, constellationEnablementConfig,
+ blacklistSvConfig));
}
return sessionId;
}
-void
-GnssAdapter::resetSvConfig(uint32_t sessionId) {
+void GnssAdapter::gnssUpdateSecondaryBandConfig(
+ uint32_t sessionId, const GnssSvTypeConfig& secondaryBandConfig) {
- LocApiResponse* locApiResponse = nullptr;
- if (sessionId != 0) {
- locApiResponse =
- new LocApiResponse(*getContext(),
- [this, sessionId] (LocationError err) {
- reportResponse(err, sessionId);});
- if (!locApiResponse) {
- LOC_LOGe("memory alloc failed");
- }
+ LocApiResponse* locApiResponse = new LocApiResponse(*getContext(),
+ [this, sessionId] (LocationError err) {
+ reportResponse(err, sessionId);});
+ if (!locApiResponse) {
+ LOC_LOGe("memory alloc failed");
}
- mLocApi->resetConstellationControl(locApiResponse);
+
+ // handle secondary band info
+ mGnssSeconaryBandConfig = secondaryBandConfig;
+ gnssSecondaryBandConfigUpdate(locApiResponse);
}
-uint32_t GnssAdapter::gnssResetSvConfigCommand() {
+uint32_t
+GnssAdapter::gnssUpdateSecondaryBandConfigCommand(
+ const GnssSvTypeConfig& secondaryBandConfig) {
// generated session id will be none-zero
uint32_t sessionId = generateSessionId();
LOC_LOGd("session id %u", sessionId);
- struct MsgResetSvConfig : public LocMsg {
+ struct MsgUpdateSecondaryBandConfig : public LocMsg {
GnssAdapter& mAdapter;
uint32_t mSessionId;
+ GnssSvTypeConfig mSecondaryBandConfig;
- inline MsgResetSvConfig(GnssAdapter& adapter,
- uint32_t sessionId) :
+ inline MsgUpdateSecondaryBandConfig(GnssAdapter& adapter,
+ uint32_t sessionId,
+ const GnssSvTypeConfig& secondaryBandConfig) :
+ LocMsg(),
+ mAdapter(adapter),
+ mSessionId(sessionId),
+ mSecondaryBandConfig(secondaryBandConfig) {}
+ inline virtual void proc() const {
+ mAdapter.gnssUpdateSecondaryBandConfig(mSessionId, mSecondaryBandConfig);
+ }
+ };
+
+ if (sessionId != 0) {
+ sendMsg(new MsgUpdateSecondaryBandConfig(*this, sessionId, secondaryBandConfig));
+ }
+ return sessionId;
+}
+
+// This function currently retrieves secondary band configuration
+// for constellation enablement/disablement.
+void
+GnssAdapter::gnssGetSecondaryBandConfig(uint32_t sessionId) {
+
+ LocApiResponse* locApiResponse = new LocApiResponse(*getContext(),
+ [this, sessionId] (LocationError err) {
+ reportResponse(err, sessionId);});
+ if (!locApiResponse) {
+ LOC_LOGe("memory alloc failed");
+ }
+
+ mLocApi->getConstellationMultiBandConfig(sessionId, locApiResponse);
+}
+
+uint32_t
+GnssAdapter::gnssGetSecondaryBandConfigCommand() {
+
+ // generated session id will be none-zero
+ uint32_t sessionId = generateSessionId();
+ LOC_LOGd("session id %u", sessionId);
+
+ struct MsgGetSecondaryBandConfig : public LocMsg {
+ GnssAdapter& mAdapter;
+ uint32_t mSessionId;
+ inline MsgGetSecondaryBandConfig(GnssAdapter& adapter,
+ uint32_t sessionId) :
LocMsg(),
mAdapter(adapter),
mSessionId(sessionId) {}
inline virtual void proc() const {
- mAdapter.resetSvConfig(mSessionId);
+ mAdapter.gnssGetSecondaryBandConfig(mSessionId);
}
};
- sendMsg(new MsgResetSvConfig(*this, sessionId));
+ if (sessionId != 0) {
+ sendMsg(new MsgGetSecondaryBandConfig(*this, sessionId));
+ }
return sessionId;
}
@@ -5341,6 +6161,13 @@
mSessionId(sessionId),
mConfigInfo(configInfo) {}
inline virtual void proc() const {
+ // save the lever ARM config info for translating position from GNSS antenna based
+ // to VRP based
+ if (mConfigInfo.leverArmValidMask & LEVER_ARM_TYPE_GNSS_TO_VRP_BIT) {
+ mAdapter.mLocConfigInfo.leverArmConfigInfo.leverArmValidMask |=
+ LEVER_ARM_TYPE_GNSS_TO_VRP_BIT;
+ mAdapter.mLocConfigInfo.leverArmConfigInfo.gnssToVRP = mConfigInfo.gnssToVRP;
+ }
mAdapter.configLeverArm(mSessionId, mConfigInfo);
}
};
@@ -5349,6 +6176,313 @@
return sessionId;
}
+bool GnssAdapter::initMeasCorr(bool bSendCbWhenNotSupported) {
+ LOC_LOGv("GnssAdapter::initMeasCorr");
+ /* Message to initialize Measurement Corrections */
+ struct MsgInitMeasCorr : public LocMsg {
+ GnssAdapter& mAdapter;
+ GnssMeasurementCorrectionsCapabilitiesMask mCapMask;
+
+ inline MsgInitMeasCorr(GnssAdapter& adapter,
+ GnssMeasurementCorrectionsCapabilitiesMask capMask) :
+ LocMsg(), mAdapter(adapter), mCapMask(capMask) {
+ LOC_LOGv("MsgInitMeasCorr");
+ }
+
+ inline virtual void proc() const {
+ LOC_LOGv("MsgInitMeasCorr::proc()");
+
+ mAdapter.mMeasCorrSetCapabilitiesCb(mCapMask);
+ }
+ };
+ if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_MEASUREMENTS_CORRECTION)) {
+ sendMsg(new MsgInitMeasCorr(*this, GNSS_MEAS_CORR_LOS_SATS |
+ GNSS_MEAS_CORR_EXCESS_PATH_LENGTH | GNSS_MEAS_CORR_REFLECTING_PLANE));
+ return true;
+ } else {
+ LOC_LOGv("MEASUREMENTS_CORRECTION feature is not supported in the modem");
+ if (bSendCbWhenNotSupported) {
+ sendMsg(new MsgInitMeasCorr(*this, 0));
+ }
+ return false;
+ }
+}
+
+bool GnssAdapter::openMeasCorrCommand(const measCorrSetCapabilitiesCb setCapabilitiesCb) {
+ LOC_LOGi("GnssAdapter::openMeasCorrCommand");
+
+ /* Send message to initialize Measurement Corrections */
+ mMeasCorrSetCapabilitiesCb = setCapabilitiesCb;
+ mIsMeasCorrInterfaceOpen = true;
+ if (isEngineCapabilitiesKnown()) {
+ LOC_LOGv("Capabilities are known, proceed with measurement corrections init");
+ return initMeasCorr(false);
+ } else {
+ LOC_LOGv("Capabilities are not known, wait for open");
+ return true;
+ }
+}
+
+bool GnssAdapter::measCorrSetCorrectionsCommand(const GnssMeasurementCorrections gnssMeasCorr) {
+ LOC_LOGi("GnssAdapter::measCorrSetCorrectionsCommand");
+
+ /* Message to set Measurement Corrections */
+ struct MsgSetCorrectionsMeasCorr : public LocMsg {
+ const GnssMeasurementCorrections mGnssMeasCorr;
+ GnssAdapter& mAdapter;
+ LocApiBase& mApi;
+
+ inline MsgSetCorrectionsMeasCorr(
+ const GnssMeasurementCorrections gnssMeasCorr,
+ GnssAdapter& adapter,
+ LocApiBase& api) :
+ LocMsg(),
+ mGnssMeasCorr(gnssMeasCorr),
+ mAdapter(adapter),
+ mApi(api) {
+ LOC_LOGv("MsgSetCorrectionsMeasCorr");
+ }
+
+ inline virtual void proc() const {
+ LOC_LOGv("MsgSetCorrectionsMeasCorr::proc()");
+ mApi.setMeasurementCorrections(mGnssMeasCorr);
+ }
+ };
+
+ if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_MEASUREMENTS_CORRECTION)) {
+ sendMsg(new MsgSetCorrectionsMeasCorr(gnssMeasCorr, *this, *mLocApi));
+ return true;
+ } else {
+ LOC_LOGw("Measurement Corrections are not supported!");
+ return false;
+ }
+}
+uint32_t GnssAdapter::antennaInfoInitCommand(const antennaInfoCb antennaInfoCallback) {
+ LOC_LOGi("GnssAdapter::antennaInfoInitCommand");
+
+ /* Message to initialize Antenna Information */
+ struct MsgInitAi : public LocMsg {
+ const antennaInfoCb mAntennaInfoCb;
+ GnssAdapter& mAdapter;
+
+ inline MsgInitAi(const antennaInfoCb antennaInfoCallback, GnssAdapter& adapter) :
+ LocMsg(), mAntennaInfoCb(antennaInfoCallback), mAdapter(adapter) {
+ LOC_LOGv("MsgInitAi");
+ }
+
+ inline virtual void proc() const {
+ LOC_LOGv("MsgInitAi::proc()");
+ mAdapter.reportGnssAntennaInformation(mAntennaInfoCb);
+ }
+ };
+ if (mIsAntennaInfoInterfaceOpened) {
+ return ANTENNA_INFO_ERROR_ALREADY_INIT;
+ } else {
+ mIsAntennaInfoInterfaceOpened = true;
+ sendMsg(new MsgInitAi(antennaInfoCallback, *this));
+ return ANTENNA_INFO_SUCCESS;
+ }
+}
+
+void
+GnssAdapter::configRobustLocation(uint32_t sessionId,
+ bool enable, bool enableForE911) {
+
+ mLocConfigInfo.robustLocationConfigInfo.isValid = true;
+ mLocConfigInfo.robustLocationConfigInfo.enable = enable;
+ mLocConfigInfo.robustLocationConfigInfo.enableFor911 = enableForE911;
+
+ LocApiResponse* locApiResponse = nullptr;
+ if (sessionId != 0) {
+ locApiResponse =
+ new LocApiResponse(*getContext(),
+ [this, sessionId] (LocationError err) {
+ reportResponse(err, sessionId);});
+ if (!locApiResponse) {
+ LOC_LOGe("memory alloc failed");
+ }
+ }
+ mLocApi->configRobustLocation(enable, enableForE911, locApiResponse);
+}
+
+uint32_t GnssAdapter::configRobustLocationCommand(
+ bool enable, bool enableForE911) {
+
+ // generated session id will be none-zero
+ uint32_t sessionId = generateSessionId();
+ LOC_LOGd("session id %u", sessionId);
+
+ struct MsgConfigRobustLocation : public LocMsg {
+ GnssAdapter& mAdapter;
+ uint32_t mSessionId;
+ bool mEnable;
+ bool mEnableForE911;
+
+ inline MsgConfigRobustLocation(GnssAdapter& adapter,
+ uint32_t sessionId,
+ bool enable,
+ bool enableForE911) :
+ LocMsg(),
+ mAdapter(adapter),
+ mSessionId(sessionId),
+ mEnable(enable),
+ mEnableForE911(enableForE911) {}
+ inline virtual void proc() const {
+ mAdapter.configRobustLocation(mSessionId, mEnable, mEnableForE911);
+ }
+ };
+
+ sendMsg(new MsgConfigRobustLocation(*this, sessionId, enable, enableForE911));
+ return sessionId;
+}
+
+void
+GnssAdapter::configMinGpsWeek(uint32_t sessionId, uint16_t minGpsWeek) {
+ // suspend all sessions for modem to take the min GPS week config
+ suspendSessions();
+
+ LocApiResponse* locApiResponse = nullptr;
+ if (sessionId != 0) {
+ locApiResponse =
+ new LocApiResponse(*getContext(),
+ [this, sessionId] (LocationError err) {
+ reportResponse(err, sessionId);});
+ if (!locApiResponse) {
+ LOC_LOGe("memory alloc failed");
+ }
+ }
+ mLocApi->configMinGpsWeek(minGpsWeek, locApiResponse);
+
+ // resume all tracking sessions after the min GPS week config
+ // has been changed
+ restartSessions(false);
+}
+
+uint32_t GnssAdapter::configMinGpsWeekCommand(uint16_t minGpsWeek) {
+ // generated session id will be none-zero
+ uint32_t sessionId = generateSessionId();
+ LOC_LOGd("session id %u", sessionId);
+
+ struct MsgConfigMinGpsWeek : public LocMsg {
+ GnssAdapter& mAdapter;
+ uint32_t mSessionId;
+ uint16_t mMinGpsWeek;
+
+ inline MsgConfigMinGpsWeek(GnssAdapter& adapter,
+ uint32_t sessionId,
+ uint16_t minGpsWeek) :
+ LocMsg(),
+ mAdapter(adapter),
+ mSessionId(sessionId),
+ mMinGpsWeek(minGpsWeek) {}
+ inline virtual void proc() const {
+ mAdapter.configMinGpsWeek(mSessionId, mMinGpsWeek);
+ }
+ };
+
+ sendMsg(new MsgConfigMinGpsWeek(*this, sessionId, minGpsWeek));
+ return sessionId;
+}
+
+uint32_t GnssAdapter::configDeadReckoningEngineParamsCommand(
+ const DeadReckoningEngineConfig& dreConfig) {
+
+ // generated session id will be none-zero
+ uint32_t sessionId = generateSessionId();
+ LOC_LOGd("session id %u", sessionId);
+
+ struct MsgConfigDrEngine : public LocMsg {
+ GnssAdapter& mAdapter;
+ uint32_t mSessionId;
+ DeadReckoningEngineConfig mDreConfig;
+
+ inline MsgConfigDrEngine(GnssAdapter& adapter,
+ uint32_t sessionId,
+ const DeadReckoningEngineConfig& dreConfig) :
+ LocMsg(),
+ mAdapter(adapter),
+ mSessionId(sessionId),
+ mDreConfig(dreConfig) {}
+ inline virtual void proc() const {
+ LocationError err = LOCATION_ERROR_NOT_SUPPORTED;
+ if (true == mAdapter.mEngHubProxy->configDeadReckoningEngineParams(mDreConfig)) {
+ err = LOCATION_ERROR_SUCCESS;
+ }
+ mAdapter.reportResponse(err, mSessionId);
+ }
+ };
+
+ sendMsg(new MsgConfigDrEngine(*this, sessionId, dreConfig));
+ return sessionId;
+}
+
+uint32_t GnssAdapter::configEngineRunStateCommand(
+ PositioningEngineMask engType, LocEngineRunState engState) {
+
+ // generated session id will be none-zero
+ uint32_t sessionId = generateSessionId();
+ LOC_LOGe("session id %u, eng type 0x%x, eng state %d, dre enabled %d",
+ sessionId, engType, engState, mDreIntEnabled);
+
+ struct MsgConfigEngineRunState : public LocMsg {
+ GnssAdapter& mAdapter;
+ uint32_t mSessionId;
+ PositioningEngineMask mEngType;
+ LocEngineRunState mEngState;
+
+ inline MsgConfigEngineRunState(GnssAdapter& adapter,
+ uint32_t sessionId,
+ PositioningEngineMask engType,
+ LocEngineRunState engState) :
+ LocMsg(),
+ mAdapter(adapter),
+ mSessionId(sessionId),
+ mEngType(engType),
+ mEngState(engState) {}
+ inline virtual void proc() const {
+ LocationError err = LOCATION_ERROR_NOT_SUPPORTED;
+ // Currently, only DR engine supports pause/resume request
+ if ((mEngType == DEAD_RECKONING_ENGINE) &&
+ (mAdapter.mDreIntEnabled == true)) {
+ if (true == mAdapter.mEngHubProxy->configEngineRunState(mEngType, mEngState)) {
+ err = LOCATION_ERROR_SUCCESS;
+ }
+ }
+ mAdapter.reportResponse(err, mSessionId);
+ }
+ };
+
+ sendMsg(new MsgConfigEngineRunState(*this, sessionId, engType, engState));
+
+ return sessionId;
+}
+
+void GnssAdapter::reportGnssConfigEvent(uint32_t sessionId, const GnssConfig& gnssConfig)
+{
+ struct MsgReportGnssConfig : public LocMsg {
+ GnssAdapter& mAdapter;
+ uint32_t mSessionId;
+ mutable GnssConfig mGnssConfig;
+ inline MsgReportGnssConfig(GnssAdapter& adapter,
+ uint32_t sessionId,
+ const GnssConfig& gnssConfig) :
+ LocMsg(),
+ mAdapter(adapter),
+ mSessionId(sessionId),
+ mGnssConfig(gnssConfig) {}
+ inline virtual void proc() const {
+ // Invoke control clients config callback
+ if (nullptr != mAdapter.mControlCallbacks.gnssConfigCb) {
+ mAdapter.mControlCallbacks.gnssConfigCb(mSessionId, mGnssConfig);
+ } else {
+ LOC_LOGe("Failed to report, callback not registered");
+ }
+ }
+ };
+
+ sendMsg(new MsgReportGnssConfig(*this, sessionId, gnssConfig));
+}
+
/* ==== Eng Hub Proxy ================================================================= */
/* ======== UTILITIES ================================================================= */
void
@@ -5397,13 +6531,23 @@
strlen(PROCESS_NAME_ENGINE_SERVICE)) == 0) &&
(processInfoList[i].proc_status == ENABLED)) {
pluginDaemonEnabled = true;
- break;
+ // check if this is DRE-INT engine
+ if ((processInfoList[i].args[1]!= nullptr) &&
+ (strncmp(processInfoList[i].args[1], "DRE-INT", sizeof("DRE-INT")) == 0)) {
+ mDreIntEnabled = true;
+ break;
+ }
}
}
- // no plugin daemon is enabled for this platform, no need to load eng hub .so
+ // no plugin daemon is enabled for this platform,
+ // check if external engine is present for which we need
+ // libloc_eng_hub.so to be loaded
if (pluginDaemonEnabled == false) {
- break;
+ UTIL_READ_CONF(LOC_PATH_IZAT_CONF, izatConfParamTable);
+ if (!loadEngHubForExternalEngine) {
+ break;
+ }
}
// load the engine hub .so, if the .so is not present
@@ -5450,16 +6594,22 @@
if (mNHzNeeded != nHzNeeded) {
mNHzNeeded = nHzNeeded;
- checkAndRestartTimeBasedSession();
+ checkAndRestartSPESession();
}
- };
+ };
+
+ GnssAdapterUpdateQwesFeatureStatusCb updateQwesFeatureStatusCb =
+ [this] (const std::unordered_map<LocationQwesFeatureType, bool> &featureMap) {
+ reportQwesCapabilities(featureMap);
+ };
getEngHubProxyFn* getter = (getEngHubProxyFn*) dlsym(handle, "getEngHubProxy");
if(getter != nullptr) {
EngineHubProxyBase* hubProxy = (*getter) (mMsgTask, mSystemStatus->getOsObserver(),
- reportPositionEventCb,
- reportSvEventCb, reqAidingDataCb,
- updateNHzRequirementCb);
+ reportPositionEventCb,
+ reportSvEventCb, reqAidingDataCb,
+ updateNHzRequirementCb,
+ updateQwesFeatureStatusCb);
if (hubProxy != nullptr) {
mEngHubProxy = hubProxy;
engHubLoadSuccessful = true;
@@ -5482,3 +6632,332 @@
firstTime = false;
return engHubLoadSuccessful;
}
+
+std::vector<double>
+GnssAdapter::parseDoublesString(char* dString) {
+ std::vector<double> dVector;
+ char* tmp = NULL;
+ char* substr;
+
+ dVector.clear();
+ for (substr = strtok_r(dString, " ", &tmp);
+ substr != NULL;
+ substr = strtok_r(NULL, " ", &tmp)) {
+ dVector.push_back(std::stod(substr));
+ }
+ return dVector;
+}
+
+void
+GnssAdapter::reportGnssAntennaInformation(const antennaInfoCb antennaInfoCallback)
+{
+#define MAX_TEXT_WIDTH 50
+#define MAX_COLUMN_WIDTH 20
+
+ /* parse antenna_corrections file and fill in
+ a vector of GnssAntennaInformation data structure */
+
+ std::vector<GnssAntennaInformation> gnssAntennaInformations;
+ GnssAntennaInformation gnssAntennaInfo;
+
+ uint32_t antennaInfoVectorSize;
+ loc_param_s_type ant_info_vector_table[] =
+ {
+ { "ANTENNA_INFO_VECTOR_SIZE", &antennaInfoVectorSize, NULL, 'n' }
+ };
+ UTIL_READ_CONF(LOC_PATH_ANT_CORR, ant_info_vector_table);
+
+ for (uint32_t i = 0; i < antennaInfoVectorSize; i++) {
+ double carrierFrequencyMHz;
+ char pcOffsetStr[LOC_MAX_PARAM_STRING];
+ uint32_t numberOfRows = 0;
+ uint32_t numberOfColumns = 0;
+ uint32_t numberOfRowsSGC = 0;
+ uint32_t numberOfColumnsSGC = 0;
+
+ gnssAntennaInfo.phaseCenterVariationCorrectionMillimeters.clear();
+ gnssAntennaInfo.phaseCenterVariationCorrectionUncertaintyMillimeters.clear();
+ gnssAntennaInfo.signalGainCorrectionDbi.clear();
+ gnssAntennaInfo.signalGainCorrectionUncertaintyDbi.clear();
+ string s1 = "CARRIER_FREQUENCY_";
+ s1 += to_string(i);
+ string s2 = "PC_OFFSET_";
+ s2 += to_string(i);
+ string s3 = "NUMBER_OF_ROWS_";
+ s3 += to_string(i);
+ string s4 = "NUMBER_OF_COLUMNS_";
+ s4 += to_string(i);
+ string s5 = "NUMBER_OF_ROWS_SGC_";
+ s5 += to_string(i);
+ string s6 = "NUMBER_OF_COLUMNS_SGC_";
+ s6 += to_string(i);
+
+ gnssAntennaInfo.size = sizeof(gnssAntennaInfo);
+ loc_param_s_type ant_cf_table[] =
+ {
+ { s1.c_str(), &carrierFrequencyMHz, NULL, 'f' },
+ { s2.c_str(), &pcOffsetStr, NULL, 's' },
+ { s3.c_str(), &numberOfRows, NULL, 'n' },
+ { s4.c_str(), &numberOfColumns, NULL, 'n' },
+ { s5.c_str(), &numberOfRowsSGC, NULL, 'n' },
+ { s6.c_str(), &numberOfColumnsSGC, NULL, 'n' },
+ };
+ UTIL_READ_CONF(LOC_PATH_ANT_CORR, ant_cf_table);
+
+ if (0 == numberOfRowsSGC) {
+ numberOfRowsSGC = numberOfRows;
+ }
+ if (0 == numberOfColumnsSGC) {
+ numberOfColumnsSGC = numberOfColumns;
+ }
+
+ gnssAntennaInfo.carrierFrequencyMHz = carrierFrequencyMHz;
+
+ // now parse pcOffsetStr to get each entry
+ std::vector<double> pcOffset;
+ pcOffset = parseDoublesString(pcOffsetStr);
+ gnssAntennaInfo.phaseCenterOffsetCoordinateMillimeters.size =
+ sizeof(gnssAntennaInfo.phaseCenterOffsetCoordinateMillimeters);
+ gnssAntennaInfo.phaseCenterOffsetCoordinateMillimeters.x = pcOffset[0];
+ gnssAntennaInfo.phaseCenterOffsetCoordinateMillimeters.xUncertainty = pcOffset[1];
+ gnssAntennaInfo.phaseCenterOffsetCoordinateMillimeters.y = pcOffset[2];
+ gnssAntennaInfo.phaseCenterOffsetCoordinateMillimeters.yUncertainty = pcOffset[3];
+ gnssAntennaInfo.phaseCenterOffsetCoordinateMillimeters.z = pcOffset[4];
+ gnssAntennaInfo.phaseCenterOffsetCoordinateMillimeters.zUncertainty = pcOffset[5];
+
+ uint16_t array_size = MAX_TEXT_WIDTH + MAX_COLUMN_WIDTH*numberOfColumns;
+ uint16_t array_size_SGC = MAX_TEXT_WIDTH + MAX_COLUMN_WIDTH*numberOfColumnsSGC;
+ for (uint32_t j = 0; j < numberOfRows; j++) {
+ char pcVarCorrStr[array_size];
+ char pcVarCorrUncStr[array_size];
+
+ string s1 = "PC_VARIATION_CORRECTION_" + to_string(i) + "_ROW_";
+ s1 += to_string(j);
+ string s2 = "PC_VARIATION_CORRECTION_UNC_" + to_string(i) + "_ROW_";
+ s2 += to_string(j);
+
+ loc_param_s_type ant_row_table[] =
+ {
+ { s1.c_str(), &pcVarCorrStr, NULL, 's' },
+ { s2.c_str(), &pcVarCorrUncStr, NULL, 's' },
+ };
+ UTIL_READ_CONF_LONG(LOC_PATH_ANT_CORR, ant_row_table, array_size);
+
+ gnssAntennaInfo.phaseCenterVariationCorrectionMillimeters.push_back(
+ parseDoublesString(pcVarCorrStr));
+ gnssAntennaInfo.phaseCenterVariationCorrectionUncertaintyMillimeters.push_back(
+ parseDoublesString(pcVarCorrUncStr));
+ }
+ for (uint32_t j = 0; j < numberOfRowsSGC; j++) {
+ char sigGainCorrStr[array_size_SGC];
+ char sigGainCorrUncStr[array_size_SGC];
+
+ string s3 = "SIGNAL_GAIN_CORRECTION_" + to_string(i) + "_ROW_";
+ s3 += to_string(j);
+ string s4 = "SIGNAL_GAIN_CORRECTION_UNC_" + to_string(i) + "_ROW_";
+ s4 += to_string(j);
+
+ loc_param_s_type ant_row_table[] =
+ {
+ { s3.c_str(), &sigGainCorrStr, NULL, 's' },
+ { s4.c_str(), &sigGainCorrUncStr, NULL, 's' },
+ };
+ UTIL_READ_CONF_LONG(LOC_PATH_ANT_CORR, ant_row_table, array_size_SGC);
+
+ gnssAntennaInfo.signalGainCorrectionDbi.push_back(
+ parseDoublesString(sigGainCorrStr));
+ gnssAntennaInfo.signalGainCorrectionUncertaintyDbi.push_back(
+ parseDoublesString(sigGainCorrUncStr));
+ }
+ gnssAntennaInformations.push_back(std::move(gnssAntennaInfo));
+ }
+ if (antennaInfoVectorSize > 0) {
+ antennaInfoCallback(gnssAntennaInformations);
+ }
+}
+
+/* ==== DGnss Usable Reporter ========================================================= */
+/* ======== UTILITIES ================================================================= */
+
+void GnssAdapter::initCDFWService()
+{
+ LOC_LOGv("mCdfwInterface %p", mCdfwInterface);
+ if (nullptr == mCdfwInterface) {
+ void* libHandle = nullptr;
+ const char* libName = "libcdfw.so";
+
+ libHandle = nullptr;
+ getCdfwInterface getter = (getCdfwInterface)dlGetSymFromLib(libHandle,
+ libName, "getQCdfwInterface");
+ if (nullptr == getter) {
+ LOC_LOGe("dlGetSymFromLib getQCdfwInterface failed");
+ } else {
+ mCdfwInterface = getter();
+ }
+
+ if (nullptr != mCdfwInterface) {
+ QDgnssSessionActiveCb qDgnssSessionActiveCb = [this] (bool sessionActive) {
+ mDGnssNeedReport = sessionActive;
+ };
+ mCdfwInterface->startDgnssApiService(*mMsgTask);
+ mQDgnssListenerHDL = mCdfwInterface->createUsableReporter(qDgnssSessionActiveCb);
+ }
+ }
+}
+
+/*==== DGnss Ntrip Source ==========================================================*/
+void GnssAdapter::enablePPENtripStreamCommand(const GnssNtripConnectionParams& params,
+ bool enableRTKEngine) {
+
+ (void)enableRTKEngine; //future parameter, not used
+ if (0 == params.size || params.hostNameOrIp.empty() || params.mountPoint.empty() ||
+ params.username.empty() || params.password.empty()) {
+ LOC_LOGe("Ntrip parameters are invalid!");
+ return;
+ }
+
+ struct enableNtripMsg : public LocMsg {
+ GnssAdapter& mAdapter;
+ const GnssNtripConnectionParams mParams;
+
+ inline enableNtripMsg(GnssAdapter& adapter,
+ const GnssNtripConnectionParams& params) :
+ LocMsg(),
+ mAdapter(adapter),
+ mParams(std::move(params)) {}
+ inline virtual void proc() const {
+ mAdapter.handleEnablePPENtrip(mParams);
+ }
+ };
+ sendMsg(new enableNtripMsg(*this, params));
+}
+
+void GnssAdapter::handleEnablePPENtrip(const GnssNtripConnectionParams& params) {
+ LOC_LOGd("%d %s %d %s %s %s %d mSendNmeaConsent %d",
+ params.useSSL, params.hostNameOrIp.data(), params.port,
+ params.mountPoint.data(), params.username.data(), params.password.data(),
+ params.requiresNmeaLocation, mSendNmeaConsent);
+
+ GnssNtripConnectionParams* pNtripParams = &(mStartDgnssNtripParams.ntripParams);
+
+ if (pNtripParams->useSSL == params.useSSL &&
+ 0 == pNtripParams->hostNameOrIp.compare(params.hostNameOrIp) &&
+ pNtripParams->port == params.port &&
+ 0 == pNtripParams->mountPoint.compare(params.mountPoint) &&
+ 0 == pNtripParams->username.compare(params.username) &&
+ 0 == pNtripParams->password.compare(params.password) &&
+ pNtripParams->requiresNmeaLocation == params.requiresNmeaLocation &&
+ mDgnssState & DGNSS_STATE_ENABLE_NTRIP_COMMAND) {
+ LOC_LOGd("received same Ntrip param");
+ return;
+ }
+
+ mDgnssState |= DGNSS_STATE_ENABLE_NTRIP_COMMAND;
+ mDgnssState |= DGNSS_STATE_NO_NMEA_PENDING;
+ mDgnssState &= ~DGNSS_STATE_NTRIP_SESSION_STARTED;
+
+ mStartDgnssNtripParams.ntripParams = std::move(params);
+ mStartDgnssNtripParams.nmea.clear();
+ if (mSendNmeaConsent && pNtripParams->requiresNmeaLocation) {
+ mDgnssState &= ~DGNSS_STATE_NO_NMEA_PENDING;
+ mDgnssLastNmeaBootTimeMilli = 0;
+ return;
+ }
+
+ checkUpdateDgnssNtrip(false);
+}
+
+void GnssAdapter::disablePPENtripStreamCommand() {
+ struct disableNtripMsg : public LocMsg {
+ GnssAdapter& mAdapter;
+
+ inline disableNtripMsg(GnssAdapter& adapter) :
+ LocMsg(),
+ mAdapter(adapter) {}
+ inline virtual void proc() const {
+ mAdapter.handleDisablePPENtrip();
+ }
+ };
+ sendMsg(new disableNtripMsg(*this));
+}
+
+void GnssAdapter::handleDisablePPENtrip() {
+ mDgnssState &= ~DGNSS_STATE_ENABLE_NTRIP_COMMAND;
+ mDgnssState |= DGNSS_STATE_NO_NMEA_PENDING;
+ stopDgnssNtrip();
+}
+
+void GnssAdapter::checkUpdateDgnssNtrip(bool isLocationValid) {
+ LOC_LOGd("isInSession %d mDgnssState 0x%x isLocationValid %d",
+ isInSession(), mDgnssState, isLocationValid);
+ if (isInSession()) {
+ uint64_t curBootTime = getBootTimeMilliSec();
+ if (mDgnssState == (DGNSS_STATE_ENABLE_NTRIP_COMMAND | DGNSS_STATE_NO_NMEA_PENDING)) {
+ mDgnssState |= DGNSS_STATE_NTRIP_SESSION_STARTED;
+ mXtraObserver.startDgnssSource(mStartDgnssNtripParams);
+ if (isDgnssNmeaRequired()) {
+ mDgnssLastNmeaBootTimeMilli = curBootTime;
+ }
+ } else if ((mDgnssState & DGNSS_STATE_NTRIP_SESSION_STARTED) && isLocationValid &&
+ isDgnssNmeaRequired() &&
+ curBootTime - mDgnssLastNmeaBootTimeMilli > DGNSS_RANGE_UPDATE_TIME_10MIN_IN_MILLI ) {
+ mXtraObserver.updateNmeaToDgnssServer(mStartDgnssNtripParams.nmea);
+ mDgnssLastNmeaBootTimeMilli = curBootTime;
+ }
+ }
+}
+
+void GnssAdapter::stopDgnssNtrip() {
+ LOC_LOGd("isInSession %d mDgnssState 0x%x", isInSession(), mDgnssState);
+ mStartDgnssNtripParams.nmea.clear();
+ if (mDgnssState & DGNSS_STATE_NTRIP_SESSION_STARTED) {
+ mDgnssState &= ~DGNSS_STATE_NTRIP_SESSION_STARTED;
+ mXtraObserver.stopDgnssSource();
+ }
+}
+
+void GnssAdapter::reportGGAToNtrip(const char* nmea) {
+
+#define POS_OF_GGA (3) //start position of "GGA"
+#define COMMAS_BEFORE_VALID (6) //"$GPGGA,,,,,,0,,,,,,,,*hh"
+
+ if (!isDgnssNmeaRequired()) {
+ return;
+ }
+
+ if (nullptr == nmea || 0 == strlen(nmea)) {
+ return;
+ }
+
+ string nmeaString(nmea);
+ size_t foundPos = nmeaString.find("GGA");
+ size_t foundNth = 0;
+ string GGAString;
+
+ if (foundPos != string::npos && foundPos >= POS_OF_GGA) {
+ size_t foundNextSentence = nmeaString.find("$", foundPos);
+ if (foundNextSentence != string::npos) {
+ /* remove other sentences after GGA */
+ GGAString = nmeaString.substr(foundPos - POS_OF_GGA, foundNextSentence);
+ } else {
+ /* GGA is the last sentence */
+ GGAString = nmeaString.substr(foundPos - POS_OF_GGA);
+ }
+ LOC_LOGd("GGAString %s", GGAString.c_str());
+
+ foundPos = GGAString.find(",");
+ while (foundPos != string::npos && foundNth < COMMAS_BEFORE_VALID) {
+ foundPos++;
+ foundNth++;
+ foundPos = GGAString.find(",", foundPos);
+ }
+
+ if (COMMAS_BEFORE_VALID == foundNth && GGAString.at(foundPos-1) != '0') {
+ mDgnssState |= DGNSS_STATE_NO_NMEA_PENDING;
+ mStartDgnssNtripParams.nmea = std::move(GGAString);
+ checkUpdateDgnssNtrip(true);
+ }
+ }
+
+ return;
+}
diff --git a/gnss/GnssAdapter.h b/gnss/GnssAdapter.h
index 136c5c0..d7b4275 100644
--- a/gnss/GnssAdapter.h
+++ b/gnss/GnssAdapter.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2020 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,6 +38,10 @@
#include <SystemStatus.h>
#include <XtraSystemStatusObserver.h>
#include <map>
+#include <functional>
+#include <loc_misc_utils.h>
+#include <queue>
+#include <NativeAgpsHandler.h>
#define MAX_URL_LEN 256
#define NMEA_SENTENCE_MAX_LENGTH 200
@@ -46,6 +50,7 @@
#define LOC_NI_NO_RESPONSE_TIME 20
#define LOC_GPS_NI_RESPONSE_IGNORE 4
#define ODCPI_EXPECTED_INJECTION_TIME_MS 10000
+#define DELETE_AIDING_DATA_EXPECTED_TIME_MS 5000
class GnssAdapter;
@@ -135,8 +140,16 @@
} PaceConfigInfo;
typedef struct {
+ bool isValid;
+ bool enable;
+ bool enableFor911;
+} RobustLocationConfigInfo;
+
+typedef struct {
TuncConfigInfo tuncConfigInfo;
PaceConfigInfo paceConfigInfo;
+ RobustLocationConfigInfo robustLocationConfigInfo;
+ LeverArmConfigInfo leverArmConfigInfo;
} LocIntegrationConfigInfo;
using namespace loc_core;
@@ -149,7 +162,40 @@
uint64_t gnssEnergyConsumedFromFirstBoot
)> GnssEnergyConsumedCallback;
-typedef void (*powerStateCallback)(bool on);
+typedef void* QDgnssListenerHDL;
+typedef std::function<void(
+ bool sessionActive
+)> QDgnssSessionActiveCb;
+
+struct CdfwInterface {
+ void (*startDgnssApiService)(const MsgTask& msgTask);
+ QDgnssListenerHDL (*createUsableReporter)(
+ QDgnssSessionActiveCb sessionActiveCb);
+ void (*destroyUsableReporter)(QDgnssListenerHDL handle);
+ void (*reportUsable)(QDgnssListenerHDL handle, bool usable);
+};
+
+typedef uint16_t DGnssStateBitMask;
+#define DGNSS_STATE_ENABLE_NTRIP_COMMAND 0X01
+#define DGNSS_STATE_NO_NMEA_PENDING 0X02
+#define DGNSS_STATE_NTRIP_SESSION_STARTED 0X04
+
+class GnssReportLoggerUtil {
+public:
+ typedef void (*LogGnssLatency)(const GnssLatencyInfo& gnssLatencyMeasInfo);
+
+ GnssReportLoggerUtil() : mLogLatency(nullptr) {
+ const char* libname = "liblocdiagiface.so";
+ void* libHandle = nullptr;
+ mLogLatency = (LogGnssLatency)dlGetSymFromLib(libHandle, libname, "LogGnssLatency");
+ }
+
+ bool isLogEnabled();
+ void log(const GnssLatencyInfo& gnssLatencyMeasInfo);
+
+private:
+ LogGnssLatency mLogLatency;
+};
class GnssAdapter : public LocAdapterBase {
@@ -171,7 +217,9 @@
LocationControlCallbacks mControlCallbacks;
uint32_t mAfwControlId;
uint32_t mNmeaMask;
+ uint64_t mPrevNmeaRptTimeNsec;
GnssSvIdConfig mGnssSvIdConfig;
+ GnssSvTypeConfig mGnssSeconaryBandConfig;
GnssSvTypeConfig mGnssSvTypeConfig;
GnssSvTypeConfigCallback mGnssSvTypeConfigCb;
bool mSupportNfwControl;
@@ -193,13 +241,30 @@
mIsE911Session = (IsInEmergencySession)cbInfo.isInEmergencySession;
}
+ /* ==== Measurement Corrections========================================================= */
+ bool mIsMeasCorrInterfaceOpen;
+ measCorrSetCapabilitiesCb mMeasCorrSetCapabilitiesCb;
+ bool initMeasCorr(bool bSendCbWhenNotSupported);
+ bool mIsAntennaInfoInterfaceOpened;
+
+ /* ==== DGNSS Data Usable Report======================================================== */
+ QDgnssListenerHDL mQDgnssListenerHDL;
+ const CdfwInterface* mCdfwInterface;
+ bool mDGnssNeedReport;
+ bool mDGnssDataUsage;
+ void reportDGnssDataUsable(const GnssSvMeasurementSet &svMeasurementSet);
+
/* ==== ODCPI ========================================================================== */
OdcpiRequestCallback mOdcpiRequestCb;
bool mOdcpiRequestActive;
+ OdcpiPrioritytype mCallbackPriority;
OdcpiTimer mOdcpiTimer;
OdcpiRequestInfo mOdcpiRequest;
void odcpiTimerExpire();
+ /* ==== DELETEAIDINGDATA =============================================================== */
+ int64_t mLastDeleteAidingDataTime;
+
/* === SystemStatus ===================================================================== */
SystemStatus* mSystemStatus;
std::string mServerUrl;
@@ -213,34 +278,49 @@
BlockCPIInfo mBlockCPIInfo;
bool mPowerOn;
uint32_t mAllowFlpNetworkFixes;
+ std::queue<GnssLatencyInfo> mGnssLatencyInfoQueue;
+ GnssReportLoggerUtil mLogger;
+ bool mDreIntEnabled;
+
+ /* === NativeAgpsHandler ======================================================== */
+ NativeAgpsHandler mNativeAgpsHandler;
/* === Misc callback from QMI LOC API ============================================== */
GnssEnergyConsumedCallback mGnssEnergyConsumedCb;
- powerStateCallback mPowerStateCb;
+ std::function<void(bool)> mPowerStateCb;
/*==== CONVERSION ===================================================================*/
static void convertOptions(LocPosMode& out, const TrackingOptions& trackingOptions);
static void convertLocation(Location& out, const UlpLocation& ulpLocation,
- const GpsLocationExtended& locationExtended,
- const LocPosTechMask techMask);
+ const GpsLocationExtended& locationExtended);
static void convertLocationInfo(GnssLocationInfoNotification& out,
- const GpsLocationExtended& locationExtended);
+ const GpsLocationExtended& locationExtended,
+ loc_sess_status status);
static uint16_t getNumSvUsed(uint64_t svUsedIdsMask,
int totalSvCntInThisConstellation);
/* ======== UTILITIES ================================================================== */
- inline void initOdcpi(const OdcpiRequestCallback& callback);
+ inline void initOdcpi(const OdcpiRequestCallback& callback, OdcpiPrioritytype priority);
inline void injectOdcpi(const Location& location);
static bool isFlpClient(LocationCallbacks& locationCallbacks);
+ /*==== DGnss Ntrip Source ==========================================================*/
+ StartDgnssNtripParams mStartDgnssNtripParams;
+ bool mSendNmeaConsent;
+ DGnssStateBitMask mDgnssState;
+ void checkUpdateDgnssNtrip(bool isLocationValid);
+ void stopDgnssNtrip();
+ uint64_t mDgnssLastNmeaBootTimeMilli;
+
protected:
/* ==== CLIENT ========================================================================= */
virtual void updateClientsEventMask();
virtual void stopClientSessions(LocationAPI* client);
+ inline void setNmeaReportRateConfig();
+ void logLatencyInfo();
public:
-
GnssAdapter();
virtual inline ~GnssAdapter() { }
@@ -248,8 +328,10 @@
/* ======== EVENTS ====(Called from QMI Thread)========================================= */
virtual void handleEngineUpEvent();
/* ======== UTILITIES ================================================================== */
- void restartSessions();
+ void restartSessions(bool modemSSR = false);
void checkAndRestartTimeBasedSession();
+ void checkAndRestartSPESession();
+ void suspendSessions();
/* ==== CLIENT ========================================================================= */
/* ======== COMMANDS ====(Called from Client Thread)==================================== */
@@ -291,10 +373,17 @@
void setConstrainedTunc(bool enable, float tuncConstraint,
uint32_t energyBudget, uint32_t sessionId);
void setPositionAssistedClockEstimator(bool enable, uint32_t sessionId);
- void updateSvConfig(uint32_t sessionId, const GnssSvTypeConfig& svTypeConfig,
- const GnssSvIdConfig& svIdConfig);
+ void gnssUpdateSvConfig(uint32_t sessionId,
+ const GnssSvTypeConfig& constellationEnablementConfig,
+ const GnssSvIdConfig& blacklistSvConfig);
+
+ void gnssUpdateSecondaryBandConfig(
+ uint32_t sessionId, const GnssSvTypeConfig& secondaryBandConfig);
+ void gnssGetSecondaryBandConfig(uint32_t sessionId);
void resetSvConfig(uint32_t sessionId);
void configLeverArm(uint32_t sessionId, const LeverArmConfigInfo& configInfo);
+ void configRobustLocation(uint32_t sessionId, bool enable, bool enableForE911);
+ void configMinGpsWeek(uint32_t sessionId, uint16_t minGpsWeek);
/* ==== NI ============================================================================= */
/* ======== COMMANDS ====(Called from Client Thread)==================================== */
@@ -313,12 +402,14 @@
void readConfigCommand();
void requestUlpCommand();
void initEngHubProxyCommand();
- uint32_t* gnssUpdateConfigCommand(GnssConfig config);
+ uint32_t* gnssUpdateConfigCommand(const GnssConfig& config);
uint32_t* gnssGetConfigCommand(GnssConfigFlagsMask mask);
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& oldMoServerUrl,
+ const std::string& moServerUrl,
+ const std::string& serverUrl,
GnssConfig& gnssConfigRequested,
GnssConfig& gnssConfigNeedEngineUpdate, size_t count = 0);
@@ -343,6 +434,7 @@
inline GnssSvTypeConfigCallback gnssGetSvTypeConfigCallback()
{ return mGnssSvTypeConfigCb; }
void setConfig();
+ void gnssSecondaryBandConfigUpdate(LocApiResponse* locApiResponse= nullptr);
/* ========= AGPS ====================================================================== */
/* ======== COMMANDS ====(Called from Client Thread)==================================== */
@@ -358,14 +450,26 @@
uint32_t setConstrainedTuncCommand (bool enable, float tuncConstraint,
uint32_t energyBudget);
uint32_t setPositionAssistedClockEstimatorCommand (bool enable);
- uint32_t gnssUpdateSvConfigCommand(const GnssSvTypeConfig& svTypeConfig,
- const GnssSvIdConfig& svIdConfig);
- uint32_t gnssResetSvConfigCommand();
+ uint32_t gnssUpdateSvConfigCommand(const GnssSvTypeConfig& constellationEnablementConfig,
+ const GnssSvIdConfig& blacklistSvConfig);
+ uint32_t gnssUpdateSecondaryBandConfigCommand(
+ const GnssSvTypeConfig& secondaryBandConfig);
+ uint32_t gnssGetSecondaryBandConfigCommand();
uint32_t configLeverArmCommand(const LeverArmConfigInfo& configInfo);
+ uint32_t configRobustLocationCommand(bool enable, bool enableForE911);
+ bool openMeasCorrCommand(const measCorrSetCapabilitiesCb setCapabilitiesCb);
+ bool measCorrSetCorrectionsCommand(const GnssMeasurementCorrections gnssMeasCorr);
+ inline void closeMeasCorrCommand() { mIsMeasCorrInterfaceOpen = false; }
+ uint32_t antennaInfoInitCommand(const antennaInfoCb antennaInfoCallback);
+ inline void antennaInfoCloseCommand() { mIsAntennaInfoInterfaceOpened = false; }
+ uint32_t configMinGpsWeekCommand(uint16_t minGpsWeek);
+ uint32_t configDeadReckoningEngineParamsCommand(const DeadReckoningEngineConfig& dreConfig);
+ uint32_t configEngineRunStateCommand(PositioningEngineMask engType,
+ LocEngineRunState engState);
/* ========= ODCPI ===================================================================== */
/* ======== COMMANDS ====(Called from Client Thread)==================================== */
- void initOdcpiCommand(const OdcpiRequestCallback& callback);
+ void initOdcpiCommand(const OdcpiRequestCallback& callback, OdcpiPrioritytype priority);
void injectOdcpiCommand(const Location& location);
/* ======== RESPONSES ================================================================== */
void reportResponse(LocationError err, uint32_t sessionId);
@@ -379,6 +483,7 @@
virtual bool isInSession() { return !mTimeBasedTrackingSessions.empty(); }
void initDefaultAgps();
bool initEngHubProxy();
+ void initCDFWService();
void odcpiTimerExpireEvent();
/* ==== REPORTS ======================================================================== */
@@ -404,6 +509,7 @@
virtual void reportSvEphemerisEvent(GnssSvEphemerisReport & svEphemeris);
virtual void reportGnssSvIdConfigEvent(const GnssSvIdConfig& config);
virtual void reportGnssSvTypeConfigEvent(const GnssSvTypeConfig& config);
+ virtual void reportGnssConfigEvent(uint32_t sessionId, const GnssConfig& gnssConfig);
virtual bool reportGnssEngEnergyConsumedEvent(uint64_t energyConsumedSinceFirstBoot);
virtual void reportLocationSystemInfoEvent(const LocationSystemInfo& locationSystemInfo);
@@ -415,11 +521,20 @@
virtual bool reportGnssAdditionalSystemInfoEvent(
GnssAdditionalSystemInfo& additionalSystemInfo);
virtual void reportNfwNotificationEvent(GnssNfwNotification& notification);
+ virtual void reportLatencyInfoEvent(const GnssLatencyInfo& gnssLatencyInfo);
+ virtual bool reportQwesCapabilities
+ (
+ const std::unordered_map<LocationQwesFeatureType, bool> &featureMap
+ );
+ void reportPdnTypeFromWds(int pdnType, AGpsExtType agpsType, std::string apnName,
+ AGpsBearerType bearerType);
/* ======== UTILITIES ================================================================= */
bool needReportForGnssClient(const UlpLocation& ulpLocation,
enum loc_sess_status status, LocPosTechMask techMask);
bool needReportForFlpClient(enum loc_sess_status status, LocPosTechMask techMask);
+ bool needToGenerateNmeaReport(const uint32_t &gpsTimeOfWeekMs,
+ const struct timespec32_t &apTimeStamp);
void reportPosition(const UlpLocation &ulpLocation,
const GpsLocationExtended &locationExtended,
enum loc_sess_status status,
@@ -434,6 +549,7 @@
void reportGnssMeasurementData(const GnssMeasurementsNotification& measurements);
void reportGnssSvIdConfig(const GnssSvIdConfig& config);
void reportGnssSvTypeConfig(const GnssSvTypeConfig& config);
+ void reportGnssConfig(uint32_t sessionId, const GnssConfig& gnssConfig);
void requestOdcpi(const OdcpiRequestInfo& request);
void invokeGnssEnergyConsumedCallback(uint64_t energyConsumedSinceFirstBoot);
void saveGnssEnergyConsumedCallback(GnssEnergyConsumedCallback energyConsumedCb);
@@ -451,6 +567,11 @@
}
void updateSystemPowerState(PowerStateType systemPowerState);
+ void reportSvPolynomial(const GnssSvPolynomial &svPolynomial);
+
+
+ std::vector<double> parseDoublesString(char* dString);
+ void reportGnssAntennaInformation(const antennaInfoCb antennaInfoCallback);
/*======== GNSSDEBUG ================================================================*/
bool getDebugReport(GnssDebugReport& report);
@@ -466,7 +587,6 @@
/*==== CONVERSION ===================================================================*/
static uint32_t convertSuplVersion(const GnssConfigSuplVersion suplVersion);
- static uint32_t convertLppProfile(const GnssConfigLppProfile lppProfile);
static uint32_t convertEP4ES(const GnssConfigEmergencyPdnForEmergencySupl);
static uint32_t convertSuplEs(const GnssConfigSuplEmergencyServices suplEmergencyServices);
static uint32_t convertLppeCp(const GnssConfigLppeControlPlaneMask lppeControlPlaneMask);
@@ -479,10 +599,12 @@
static bool convertToGnssSvIdConfig(
const std::vector<GnssSvIdSource>& blacklistedSvIds, GnssSvIdConfig& config);
static void convertFromGnssSvIdConfig(
- const GnssSvIdConfig& svConfig, GnssConfig& config);
+ const GnssSvIdConfig& svConfig, std::vector<GnssSvIdSource>& blacklistedSvIds);
static void convertGnssSvIdMaskToList(
uint64_t svIdMask, std::vector<GnssSvIdSource>& svIds,
GnssSvId initialSvId, GnssSvType svType);
+ static void computeVRPBasedLla(const UlpLocation& loc, GpsLocationExtended& locExt,
+ const LeverArmConfigInfo& leverArmConfigInfo);
void injectLocationCommand(double latitude, double longitude, float accuracy);
void injectLocationExtCommand(const GnssLocationInfoNotification &locationInfo);
@@ -493,10 +615,11 @@
/* ==== MISCELLANEOUS ================================================================== */
/* ======== COMMANDS ====(Called from Client Thread)==================================== */
- void getPowerStateChangesCommand(void* powerStateCb);
+ void getPowerStateChangesCommand(std::function<void(bool)> powerStateCb);
/* ======== UTILITIES ================================================================== */
void reportPowerStateIfChanged();
- void savePowerStateCallback(powerStateCallback powerStateCb){ mPowerStateCb = powerStateCb; }
+ void savePowerStateCallback(std::function<void(bool)> powerStateCb){
+ mPowerStateCb = powerStateCb; }
bool getPowerState() { return mPowerOn; }
inline PowerStateType getSystemPowerState() { return mSystemPowerState; }
@@ -505,7 +628,24 @@
void setSuplHostServer(const char* server, int port, LocServerType type);
void notifyClientOfCachedLocationSystemInfo(LocationAPI* client,
const LocationCallbacks& callbacks);
+ LocationCapabilitiesMask getCapabilities();
void updateSystemPowerStateCommand(PowerStateType systemPowerState);
+
+ /*==== DGnss Usable Report Flag ====================================================*/
+ inline void setDGnssUsableFLag(bool dGnssNeedReport) { mDGnssNeedReport = dGnssNeedReport;}
+ inline bool isNMEAPrintEnabled() {
+ return ((mContext != NULL) && (0 != mContext->mGps_conf.ENABLE_NMEA_PRINT));
+ }
+
+ /*==== DGnss Ntrip Source ==========================================================*/
+ void updateNTRIPGGAConsentCommand(bool consentAccepted) { mSendNmeaConsent = consentAccepted; }
+ void enablePPENtripStreamCommand(const GnssNtripConnectionParams& params, bool enableRTKEngine);
+ void disablePPENtripStreamCommand();
+ void handleEnablePPENtrip(const GnssNtripConnectionParams& params);
+ void handleDisablePPENtrip();
+ void reportGGAToNtrip(const char* nmea);
+ inline bool isDgnssNmeaRequired() { return mSendNmeaConsent &&
+ mStartDgnssNtripParams.ntripParams.requiresNmeaLocation;}
};
#endif //GNSS_ADAPTER_H
diff --git a/gnss/Makefile.am b/gnss/Makefile.am
index db20c15..dd313a1 100644
--- a/gnss/Makefile.am
+++ b/gnss/Makefile.am
@@ -13,7 +13,8 @@
location_gnss.cpp \
GnssAdapter.cpp \
XtraSystemStatusObserver.cpp \
- Agps.cpp
+ Agps.cpp \
+ NativeAgpsHandler.cpp
if USE_GLIB
libgnss_la_CFLAGS = -DUSE_GLIB $(AM_CFLAGS) @GLIB_CFLAGS@
diff --git a/gnss/NativeAgpsHandler.cpp b/gnss/NativeAgpsHandler.cpp
new file mode 100644
index 0000000..ce4c03a
--- /dev/null
+++ b/gnss/NativeAgpsHandler.cpp
@@ -0,0 +1,127 @@
+/* Copyright (c) 2020, 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_NativeAgpsHandler"
+
+#include <LocAdapterBase.h>
+#include <SystemStatus.h>
+#include <DataItemId.h>
+#include <DataItemsFactoryProxy.h>
+#include <DataItemConcreteTypesBase.h>
+#include <loc_log.h>
+#include <NativeAgpsHandler.h>
+#include <GnssAdapter.h>
+
+using namespace loc_core;
+
+// IDataItemObserver overrides
+void NativeAgpsHandler::getName(string& name) {
+ name = "NativeAgpsHandler";
+}
+
+void NativeAgpsHandler::notify(const list<IDataItemCore*>& dlist) {
+ for (auto each : dlist) {
+ switch (each->getId()) {
+ case NETWORKINFO_DATA_ITEM_ID: {
+ NetworkInfoDataItemBase* networkInfo =
+ static_cast<NetworkInfoDataItemBase*>(each);
+ uint64_t mobileBit = (uint64_t )1 << loc_core::TYPE_MOBILE;
+ uint64_t allTypes = networkInfo->mAllTypes;
+ mConnected = ((networkInfo->mAllTypes & mobileBit) == mobileBit);
+ /**
+ * mApn Telephony preferred Access Point Name to use for
+ * carrier data connection when connected to a cellular network.
+ * Empty string, otherwise.
+ */
+ mApn = networkInfo->mApn;
+ LOC_LOGd("updated mConnected:%d, mApn: %s", mConnected, mApn.c_str());
+ break;
+ }
+ default:
+ break;
+ }
+ }
+}
+
+NativeAgpsHandler* NativeAgpsHandler::sLocalHandle = nullptr;
+NativeAgpsHandler::NativeAgpsHandler(IOsObserver* sysStatObs, GnssAdapter& adapter) :
+ mSystemStatusObsrvr(sysStatObs), mConnected(false), mAdapter(adapter) {
+ sLocalHandle = this;
+ list<DataItemId> subItemIdList = {NETWORKINFO_DATA_ITEM_ID};
+ mSystemStatusObsrvr->subscribe(subItemIdList, this);
+}
+
+NativeAgpsHandler::~NativeAgpsHandler() {
+ if (nullptr != mSystemStatusObsrvr) {
+ LOC_LOGd("Unsubscribe for network info.");
+ list<DataItemId> subItemIdList = {NETWORKINFO_DATA_ITEM_ID};
+ mSystemStatusObsrvr->unsubscribe(subItemIdList, this);
+ }
+ sLocalHandle = nullptr;
+ mSystemStatusObsrvr = nullptr;
+}
+
+
+AgpsCbInfo NativeAgpsHandler::getAgpsCbInfo() {
+ AgpsCbInfo nativeCbInfo = {};
+ nativeCbInfo.statusV4Cb = (void*)agnssStatusIpV4Cb;
+ nativeCbInfo.atlType = AGPS_ATL_TYPE_WWAN;
+ return nativeCbInfo;
+}
+
+void NativeAgpsHandler::agnssStatusIpV4Cb(AGnssExtStatusIpV4 statusInfo) {
+ if (nullptr != sLocalHandle) {
+ sLocalHandle->processATLRequestRelease(statusInfo);
+ } else {
+ LOC_LOGe("sLocalHandle is null");
+ }
+}
+
+void NativeAgpsHandler::processATLRequestRelease(AGnssExtStatusIpV4 statusInfo) {
+ if (LOC_AGPS_TYPE_WWAN_ANY == statusInfo.type) {
+ LOC_LOGd("status.type = %d status.apnTypeMask = 0x%X", statusInfo.type,
+ statusInfo.apnTypeMask);
+ switch (statusInfo.status) {
+ case LOC_GPS_REQUEST_AGPS_DATA_CONN:
+ if (mConnected) {
+ mAdapter.dataConnOpenCommand(LOC_AGPS_TYPE_WWAN_ANY, mApn.c_str(), mApn.size(),
+ AGPS_APN_BEARER_IPV4);
+ } else {
+ mAdapter.dataConnFailedCommand(LOC_AGPS_TYPE_WWAN_ANY);
+ }
+ break;
+ case LOC_GPS_RELEASE_AGPS_DATA_CONN:
+ mAdapter.dataConnClosedCommand(LOC_AGPS_TYPE_WWAN_ANY);
+ break;
+ default:
+ LOC_LOGe("Invalid Request: %d", statusInfo.status);
+ }
+ } else {
+ LOC_LOGe("mAgpsManger is null or invalid request type!");
+ }
+}
diff --git a/gnss/NativeAgpsHandler.h b/gnss/NativeAgpsHandler.h
new file mode 100644
index 0000000..fb0b46c
--- /dev/null
+++ b/gnss/NativeAgpsHandler.h
@@ -0,0 +1,64 @@
+/* Copyright (c) 2020, 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 NATIVEAGPSHANDLER_H
+#define NATIVEAGPSHANDLER_H
+
+#include <cinttypes>
+#include <string.h>
+#include <gps_extended_c.h>
+#include <IDataItemObserver.h>
+#include <IDataItemCore.h>
+#include <IOsObserver.h>
+
+using namespace std;
+using loc_core::IOsObserver;
+using loc_core::IDataItemObserver;
+using loc_core::IDataItemCore;
+
+class GnssAdapter;
+
+class NativeAgpsHandler : public IDataItemObserver {
+public:
+ NativeAgpsHandler(IOsObserver* sysStatObs, GnssAdapter& adapter);
+ ~NativeAgpsHandler();
+ AgpsCbInfo getAgpsCbInfo();
+ // IDataItemObserver overrides
+ virtual void notify(const list<IDataItemCore*>& dlist);
+ inline virtual void getName(string& name);
+private:
+ static NativeAgpsHandler* sLocalHandle;
+ static void agnssStatusIpV4Cb(AGnssExtStatusIpV4 statusInfo);
+ void processATLRequestRelease(AGnssExtStatusIpV4 statusInfo);
+ IOsObserver* mSystemStatusObsrvr;
+ bool mConnected;
+ string mApn;
+ GnssAdapter& mAdapter;
+};
+
+#endif // NATIVEAGPSHANDLER_H
diff --git a/gnss/XtraSystemStatusObserver.cpp b/gnss/XtraSystemStatusObserver.cpp
index a58f735..d65622f 100644
--- a/gnss/XtraSystemStatusObserver.cpp
+++ b/gnss/XtraSystemStatusObserver.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, 2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2020 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
@@ -72,9 +72,13 @@
LOC_LOGd("ping received");
#ifdef USE_GLIB
} else if (!STRNCMP(data, "connectBackhaul")) {
- mSystemStatusObsrvr->connectBackhaul();
+ char clientName[30] = {0};
+ sscanf(data, "%*s %29s", clientName);
+ mSystemStatusObsrvr->connectBackhaul(string(clientName));
} else if (!STRNCMP(data, "disconnectBackhaul")) {
- mSystemStatusObsrvr->disconnectBackhaul();
+ char clientName[30] = {0};
+ sscanf(data, "%*s %29s", clientName);
+ mSystemStatusObsrvr->disconnectBackhaul(string(clientName));
#endif
} else if (!STRNCMP(data, "requestStatus")) {
int32_t xtraStatusUpdated = 0;
@@ -88,6 +92,8 @@
mXSSO(xsso), mXtraStatusUpdated(xtraStatusUpdated) {}
inline void proc() const override {
mXSSO.onStatusRequested(mXtraStatusUpdated);
+ /* SSR for DGnss Ntrip Source*/
+ mXSSO.restartDgnssSource();
}
};
mMsgTask->sendMsg(new HandleStatusRequestMsg(mXSSO, xtraStatusUpdated));
@@ -231,6 +237,55 @@
return ( LocIpc::send(*mSender, (const uint8_t*)s.data(), s.size()) );
}
+void XtraSystemStatusObserver::startDgnssSource(const StartDgnssNtripParams& params) {
+ stringstream ss;
+ const GnssNtripConnectionParams* ntripParams = &(params.ntripParams);
+
+ ss << "startDgnssSource" << endl;
+ ss << ntripParams->useSSL << endl;
+ ss << ntripParams->hostNameOrIp.data() << endl;
+ ss << ntripParams->port << endl;
+ ss << ntripParams->mountPoint.data() << endl;
+ ss << ntripParams->username.data() << endl;
+ ss << ntripParams->password.data() << endl;
+ if (ntripParams->requiresNmeaLocation && !params.nmea.empty()) {
+ ss << params.nmea.data() << endl;
+ }
+ string s = ss.str();
+
+ LOC_LOGd("%s", s.data());
+ LocIpc::send(*mSender, (const uint8_t*)s.data(), s.size());
+ // make a local copy of the string for SSR
+ mNtripParamsString.assign(std::move(s));
+}
+
+void XtraSystemStatusObserver::restartDgnssSource() {
+ if (!mNtripParamsString.empty()) {
+ LocIpc::send(*mSender,
+ (const uint8_t*)mNtripParamsString.data(), mNtripParamsString.size());
+ LOC_LOGv("Xtra SSR %s", mNtripParamsString.data());
+ }
+}
+
+void XtraSystemStatusObserver::stopDgnssSource() {
+ LOC_LOGv();
+ mNtripParamsString.clear();
+
+ const char s[] = "stopDgnssSource";
+ LocIpc::send(*mSender, (const uint8_t*)s, strlen(s));
+}
+
+void XtraSystemStatusObserver::updateNmeaToDgnssServer(const string& nmea)
+{
+ stringstream ss;
+ ss << "updateDgnssServerNmea" << endl;
+ ss << nmea.data() << endl;
+
+ string s = ss.str();
+ LOC_LOGd("%s", s.data());
+ LocIpc::send(*mSender, (const uint8_t*)s.data(), s.size());
+}
+
void XtraSystemStatusObserver::subscribe(bool yes)
{
// Subscription data list
diff --git a/gnss/XtraSystemStatusObserver.h b/gnss/XtraSystemStatusObserver.h
index 3a5259d..56a3a9c 100644
--- a/gnss/XtraSystemStatusObserver.h
+++ b/gnss/XtraSystemStatusObserver.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2020 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
@@ -33,6 +33,7 @@
#include <MsgTask.h>
#include <LocIpc.h>
#include <LocTimer.h>
+#include <stdlib.h>
using namespace std;
using namespace loc_util;
@@ -40,6 +41,22 @@
using loc_core::IDataItemObserver;
using loc_core::IDataItemCore;
+struct StartDgnssNtripParams {
+ GnssNtripConnectionParams ntripParams;
+ string nmea;
+
+ void clear() {
+ ntripParams.hostNameOrIp.clear();
+ ntripParams.mountPoint.clear();
+ ntripParams.username.clear();
+ ntripParams.password.clear();
+ ntripParams.port = 0;
+ ntripParams.useSSL = false;
+ ntripParams.requiresNmeaLocation = false;
+ nmea.clear();
+ }
+};
+
class XtraSystemStatusObserver : public IDataItemObserver {
public :
// constructor & destructor
@@ -62,6 +79,10 @@
inline const MsgTask* getMsgTask() { return mMsgTask; }
void subscribe(bool yes);
bool onStatusRequested(int32_t xtraStatusUpdated);
+ void startDgnssSource(const StartDgnssNtripParams& params);
+ void restartDgnssSource();
+ void stopDgnssSource();
+ void updateNmeaToDgnssServer(const string& nmea);
private:
IOsObserver* mSystemStatusObsrvr;
@@ -76,6 +97,7 @@
bool mReqStatusReceived;
bool mIsConnectivityStatusKnown;
shared_ptr<LocIpcSender> mSender;
+ string mNtripParamsString;
class DelayLocTimer : public LocTimer {
LocIpcSender& mSender;
diff --git a/gnss/location_gnss.cpp b/gnss/location_gnss.cpp
index c3ea105..8f67369 100644
--- a/gnss/location_gnss.cpp
+++ b/gnss/location_gnss.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2020, 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,7 +50,7 @@
static void setControlCallbacks(LocationControlCallbacks& controlCallbacks);
static uint32_t enable(LocationTechnologyType techType);
static void disable(uint32_t id);
-static uint32_t* gnssUpdateConfig(GnssConfig config);
+static uint32_t* gnssUpdateConfig(const GnssConfig& config);
static uint32_t* gnssGetConfig(GnssConfigFlagsMask mask);
static void gnssUpdateSvTypeConfig(GnssSvTypeConfig& config);
@@ -66,14 +66,14 @@
static void agpsDataConnClosed(AGpsExtType agpsType);
static void agpsDataConnFailed(AGpsExtType agpsType);
static void getDebugReport(GnssDebugReport& report);
-static void updateConnectionStatus(bool connected, int8_t type, bool roaming = false,
- NetworkHandle networkHandle = NETWORK_HANDLE_UNKNOWN);
+static void updateConnectionStatus(bool connected, int8_t type, bool roaming,
+ NetworkHandle networkHandle, string& apn);
static void getGnssEnergyConsumed(GnssEnergyConsumedCallback energyConsumedCb);
static void enableNfwLocationAccess(bool enable);
static void nfwInit(const NfwCbInfo& cbInfo);
-static void getPowerStateChanges(void* powerStateCb);
+static void getPowerStateChanges(std::function<void(bool)> powerStateCb);
-static void odcpiInit(const OdcpiRequestCallback& callback);
+static void odcpiInit(const OdcpiRequestCallback& callback, OdcpiPrioritytype priority);
static void odcpiInject(const Location& location);
static void blockCPI(double latitude, double longitude, float accuracy,
@@ -83,10 +83,27 @@
static uint32_t setConstrainedTunc (bool enable, float tuncConstraint,
uint32_t energyBudget);
static uint32_t setPositionAssistedClockEstimator(bool enable);
-static uint32_t gnssUpdateSvConfig(const GnssSvTypeConfig& svTypeConfig,
- const GnssSvIdConfig& svIdConfig);
+static uint32_t gnssUpdateSvConfig(const GnssSvTypeConfig& constellationEnablementConfig,
+ const GnssSvIdConfig& blacklistSvConfig);
static uint32_t gnssResetSvConfig();
static uint32_t configLeverArm(const LeverArmConfigInfo& configInfo);
+static uint32_t configRobustLocation(bool enable, bool enableForE911);
+static uint32_t configMinGpsWeek(uint16_t minGpsWeek);
+static uint32_t configDeadReckoningEngineParams(const DeadReckoningEngineConfig& dreConfig);
+static uint32_t gnssUpdateSecondaryBandConfig(const GnssSvTypeConfig& secondaryBandConfig);
+static uint32_t gnssGetSecondaryBandConfig();
+static void resetNetworkInfo();
+
+static void updateNTRIPGGAConsent(bool consentAccepted);
+static void enablePPENtripStream(const GnssNtripConnectionParams& params, bool enableRTKEngine);
+static void disablePPENtripStream();
+
+static bool measCorrInit(const measCorrSetCapabilitiesCb setCapabilitiesCb);
+static bool measCorrSetCorrections(const GnssMeasurementCorrections gnssMeasCorr);
+static void measCorrClose();
+static uint32_t antennaInfoInit(const antennaInfoCb antennaInfoCallback);
+static void antennaInfoClose();
+static uint32_t configEngineRunState(PositioningEngineMask engType, LocEngineRunState engState);
static const GnssInterface gGnssInterface = {
sizeof(GnssInterface),
@@ -130,8 +147,22 @@
setConstrainedTunc,
setPositionAssistedClockEstimator,
gnssUpdateSvConfig,
- gnssResetSvConfig,
configLeverArm,
+ measCorrInit,
+ measCorrSetCorrections,
+ measCorrClose,
+ antennaInfoInit,
+ antennaInfoClose,
+ configRobustLocation,
+ configMinGpsWeek,
+ configDeadReckoningEngineParams,
+ updateNTRIPGGAConsent,
+ enablePPENtripStream,
+ disablePPENtripStream,
+ gnssUpdateSecondaryBandConfig,
+ gnssGetSecondaryBandConfig,
+ resetNetworkInfo,
+ configEngineRunState
};
#ifndef DEBUG_X86
@@ -236,7 +267,7 @@
}
}
-static uint32_t* gnssUpdateConfig(GnssConfig config)
+static uint32_t* gnssUpdateConfig(const GnssConfig& config)
{
if (NULL != gGnssAdapter) {
return gGnssAdapter->gnssUpdateConfigCommand(config);
@@ -340,17 +371,18 @@
}
static void updateConnectionStatus(bool connected, int8_t type,
- bool roaming, NetworkHandle networkHandle) {
+ bool roaming, NetworkHandle networkHandle,
+ string& apn) {
if (NULL != gGnssAdapter) {
gGnssAdapter->getSystemStatus()->eventConnectionStatus(
- connected, type, roaming, networkHandle);
+ connected, type, roaming, networkHandle, apn);
}
}
-static void odcpiInit(const OdcpiRequestCallback& callback)
+static void odcpiInit(const OdcpiRequestCallback& callback, OdcpiPrioritytype priority)
{
if (NULL != gGnssAdapter) {
- gGnssAdapter->initOdcpiCommand(callback);
+ gGnssAdapter->initOdcpiCommand(callback, priority);
}
}
@@ -386,7 +418,8 @@
gGnssAdapter->initNfwCommand(cbInfo);
}
}
-static void getPowerStateChanges(void* powerStateCb)
+
+static void getPowerStateChanges(std::function<void(bool)> powerStateCb)
{
if (NULL != gGnssAdapter) {
gGnssAdapter->getPowerStateChangesCommand(powerStateCb);
@@ -406,6 +439,12 @@
}
}
+static void resetNetworkInfo() {
+ if (NULL != gGnssAdapter) {
+ gGnssAdapter->getSystemStatus()->resetNetworkInfo();
+ }
+}
+
static void updateSystemPowerState(PowerStateType systemPowerState) {
if (NULL != gGnssAdapter) {
gGnssAdapter->updateSystemPowerStateCommand(systemPowerState);
@@ -429,19 +468,11 @@
}
static uint32_t gnssUpdateSvConfig(
- const GnssSvTypeConfig& svTypeConfig,
- const GnssSvIdConfig& svIdConfig) {
+ const GnssSvTypeConfig& constellationEnablementConfig,
+ const GnssSvIdConfig& blacklistSvConfig) {
if (NULL != gGnssAdapter) {
return gGnssAdapter->gnssUpdateSvConfigCommand(
- svTypeConfig, svIdConfig);
- } else {
- return 0;
- }
-}
-
-static uint32_t gnssResetSvConfig() {
- if (NULL != gGnssAdapter) {
- return gGnssAdapter->gnssResetSvConfigCommand();
+ constellationEnablementConfig, blacklistSvConfig);
} else {
return 0;
}
@@ -454,3 +485,109 @@
return 0;
}
}
+
+static bool measCorrInit(const measCorrSetCapabilitiesCb setCapabilitiesCb) {
+ if (NULL != gGnssAdapter) {
+ return gGnssAdapter->openMeasCorrCommand(setCapabilitiesCb);
+ } else {
+ return false;
+ }
+}
+
+static bool measCorrSetCorrections(const GnssMeasurementCorrections gnssMeasCorr) {
+ if (NULL != gGnssAdapter) {
+ return gGnssAdapter->measCorrSetCorrectionsCommand(gnssMeasCorr);
+ } else {
+ return false;
+ }
+}
+
+static void measCorrClose() {
+ if (NULL != gGnssAdapter) {
+ gGnssAdapter->closeMeasCorrCommand();
+ }
+}
+
+static uint32_t antennaInfoInit(const antennaInfoCb antennaInfoCallback) {
+ if (NULL != gGnssAdapter) {
+ return gGnssAdapter->antennaInfoInitCommand(antennaInfoCallback);
+ } else {
+ return ANTENNA_INFO_ERROR_GENERIC;
+ }
+}
+
+static void antennaInfoClose() {
+ if (NULL != gGnssAdapter) {
+ return gGnssAdapter->antennaInfoCloseCommand();
+ }
+}
+
+static uint32_t configRobustLocation(bool enable, bool enableForE911){
+ if (NULL != gGnssAdapter) {
+ return gGnssAdapter->configRobustLocationCommand(enable, enableForE911);
+ } else {
+ return 0;
+ }
+}
+
+static uint32_t configMinGpsWeek(uint16_t minGpsWeek){
+ if (NULL != gGnssAdapter) {
+ return gGnssAdapter->configMinGpsWeekCommand(minGpsWeek);
+ } else {
+ return 0;
+ }
+}
+
+static uint32_t configDeadReckoningEngineParams(const DeadReckoningEngineConfig& dreConfig){
+ if (NULL != gGnssAdapter) {
+ return gGnssAdapter->configDeadReckoningEngineParamsCommand(dreConfig);
+ } else {
+ return 0;
+ }
+}
+
+static uint32_t gnssUpdateSecondaryBandConfig(
+ const GnssSvTypeConfig& secondaryBandConfig) {
+ if (NULL != gGnssAdapter) {
+ return gGnssAdapter->gnssUpdateSecondaryBandConfigCommand(secondaryBandConfig);
+ } else {
+ return 0;
+ }
+}
+
+static uint32_t gnssGetSecondaryBandConfig(){
+ if (NULL != gGnssAdapter) {
+ return gGnssAdapter->gnssGetSecondaryBandConfigCommand();
+ } else {
+ return 0;
+ }
+}
+
+static void updateNTRIPGGAConsent(bool consentAccepted){
+ if (NULL != gGnssAdapter) {
+ // Call will be enabled once GnssAdapter impl. is ready.
+ gGnssAdapter->updateNTRIPGGAConsentCommand(consentAccepted);
+ }
+}
+
+static void enablePPENtripStream(const GnssNtripConnectionParams& params, bool enableRTKEngine){
+ if (NULL != gGnssAdapter) {
+ // Call will be enabled once GnssAdapter impl. is ready.
+ gGnssAdapter->enablePPENtripStreamCommand(params, enableRTKEngine);
+ }
+}
+
+static void disablePPENtripStream(){
+ if (NULL != gGnssAdapter) {
+ // Call will be enabled once GnssAdapter impl. is ready.
+ gGnssAdapter->disablePPENtripStreamCommand();
+ }
+}
+
+static uint32_t configEngineRunState(PositioningEngineMask engType, LocEngineRunState engState) {
+ if (NULL != gGnssAdapter) {
+ return gGnssAdapter->configEngineRunStateCommand(engType, engState);
+ } else {
+ return 0;
+ }
+}
diff --git a/gps_vendor_product.mk b/gps_vendor_product.mk
index 6e938b3..cd35684 100644
--- a/gps_vendor_product.mk
+++ b/gps_vendor_product.mk
@@ -1,14 +1,48 @@
# HAL packages
-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
+ifneq ($(BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE),)
+
+# GPS-HIDL
+LOC_BOARD_PLATFORM_LIST += msm8937
+LOC_BOARD_PLATFORM_LIST += msm8953
+LOC_BOARD_PLATFORM_LIST += msm8998
+LOC_BOARD_PLATFORM_LIST += apq8098_latv
+LOC_BOARD_PLATFORM_LIST += sdm710
+LOC_BOARD_PLATFORM_LIST += qcs605
+LOC_BOARD_PLATFORM_LIST += sdm845
+LOC_BOARD_PLATFORM_LIST += sdm660
+LOC_BOARD_PLATFORM_LIST += msmnile
+LOC_BOARD_PLATFORM_LIST += sdmshrike
+LOC_BOARD_PLATFORM_LIST += $(MSMSTEPPE)
+LOC_BOARD_PLATFORM_LIST += $(TRINKET)
+LOC_BOARD_PLATFORM_LIST += kona
+LOC_BOARD_PLATFORM_LIST += atoll
+LOC_BOARD_PLATFORM_LIST += lito
+LOC_BOARD_PLATFORM_LIST += bengal
+LOC_BOARD_PLATFORM_LIST += lahaina
+LOC_BOARD_PLATFORM_LIST += holi
+
+# Add product packages
+ifneq (,$(filter $(LOC_BOARD_PLATFORM_LIST),$(TARGET_BOARD_PLATFORM)))
+
PRODUCT_PACKAGES += gps.conf
-PRODUCT_PACKAGES += libloc_core
-PRODUCT_PACKAGES += libgnss
+PRODUCT_PACKAGES += flp.conf
+PRODUCT_PACKAGES += gnss_antenna_info.conf
+PRODUCT_PACKAGES += gnss@2.0-base.policy
+PRODUCT_PACKAGES += gnss@2.0-xtra-daemon.policy
+PRODUCT_PACKAGES += gnss@2.0-xtwifi-client.policy
+PRODUCT_PACKAGES += gnss@2.0-xtwifi-inet-agent.policy
+PRODUCT_PACKAGES += libloc_pla_headers
+PRODUCT_PACKAGES += liblocation_api_headers
+PRODUCT_PACKAGES += libgps.utils_headers
PRODUCT_PACKAGES += liblocation_api
PRODUCT_PACKAGES += libgps.utils
PRODUCT_PACKAGES += libbatching
PRODUCT_PACKAGES += libgeofencing
+PRODUCT_PACKAGES += libloc_core
+PRODUCT_PACKAGES += libgnss
+
+PRODUCT_PACKAGES += android.hardware.gnss@2.1-impl-qti
+PRODUCT_PACKAGES += android.hardware.gnss@2.1-service-qti
+
+endif # ifneq (,$(filter $(LOC_BOARD_PLATFORM_LIST),$(TARGET_BOARD_PLATFORM)))
+endif # ifneq ($(BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE),)
diff --git a/location/Android.bp b/location/Android.bp
new file mode 100644
index 0000000..9126305
--- /dev/null
+++ b/location/Android.bp
@@ -0,0 +1,45 @@
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_qcom_sm7250_gps_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-BSD
+ default_applicable_licenses: ["hardware_qcom_sm7250_gps_license"],
+}
+
+cc_library_shared {
+
+ name: "liblocation_api",
+ vendor: true,
+
+
+
+ shared_libs: [
+ "libutils",
+ "libcutils",
+ "libgps.utils",
+ "libdl",
+ "liblog",
+ ],
+
+ srcs: [
+ "LocationAPI.cpp",
+ "LocationAPIClientBase.cpp",
+ ],
+
+ cflags: ["-fno-short-enums"] + GNSS_CFLAGS,
+
+ header_libs: [
+ "libloc_pla_headers",
+ "libgps.utils_headers",
+ ],
+
+}
+
+cc_library_headers {
+
+ name: "liblocation_api_headers",
+ export_include_dirs: ["."],
+ vendor: true,
+}
diff --git a/location/Android.mk b/location/Android.mk
deleted file mode 100644
index 2a59541..0000000
--- a/location/Android.mk
+++ /dev/null
@@ -1,44 +0,0 @@
-ifneq ($(BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE),)
-ifneq ($(BUILD_TINY_ANDROID),true)
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := liblocation_api
-LOCAL_SANITIZE += $(GNSS_SANITIZE)
-# activate the following line for debug purposes only, comment out for production
-#LOCAL_SANITIZE_DIAG += $(GNSS_SANITIZE_DIAG)
-LOCAL_VENDOR_MODULE := true
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SHARED_LIBRARIES := \
- libutils \
- libcutils \
- libgps.utils \
- libdl \
- liblog
-
-LOCAL_SRC_FILES += \
- LocationAPI.cpp \
- LocationAPIClientBase.cpp
-
-LOCAL_CFLAGS += \
- -fno-short-enums
-
-LOCAL_HEADER_LIBRARIES := \
- libloc_pla_headers \
- libgps.utils_headers
-
-LOCAL_PRELINK_MODULE := false
-
-LOCAL_CFLAGS += $(GNSS_CFLAGS)
-include $(BUILD_SHARED_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := liblocation_api_headers
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
-include $(BUILD_HEADER_LIBRARY)
-
-endif # not BUILD_TINY_ANDROID
-endif # BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE
diff --git a/location/ILocationAPI.h b/location/ILocationAPI.h
index 87aa99b..29846ac 100644
--- a/location/ILocationAPI.h
+++ b/location/ILocationAPI.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2018 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2018-2020 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
@@ -179,7 +179,7 @@
LOCATION_ERROR_SUCCESS if session was successful
LOCATION_ERROR_INVALID_PARAMETER if any other parameters are invalid
LOCATION_ERROR_GENERAL_FAILURE if failure for any other reason */
- virtual uint32_t* gnssUpdateConfig(GnssConfig config) = 0;
+ virtual uint32_t* gnssUpdateConfig(const GnssConfig& config) = 0;
/** @brief Delete specific gnss aiding data for testing, which returns a session id
that will be returned in responseCallback to match command with response.
@@ -191,27 +191,17 @@
virtual uint32_t gnssDeleteAidingData(GnssAidingData& data) = 0;
/** @brief
- Reset the constellation settings to modem default.
-
- @param
- None
-
- @return
- A session id that will be returned in responseCallback to
- match command with response. This effect is global for all
- clients of LocationAPI responseCallback returns:
- LOCATION_ERROR_SUCCESS if successful
- LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
- */
- virtual uint32_t resetConstellationConfig() = 0;
-
- /** @brief
- Configure the constellation to be used by the GNSS engine on
+ Configure the constellation and SVs to be used by the GNSS engine on
modem.
@param
- constellationConfig: specify the constellation configuration
- used by GNSS engine.
+ constellationEnablementConfig: configuration to enable/disable SV
+ constellation to be used by SPE engine. When size in
+ constellationEnablementConfig is set to 0, this indicates to reset SV
+ constellation configuration to modem NV default.
+
+ blacklistSvConfig: configuration to blacklist or unblacklist SVs
+ used by SPE engine
@return
A session id that will be returned in responseCallback to
@@ -221,8 +211,26 @@
LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
*/
virtual uint32_t configConstellations(
- const GnssSvTypeConfig& svTypeConfig,
- const GnssSvIdConfig& svIdConfig) = 0;
+ const GnssSvTypeConfig& constellationEnablementConfig,
+ const GnssSvIdConfig& blacklistSvConfig) = 0;
+
+ /** @brief
+ Configure the secondary band of constellations to be used by
+ the GNSS engine on modem.
+
+ @param
+ secondaryBandConfig: configuration the secondary band usage
+ for SPE engine
+
+ @return
+ A session id that will be returned in responseCallback to
+ match command with response. This effect is global for all
+ clients of LocationAPI responseCallback returns:
+ LOCATION_ERROR_SUCCESS if successful
+ LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
+ */
+ virtual uint32_t configConstellationSecondaryBand(
+ const GnssSvTypeConfig& secondaryBandConfig) = 0;
/** @brief
Enable or disable the constrained time uncertainty feature.
@@ -302,6 +310,97 @@
LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
*/
virtual uint32_t configLeverArm(const LeverArmConfigInfo& configInfo) = 0;
+
+ /** @brief
+ Configure the robust location setting.
+
+ @param
+ enable: true to enable robust location and false to disable
+ robust location.
+
+ @param
+ enableForE911: true to enable robust location when device is on
+ E911 session and false to disable on E911 session.
+ This parameter is only valid if robust location is enabled.
+
+ @return
+ A session id that will be returned in responseCallback to
+ match command with response. This effect is global for all
+ clients of LocationAPI responseCallback returns:
+ LOCATION_ERROR_SUCCESS if successful
+ LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
+ */
+ virtual uint32_t configRobustLocation(bool enable, bool enableForE911) = 0;
+
+ /** @brief
+ Config the minimum GPS week used by modem GNSS engine.
+
+ @param
+ minGpsWeek: minimum GPS week to be used by modem GNSS engine.
+
+ @return
+ A session id that will be returned in responseCallback to
+ match command with response. This effect is global for all
+ clients of LocationAPI responseCallback returns:
+ LOCATION_ERROR_SUCCESS if successful
+ LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
+ */
+ virtual uint32_t configMinGpsWeek(uint16_t minGpsWeek) = 0;
+
+ /** @brief
+ Configure the vehicle body-to-Sensor mount parameters and
+ other parameters for dead reckoning position engine.
+
+ @param
+ dreConfig: vehicle body-to-Sensor mount angles and other
+ parameters.
+
+ @return
+ A session id that will be returned in responseCallback to
+ match command with response. This effect is global for all
+ clients of LocationAPI responseCallback returns:
+ LOCATION_ERROR_SUCCESS if successful
+ LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
+ */
+ virtual uint32_t configDeadReckoningEngineParams(const DeadReckoningEngineConfig& dreConfig)=0;
+
+ /** @brief
+ This API is used to instruct the specified engine to be in
+ the pause/resume state. <br/>
+
+ When the engine is placed in paused state, the engine will
+ stop. If there is an on-going session, engine will no longer
+ produce fixes. In the paused state, calling API to delete
+ aiding data from the paused engine may not have effect.
+ Request to delete Aiding data shall be issued after
+ engine resume. <br/>
+
+ Currently, only DRE engine will support pause/resume
+ request. responseCb() will return not supported when request
+ is made to pause/resume none-DRE engine. <br/>
+
+ Request to pause/resume DRE engine can be made with or
+ without an on-going session. With QDR engine, on resume,
+ GNSS position & heading re-acquisition is needed for DR
+ engine to engage. If DR engine is already in the requested
+ state, the request will be no-op. <br/>
+
+ @param
+ engType: the engine that is instructed to change its run
+ state. <br/>
+
+ engState: the new engine run state that the engine is
+ instructed to be in. <br/>
+
+ @return
+ A session id that will be returned in responseCallback to
+ match command with response. This effect is global for all
+ clients of LocationAPI responseCallback returns:
+ LOCATION_ERROR_SUCCESS if successful
+ LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
+ */
+ virtual uint32_t configEngineRunState(PositioningEngineMask engType,
+ LocEngineRunState engState) = 0;
};
#endif /* ILOCATIONAPI_H */
diff --git a/location/LocationAPI.cpp b/location/LocationAPI.cpp
index 7c125b8..3a50c46 100644
--- a/location/LocationAPI.cpp
+++ b/location/LocationAPI.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2020 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
@@ -39,6 +39,15 @@
typedef const GnssInterface* (getGnssInterface)();
typedef const GeofenceInterface* (getGeofenceInterface)();
typedef const BatchingInterface* (getBatchingInterface)();
+typedef void (createOSFramework)();
+typedef void (destroyOSFramework)();
+
+// GTP services
+typedef uint32_t (setOptInStatusGetter)(bool userConsent, responseCallback* callback);
+typedef void (enableProviderGetter)();
+typedef void (disableProviderGetter)();
+typedef void (getSingleNetworkLocationGetter)(trackingCallback* callback);
+typedef void (stopNetworkLocationGetter)(trackingCallback* callback);
typedef struct {
// bit mask of the adpaters that we need to wait for the removeClientCompleteCallback
@@ -68,6 +77,7 @@
static bool gGnssLoadFailed = false;
static bool gBatchingLoadFailed = false;
static bool gGeofenceLoadFailed = false;
+static uint32_t gOSFrameworkRefCount = 0;
template <typename T1, typename T2>
static const T1* loadLocationInterface(const char* library, const char* name) {
@@ -80,13 +90,49 @@
}
}
+static void createOSFrameworkInstance() {
+ void* libHandle = nullptr;
+ createOSFramework* getter = (createOSFramework*)dlGetSymFromLib(libHandle,
+ "liblocationservice_glue.so", "createOSFramework");
+ if (getter != nullptr) {
+ (*getter)();
+ } else {
+ LOC_LOGe("dlGetSymFromLib failed for liblocationservice_glue.so");
+ }
+}
+
+static void destroyOSFrameworkInstance() {
+ void* libHandle = nullptr;
+ destroyOSFramework* getter = (destroyOSFramework*)dlGetSymFromLib(libHandle,
+ "liblocationservice_glue.so", "destroyOSFramework");
+ if (getter != nullptr) {
+ (*getter)();
+ } else {
+ LOC_LOGe("dlGetSymFromLib failed for liblocationservice_glue.so");
+ }
+}
+
+static bool needsGnssTrackingInfo(LocationCallbacks& locationCallbacks)
+{
+ return (locationCallbacks.gnssLocationInfoCb != nullptr ||
+ locationCallbacks.engineLocationsInfoCb != nullptr ||
+ locationCallbacks.gnssSvCb != nullptr ||
+ locationCallbacks.gnssNmeaCb != nullptr ||
+ locationCallbacks.gnssDataCb != nullptr ||
+ locationCallbacks.gnssMeasurementsCb != nullptr);
+}
+
static bool isGnssClient(LocationCallbacks& locationCallbacks)
{
return (locationCallbacks.gnssNiCb != nullptr ||
locationCallbacks.trackingCb != nullptr ||
locationCallbacks.gnssLocationInfoCb != nullptr ||
locationCallbacks.engineLocationsInfoCb != nullptr ||
- locationCallbacks.gnssMeasurementsCb != nullptr);
+ locationCallbacks.gnssSvCb != nullptr ||
+ locationCallbacks.gnssNmeaCb != nullptr ||
+ locationCallbacks.gnssDataCb != nullptr ||
+ locationCallbacks.gnssMeasurementsCb != nullptr ||
+ locationCallbacks.locationSystemInfoCb != nullptr);
}
static bool isBatchingClient(LocationCallbacks& locationCallbacks)
@@ -118,10 +164,11 @@
}
pthread_mutex_unlock(&gDataMutex);
- if ((true == invokeCallback) && (nullptr != destroyCompleteCb)) {
+ if (invokeCallback) {
LOC_LOGd("invoke client destroy cb");
- (destroyCompleteCb) ();
- LOC_LOGd("finish invoke client destroy cb");
+ if (!destroyCompleteCb) {
+ (destroyCompleteCb) ();
+ }
delete this;
}
@@ -143,11 +190,12 @@
}
LocationAPI*
-LocationAPI::createInstance(LocationCallbacks& locationCallbacks)
+LocationAPI::createInstance (LocationCallbacks& locationCallbacks)
{
if (nullptr == locationCallbacks.capabilitiesCb ||
nullptr == locationCallbacks.responseCb ||
nullptr == locationCallbacks.collectiveResponseCb) {
+ LOC_LOGe("missing mandatory callback, return null");
return NULL;
}
@@ -156,6 +204,11 @@
pthread_mutex_lock(&gDataMutex);
+ gOSFrameworkRefCount++;
+ if (1 == gOSFrameworkRefCount) {
+ createOSFrameworkInstance();
+ }
+
if (isGnssClient(locationCallbacks)) {
if (NULL == gData.gnssInterface && !gGnssLoadFailed) {
gData.gnssInterface =
@@ -234,15 +287,12 @@
pthread_mutex_lock(&gDataMutex);
auto it = gData.clientData.find(this);
if (it != gData.clientData.end()) {
- bool removeFromGnssInf =
- (isGnssClient(it->second) && NULL != gData.gnssInterface);
- bool removeFromBatchingInf =
- (isBatchingClient(it->second) && NULL != gData.batchingInterface);
- bool removeFromGeofenceInf =
- (isGeofenceClient(it->second) && NULL != gData.geofenceInterface);
+ bool removeFromGnssInf = (NULL != gData.gnssInterface);
+ bool removeFromBatchingInf = (NULL != gData.batchingInterface);
+ bool removeFromGeofenceInf = (NULL != gData.geofenceInterface);
bool needToWait = (removeFromGnssInf || removeFromBatchingInf || removeFromGeofenceInf);
LOC_LOGe("removeFromGnssInf: %d, removeFromBatchingInf: %d, removeFromGeofenceInf: %d,"
- "need %d", removeFromGnssInf, removeFromBatchingInf, removeFromGeofenceInf,
+ "needToWait: %d", removeFromGnssInf, removeFromBatchingInf, removeFromGeofenceInf,
needToWait);
if ((NULL != destroyCompleteCb) && (true == needToWait)) {
@@ -258,7 +308,7 @@
destroyCbData.waitAdapterMask |=
(removeFromGeofenceInf ? LOCATION_ADAPTER_GEOFENCE_TYPE_BIT : 0);
gData.destroyClientData[this] = destroyCbData;
- LOC_LOGe("destroy data stored in the map: 0x%x", destroyCbData.waitAdapterMask);
+ LOC_LOGi("destroy data stored in the map: 0x%x", destroyCbData.waitAdapterMask);
}
if (removeFromGnssInf) {
@@ -276,7 +326,7 @@
gData.clientData.erase(it);
- if ((NULL != destroyCompleteCb) && (false == needToWait)) {
+ if (!needToWait) {
invokeDestroyCb = true;
}
} else {
@@ -284,9 +334,16 @@
__func__, __LINE__, this);
}
+ if (1 == gOSFrameworkRefCount) {
+ destroyOSFrameworkInstance();
+ }
+ gOSFrameworkRefCount--;
+
pthread_mutex_unlock(&gDataMutex);
- if (invokeDestroyCb == true) {
- (destroyCompleteCb) ();
+ if (invokeDestroyCb) {
+ if (!destroyCompleteCb) {
+ (destroyCompleteCb) ();
+ }
delete this;
}
}
@@ -592,6 +649,52 @@
pthread_mutex_unlock(&gDataMutex);
}
+void LocationAPI::enableNetworkProvider() {
+ void* libHandle = nullptr;
+ enableProviderGetter* setter = (enableProviderGetter*)dlGetSymFromLib(libHandle,
+ "liblocationservice_glue.so", "enableNetworkProvider");
+ if (setter != nullptr) {
+ (*setter)();
+ } else {
+ LOC_LOGe("dlGetSymFromLib failed for liblocationservice_glue.so");
+ }
+}
+
+void LocationAPI::disableNetworkProvider() {
+ void* libHandle = nullptr;
+ disableProviderGetter* setter = (disableProviderGetter*)dlGetSymFromLib(libHandle,
+ "liblocationservice_glue.so", "disableNetworkProvider");
+ if (setter != nullptr) {
+ (*setter)();
+ } else {
+ LOC_LOGe("dlGetSymFromLib failed for liblocationservice_glue.so");
+ }
+}
+
+void LocationAPI::startNetworkLocation(trackingCallback* callback) {
+ void* libHandle = nullptr;
+ getSingleNetworkLocationGetter* setter =
+ (getSingleNetworkLocationGetter*)dlGetSymFromLib(libHandle,
+ "liblocationservice_glue.so", "startNetworkLocation");
+ if (setter != nullptr) {
+ (*setter)(callback);
+ } else {
+ LOC_LOGe("dlGetSymFromLib failed for liblocationservice_glue.so");
+ }
+}
+
+void LocationAPI::stopNetworkLocation(trackingCallback* callback) {
+ void* libHandle = nullptr;
+ stopNetworkLocationGetter* setter = (stopNetworkLocationGetter*)dlGetSymFromLib(libHandle,
+ "liblocationservice_glue.so", "stopNetworkLocation");
+ if (setter != nullptr) {
+ LOC_LOGe("called");
+ (*setter)(callback);
+ } else {
+ LOC_LOGe("dlGetSymFromLib failed for liblocationservice_glue.so");
+ }
+}
+
LocationControlAPI*
LocationControlAPI::createInstance(LocationControlCallbacks& locationControlCallbacks)
{
@@ -676,7 +779,7 @@
}
uint32_t*
-LocationControlAPI::gnssUpdateConfig(GnssConfig config)
+LocationControlAPI::gnssUpdateConfig(const GnssConfig& config)
{
uint32_t* ids = NULL;
pthread_mutex_lock(&gDataMutex);
@@ -724,12 +827,15 @@
return id;
}
-uint32_t LocationControlAPI::resetConstellationConfig() {
+uint32_t LocationControlAPI::configConstellations(
+ const GnssSvTypeConfig& constellationEnablementConfig,
+ const GnssSvIdConfig& blacklistSvConfig) {
uint32_t id = 0;
pthread_mutex_lock(&gDataMutex);
if (gData.gnssInterface != NULL) {
- id = gData.gnssInterface->gnssResetSvConfig();
+ id = gData.gnssInterface->gnssUpdateSvConfig(
+ constellationEnablementConfig, blacklistSvConfig);
} else {
LOC_LOGe("No gnss interface available for Location Control API");
}
@@ -738,15 +844,13 @@
return id;
}
-uint32_t LocationControlAPI::configConstellations(
- const GnssSvTypeConfig& svTypeConfig,
- const GnssSvIdConfig& svIdConfig) {
+uint32_t LocationControlAPI::configConstellationSecondaryBand(
+ const GnssSvTypeConfig& secondaryBandConfig) {
uint32_t id = 0;
pthread_mutex_lock(&gDataMutex);
if (gData.gnssInterface != NULL) {
- id = gData.gnssInterface->gnssUpdateSvConfig(
- svTypeConfig, svIdConfig);
+ id = gData.gnssInterface->gnssUpdateSecondaryBandConfig(secondaryBandConfig);
} else {
LOC_LOGe("No gnss interface available for Location Control API");
}
@@ -799,3 +903,74 @@
pthread_mutex_unlock(&gDataMutex);
return id;
}
+
+uint32_t LocationControlAPI::configRobustLocation(bool enable, bool enableForE911) {
+ uint32_t id = 0;
+ pthread_mutex_lock(&gDataMutex);
+
+ if (gData.gnssInterface != NULL) {
+ id = gData.gnssInterface->configRobustLocation(enable, enableForE911);
+ } else {
+ LOC_LOGe("No gnss interface available for Location Control API");
+ }
+
+ pthread_mutex_unlock(&gDataMutex);
+ return id;
+}
+
+uint32_t LocationControlAPI::configMinGpsWeek(uint16_t minGpsWeek) {
+ uint32_t id = 0;
+ pthread_mutex_lock(&gDataMutex);
+
+ if (gData.gnssInterface != NULL) {
+ id = gData.gnssInterface->configMinGpsWeek(minGpsWeek);
+ } else {
+ LOC_LOGe("No gnss interface available for Location Control API");
+ }
+
+ pthread_mutex_unlock(&gDataMutex);
+ return id;
+}
+
+uint32_t LocationControlAPI::configDeadReckoningEngineParams(
+ const DeadReckoningEngineConfig& dreConfig) {
+ uint32_t id = 0;
+ pthread_mutex_lock(&gDataMutex);
+
+ if (gData.gnssInterface != NULL) {
+ id = gData.gnssInterface->configDeadReckoningEngineParams(dreConfig);
+ } else {
+ LOC_LOGe("No gnss interface available for Location Control API");
+ }
+
+ pthread_mutex_unlock(&gDataMutex);
+ return id;
+}
+
+uint32_t LocationControlAPI::configEngineRunState(
+ PositioningEngineMask engType, LocEngineRunState engState) {
+ uint32_t id = 0;
+ pthread_mutex_lock(&gDataMutex);
+
+ if (gData.gnssInterface != NULL) {
+ id = gData.gnssInterface->configEngineRunState(engType, engState);
+ } else {
+ LOC_LOGe("No gnss interface available for Location Control API");
+ }
+
+ pthread_mutex_unlock(&gDataMutex);
+ return id;
+}
+
+uint32_t LocationControlAPI::setOptInStatus(bool userConsent) {
+ void* libHandle = nullptr;
+ uint32_t sessionId = 0;
+ setOptInStatusGetter* setter = (setOptInStatusGetter*)dlGetSymFromLib(libHandle,
+ "liblocationservice_glue.so", "setOptInStatus");
+ if (setter != nullptr) {
+ sessionId = (*setter)(userConsent, &gData.controlCallbacks.responseCb);
+ } else {
+ LOC_LOGe("dlGetSymFromLib failed for liblocationservice_glue.so");
+ }
+ return sessionId;
+}
diff --git a/location/LocationAPI.h b/location/LocationAPI.h
index f70fc2f..7c70506 100644
--- a/location/LocationAPI.h
+++ b/location/LocationAPI.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2020 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
@@ -178,6 +178,20 @@
LOCATION_ERROR_INVALID_PARAMETER if any parameters in GnssNiResponse are invalid
LOCATION_ERROR_ID_UNKNOWN if id does not match a gnssNiCallback */
virtual void gnssNiResponse(uint32_t id, GnssNiResponse response) override;
+
+ /* ================================== NETWORK PROVIDER =========================== */
+
+ /* enableNetworkProvider enables Network Provider */
+ virtual void enableNetworkProvider();
+
+ /* disableNetworkProvider disables Network Provider */
+ virtual void disableNetworkProvider();
+
+ /* startNetworkLocation start a single shot network location request */
+ virtual void startNetworkLocation(trackingCallback* callback);
+
+ /* stopNetworkLocation stop any ongoing network location request */
+ virtual void stopNetworkLocation(trackingCallback* callback);
};
typedef struct {
@@ -235,8 +249,11 @@
collectiveResponseCallback returns:
LOCATION_ERROR_SUCCESS if session was successful
LOCATION_ERROR_INVALID_PARAMETER if any other parameters are invalid
- LOCATION_ERROR_GENERAL_FAILURE if failure for any other reason */
- virtual uint32_t* gnssUpdateConfig(GnssConfig config) override;
+ LOCATION_ERROR_GENERAL_FAILURE if failure for any other reason
+
+ PLEASE NOTE: It is caller's resposibility to FREE the memory of the return value.
+ The memory must be freed by delete [].*/
+ virtual uint32_t* gnssUpdateConfig(const GnssConfig& config) override;
/* gnssGetConfig fetches the current constellation and SV configuration
on the GNSS engine.
@@ -250,7 +267,10 @@
LOCATION_ERROR_CALLBACK_MISSING If no gnssConfigCallback
was passed in createInstance
LOCATION_ERROR_NOT_SUPPORTED If read of requested configuration
- is not supported */
+ is not supported
+
+ PLEASE NOTE: It is caller's resposibility to FREE the memory of the return value.
+ The memory must be freed by delete [].*/
uint32_t* gnssGetConfig(GnssConfigFlagsMask mask);
/* delete specific gnss aiding data for testing, which returns a session id
@@ -263,27 +283,17 @@
virtual uint32_t gnssDeleteAidingData(GnssAidingData& data) override;
/** @brief
- Reset the constellation settings to modem default.
-
- @param
- None
-
- @return
- A session id that will be returned in responseCallback to
- match command with response. This effect is global for all
- clients of LocationAPI responseCallback returns:
- LOCATION_ERROR_SUCCESS if successful
- LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
- */
- virtual uint32_t resetConstellationConfig() override;
-
- /** @brief
- Configure the constellation to be used by the GNSS engine on
+ Configure the constellation and SVs to be used by the GNSS engine on
modem.
@param
- constellationConfig: specify the constellation configuration
- used by GNSS engine.
+ constellationEnablementConfig: configuration to enable/disable SV
+ constellation to be used by SPE engine. When size in
+ constellationEnablementConfig is set to 0, this indicates to reset SV
+ constellation configuration to modem NV default.
+
+ blacklistSvConfig: configuration to blacklist or unblacklist SVs
+ used by SPE engine
@return
A session id that will be returned in responseCallback to
@@ -293,8 +303,26 @@
LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
*/
virtual uint32_t configConstellations(
- const GnssSvTypeConfig& svTypeConfig,
- const GnssSvIdConfig& svIdConfig) override;
+ const GnssSvTypeConfig& constellationEnablementConfig,
+ const GnssSvIdConfig& blacklistSvConfig) override;
+
+ /** @brief
+ Configure the secondary band of constellations to be used by
+ the GNSS engine on modem.
+
+ @param
+ secondaryBandConfig: configuration the secondary band usage
+ for SPE engine
+
+ @return
+ A session id that will be returned in responseCallback to
+ match command with response. This effect is global for all
+ clients of LocationAPI responseCallback returns:
+ LOCATION_ERROR_SUCCESS if successful
+ LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
+ */
+ virtual uint32_t configConstellationSecondaryBand(
+ const GnssSvTypeConfig& secondaryBandConfig) override;
/** @brief
Enable or disable the constrained time uncertainty feature.
@@ -374,6 +402,111 @@
LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
*/
virtual uint32_t configLeverArm(const LeverArmConfigInfo& configInfo) override;
+
+ /** @brief
+ Configure the robust location setting.
+
+ @param
+ enable: true to enable robust location and false to disable
+ robust location.
+
+ @param
+ enableForE911: true to enable robust location when device is
+ on E911 session and false to disable on E911 session.
+ This parameter is only valid if robust location is enabled.
+
+ @return
+ A session id that will be returned in responseCallback to
+ match command with response. This effect is global for all
+ clients of LocationAPI responseCallback returns:
+ LOCATION_ERROR_SUCCESS if successful
+ LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
+ */
+ virtual uint32_t configRobustLocation(bool enable, bool enableForE911) override;
+
+ /** @brief
+ Config the minimal GPS week used by modem GNSS engine.
+
+ @param
+ minGpsWeek: minimal GPS week to be used by modem GNSS engine.
+
+ @return
+ A session id that will be returned in responseCallback to
+ match command with response. This effect is global for all
+ clients of LocationAPI responseCallback returns:
+ LOCATION_ERROR_SUCCESS if successful
+ LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
+ */
+ virtual uint32_t configMinGpsWeek(uint16_t minGpsWeek) override;
+
+ /** @brief
+ Configure the vehicle body-to-Sensor mount parameters and
+ other parameters for dead reckoning position engine.
+
+ @param
+ dreConfig: vehicle body-to-Sensor mount angles and other
+ parameters.
+
+ @return
+ A session id that will be returned in responseCallback to
+ match command with response. This effect is global for all
+ clients of LocationAPI responseCallback returns:
+ LOCATION_ERROR_SUCCESS if successful
+ LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
+ */
+ virtual uint32_t configDeadReckoningEngineParams(
+ const DeadReckoningEngineConfig& dreConfig) override;
+
+ /** @brief
+ This API is used to instruct the specified engine to be in
+ the pause/resume state. <br/>
+
+ When the engine is placed in paused state, the engine will
+ stop. If there is an on-going session, engine will no longer
+ produce fixes. In the paused state, calling API to delete
+ aiding data from the paused engine may not have effect.
+ Request to delete Aiding data shall be issued after
+ engine resume. <br/>
+
+ Currently, only DRE engine will support pause/resume
+ request. responseCb() will return not supported when request
+ is made to pause/resume none-DRE engine. <br/>
+
+ Request to pause/resume DRE engine can be made with or
+ without an on-going session. With QDR engine, on resume, GNSS
+ position & heading re-acquisition is needed for DR engine to
+ engage. If DR engine is already in the requested state, the
+ request will be no-op. <br/>
+
+ @param
+ engType: the engine that is instructed to change its run
+ state. <br/>
+
+ engState: the new engine run state that the engine is
+ instructed to be in. <br/>
+
+ @return
+ A session id that will be returned in responseCallback to
+ match command with response. This effect is global for all
+ clients of LocationAPI responseCallback returns:
+ LOCATION_ERROR_SUCCESS if successful
+ LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
+ */
+ virtual uint32_t configEngineRunState(PositioningEngineMask engType,
+ LocEngineRunState engState) override;
+
+ /** @brief
+ Set the EULA opt-in status from system user. This is used as consent to
+ use network-based positioning.
+
+ @param
+ userConsnt: user agrees to use GTP service or not.
+
+ @return
+ A session id that will be returned in responseCallback to
+ match command with response.
+ */
+ virtual uint32_t setOptInStatus(bool userConsent);
};
#endif /* LOCATIONAPI_H */
diff --git a/location/LocationAPIClientBase.cpp b/location/LocationAPIClientBase.cpp
index 5a09712..ea15a76 100644
--- a/location/LocationAPIClientBase.cpp
+++ b/location/LocationAPIClientBase.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017, 2020-2021 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
@@ -158,6 +158,7 @@
}
mRequestQueues[CTRL_REQUEST_CONFIG_UPDATE].push(new GnssUpdateConfigRequest(*this));
retVal = LOCATION_ERROR_SUCCESS;
+ delete [] idArray;
}
}
}
@@ -180,6 +181,7 @@
}
mRequestQueues[CTRL_REQUEST_CONFIG_GET].push(new GnssGetConfigRequest(*this));
retVal = LOCATION_ERROR_SUCCESS;
+ delete [] idArray;
}
}
pthread_mutex_unlock(&mMutex);
@@ -310,26 +312,45 @@
pthread_mutex_unlock(&mMutex);
}
-LocationAPIClientBase::~LocationAPIClientBase()
+void LocationAPIClientBase::destroy()
{
+ LOC_LOGD("LocationAPIClientBase::destroy()");
+
pthread_mutex_lock(&mMutex);
mGeofenceBreachCallback = nullptr;
- if (mLocationAPI) {
- mLocationAPI->destroy();
- mLocationAPI = nullptr;
- }
-
for (int i = 0; i < REQUEST_MAX; i++) {
mRequestQueues[i].reset((uint32_t)0);
}
+ LocationAPI* localHandle = nullptr;
+ if (nullptr != mLocationAPI) {
+ localHandle = mLocationAPI;
+ mLocationAPI = nullptr;
+ }
+
pthread_mutex_unlock(&mMutex);
+ // Invoking destroy has the possibility of destroy complete callback
+ // being invoked right away in the same context, hence no instance
+ // member must be accessed after the destroy call.
+ if (nullptr != localHandle) {
+ localHandle->destroy([this]() {onLocationApiDestroyCompleteCb();});
+ }
+}
+
+LocationAPIClientBase::~LocationAPIClientBase()
+{
pthread_mutex_destroy(&mMutex);
}
+void LocationAPIClientBase::onLocationApiDestroyCompleteCb()
+{
+ LOC_LOGD("LocationAPIClientBase::onLocationApiDestroyCompleteCb()");
+ delete this;
+}
+
uint32_t LocationAPIClientBase::locAPIStartTracking(TrackingOptions& options)
{
uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
@@ -613,7 +634,7 @@
}
} else {
retVal = LOCATION_ERROR_ID_UNKNOWN;
- LOC_LOGE("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__, id);
+ LOC_LOGd("unknown session id: %d, might flush() a stopped session", id);
}
}
pthread_mutex_unlock(&mMutex);
@@ -799,7 +820,9 @@
void LocationAPIClientBase::locAPIRemoveAllGeofences()
{
std::vector<uint32_t> sessionsVec = mGeofenceBiDict.getAllSessions();
- locAPIRemoveGeofences(sessionsVec.size(), &sessionsVec[0]);
+ if (sessionsVec.size() > 0) {
+ locAPIRemoveGeofences(sessionsVec.size(), &sessionsVec[0]);
+ }
}
void LocationAPIClientBase::locAPIGnssNiResponse(uint32_t id, GnssNiResponse response)
diff --git a/location/LocationAPIClientBase.h b/location/LocationAPIClientBase.h
index 098000c..ac1ebe6 100644
--- a/location/LocationAPIClientBase.h
+++ b/location/LocationAPIClientBase.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2020 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
@@ -200,10 +200,12 @@
class LocationAPIClientBase {
public:
LocationAPIClientBase();
- virtual ~LocationAPIClientBase();
LocationAPIClientBase(const LocationAPIClientBase&) = delete;
LocationAPIClientBase& operator=(const LocationAPIClientBase&) = delete;
+ void destroy();
+ void onLocationApiDestroyCompleteCb();
+
void locAPISetCallbacks(LocationCallbacks& locationCallbacks);
void removeSession(uint32_t session);
LocationAPIRequest* getRequestBySession(uint32_t session);
@@ -283,6 +285,9 @@
inline virtual void onLocationSystemInfoCb(LocationSystemInfo /*locationSystemInfo*/) {}
+protected:
+ virtual ~LocationAPIClientBase();
+
private:
// private inner classes
typedef struct {
diff --git a/location/LocationDataTypes.h b/location/LocationDataTypes.h
index 65b5e13..b85464a 100644
--- a/location/LocationDataTypes.h
+++ b/location/LocationDataTypes.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2018-2020 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,10 +34,11 @@
#include <functional>
#include <list>
#include <string.h>
+#include <string>
#define GNSS_NI_REQUESTOR_MAX (256)
#define GNSS_NI_MESSAGE_ID_MAX (2048)
-#define GNSS_SV_MAX (176)
+#define GNSS_SV_MAX (128)
#define GNSS_MEASUREMENTS_MAX (128)
#define GNSS_UTC_TIME_OFFSET (3657)
@@ -60,7 +61,8 @@
LOCATION_ERROR_ID_UNKNOWN,
LOCATION_ERROR_ALREADY_STARTED,
LOCATION_ERROR_GEOFENCES_AT_MAX,
- LOCATION_ERROR_NOT_SUPPORTED
+ LOCATION_ERROR_NOT_SUPPORTED,
+ LOCATION_ERROR_TIMEOUT,
} LocationError;
// Flags to indicate which values are valid in a Location
@@ -75,14 +77,25 @@
LOCATION_HAS_SPEED_ACCURACY_BIT = (1<<6), // location has valid speed accuracy
LOCATION_HAS_BEARING_ACCURACY_BIT = (1<<7), // location has valid bearing accuracy
LOCATION_HAS_SPOOF_MASK = (1<<8), // location has valid spoof mask
+ LOCATION_HAS_ELAPSED_REAL_TIME = (1<<9), // location has valid elapsed real time
+ LOCATION_HAS_CONFORMITY_INDEX_BIT = (1<<10), // location has valid conformity index
} LocationFlagsBits;
typedef uint16_t LocationTechnologyMask;
+// mask indicating location calculations including...
typedef enum {
- LOCATION_TECHNOLOGY_GNSS_BIT = (1<<0), // location was calculated using GNSS
- LOCATION_TECHNOLOGY_CELL_BIT = (1<<1), // location was calculated using Cell
- LOCATION_TECHNOLOGY_WIFI_BIT = (1<<2), // location was calculated using WiFi
- LOCATION_TECHNOLOGY_SENSORS_BIT = (1<<3), // location was calculated using Sensors
+ LOCATION_TECHNOLOGY_GNSS_BIT = (1<<0), // using GNSS
+ LOCATION_TECHNOLOGY_CELL_BIT = (1<<1), // using Cell
+ LOCATION_TECHNOLOGY_WIFI_BIT = (1<<2), // using WiFi
+ LOCATION_TECHNOLOGY_SENSORS_BIT = (1<<3), // using Sensors
+ LOCATION_TECHNOLOGY_REFERENCE_LOCATION_BIT = (1<<4), // using reference location
+ LOCATION_TECHNOLOGY_INJECTED_COARSE_POSITION_BIT = (1<<5), // using CPI
+ LOCATION_TECHNOLOGY_AFLT_BIT = (1<<6), // AFLT
+ LOCATION_TECHNOLOGY_HYBRID_BIT = (1<<7), // HYBRID
+ LOCATION_TECHNOLOGY_PPE_BIT = (1<<8), // PPE
+ LOCATION_TECHNOLOGY_VEH_BIT = (1<<9), // using vehicular data
+ LOCATION_TECHNOLOGY_VIS_BIT = (1<<10), // using visual data
+ LOCATION_TECHNOLOGY_DGNSS_BIT = (1<<11), // DGNSS
} LocationTechnologyBits;
typedef uint32_t LocationSpoofMask;
@@ -102,29 +115,26 @@
typedef uint32_t GnssLocationNavSolutionMask;
typedef enum {
- LOCATION_SBAS_CORRECTION_IONO_BIT = (1<<0), // SBAS ionospheric correction is used
- LOCATION_SBAS_CORRECTION_FAST_BIT = (1<<1), // SBAS fast correction is used
- LOCATION_SBAS_CORRECTION_LONG_BIT = (1<<2), // SBAS long-tem correction is used
- LOCATION_SBAS_INTEGRITY_BIT = (1<<3), // SBAS integrity information is used
- LOCATION_NAV_CORRECTION_DGNSS_BIT = (1<<4), // Position Report is DGNSS corrected
- LOCATION_NAV_CORRECTION_RTK_BIT = (1<<5), // Position Report is RTK corrected
- LOCATION_NAV_CORRECTION_PPP_BIT = (1<<6) // Position Report is PPP corrected
+ // SBAS ionospheric correction is used
+ LOCATION_SBAS_CORRECTION_IONO_BIT = (1<<0),
+ // SBAS fast correction is used
+ LOCATION_SBAS_CORRECTION_FAST_BIT = (1<<1),
+ // SBAS long-tem correction is used
+ LOCATION_SBAS_CORRECTION_LONG_BIT = (1<<2),
+ // SBAS integrity information is used
+ LOCATION_SBAS_INTEGRITY_BIT = (1<<3),
+ // Position Report is DGNSS corrected
+ LOCATION_NAV_CORRECTION_DGNSS_BIT = (1<<4),
+ // Position Report is RTK corrected
+ LOCATION_NAV_CORRECTION_RTK_BIT = (1<<5),
+ // Position Report is PPP corrected
+ LOCATION_NAV_CORRECTION_PPP_BIT = (1<<6),
+ // Posiiton Report is RTF fixed corrected
+ LOCATION_NAV_CORRECTION_RTK_FIXED_BIT = (1<<7),
+ // Position report is computed with only SBAS corrected SVs.
+ LOCATION_NAV_CORRECTION_ONLY_SBAS_CORRECTED_SV_USED_BIT = (1<<8)
} GnssLocationNavSolutionBits;
-typedef uint32_t GnssLocationPosTechMask;
-typedef enum {
- LOCATION_POS_TECH_DEFAULT_BIT = 0,
- LOCATION_POS_TECH_SATELLITE_BIT = (1<<0),
- LOCATION_POS_TECH_CELLID_BIT = (1<<1),
- LOCATION_POS_TECH_WIFI_BIT = (1<<2),
- LOCATION_POS_TECH_SENSORS_BIT = (1<<3),
- LOCATION_POS_TECH_REFERENCE_LOCATION_BIT = (1<<4),
- LOCATION_POS_TECH_INJECTED_COARSE_POSITION_BIT = (1<<5),
- LOCATION_POS_TECH_AFLT_BIT = (1<<6),
- LOCATION_POS_TECH_HYBRID_BIT = (1<<7),
- LOCATION_POS_TECH_PPE_BIT = (1<<8)
-} GnssLocationPosTechBits;
-
typedef uint32_t GnssLocationPosDataMask;
typedef enum {
LOCATION_NAV_DATA_HAS_LONG_ACCEL_BIT = (1<<0), // Navigation data has Forward Acceleration
@@ -144,39 +154,65 @@
LOCATION_NAV_DATA_HAS_PITCH_UNC_BIT = (1<<9)
} GnssLocationPosDataBits;
-typedef uint32_t GnssLocationInfoFlagMask;
+typedef uint32_t GnssLocationPosDataMaskExt;
typedef enum {
- GNSS_LOCATION_INFO_ALTITUDE_MEAN_SEA_LEVEL_BIT = (1<<0), // valid altitude mean sea level
- GNSS_LOCATION_INFO_DOP_BIT = (1<<1), // valid pdop, hdop, and vdop
- GNSS_LOCATION_INFO_MAGNETIC_DEVIATION_BIT = (1<<2), // valid magnetic deviation
- GNSS_LOCATION_INFO_HOR_RELIABILITY_BIT = (1<<3), // valid horizontal reliability
- GNSS_LOCATION_INFO_VER_RELIABILITY_BIT = (1<<4), // valid vertical reliability
- GNSS_LOCATION_INFO_HOR_ACCURACY_ELIP_SEMI_MAJOR_BIT = (1<<5), // valid elipsode semi major
- GNSS_LOCATION_INFO_HOR_ACCURACY_ELIP_SEMI_MINOR_BIT = (1<<6), // valid elipsode semi minor
- GNSS_LOCATION_INFO_HOR_ACCURACY_ELIP_AZIMUTH_BIT = (1<<7), // valid accuracy elipsode azimuth
- GNSS_LOCATION_INFO_GNSS_SV_USED_DATA_BIT = (1<<8), // valid svUsedInPosition,
- // numOfMeasReceived
- // and measUsageInfo
- GNSS_LOCATION_INFO_NAV_SOLUTION_MASK_BIT = (1<<9), // valid navSolutionMask
- GNSS_LOCATION_INFO_POS_TECH_MASK_BIT = (1<<10),// valid LocPosTechMask
- GNSS_LOCATION_INFO_SV_SOURCE_INFO_BIT = (1<<11),// valid LocSvInfoSource
- GNSS_LOCATION_INFO_POS_DYNAMICS_DATA_BIT = (1<<12),// valid position dynamics data
- GNSS_LOCATION_INFO_EXT_DOP_BIT = (1<<13),// valid gdop, tdop
- GNSS_LOCATION_INFO_NORTH_STD_DEV_BIT = (1<<14),// valid North standard deviation
- GNSS_LOCATION_INFO_EAST_STD_DEV_BIT = (1<<15),// valid East standard deviation
- GNSS_LOCATION_INFO_NORTH_VEL_BIT = (1<<16),// valid North Velocity
- GNSS_LOCATION_INFO_EAST_VEL_BIT = (1<<17),// valid East Velocity
- GNSS_LOCATION_INFO_UP_VEL_BIT = (1<<18),// valid Up Velocity
- GNSS_LOCATION_INFO_NORTH_VEL_UNC_BIT = (1<<19),// valid North Velocity Uncertainty
- GNSS_LOCATION_INFO_EAST_VEL_UNC_BIT = (1<<20),// valid East Velocity Uncertainty
- GNSS_LOCATION_INFO_UP_VEL_UNC_BIT = (1<<21),// valid Up Velocity Uncertainty
- GNSS_LOCATION_INFO_LEAP_SECONDS_BIT = (1<<22),// valid leap seconds
- GNSS_LOCATION_INFO_TIME_UNC_BIT = (1<<23),// valid time uncertainty
- GNSS_LOCATION_INFO_NUM_SV_USED_IN_POSITION_BIT = (1<<24), // number of SV used in position
- GNSS_LOCATION_INFO_CALIBRATION_CONFIDENCE_BIT = (1<<25), // valid sensor cal confidence
- GNSS_LOCATION_INFO_CALIBRATION_STATUS_BIT = (1<<26), // valid sensor cal status
- GNSS_LOCATION_INFO_OUTPUT_ENG_TYPE_BIT = (1<<27), // valid output engine type
- GNSS_LOCATION_INFO_OUTPUT_ENG_MASK_BIT = (1<<28), // valid output engine mask
+ // Navigation data has pitch rate
+ LOCATION_NAV_DATA_HAS_PITCH_RATE_BIT = (1<<0),
+ // Navigation data has body pitch rate uncertainty
+ LOCATION_NAV_DATA_HAS_PITCH_RATE_UNC_BIT = (1<<1),
+ // Navigation data has body roll
+ LOCATION_NAV_DATA_HAS_ROLL_BIT = (1<<2),
+ // Navigation data has body roll uncertainty
+ LOCATION_NAV_DATA_HAS_ROLL_UNC_BIT = (1<<3),
+ // Navigation data has body rate roll
+ LOCATION_NAV_DATA_HAS_ROLL_RATE_BIT = (1<<4),
+ // Navigation data has body roll rate uncertainty
+ LOCATION_NAV_DATA_HAS_ROLL_RATE_UNC_BIT = (1<<5),
+ // Navigation data has body yaw
+ LOCATION_NAV_DATA_HAS_YAW_BIT = (1<<6),
+ // Navigation data has body roll uncertainty
+ LOCATION_NAV_DATA_HAS_YAW_UNC_BIT = (1<<7)
+} GnssLocationPosDataBitsExt;
+
+typedef uint64_t GnssLocationInfoFlagMask;
+typedef enum {
+ GNSS_LOCATION_INFO_ALTITUDE_MEAN_SEA_LEVEL_BIT = (1<<0), // altitude mean sea level
+ GNSS_LOCATION_INFO_DOP_BIT = (1<<1), // pdop, hdop, and vdop
+ GNSS_LOCATION_INFO_MAGNETIC_DEVIATION_BIT = (1<<2), // magnetic deviation
+ GNSS_LOCATION_INFO_HOR_RELIABILITY_BIT = (1<<3), // horizontal reliability
+ GNSS_LOCATION_INFO_VER_RELIABILITY_BIT = (1<<4), // vertical reliability
+ GNSS_LOCATION_INFO_HOR_ACCURACY_ELIP_SEMI_MAJOR_BIT = (1<<5), // elipsode semi major
+ GNSS_LOCATION_INFO_HOR_ACCURACY_ELIP_SEMI_MINOR_BIT = (1<<6), // elipsode semi minor
+ GNSS_LOCATION_INFO_HOR_ACCURACY_ELIP_AZIMUTH_BIT = (1<<7), // accuracy elipsode azimuth
+ GNSS_LOCATION_INFO_GNSS_SV_USED_DATA_BIT = (1<<8), // svUsedInPosition,
+ // numOfMeasReceived
+ // and measUsageInfo
+ GNSS_LOCATION_INFO_NAV_SOLUTION_MASK_BIT = (1<<9), // navSolutionMask
+ GNSS_LOCATION_INFO_SV_SOURCE_INFO_BIT = (1<<10), // LocSvInfoSource
+ GNSS_LOCATION_INFO_POS_DYNAMICS_DATA_BIT = (1<<11), // position dynamics data &
+ // Position Dynamics Ext
+ GNSS_LOCATION_INFO_EXT_DOP_BIT = (1<<12), // gdop, tdop
+ GNSS_LOCATION_INFO_NORTH_STD_DEV_BIT = (1<<13), // North standard deviation
+ GNSS_LOCATION_INFO_EAST_STD_DEV_BIT = (1<<14), // East standard deviation
+ GNSS_LOCATION_INFO_NORTH_VEL_BIT = (1<<15), // North Velocity
+ GNSS_LOCATION_INFO_EAST_VEL_BIT = (1<<16), // East Velocity
+ GNSS_LOCATION_INFO_UP_VEL_BIT = (1<<17), // Up Velocity
+ GNSS_LOCATION_INFO_NORTH_VEL_UNC_BIT = (1<<18), // North Velocity Uncertainty
+ GNSS_LOCATION_INFO_EAST_VEL_UNC_BIT = (1<<19), // East Velocity Uncertainty
+ GNSS_LOCATION_INFO_UP_VEL_UNC_BIT = (1<<20), // Up Velocity Uncertainty
+ GNSS_LOCATION_INFO_LEAP_SECONDS_BIT = (1<<21), // leap seconds
+ GNSS_LOCATION_INFO_TIME_UNC_BIT = (1<<22), // time uncertainty
+ GNSS_LOCATION_INFO_NUM_SV_USED_IN_POSITION_BIT = (1<<23), // number of SV used in position
+ GNSS_LOCATION_INFO_CALIBRATION_CONFIDENCE_BIT = (1<<24), // sensor cal confidence
+ GNSS_LOCATION_INFO_CALIBRATION_STATUS_BIT = (1<<25), // sensor cal status
+ GNSS_LOCATION_INFO_OUTPUT_ENG_TYPE_BIT = (1<<26), // output engine type
+ GNSS_LOCATION_INFO_OUTPUT_ENG_MASK_BIT = (1<<27), // output engine mask
+ GNSS_LOCATION_INFO_CONFORMITY_INDEX_BIT = (1<<28), // conformity index
+ GNSS_LOCATION_INFO_LLA_VRP_BASED_BIT = (1<<29), // VRP-based lat/long/alt
+ GNSS_LOCATION_INFO_ENU_VELOCITY_VRP_BASED_BIT = (1<<30), // VRP-based east/north/up vel
+ GNSS_LOCATION_INFO_DR_SOLUTION_STATUS_MASK_BIT = (1ULL<<31), // Valid DR solution status
+ GNSS_LOCATION_INFO_ALTITUDE_ASSUMED_BIT = (1ULL<<32), // Valid altitude assumed
+ GNSS_LOCATION_INFO_SESSION_STATUS_BIT = (1ULL<<33), // session status
} GnssLocationInfoFlagBits;
typedef enum {
@@ -200,7 +236,8 @@
GEOFENCE_STATUS_AVAILABILE_YES,
} GeofenceStatusAvailable;
-typedef uint32_t LocationCapabilitiesMask;
+// Set of masks for Modem and QWES capabilities.
+typedef uint64_t LocationCapabilitiesMask;
typedef enum {
// supports startTracking API with minInterval param
LOCATION_CAPABILITIES_TIME_BASED_TRACKING_BIT = (1<<0),
@@ -228,8 +265,92 @@
LOCATION_CAPABILITIES_AGPM_BIT = (1<<11),
// support location privacy
LOCATION_CAPABILITIES_PRIVACY_BIT = (1<<12),
+ // support measurement corrections
+ LOCATION_CAPABILITIES_MEASUREMENTS_CORRECTION_BIT = (1<<13),
+ // support Robust Location
+ LOCATION_CAPABILITIES_CONFORMITY_INDEX_BIT = (1<<14),
+ // support precise location edgnss
+ LOCATION_CAPABILITIES_EDGNSS_BIT = (1<<15),
+ // Modem supports Carrier Phase for Precise Positioning
+ // Measurement Engine (PPME).
+ LOCATION_CAPABILITIES_QWES_CARRIER_PHASE_BIT = (1<<16),
+ // Modem supports SV Polynomial for tightly coupled external
+ // DR support. This is a Standalone Feature.
+ LOCATION_CAPABILITIES_QWES_SV_POLYNOMIAL_BIT = (1<<17),
+ // Modem supports SV Ephemeris for tightly coupled external
+ // PPE engines. This is a Standalone Feature.
+ LOCATION_CAPABILITIES_QWES_SV_EPHEMERIS_BIT = (1<<18),
+ // Modem supports GNSS Single Frequency feature. This is a
+ // Standalone Feature.
+ LOCATION_CAPABILITIES_QWES_GNSS_SINGLE_FREQUENCY = (1<<19),
+ // Modem supports GNSS Multi Frequency feature. Multi Frequency
+ // enables Single frequency also.
+ LOCATION_CAPABILITIES_QWES_GNSS_MULTI_FREQUENCY = (1<<20),
+ // This mask indicates VPe license bundle is enabled. VEPP
+ // bundle include Carrier Phase and SV Polynomial features.
+ LOCATION_CAPABILITIES_QWES_VPE = (1<<21),
+ // This mask indicates support for CV2X Location basic features.
+ // This bundle includes features for GTS Time & Freq, C-TUNC
+ // (Constrained Time uncertainity.
+ LOCATION_CAPABILITIES_QWES_CV2X_LOCATION_BASIC = (1<<22),
+ // This mask indicates support for CV2X Location premium features.
+ // This bundle includes features for CV2X Location Basic features,
+ // QDR3 feature, and PACE. (Position Assisted Clock Estimator.
+ LOCATION_CAPABILITIES_QWES_CV2X_LOCATION_PREMIUM = (1<<23),
+ // This mask indicates that PPE (Precise Positioning Engine)
+ // library is enabled or Precise Positioning Framework (PPF)
+ // is available. This bundle includes features for Carrier
+ // Phase and SV Ephermeris.
+ LOCATION_CAPABILITIES_QWES_PPE = (1<<24),
+ // This mask indicates QDR2_C license bundle is enabled. This
+ // bundle includes features for SV Polynomial.
+ LOCATION_CAPABILITIES_QWES_QDR2 = (1<<25),
+ // This mask indicates QDR3_C license bundle is enabled. This
+ // bundle includes features for SV Polynomial.
+ LOCATION_CAPABILITIES_QWES_QDR3 = (1<<26),
} LocationCapabilitiesBits;
+typedef uint8_t LocationQwesFeatureType;
+typedef enum {
+ // Modem supports Carrier Phase for Precise Positioning
+ // Measurement Engine (PPME).
+ LOCATION_QWES_FEATURE_TYPE_CARRIER_PHASE = 1,
+ // Modem supports SV Polynomial for tightly coupled external
+ // DR support. This is a Standalone Feature.
+ LOCATION_QWES_FEATURE_TYPE_SV_POLYNOMIAL,
+ // Modem supports SV Ephemeris for tightly coupled external
+ // PPE support. This is a Standalone Feature.
+ LOCATION_QWES_FEATURE_TYPE_SV_EPH,
+ // Modem supports GNSS Single Frequency feature. This is a
+ // Standalone Feature.
+ LOCATION_QWES_FEATURE_TYPE_GNSS_SINGLE_FREQUENCY,
+ // Modem supports GNSS Multi Frequency feature. Multi Frequency
+ // enables Single frequency also.
+ LOCATION_QWES_FEATURE_TYPE_GNSS_MULTI_FREQUENCY,
+ // This indicates Time and Frequency status.
+ LOCATION_QWES_FEATURE_TYPE_TIME_FREQUENCY,
+ // This indicates Time Uncertainty status.
+ LOCATION_QWES_FEATURE_TYPE_TIME_UNCERTAINTY,
+ // This indicates Clock Estimate status.
+ LOCATION_QWES_FEATURE_TYPE_CLOCK_ESTIMATE,
+ // This mask indicates that PPE (Precise Positioning Engine)
+ // library is enabled or Precise Positioning Framework (PPF)
+ // is available. This bundle includes features for Carrier
+ // Phase and SV Ephermeris.
+ LOCATION_QWES_FEATURE_TYPE_PPE,
+ // This indicates QDR2_C license bundle is enabled. This
+ // bundle includes features for SV Polynomial.
+ LOCATION_QWES_FEATURE_TYPE_QDR2,
+ // This indicates QDR3_C license bundle is enabled. This
+ // bundle includes features for SV Polynomial.
+ LOCATION_QWES_FEATURE_TYPE_QDR3,
+ // This indicates VEPP license bundle is enabled. VEPP
+ // bundle include Carrier Phase and SV Polynomial features.
+ LOCATION_QWES_FEATURE_TYPE_VPE,
+ // Max value
+ LOCATION_QWES_FEATURE_TYPE_MAX
+} LocationQwesFeatureTypes;
+
typedef enum {
LOCATION_TECHNOLOGY_TYPE_GNSS = 0,
} LocationTechnologyType;
@@ -252,12 +373,14 @@
} GnssConfigSuplVersion;
// LTE Positioning Profile
+typedef uint16_t GnssConfigLppProfileMask;
typedef enum {
- GNSS_CONFIG_LPP_PROFILE_RRLP_ON_LTE = 0, // RRLP on LTE (Default)
- GNSS_CONFIG_LPP_PROFILE_USER_PLANE, // LPP User Plane (UP) on LTE
- GNSS_CONFIG_LPP_PROFILE_CONTROL_PLANE, // LPP_Control_Plane (CP)
- GNSS_CONFIG_LPP_PROFILE_USER_PLANE_AND_CONTROL_PLANE, // Both LPP UP and CP
-} GnssConfigLppProfile;
+ GNSS_CONFIG_LPP_PROFILE_RRLP_ON_LTE = 0, // RRLP on LTE (Default)
+ GNSS_CONFIG_LPP_PROFILE_USER_PLANE_BIT = (1<<0), // LPP User Plane (UP) on LTE
+ GNSS_CONFIG_LPP_PROFILE_CONTROL_PLANE_BIT = (1<<1), // LPP_Control_Plane (CP)
+ GNSS_CONFIG_LPP_PROFILE_USER_PLANE_OVER_NR5G_SA_BIT = (1<<2), // LPP User Plane (UP) on LTE
+ GNSS_CONFIG_LPP_PROFILE_CONTROL_PLANE_OVER_NR5G_SA_BIT = (1<<3), // LPP_Control_Plane (CP)
+} GnssConfigLppProfileBits;
// Technology for LPPe Control Plane
typedef uint16_t GnssConfigLppeControlPlaneMask;
@@ -318,6 +441,10 @@
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),
+ GNSS_CONFIG_FLAGS_ROBUST_LOCATION_BIT = (1<<12),
+ GNSS_CONFIG_FLAGS_MIN_GPS_WEEK_BIT = (1<<13),
+ GNSS_CONFIG_FLAGS_MIN_SV_ELEVATION_BIT = (1<<14),
+ GNSS_CONFIG_FLAGS_CONSTELLATION_SECONDARY_BAND_BIT = (1<<15),
} GnssConfigFlagsBits;
typedef enum {
@@ -385,6 +512,7 @@
GNSS_SV_OPTIONS_HAS_ALMANAC_BIT = (1<<1),
GNSS_SV_OPTIONS_USED_IN_FIX_BIT = (1<<2),
GNSS_SV_OPTIONS_HAS_CARRIER_FREQUENCY_BIT = (1<<3),
+ GNSS_SV_OPTIONS_HAS_GNSS_SIGNAL_TYPE_BIT = (1<<4)
} GnssSvOptionsBits;
typedef enum {
@@ -459,6 +587,11 @@
GNSS_MEASUREMENTS_DATA_MULTIPATH_INDICATOR_BIT = (1<<15),
GNSS_MEASUREMENTS_DATA_SIGNAL_TO_NOISE_RATIO_BIT = (1<<16),
GNSS_MEASUREMENTS_DATA_AUTOMATIC_GAIN_CONTROL_BIT = (1<<17),
+ GNSS_MEASUREMENTS_DATA_FULL_ISB_BIT = (1<<18),
+ GNSS_MEASUREMENTS_DATA_FULL_ISB_UNCERTAINTY_BIT = (1<<19),
+ GNSS_MEASUREMENTS_DATA_SATELLITE_ISB_BIT = (1<<20),
+ GNSS_MEASUREMENTS_DATA_SATELLITE_ISB_UNCERTAINTY_BIT = (1<<21),
+ GNSS_MEASUREMENTS_DATA_CYCLE_SLIP_COUNT_BIT = (1<<22),
} GnssMeasurementsDataFlagsBits;
typedef uint32_t GnssMeasurementsStateMask;
@@ -483,6 +616,15 @@
GNSS_MEASUREMENTS_STATE_2ND_CODE_LOCK_BIT = (1<<16),
} GnssMeasurementsStateBits;
+typedef uint16_t GnssSingleSatCorrectionMask;
+typedef enum {
+ GNSS_MEAS_CORR_UNKNOWN_BIT = 0,
+ GNSS_MEAS_CORR_HAS_SAT_IS_LOS_PROBABILITY_BIT = (1 << 0),
+ GNSS_MEAS_CORR_HAS_EXCESS_PATH_LENGTH_BIT = (1 << 1),
+ GNSS_MEAS_CORR_HAS_EXCESS_PATH_LENGTH_UNC_BIT = (1 << 2),
+ GNSS_MEAS_CORR_HAS_REFLECTING_PLANE_BIT = (1 << 3),
+} GnssSingleSatCorrectionBits;
+
typedef enum {
GNSS_MEASUREMENTS_MULTIPATH_INDICATOR_UNKNOWN = 0,
GNSS_MEASUREMENTS_MULTIPATH_INDICATOR_PRESENT,
@@ -500,6 +642,7 @@
GNSS_MEASUREMENTS_CLOCK_FLAGS_DRIFT_BIT = (1<<6),
GNSS_MEASUREMENTS_CLOCK_FLAGS_DRIFT_UNCERTAINTY_BIT = (1<<7),
GNSS_MEASUREMENTS_CLOCK_FLAGS_HW_CLOCK_DISCONTINUITY_COUNT_BIT = (1<<8),
+ GNSS_MEASUREMENTS_CLOCK_FLAGS_ELAPSED_REAL_TIME_BIT = (1<<9),
} GnssMeasurementsClockFlagsBits;
typedef uint32_t GnssAidingDataSvMask;
@@ -527,7 +670,9 @@
GNSS_AIDING_DATA_SV_TYPE_BEIDOU_BIT = (1<<3),
GNSS_AIDING_DATA_SV_TYPE_GALILEO_BIT = (1<<4),
GNSS_AIDING_DATA_SV_TYPE_NAVIC_BIT = (1<<5),
+ GNSS_AIDING_DATA_SV_TYPE_MAX = (1<<6),
} GnssAidingDataSvTypeBits;
+#define GNSS_AIDING_DATA_SV_TYPE_MASK_ALL (GNSS_AIDING_DATA_SV_TYPE_MAX-1)
/* Gnss constellation type mask */
typedef uint16_t GnssConstellationTypeMask;
@@ -538,7 +683,7 @@
GNSS_CONSTELLATION_TYPE_BEIDOU_BIT = (1<<3),
GNSS_CONSTELLATION_TYPE_GALILEO_BIT = (1<<4),
GNSS_CONSTELLATION_TYPE_SBAS_BIT = (1<<5),
- GNSS_CONSTELLATION_TYPE_NAVIC_BIT = (1<<6)
+ GNSS_CONSTELLATION_TYPE_NAVIC_BIT = (1<<6),
} GnssConstellationTypeBits;
#define GNSS_CONSTELLATION_TYPE_MASK_ALL\
@@ -624,7 +769,7 @@
GNSS_LOC_SV_SYSTEM_QZSS = 6,
/**< QZSS satellite. */
GNSS_LOC_SV_SYSTEM_NAVIC = 7,
- /**< QZSS satellite. */
+ /**< NAVIC satellite. */
GNSS_LOC_SV_SYSTEM_MAX = 7,
/**< Max enum of valid SV system. */
} Gnss_LocSvSystemEnumType;
@@ -657,10 +802,22 @@
typedef enum {
STANDARD_POSITIONING_ENGINE = (1 << 0),
DEAD_RECKONING_ENGINE = (1 << 1),
- PRECISE_POSITIONING_ENGINE = (1 << 2)
+ PRECISE_POSITIONING_ENGINE = (1 << 2),
+ VP_POSITIONING_ENGINE = (1 << 3)
} PositioningEngineBits;
#define POSITION_ENGINE_MASK_ALL \
- (STANDARD_POSITIONING_ENGINE|DEAD_RECKONING_ENGINE|PRECISE_POSITIONING_ENGINE)
+ (STANDARD_POSITIONING_ENGINE|DEAD_RECKONING_ENGINE| \
+ PRECISE_POSITIONING_ENGINE|VP_POSITIONING_ENGINE)
+
+/** Specify the position engine running state. <br/> */
+enum LocEngineRunState {
+ /** Request the position engine to be put into resume state.
+ * <br/> */
+ LOC_ENGINE_RUN_STATE_PAUSE = 1,
+ /** Request the position engine to be put into resume state.
+ * <br/> */
+ LOC_ENGINE_RUN_STATE_RESUME = 2,
+};
typedef uint64_t GnssDataMask;
typedef enum {
@@ -710,11 +867,17 @@
GnssAidingDataCommonMask mask; // bitwise OR of GnssAidingDataCommonBits
} GnssAidingDataCommon;
+typedef uint32_t DrEngineAidingDataMask;
+typedef enum {
+ DR_ENGINE_AIDING_DATA_CALIBRATION_BIT = (1<<0), // Calibration data for DRE engine
+} DrEngineAidingDataBits;
+
typedef struct {
bool deleteAll; // if true, delete all aiding data and ignore other params
GnssAidingDataSv sv; // SV specific aiding data
GnssAidingDataCommon common; // common aiding data
- PositioningEngineMask posEngineMask; // engines to perform the delete operation on.
+ DrEngineAidingDataMask dreAidingDataMask;// aiding data mask for dr engine
+ PositioningEngineMask posEngineMask; // engines to perform the delete operation on.
} GnssAidingData;
typedef uint16_t DrCalibrationStatusMask;
@@ -744,14 +907,18 @@
float verticalAccuracy; // in meters
float speedAccuracy; // in meters/second
float bearingAccuracy; // in degrees (0 to 359.999)
+ float conformityIndex; // in range [0, 1]
LocationTechnologyMask techMask;
- LocationSpoofMask spoofMask;
+ LocationSpoofMask spoofMask;
+ uint64_t elapsedRealTime; // in ns
+ uint64_t elapsedRealTimeUnc; // in ns
} Location;
typedef enum {
LOC_REQ_ENGINE_FUSED_BIT = (1<<0),
LOC_REQ_ENGINE_SPE_BIT = (1<<1),
LOC_REQ_ENGINE_PPE_BIT = (1<<2),
+ LOC_REQ_ENGINE_VPE_BIT = (1<<3)
} LocReqEngineTypeMask;
typedef enum {
@@ -760,6 +927,7 @@
LOC_OUTPUT_ENGINE_SPE = 1,
/** This is the GNSS fix with correction PPP/RTK correction */
LOC_OUTPUT_ENGINE_PPE = 2,
+ LOC_OUTPUT_ENGINE_VPE = 3,
LOC_OUTPUT_ENGINE_COUNT,
} LocOutputEngineType;
@@ -882,14 +1050,11 @@
GnssSignalTypeMask gnssSignalType;
/** Specifies GNSS Constellation Type */
Gnss_LocSvSystemEnumType gnssConstellation;
- /** GNSS SV ID.
- For GPS: 1 to 32
- For GLONASS: 65 to 96. When slot-number to SV ID mapping is unknown, set as 255.
- For SBAS: 120 to 151
- For QZSS-L1CA:193 to 197
- For BDS: 201 to 237
- For GAL: 301 to 336
- For NAVIC: 401 to 414 */
+ /** Unique SV Identifier.
+ * For SV Range of supported constellation, please refer to
+ * the comment section of svId in GnssSv.
+ * For GLONASS: When slot-number to SV ID mapping is unknown, set as 255.
+ */
uint16_t gnssSvId;
} GnssMeasUsageInfo;
@@ -911,6 +1076,18 @@
} GnssLocationPositionDynamics;
typedef struct {
+ GnssLocationPosDataMaskExt bodyFrameDataMask; // Contains Ext Body frame LocPosDataMask bits
+ float pitchRate; // Body pitch rate (Radians/second)
+ float pitchRateUnc; // Uncertainty of pitch rate (Radians/second)
+ float roll; // Roll of body frame. Clockwise positive. (radian
+ float rollUnc; // Uncertainty of Roll, 68% confidence level (radian)
+ float rollRate; // Roll rate of body frame. Clockwise positive. (radian/second)
+ float rollRateUnc; // Uncertainty of Roll rate, 68% confidence level (radian/second)
+ float yaw; // Yaw of body frame. Clockwise positive (radian)
+ float yawUnc; // Uncertainty of Yaw, 68% confidence level (radian)
+} GnssLocationPositionDynamicsExt;
+
+typedef struct {
/** Validity mask for below fields */
GnssSystemTimeStructTypeFlags validityMask;
/** Extended week number at reference tick.
@@ -999,6 +1176,22 @@
SystemTimeStructUnion u;
} GnssSystemTime;
+typedef uint32_t DrSolutionStatusMask;
+#define VEHICLE_SENSOR_SPEED_INPUT_DETECTED (1<<0)
+#define VEHICLE_SENSOR_SPEED_INPUT_USED (1<<1)
+
+typedef struct {
+ double latitude; // in degree
+ double longitude; // in degree
+ float altitude; // altitude wrt to ellipsoid
+} LLAInfo;
+
+enum loc_sess_status {
+ LOC_SESS_SUCCESS,
+ LOC_SESS_INTERMEDIATE,
+ LOC_SESS_FAILURE
+};
+
typedef struct {
uint32_t size; // set to sizeof(GnssLocationInfo)
Location location; // basic locaiton info, latitude, longitude, and etc
@@ -1026,7 +1219,6 @@
uint16_t numSvUsedInPosition;
GnssLocationSvUsedInPosition svUsedInPosition;// Gnss sv used in position data
GnssLocationNavSolutionMask navSolutionMask; // Nav solution mask to indicate sbas corrections
- GnssLocationPosTechMask posTechMask; // Position technology used in computing this fix
GnssLocationPositionDynamics bodyFrameData; // Body Frame Dynamics: 4wayAcceleration and
// pitch set with validity
GnssSystemTime gnssSystemTime; // GNSS System Time
@@ -1040,12 +1232,27 @@
// location engine type. When the fix. when the type is set to
// LOC_ENGINE_SRC_FUSED, the fix is the propagated/aggregated
// reports from all engines running on the system (e.g.:
- // DR/SPE/PPE). To check which location engine contributes to
+ // DR/SPE/PPE/VPE). To check which location engine contributes to
// the fused output, check for locOutputEngMask.
LocOutputEngineType locOutputEngType;
// when loc output eng type is set to fused, this field
// indicates the set of engines contribute to the fix.
PositioningEngineMask locOutputEngMask;
+ // When robust location is enabled, this field
+ // will how well the various input data considered for
+ // navigation solution conform to expectations.
+ // Range: 0 (least conforming) to 1 (most conforming)
+ float conformityIndex;
+ GnssLocationPositionDynamicsExt bodyFrameDataExt; // Additional Body Frame Dynamics
+ // VRR-based latitude/longitude/altitude
+ LLAInfo llaVRPBased;
+ // VRR-based east, north, and up velocity
+ float enuVelocityVRPBased[3];
+ DrSolutionStatusMask drSolutionStatusMask;
+ // true: altitude is assumed, false: altitude is calculated
+ bool altitudeAssumed;
+ // location session status
+ loc_sess_status sessionStatus;
} GnssLocationInfoNotification;
typedef struct {
@@ -1061,16 +1268,49 @@
char extras[GNSS_NI_MESSAGE_ID_MAX];
} GnssNiNotification;
+// carrier frequency of the signal tracked
+#define GPS_L1CA_CARRIER_FREQUENCY (1575420000.0)
+#define GPS_L1C_CARRIER_FREQUENCY (1575420000.0)
+#define GPS_L2C_L_CARRIER_FREQUENCY (1227600000.0)
+#define GPS_L5_Q_CARRIER_FREQUENCY (1176450000.0)
+#define GLONASS_G1_CARRIER_FREQUENCY (1602000000.0)
+#define GLONASS_G2_CARRIER_FREQUENCY (1246000000.0)
+#define GALILEO_E1_C_CARRIER_FREQUENCY (1575420000.0)
+#define GALILEO_E5A_Q_CARRIER_FREQUENCY (1176450000.0)
+#define GALILEO_E5B_Q_CARRIER_FREQUENCY (1207140000.0)
+#define BEIDOU_B1_I_CARRIER_FREQUENCY (1561098000.0)
+#define BEIDOU_B1C_CARRIER_FREQUENCY (1575420000.0)
+#define BEIDOU_B2_I_CARRIER_FREQUENCY (1207140000.0)
+#define BEIDOU_B2A_I_CARRIER_FREQUENCY (1176450000.0)
+#define BEIDOU_B2A_Q_CARRIER_FREQUENCY (1176450000.0)
+#define QZSS_L1CA_CARRIER_FREQUENCY (1575420000.0)
+#define QZSS_L1S_CARRIER_FREQUENCY (1575420000.0)
+#define QZSS_L2C_L_CARRIER_FREQUENCY (1227600000.0)
+#define QZSS_L5_Q_CARRIER_FREQUENCY (1176450000.0)
+#define SBAS_L1_CA_CARRIER_FREQUENCY (1575420000.0)
+#define NAVIC_L5_CARRIER_FREQUENCY (1176450000.0)
+
typedef struct {
uint32_t size; // set to sizeof(GnssSv)
- uint16_t svId; // Unique Identifier
- GnssSvType type; // type of SV (GPS, SBAS, GLONASS, QZSS, BEIDOU, GALILEO)
+ // Unique SV Identifier.
+ // SV Range for supported constellation is specified as below:
+ // - For GPS: 1 to 32
+ // - For GLONASS: 65 to 96
+ // - For SBAS: 120 to 158 and 183 to 191
+ // - For QZSS: 193 to 197
+ // - For BDS: 201 to 263
+ // - For GAL: 301 to 336
+ // - For NAVIC: 401 to 414
+ uint16_t svId;
+ GnssSvType type; // type of SV (GPS, SBAS, GLONASS, QZSS, BEIDOU, GALILEO, NAVIC)
float cN0Dbhz; // signal strength
float elevation; // elevation of SV (in degrees)
float azimuth; // azimuth of SV (in degrees)
GnssSvOptionsMask gnssSvOptionsMask; // Bitwise OR of GnssSvOptionsBits
float carrierFrequencyHz; // carrier frequency of the signal tracked
GnssSignalTypeMask gnssSignalTypeMask; // Specifies GNSS signal type
+ double basebandCarrierToNoiseDbHz; // baseband signal strength
+ uint16_t gloFrequency; // GLONASS Frequency channel number
} GnssSv;
struct GnssConfigSetAssistanceServer {
@@ -1091,8 +1331,13 @@
};
typedef struct {
- uint32_t size; // set to sizeof(GnssMeasurementsData)
- GnssMeasurementsDataFlagsMask flags; // bitwise OR of GnssMeasurementsDataFlagsBits
+ // set to sizeof(GnssMeasurementsData)
+ uint32_t size;
+ // bitwise OR of GnssMeasurementsDataFlagsBits
+ GnssMeasurementsDataFlagsMask flags;
+ // Unique SV Identifier
+ // For SV Range of supported constellation,
+ // please refer to the comment section of svId in GnssSv.
int16_t svId;
GnssSvType svType;
double timeOffsetNs;
@@ -1114,9 +1359,58 @@
double agcLevelDb;
GnssMeasurementsCodeType codeType;
char otherCodeTypeName[GNSS_MAX_NAME_LENGTH];
+ double basebandCarrierToNoiseDbHz;
+ GnssSignalTypeMask gnssSignalType;
+ double fullInterSignalBiasNs;
+ double fullInterSignalBiasUncertaintyNs;
+ double satelliteInterSignalBiasNs;
+ double satelliteInterSignalBiasUncertaintyNs;
+ int16_t gloFrequency;
+ uint8_t cycleSlipCount;
} GnssMeasurementsData;
typedef struct {
+ GnssSvType svType;
+ float carrierFrequencyHz;
+ GnssMeasurementsCodeType codeType;
+ char otherCodeTypeName[GNSS_MAX_NAME_LENGTH];
+} GnssMeasurementsSignalType;
+
+typedef struct {
+ uint32_t size; // set to sizeof(GnssReflectingPlane)
+ double latitudeDegrees;
+ double longitudeDegrees;
+ double altitudeMeters;
+ double azimuthDegrees;
+} GnssReflectingPlane;
+
+typedef struct {
+ uint32_t size; // set to sizeof(GnssSingleSatCorrection)
+ GnssSingleSatCorrectionMask flags;
+ GnssSvType svType;
+ uint16_t svId;
+ float carrierFrequencyHz;
+ float probSatIsLos;
+ float excessPathLengthMeters;
+ float excessPathLengthUncertaintyMeters;
+ GnssReflectingPlane reflectingPlane;
+} GnssSingleSatCorrection;
+
+typedef struct {
+ uint32_t size; // set to sizeof(GnssMeasurementCorrections)
+ double latitudeDegrees;
+ double longitudeDegrees;
+ double altitudeMeters;
+ double horizontalPositionUncertaintyMeters;
+ double verticalPositionUncertaintyMeters;
+ uint64_t toaGpsNanosecondsOfWeek;
+ std::vector<GnssSingleSatCorrection> satCorrections;
+ bool hasEnvironmentBearing;
+ float environmentBearingDegrees;
+ float environmentBearingUncertaintyDegrees;
+} GnssMeasurementCorrections;
+
+typedef struct {
uint32_t size; // set to sizeof(GnssMeasurementsClock)
GnssMeasurementsClockFlagsMask flags; // bitwise OR of GnssMeasurementsClockFlagsBits
int16_t leapSecond;
@@ -1128,6 +1422,9 @@
double driftNsps;
double driftUncertaintyNsps;
uint32_t hwClockDiscontinuityCount;
+ GnssMeasurementsSignalType referenceSignalTypeForIsb;
+ uint64_t elapsedRealTime; // in ns
+ uint64_t elapsedRealTimeUnc; // in ns
} GnssMeasurementsClock;
typedef struct {
@@ -1163,7 +1460,9 @@
struct GnssSvIdSource{
uint32_t size; // set to sizeof(GnssSvIdSource)
GnssSvType constellation; // constellation for the sv to blacklist
- GnssSvId svId; // sv id to blacklist
+ GnssSvId svId; // Unique SV Identifier,
+ // For SV Range of supported constellation,
+ // please refer to the comment section of svId in GnssSv.
};
inline bool operator ==(GnssSvIdSource const& left, GnssSvIdSource const& right) {
return left.size == right.size &&
@@ -1171,7 +1470,7 @@
}
#define GNSS_SV_CONFIG_ALL_BITS_ENABLED_MASK ((uint64_t)0xFFFFFFFFFFFFFFFF)
-typedef struct {
+struct GnssSvIdConfig {
uint32_t size; // set to sizeof(GnssSvIdConfig)
// GLONASS - SV 65 maps to bit 0
@@ -1196,7 +1495,95 @@
#define GNSS_SV_CONFIG_SBAS_INITIAL_SV_LENGTH 39
#define GNSS_SV_CONFIG_SBAS_INITIAL2_SV_ID 183
uint64_t sbasBlacklistSvMask;
-} GnssSvIdConfig;
+
+ //Navic - SV 401 maps to bit 0
+#define GNSS_SV_CONFIG_NAVIC_INITIAL_SV_ID 401
+ uint64_t navicBlacklistSvMask;
+
+ inline bool equals(const GnssSvIdConfig& inConfig) {
+ if ((inConfig.size == size) &&
+ (inConfig.gloBlacklistSvMask == gloBlacklistSvMask) &&
+ (inConfig.bdsBlacklistSvMask == bdsBlacklistSvMask) &&
+ (inConfig.qzssBlacklistSvMask == qzssBlacklistSvMask) &&
+ (inConfig.galBlacklistSvMask == galBlacklistSvMask) &&
+ (inConfig.sbasBlacklistSvMask == sbasBlacklistSvMask) &&
+ (inConfig.navicBlacklistSvMask == navicBlacklistSvMask)) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+};
+
+// Specify the valid mask for robust location configure
+// defined in GnssConfigRobustLocation.
+enum GnssConfigRobustLocationValidMask {
+ // GnssConfigRobustLocation has valid enabled field.
+ GNSS_CONFIG_ROBUST_LOCATION_ENABLED_VALID_BIT = (1<<0),
+ // GnssConfigRobustLocation has valid enabledForE911 field.
+ GNSS_CONFIG_ROBUST_LOCATION_ENABLED_FOR_E911_VALID_BIT = (1<<1),
+ // GnssConfigRobustLocation has valid version field.
+ GNSS_CONFIG_ROBUST_LOCATION_VERSION_VALID_BIT = (1<<2),
+};
+
+struct GnssConfigRobustLocationVersion {
+ // Major version number
+ uint8_t major;
+ // Minor version number
+ uint16_t minor;
+ inline bool equals(const GnssConfigRobustLocationVersion& version) const {
+ return (version.major == major && version.minor == minor);
+ }
+};
+
+// specify the robust location configuration used by modem GNSS engine
+struct GnssConfigRobustLocation {
+ GnssConfigRobustLocationValidMask validMask;
+ bool enabled;
+ bool enabledForE911;
+ GnssConfigRobustLocationVersion version;
+
+ inline bool equals(const GnssConfigRobustLocation& config) const {
+ if (config.validMask == validMask &&
+ config.enabled == enabled &&
+ config.enabledForE911 == enabledForE911 &&
+ config.version.equals(version)) {
+ return true;
+ }
+ return false;
+ }
+};
+
+/* Mask indicating enabled or disabled constellations and
+ secondary frequency.*/
+typedef uint64_t GnssSvTypesMask;
+typedef enum {
+ GNSS_SV_TYPES_MASK_GLO_BIT = (1<<0),
+ GNSS_SV_TYPES_MASK_BDS_BIT = (1<<1),
+ GNSS_SV_TYPES_MASK_QZSS_BIT = (1<<2),
+ GNSS_SV_TYPES_MASK_GAL_BIT = (1<<3),
+ GNSS_SV_TYPES_MASK_NAVIC_BIT = (1<<4),
+ GNSS_SV_TYPES_MASK_GPS_BIT = (1<<5),
+} GnssSvTypesMaskBits;
+#define GNSS_SV_TYPES_MASK_ALL \
+ (GNSS_SV_TYPES_MASK_GPS_BIT|GNSS_SV_TYPES_MASK_GLO_BIT|GNSS_SV_TYPES_MASK_BDS_BIT|\
+ GNSS_SV_TYPES_MASK_QZSS_BIT|GNSS_SV_TYPES_MASK_GAL_BIT|GNSS_SV_TYPES_MASK_NAVIC_BIT)
+
+/* This SV Type config is injected directly to GNSS Adapter
+ * bypassing Location API */
+struct GnssSvTypeConfig{
+ uint32_t size; // set to sizeof(GnssSvTypeConfig)
+ // Enabled Constellations
+ GnssSvTypesMask enabledSvTypesMask;
+ // Disabled Constellations
+ GnssSvTypesMask blacklistedSvTypesMask;
+
+ inline bool equals (const GnssSvTypeConfig& inConfig) const {
+ return ((inConfig.size == size) &&
+ (inConfig.enabledSvTypesMask == enabledSvTypesMask) &&
+ (inConfig.blacklistedSvTypesMask == blacklistedSvTypesMask));
+ }
+};
struct GnssConfig{
uint32_t size; // set to sizeof(GnssConfig)
@@ -1204,7 +1591,7 @@
GnssConfigGpsLock gpsLock;
GnssConfigSuplVersion suplVersion;
GnssConfigSetAssistanceServer assistanceServer;
- GnssConfigLppProfile lppProfile;
+ GnssConfigLppProfileMask lppProfileMask;
GnssConfigLppeControlPlaneMask lppeControlPlaneMask;
GnssConfigLppeUserPlaneMask lppeUserPlaneMask;
GnssConfigAGlonassPositionProtocolMask aGlonassPositionProtocolMask;
@@ -1213,13 +1600,17 @@
GnssConfigSuplModeMask suplModeMask; //bitwise OR of GnssConfigSuplModeBits
std::vector<GnssSvIdSource> blacklistedSvIds;
uint32_t emergencyExtensionSeconds;
+ GnssConfigRobustLocation robustLocationConfig;
+ uint16_t minGpsWeek;
+ uint8_t minSvElevation;
+ GnssSvTypeConfig secondaryBandConfig;
inline bool equals(const GnssConfig& config) {
if (flags == config.flags &&
gpsLock == config.gpsLock &&
suplVersion == config.suplVersion &&
assistanceServer.equals(config.assistanceServer) &&
- lppProfile == config.lppProfile &&
+ lppProfileMask == config.lppProfileMask &&
lppeControlPlaneMask == config.lppeControlPlaneMask &&
lppeUserPlaneMask == config.lppeUserPlaneMask &&
aGlonassPositionProtocolMask == config.aGlonassPositionProtocolMask &&
@@ -1227,7 +1618,11 @@
suplEmergencyServices == config.suplEmergencyServices &&
suplModeMask == config.suplModeMask &&
blacklistedSvIds == config.blacklistedSvIds &&
- emergencyExtensionSeconds == config.emergencyExtensionSeconds) {
+ emergencyExtensionSeconds == config.emergencyExtensionSeconds &&
+ robustLocationConfig.equals(config.robustLocationConfig) &&
+ minGpsWeek == config.minGpsWeek &&
+ minSvElevation == config.minSvElevation &&
+ secondaryBandConfig.equals(config.secondaryBandConfig)) {
return true;
}
return false;
@@ -1253,7 +1648,11 @@
} GnssDebugTime;
typedef struct {
- uint32_t size; // set to sizeof
+ // set to sizeof
+ uint32_t size;
+ // Unique SV Identifier
+ // For SV Range of supported constellation,
+ // please refer to the comment section of svId in GnssSv.
uint32_t svid;
GnssSvType constellation;
GnssEphemerisType mEphemerisType;
@@ -1323,25 +1722,10 @@
LeapSecondSystemInfo leapSecondSysInfo;
};
-/* Mask indicating enabled or disabled constellations */
-typedef uint64_t GnssSvTypesMask;
-typedef enum {
- GNSS_SV_TYPES_MASK_GLO_BIT = (1<<0),
- GNSS_SV_TYPES_MASK_BDS_BIT = (1<<1),
- GNSS_SV_TYPES_MASK_QZSS_BIT = (1<<2),
- GNSS_SV_TYPES_MASK_GAL_BIT = (1<<3),
- GNSS_SV_TYPES_MASK_NAVIC_BIT = (1<<4),
-} GnssSvTypesMaskBits;
-
-/* This SV Type config is injected directly to GNSS Adapter
- * bypassing Location API */
-typedef struct {
- uint32_t size; // set to sizeof(GnssSvTypeConfig)
- // Enabled Constellations
- GnssSvTypesMask enabledSvTypesMask;
- // Disabled Constellations
- GnssSvTypesMask blacklistedSvTypesMask;
-} GnssSvTypeConfig;
+// Specify the set of terrestrial technologies
+enum TerrestrialTechMask {
+ TERRESTRIAL_TECH_GTP_WWAN = 1 << 0,
+};
// Specify parameters related to lever arm
struct LeverArmParams {
@@ -1383,6 +1767,103 @@
LeverArmParams veppImuToGnss;
};
+// Specify vehicle body-to-Sensor mount parameters to be used
+// by dead reckoning positioning engine.
+struct BodyToSensorMountParams {
+ // The misalignment of the sensor board along the
+ // horizontal plane of the vehicle chassis measured looking
+ // from the vehicle to forward direction. In unit of degree.
+ float rollOffset;
+ // The misalignment along the horizontal plane of the vehicle
+ // chassis measured looking from the vehicle to the right
+ // side. Positive pitch indicates vehicle is inclined such
+ // that forward wheels are at higher elevation than rear
+ // wheels. In unit of degree.
+ float yawOffset;
+ // The angle between the vehicle forward direction and the
+ // sensor axis as seen from the top of the vehicle, and
+ // measured in counterclockwise direction. In unit of degree.
+ float pitchOffset;
+ // Single uncertainty number that may be the largest of the
+ // roll, pitch and yaw offset uncertainties.
+ float offsetUnc;
+};
+
+typedef uint64_t DeadReckoningEngineConfigValidMask;
+// Specify the valid mask for the configuration paramters of
+// dead reckoning position engine.
+enum DeadReckoningEngineConfigValidBit {
+ // DeadReckoningEngineConfig has valid
+ // DeadReckoningEngineConfig::DeadReckoningEngineConfig.
+ BODY_TO_SENSOR_MOUNT_PARAMS_BIT = (1<<0),
+ // DeadReckoningEngineConfig has valid
+ // DeadReckoningEngineConfig::vehicleSpeedScaleFactor.
+ VEHICLE_SPEED_SCALE_FACTOR_BIT = (1<<1),
+ // DeadReckoningEngineConfig has valid
+ // DeadReckoningEngineConfig::vehicleSpeedScaleFactorUnc.
+ VEHICLE_SPEED_SCALE_FACTOR_UNC_BIT = (1<<2),
+ // DeadReckoningEngineConfig has valid
+ // DeadReckoningEngineConfig::gyroScaleFactor.
+ GYRO_SCALE_FACTOR_BIT = (1<<3),
+ // DeadReckoningEngineConfig has valid
+ // DeadReckoningEngineConfig::gyroScaleFactorUnc.
+ GYRO_SCALE_FACTOR_UNC_BIT = (1<<4),
+};
+
+// Specify the configuration parameters for the dead reckoning
+// position engine
+struct DeadReckoningEngineConfig{
+ // Specify the valid fields in the config.
+ DeadReckoningEngineConfigValidMask validMask;
+ // Body to sensor mount parameters for use by dead reckoning
+ // positioning engine
+ BodyToSensorMountParams bodyToSensorMountParams;
+
+ // Vehicle Speed Scale Factor configuration input for the dead
+ // reckoning positioning engine. The multiplicative scale
+ // factor is applied to received Vehicle Speed value (in m/s)
+ // to obtain the true Vehicle Speed.
+ //
+ // Range is [0.9 to 1.1].
+ //
+ // Note: The scale factor is specific to a given vehicle
+ // make & model.
+ float vehicleSpeedScaleFactor;
+ // Vehicle Speed Scale Factor Uncertainty (68% confidence)
+ // configuration input for the dead reckoning positioning
+ // engine.
+ //
+ // Range is [0.0 to 0.1].
+ //
+ // Note: The scale factor unc is specific to a given vehicle
+ // make & model.
+ float vehicleSpeedScaleFactorUnc;
+
+ // Gyroscope Scale Factor configuration input for the dead
+ // reckoning positioning engine. The multiplicative scale
+ // factor is applied to received gyroscope value to obtain the
+ // true value.
+ //
+ // Range is [0.9 to 1.1].
+ //
+ // Note: The scale factor is specific to the Gyroscope sensor
+ // and typically derived from either sensor data-sheet or
+ // from actual calibration.
+ float gyroScaleFactor;
+
+ // Gyroscope Scale Factor uncertainty (68% confidence)
+ // configuration input for the dead reckoning positioning
+ // engine.
+ //
+ // Range is [0.0 to 0.1].
+ // engine.
+ //
+ // Note: The scale factor unc is specific to the make & model
+ // of Gyroscope sensor and typically derived from either
+ // sensor data-sheet or from actual calibration.
+ float gyroScaleFactorUnc;
+};
+
/* Provides the capabilities of the system
capabilities callback is called once soon after createInstance is called */
typedef std::function<void(
@@ -1496,7 +1977,8 @@
/* Provides the current GNSS configuration to the client */
typedef std::function<void(
- GnssConfig& config
+ uint32_t session_id,
+ const GnssConfig& config
)> gnssConfigCallback;
/* LocationSystemInfoCb is for receiving rare occuring location
@@ -1536,4 +2018,53 @@
engineLocationsInfoCallback engineLocationsInfoCb; // optional
} LocationCallbacks;
+typedef struct {
+ uint32_t size; // set to sizeof
+ double x;
+ double xUncertainty;
+ double y;
+ double yUncertainty;
+ double z;
+ double zUncertainty;
+} GnssCoordinate;
+
+typedef struct {
+ uint32_t size; // set to sizeof
+ double carrierFrequencyMHz;
+ GnssCoordinate phaseCenterOffsetCoordinateMillimeters;
+ std::vector<std::vector<double>> phaseCenterVariationCorrectionMillimeters;
+ std::vector<std::vector<double>> phaseCenterVariationCorrectionUncertaintyMillimeters;
+ std::vector<std::vector<double>> signalGainCorrectionDbi;
+ std::vector<std::vector<double>> signalGainCorrectionUncertaintyDbi;
+} GnssAntennaInformation;
+
+typedef struct {
+ uint32_t size; // set to sizeof
+ bool requiresNmeaLocation;
+ std::string hostNameOrIp; // null terminated string
+ std::string mountPoint; // null terminated string
+ std::string username; // null terminated string
+ std::string password; // null terminated string
+ uint32_t port;
+ bool useSSL;
+} GnssNtripConnectionParams;
+
+typedef struct {
+ uint64_t meQtimer1;
+ uint64_t meQtimer2;
+ uint64_t meQtimer3;
+ uint64_t peQtimer1;
+ uint64_t peQtimer2;
+ uint64_t peQtimer3;
+ uint64_t smQtimer1;
+ uint64_t smQtimer2;
+ uint64_t smQtimer3;
+ uint64_t locMwQtimer;
+ uint64_t hlosQtimer1;
+ uint64_t hlosQtimer2;
+ uint64_t hlosQtimer3;
+ uint64_t hlosQtimer4;
+ uint64_t hlosQtimer5;
+} GnssLatencyInfo;
+
#endif /* LOCATIONDATATYPES_H */
diff --git a/location/Makefile.am b/location/Makefile.am
index fccdf94..6a5a750 100644
--- a/location/Makefile.am
+++ b/location/Makefile.am
@@ -11,6 +11,10 @@
LocationAPI.cpp \
LocationAPIClientBase.cpp
+if USE_EXTERNAL_AP
+AM_CFLAGS += -DFEATURE_EXTERNAL_AP
+endif
+
if USE_GLIB
liblocation_api_la_CFLAGS = -DUSE_GLIB $(AM_CFLAGS) @GLIB_CFLAGS@
liblocation_api_la_LDFLAGS = -lstdc++ -Wl,-z,defs -lpthread @GLIB_LIBS@ -shared -version-info 1:0:0
diff --git a/location/configure.ac b/location/configure.ac
index 39abb69..f8376f5 100644
--- a/location/configure.ac
+++ b/location/configure.ac
@@ -74,6 +74,19 @@
AM_CONDITIONAL(USE_GLIB, test "x${with_glib}" = "xyes")
+# External AP
+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"
+fi
+
+AM_CONDITIONAL(USE_EXTERNAL_AP, test "x${with_external_ap}" = "xyes")
+
AC_CONFIG_FILES([ \
Makefile \
location-api.pc \
diff --git a/location/location_interface.h b/location/location_interface.h
index 6edb911..69d4f0c 100644
--- a/location/location_interface.h
+++ b/location/location_interface.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2020 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,6 +31,7 @@
#include <LocationAPI.h>
#include <gps_extended_c.h>
+#include <functional>
/* Used for callback to deliver GNSS energy consumed */
/** @fn
@@ -62,7 +63,7 @@
void (*setControlCallbacks)(LocationControlCallbacks& controlCallbacks);
uint32_t (*enable)(LocationTechnologyType techType);
void (*disable)(uint32_t id);
- uint32_t* (*gnssUpdateConfig)(GnssConfig config);
+ uint32_t* (*gnssUpdateConfig)(const GnssConfig& config);
uint32_t* (*gnssGetConfig)(GnssConfigFlagsMask config);
void (*gnssUpdateSvTypeConfig)(GnssSvTypeConfig& config);
void (*gnssGetSvTypeConfig)(GnssSvTypeConfigCallback& callback);
@@ -77,24 +78,39 @@
void (*agpsDataConnFailed)(AGpsExtType agpsType);
void (*getDebugReport)(GnssDebugReport& report);
void (*updateConnectionStatus)(bool connected, int8_t type, bool roaming,
- NetworkHandle networkHandle);
- void (*odcpiInit)(const OdcpiRequestCallback& callback);
+ NetworkHandle networkHandle, std::string& apn);
+ void (*odcpiInit)(const OdcpiRequestCallback& callback, OdcpiPrioritytype priority);
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);
+ void (*getPowerStateChanges)(std::function<void(bool)> powerStateCb);
void (*injectLocationExt)(const GnssLocationInfoNotification &locationInfo);
void (*updateBatteryStatus)(bool charging);
void (*updateSystemPowerState)(PowerStateType systemPowerState);
uint32_t (*setConstrainedTunc) (bool enable, float tuncConstraint, uint32_t energyBudget);
uint32_t (*setPositionAssistedClockEstimator) (bool enable);
- uint32_t (*gnssUpdateSvConfig)(const GnssSvTypeConfig& svTypeConfig,
- const GnssSvIdConfig& svIdConfig);
- uint32_t (*gnssResetSvConfig)();
+ uint32_t (*gnssUpdateSvConfig)(const GnssSvTypeConfig& constellationEnablementConfig,
+ const GnssSvIdConfig& blacklistSvConfig);
uint32_t (*configLeverArm)(const LeverArmConfigInfo& configInfo);
+ bool (*measCorrInit)(const measCorrSetCapabilitiesCb setCapabilitiesCb);
+ bool (*measCorrSetCorrections)(const GnssMeasurementCorrections gnssMeasCorr);
+ void (*measCorrClose)();
+ uint32_t (*antennaInfoInit)(const antennaInfoCb antennaInfoCallback);
+ void (*antennaInfoClose) ();
+ uint32_t (*configRobustLocation)(bool enable, bool enableForE911);
+ uint32_t (*configMinGpsWeek)(uint16_t minGpsWeek);
+ uint32_t (*configDeadReckoningEngineParams)(const DeadReckoningEngineConfig& dreConfig);
+ void (*updateNTRIPGGAConsent)(bool consentAccepted);
+ void (*enablePPENtripStream)(const GnssNtripConnectionParams& params, bool enableRTKEngine);
+ void (*disablePPENtripStream)();
+ uint32_t (*gnssUpdateSecondaryBandConfig)(const GnssSvTypeConfig& secondaryBandConfig);
+ uint32_t (*gnssGetSecondaryBandConfig)();
+ void (*resetNetworkInfo)();
+ uint32_t (*configEngineRunState)(PositioningEngineMask engType,
+ LocEngineRunState engState);
};
struct BatchingInterface {
diff --git a/pla/Android.bp b/pla/Android.bp
new file mode 100644
index 0000000..70904c9
--- /dev/null
+++ b/pla/Android.bp
@@ -0,0 +1,16 @@
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_qcom_sm7250_gps_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-BSD
+ default_applicable_licenses: ["hardware_qcom_sm7250_gps_license"],
+}
+
+cc_library_headers {
+
+ name: "libloc_pla_headers",
+ export_include_dirs: ["android"],
+ vendor: true,
+}
diff --git a/pla/Android.mk b/pla/Android.mk
deleted file mode 100644
index a57861d..0000000
--- a/pla/Android.mk
+++ /dev/null
@@ -1,29 +0,0 @@
-GNSS_CFLAGS := \
- -Werror \
- -Wno-error=unused-parameter \
- -Wno-error=macro-redefined \
- -Wno-error=reorder \
- -Wno-error=missing-braces \
- -Wno-error=self-assign \
- -Wno-error=enum-conversion \
- -Wno-error=logical-op-parentheses \
- -Wno-error=null-arithmetic \
- -Wno-error=null-conversion \
- -Wno-error=parentheses-equality \
- -Wno-error=undefined-bool-conversion \
- -Wno-error=tautological-compare \
- -Wno-error=switch \
- -Wno-error=date-time
-
-ifneq ($(BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE),)
-ifneq ($(BUILD_TINY_ANDROID),true)
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := libloc_pla_headers
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/android
-include $(BUILD_HEADER_LIBRARY)
-
-endif # not BUILD_TINY_ANDROID
-endif # BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE
diff --git a/pla/android/loc_pla.h b/pla/android/loc_pla.h
index 6104bfb..34cb591 100644
--- a/pla/android/loc_pla.h
+++ b/pla/android/loc_pla.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014, 2020 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,7 +31,8 @@
#ifdef __cplusplus
#include <utils/SystemClock.h>
-#define uptimeMillis android::uptimeMillis
+#define uptimeMillis() android::uptimeMillis()
+#define elapsedRealtime() android::elapsedRealtime()
#endif
#ifdef __cplusplus
@@ -58,6 +59,36 @@
#define LOC_PATH_APDR_CONF_STR "/vendor/etc/apdr.conf"
#define LOC_PATH_XTWIFI_CONF_STR "/vendor/etc/xtwifi.conf"
#define LOC_PATH_QUIPC_CONF_STR "/vendor/etc/quipc.conf"
+#define LOC_PATH_ANT_CORR_STR "/vendor/etc/gnss_antenna_info.conf"
+#define LOC_PATH_SLIM_CONF_STR "/vendor/etc/slim.conf"
+#define LOC_PATH_VPE_CONF_STR "/vendor/etc/vpeglue.conf"
+
+/*!
+ * @brief Function for memory block copy
+ *
+ * @param[out] p_Dest Destination buffer.
+ * @param[in] q_DestSize Destination buffer size.
+ * @param[in] p_Src Source buffer.
+ * @param[in] q_SrcSize Source buffer size.
+ *
+ * @return Number of bytes copied.
+ */
+static inline size_t memscpy (void *p_Dest, size_t q_DestSize, const void *p_Src, size_t q_SrcSize)
+{
+ size_t res = (q_DestSize < q_SrcSize) ? q_DestSize : q_SrcSize;
+ if (p_Dest && p_Src && q_DestSize > 0 && q_SrcSize > 0) {
+ memcpy(p_Dest, p_Src, res);
+ } else {
+ res = 0;
+ }
+ return res;
+}
+
+/*API for boot kpi marker prints */
+inline int loc_boot_kpi_marker(const char * pFmt, ...)
+{
+ return -1;
+}
#ifdef __cplusplus
}
diff --git a/pla/oe/loc_pla.h b/pla/oe/loc_pla.h
index e795a23..268b6bf 100644
--- a/pla/oe/loc_pla.h
+++ b/pla/oe/loc_pla.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014, 2020 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
@@ -37,16 +37,39 @@
#include <sys/time.h>
#include <time.h>
-inline int64_t uptimeMillis()
+#if defined(__GNUC__) && defined(__GNUC_PREREQ)
+#if __GNUC_PREREQ(6,0)
+ #pragma message "GNU C version is above 6"
+#else
+ #pragma message "GNU C version is less than 6"
+ #define NO_UNORDERED_SET_OR_MAP
+#endif
+#endif
+
+// use set/map instead of unordered_set/unordered_map for
+// older GCC versions
+#ifdef NO_UNORDERED_SET_OR_MAP
+#define unordered_set set
+#define unordered_map map
+#endif
+
+inline int64_t sysTimeMillis(int clock)
{
struct timespec ts;
int64_t time_ms = 0;
- clock_gettime(CLOCK_BOOTTIME, &ts);
+ clock_gettime(clock, &ts);
time_ms += (ts.tv_sec * 1000000000LL);
time_ms += ts.tv_nsec + 500000LL;
return time_ms / 1000000LL;
}
+inline int64_t uptimeMillis() {
+ return sysTimeMillis(CLOCK_MONOTONIC);
+}
+inline int64_t elapsedRealtime() {
+ return sysTimeMillis(CLOCK_BOOTTIME);
+}
+
extern "C" {
#endif
@@ -54,12 +77,18 @@
#include <cutils/properties.h>
#include <cutils/threads.h>
#include <cutils/sched_policy.h>
+#else
+#define set_sched_policy(a, b)
#endif /* FEATURE_EXTERNAL_AP */
#include <pthread.h>
#include <sys/time.h>
#include <sys/types.h>
#include <string.h>
#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#define MAX_COMMAND_STR_LEN (255)
+#define BOOT_KPI_FILE "/sys/kernel/debug/bootkpi/kpi_values"
#ifndef OFF_TARGET
#include <glib.h>
#define strlcat g_strlcat
@@ -82,6 +111,9 @@
#define LOC_PATH_APDR_CONF_STR "/etc/apdr.conf"
#define LOC_PATH_XTWIFI_CONF_STR "/etc/xtwifi.conf"
#define LOC_PATH_QUIPC_CONF_STR "/etc/quipc.conf"
+#define LOC_PATH_ANT_CORR_STR "/etc/gnss_antenna_info.conf"
+#define LOC_PATH_SLIM_CONF_STR "/etc/slim.conf"
+#define LOC_PATH_VPE_CONF_STR "/etc/vpeglue.conf"
#ifdef FEATURE_EXTERNAL_AP
#define PROPERTY_VALUE_MAX 92
@@ -93,6 +125,49 @@
}
#endif /* FEATURE_EXTERNAL_AP */
+/*!
+ * @brief Function for memory block copy
+ *
+ * @param[out] p_Dest Destination buffer.
+ * @param[in] q_DestSize Destination buffer size.
+ * @param[in] p_Src Source buffer.
+ * @param[in] q_SrcSize Source buffer size.
+ *
+ * @return Number of bytes copied.
+ */
+static inline size_t memscpy (void *p_Dest, size_t q_DestSize, const void *p_Src, size_t q_SrcSize)
+{
+ size_t res = (q_DestSize < q_SrcSize) ? q_DestSize : q_SrcSize;
+ if (p_Dest && p_Src && q_DestSize > 0 && q_SrcSize > 0) {
+ memcpy(p_Dest, p_Src, res);
+ } else {
+ res = 0;
+ }
+ return res;
+}
+
+/*API for boot kpi marker prints */
+static inline int loc_boot_kpi_marker(const char * pFmt, ...)
+{
+ int result = 0;
+ FILE *stream = NULL;
+ char data[MAX_COMMAND_STR_LEN] = {};
+ char buf[MAX_COMMAND_STR_LEN] = {};
+
+ va_list ap;
+ va_start(ap, pFmt);
+ vsnprintf(&buf[0], sizeof(buf), pFmt, ap);
+ snprintf(data, sizeof(data), "echo -n %s > %s", buf, BOOT_KPI_FILE);
+ stream = popen(data, "w" );
+ if (NULL == stream) {
+ result = -1;
+ } else {
+ pclose(stream);
+ }
+ va_end(ap);
+ return result;
+}
+
#ifdef __cplusplus
}
#endif /*__cplusplus */
diff --git a/utils/Android.bp b/utils/Android.bp
new file mode 100644
index 0000000..bdaba99
--- /dev/null
+++ b/utils/Android.bp
@@ -0,0 +1,64 @@
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_qcom_sm7250_gps_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ // SPDX-license-identifier-BSD
+ default_applicable_licenses: ["hardware_qcom_sm7250_gps_license"],
+}
+
+cc_library_shared {
+
+ name: "libgps.utils",
+ vendor: true,
+
+
+
+ //# Libs
+ shared_libs: [
+ "libdl",
+ "libutils",
+ "libcutils",
+ "liblog",
+ "libprocessgroup",
+ ],
+
+ srcs: [
+ "loc_log.cpp",
+ "loc_cfg.cpp",
+ "msg_q.c",
+ "linked_list.c",
+ "loc_target.cpp",
+ "LocHeap.cpp",
+ "LocTimer.cpp",
+ "LocThread.cpp",
+ "MsgTask.cpp",
+ "loc_misc_utils.cpp",
+ "loc_nmea.cpp",
+ "LocIpc.cpp",
+ "LogBuffer.cpp",
+ ],
+
+ cflags: [
+ "-fno-short-enums",
+ "-D_ANDROID_",
+ ] + GNSS_CFLAGS,
+
+ //# Includes
+ ldflags: ["-Wl,--export-dynamic"],
+
+ header_libs: [
+ "libutils_headers",
+ "libloc_pla_headers",
+ "liblocation_api_headers",
+ ],
+}
+
+cc_library_headers {
+
+ name: "libgps.utils_headers",
+ export_include_dirs: ["."],
+ vendor: true,
+}
diff --git a/utils/Android.mk b/utils/Android.mk
deleted file mode 100644
index 57d485d..0000000
--- a/utils/Android.mk
+++ /dev/null
@@ -1,69 +0,0 @@
-ifneq ($(BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE),)
-ifneq ($(BUILD_TINY_ANDROID),true)
-#Compile this library only for builds with the latest modem image
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-
-## Libs
-LOCAL_SHARED_LIBRARIES := \
- libdl \
- libutils \
- libcutils \
- liblog \
- libprocessgroup
-
-LOCAL_SRC_FILES += \
- loc_log.cpp \
- loc_cfg.cpp \
- msg_q.c \
- linked_list.c \
- loc_target.cpp \
- LocHeap.cpp \
- LocTimer.cpp \
- LocThread.cpp \
- MsgTask.cpp \
- loc_misc_utils.cpp \
- loc_nmea.cpp \
- LocIpc.cpp \
- LogBuffer.cpp
-
-# Flag -std=c++11 is not accepted by compiler when LOCAL_CLANG is set to true
-LOCAL_CFLAGS += \
- -fno-short-enums \
- -D_ANDROID_
-
-ifeq ($(TARGET_BUILD_VARIANT),user)
- LOCAL_CFLAGS += -DTARGET_BUILD_VARIANT_USER
-endif
-
-LOCAL_LDFLAGS += -Wl,--export-dynamic
-
-## Includes
-LOCAL_HEADER_LIBRARIES := \
- libutils_headers \
- libloc_pla_headers \
- liblocation_api_headers
-
-LOCAL_MODULE := libgps.utils
-LOCAL_SANITIZE += $(GNSS_SANITIZE)
-# activate the following line for debug purposes only, comment out for production
-#LOCAL_SANITIZE_DIAG += $(GNSS_SANITIZE_DIAG)
-LOCAL_VENDOR_MODULE := true
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_PRELINK_MODULE := false
-
-LOCAL_CFLAGS += $(GNSS_CFLAGS)
-
-include $(BUILD_SHARED_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := libgps.utils_headers
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
-include $(BUILD_HEADER_LIBRARY)
-
-endif # not BUILD_TINY_ANDROID
-endif # BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE
diff --git a/utils/LocHeap.cpp b/utils/LocHeap.cpp
index d667f14..4d047e4 100644
--- a/utils/LocHeap.cpp
+++ b/utils/LocHeap.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015, 2020 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
@@ -28,6 +28,8 @@
*/
#include <LocHeap.h>
+namespace loc_util {
+
class LocHeapNode {
friend class LocHeap;
@@ -266,6 +268,8 @@
return locNode;
}
+} // namespace loc_util
+
#ifdef __LOC_UNIT_TEST__
bool LocHeap::checkTree() {
return ((NULL == mTree) || mTree->checkNodes());
@@ -274,81 +278,3 @@
return (NULL == mTree) ? 0 : mTree->getSize();
}
#endif
-
-#ifdef __LOC_DEBUG__
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <time.h>
-
-class LocHeapDebug : public LocHeap {
-public:
- bool checkTree() {
- return ((NULL == mTree) || mTree->checkNodes());
- }
-
- uint32_t getTreeSize() {
- return (NULL == mTree) ? 0 : (mTree->getSize());
- }
-};
-
-class LocHeapDebugData : public LocRankable {
- const int mID;
-public:
- LocHeapDebugData(int id) : mID(id) {}
- inline virtual int ranks(LocRankable& rankable) {
- LocHeapDebugData* testData = dynamic_cast<LocHeapDebugData*>(&rankable);
- return testData->mID - mID;
- }
-};
-
-// For Linux command line testing:
-// compilation: g++ -D__LOC_HOST_DEBUG__ -D__LOC_DEBUG__ -g -I. -I../../../../vendor/qcom/proprietary/gps-internal/unit-tests/fakes_for_host -I../../../../system/core/include LocHeap.cpp
-// test: valgrind --leak-check=full ./a.out 100
-int main(int argc, char** argv) {
- srand(time(NULL));
- int tries = atoi(argv[1]);
- int checks = tries >> 3;
- LocHeapDebug heap;
- int treeSize = 0;
-
- for (int i = 0; i < tries; i++) {
- if (i % checks == 0 && !heap.checkTree()) {
- printf("tree check failed before %dth op\n", i);
- }
- int r = rand();
-
- if (r & 1) {
- LocHeapDebugData* data = new LocHeapDebugData(r >> 1);
- heap.push(dynamic_cast<LocRankable&>(*data));
- treeSize++;
- } else {
- LocRankable* rankable = heap.pop();
- if (rankable) {
- delete rankable;
- }
- treeSize ? treeSize-- : 0;
- }
-
- printf("%s: %d == %d\n", (r&1)?"push":"pop", treeSize, heap.getTreeSize());
- if (treeSize != heap.getTreeSize()) {
- printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
- tries = i+1;
- break;
- }
- }
-
- if (!heap.checkTree()) {
- printf("!!!!!!!!!!tree check failed at the end after %d ops!!!!!!!\n", tries);
- } else {
- printf("success!\n");
- }
-
- for (LocRankable* data = heap.pop(); NULL != data; data = heap.pop()) {
- delete data;
- }
-
- return 0;
-}
-
-#endif
diff --git a/utils/LocHeap.h b/utils/LocHeap.h
index b491948..bb62d6b 100644
--- a/utils/LocHeap.h
+++ b/utils/LocHeap.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015, 2020 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 <stddef.h>
#include <string.h>
+namespace loc_util {
+
// abstract class to be implemented by client to provide a rankable class
class LocRankable {
public:
@@ -93,4 +95,6 @@
#endif
};
+} // namespace loc_util
+
#endif //__LOC_HEAP__
diff --git a/utils/LocIpc.cpp b/utils/LocIpc.cpp
index e9dbe9d..746ca87 100644
--- a/utils/LocIpc.cpp
+++ b/utils/LocIpc.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2020 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
@@ -139,8 +139,20 @@
}
public:
inline LocIpcLocalSender(const char* name) : LocIpcSender(),
- mSock(make_shared<Sock>((nullptr == name) ? -1 : (::socket(AF_UNIX, SOCK_DGRAM, 0)))),
+ mSock(nullptr),
mAddr({.sun_family = AF_UNIX, {}}) {
+
+ int fd = -1;
+ if (nullptr != name) {
+ fd = ::socket(AF_UNIX, SOCK_DGRAM, 0);
+ if (fd >= 0) {
+ timeval timeout;
+ timeout.tv_sec = 2;
+ timeout.tv_usec = 0;
+ setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
+ }
+ }
+ mSock.reset(new Sock(fd));
if (mSock != nullptr && mSock->isValid()) {
snprintf(mAddr.sun_path, sizeof(mAddr.sun_path), "%s", name);
}
@@ -301,7 +313,7 @@
mAbortCalled(false),
mLocIpc(locIpc),
mIpcRecver(move(ipcRecver)) {}
- inline bool run() override {
+ inline virtual bool run() override {
if (mIpcRecver != nullptr) {
mLocIpc.startBlockingListening(*(mIpcRecver.get()));
if (!mAbortCalled) {
@@ -311,7 +323,7 @@
// return false so the calling thread exits while loop
return false;
}
- inline void abort() {
+ inline virtual void interrupt() override {
mAbortCalled = true;
if (mIpcRecver != nullptr) {
mIpcRecver->abort();
@@ -323,8 +335,7 @@
if (ipcRecver != nullptr && ipcRecver->isRecvable()) {
std::string threadName("LocIpc-");
threadName.append(ipcRecver->getName());
- mRunnable = new LocIpcRunnable(*this, ipcRecver);
- return mThread.start(threadName.c_str(), mRunnable);
+ return mThread.start(threadName.c_str(), make_shared<LocIpcRunnable>(*this, ipcRecver));
} else {
LOC_LOGe("ipcRecver is null OR ipcRecver->recvable() is fasle");
return false;
@@ -344,10 +355,7 @@
}
void LocIpc::stopNonBlockingListening() {
- if (mRunnable) {
- mRunnable->abort();
- mRunnable = nullptr;
- }
+ mThread.stop();
}
void LocIpc::stopBlockingListening(LocIpcRecver& ipcRecver) {
@@ -376,15 +384,17 @@
return (nullptr == creator) ? nullptr : creator(service, instance);
}
unique_ptr<LocIpcRecver> LocIpc::getLocIpcQrtrRecver(const shared_ptr<ILocIpcListener>& listener,
- int service, int instance) {
- typedef unique_ptr<LocIpcRecver> (*creator_t)(const shared_ptr<ILocIpcListener>&, int, int);
+ int service, int instance,
+ const shared_ptr<LocIpcQrtrWatcher>& watcher) {
+ typedef unique_ptr<LocIpcRecver> (*creator_t)(const shared_ptr<ILocIpcListener>&, int, int,
+ const shared_ptr<LocIpcQrtrWatcher>& watcher);
static creator_t creator = (creator_t)dlGetSymFromLib(sLibQrtrHandle, sLibQrtrName,
#ifdef USE_GLIB
- "_ZN8loc_util22createLocIpcQrtrRecverERKSt10shared_ptrINS_15ILocIpcListenerEEii");
+ "_ZN8loc_util22createLocIpcQrtrRecverERKSt10shared_ptrINS_15ILocIpcListenerEEiiRKS0_INS_17LocIpcQrtrWatcherEE");
#else
- "_ZN8loc_util22createLocIpcQrtrRecverERKNSt3__110shared_ptrINS_15ILocIpcListenerEEEii");
+ "_ZN8loc_util22createLocIpcQrtrRecverERKNSt3__110shared_ptrINS_15ILocIpcListenerEEEiiRKNS1_INS_17LocIpcQrtrWatcherEEE");
#endif
- return (nullptr == creator) ? nullptr : creator(listener, service, instance);
+ return (nullptr == creator) ? nullptr : creator(listener, service, instance, watcher);
}
shared_ptr<LocIpcSender> LocIpc::getLocIpcInetTcpSender(const char* serverName, int32_t port) {
return make_shared<LocIpcInetTcpSender>(serverName, port);
@@ -405,7 +415,13 @@
typedef pair<shared_ptr<LocIpcSender>, unique_ptr<LocIpcRecver>> (*creator_t)(const shared_ptr<ILocIpcListener>&, int);
static void* sLibEmuHandle = nullptr;
static creator_t creator = (creator_t)dlGetSymFromLib(sLibEmuHandle, "libloc_emu.so",
- "_ZN13QmiLocService41createLocIpcQmiLocServiceSenderRecverPairERKNSt3__110shared_ptrIN8loc_util15ILocIpcListenerEEEi");
+#ifdef USE_GLIB
+ "_ZN13QmiLocService41createLocIpcQmiLocServiceSenderRecverPair"\
+ "ERKSt10shared_ptrIN8loc_util15ILocIpcListenerEEi");
+#else
+ "_ZN13QmiLocService41createLocIpcQmiLocServiceSenderRecverPair"\
+ "ERKNSt3__110shared_ptrIN8loc_util15ILocIpcListenerEEEi");
+#endif
return (nullptr == creator) ?
make_pair<shared_ptr<LocIpcSender>, unique_ptr<LocIpcRecver>>(nullptr, nullptr) :
creator(listener, instance);
diff --git a/utils/LocIpc.h b/utils/LocIpc.h
index d6f8d1d..b2586e6 100644
--- a/utils/LocIpc.h
+++ b/utils/LocIpc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018, 2020 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
@@ -35,16 +35,16 @@
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
+#include <unordered_set>
+#include <mutex>
#include <LocThread.h>
using namespace std;
namespace loc_util {
-
class LocIpcRecver;
class LocIpcSender;
-class LocIpcRunnable;
class ILocIpcListener {
protected:
@@ -56,10 +56,39 @@
virtual void onReceive(const char* data, uint32_t len, const LocIpcRecver* recver) = 0;
};
+class LocIpcQrtrWatcher {
+ const unordered_set<int> mServicesToWatch;
+ unordered_set<int> mClientsToWatch;
+ mutex mMutex;
+ inline bool isInWatch(const unordered_set<int>& idsToWatch, int id) {
+ return idsToWatch.find(id) != idsToWatch.end();
+ }
+protected:
+ inline virtual ~LocIpcQrtrWatcher() {}
+ inline LocIpcQrtrWatcher(unordered_set<int> servicesToWatch)
+ : mServicesToWatch(servicesToWatch) {}
+public:
+ enum class ServiceStatus { UP, DOWN };
+ inline bool isServiceInWatch(int serviceId) {
+ return isInWatch(mServicesToWatch, serviceId);
+ }
+ inline bool isClientInWatch(int nodeId) {
+ lock_guard<mutex> lock(mMutex);
+ return isInWatch(mClientsToWatch, nodeId);
+ }
+ inline void addClientToWatch(int nodeId) {
+ lock_guard<mutex> lock(mMutex);
+ mClientsToWatch.emplace(nodeId);
+ }
+ virtual void onServiceStatusChange(int sericeId, int instanceId, ServiceStatus status,
+ const LocIpcSender& sender) = 0;
+ inline virtual void onClientGone(int nodeId, int portId) {}
+ inline const unordered_set<int>& getServicesToWatch() { return mServicesToWatch; }
+};
class LocIpc {
public:
- inline LocIpc() : mRunnable(nullptr) {}
+ inline LocIpc() = default;
inline virtual ~LocIpc() {
stopNonBlockingListening();
}
@@ -82,9 +111,16 @@
static unique_ptr<LocIpcRecver>
getLocIpcInetTcpRecver(const shared_ptr<ILocIpcListener>& listener,
const char* serverName, int32_t port);
+ inline static unique_ptr<LocIpcRecver>
+ getLocIpcQrtrRecver(const shared_ptr<ILocIpcListener>& listener,
+ int service, int instance) {
+ const shared_ptr<LocIpcQrtrWatcher> qrtrWatcher = nullptr;
+ return getLocIpcQrtrRecver(listener, service, instance, qrtrWatcher);
+ }
static unique_ptr<LocIpcRecver>
getLocIpcQrtrRecver(const shared_ptr<ILocIpcListener>& listener,
- int service, int instance);
+ int service, int instance,
+ const shared_ptr<LocIpcQrtrWatcher>& qrtrWatcher);
static pair<shared_ptr<LocIpcSender>, unique_ptr<LocIpcRecver>>
getLocIpcQmiLocServiceSenderRecverPair(const shared_ptr<ILocIpcListener>& listener,
@@ -114,7 +150,6 @@
private:
LocThread mThread;
- LocIpcRunnable *mRunnable;
};
/* this is only when client needs to implement Sender / Recver that are not already provided by
@@ -127,7 +162,6 @@
virtual ssize_t send(const uint8_t data[], uint32_t length, int32_t msgId) const = 0;
public:
virtual ~LocIpcSender() = default;
- virtual void informRecverRestarted() {}
inline bool isSendable() const { return isOperable(); }
inline bool sendData(const uint8_t data[], uint32_t length, int32_t msgId) const {
return isSendable() && (send(data, length, msgId) > 0);
@@ -135,6 +169,7 @@
virtual unique_ptr<LocIpcRecver> getRecver(const shared_ptr<ILocIpcListener>& listener) {
return nullptr;
}
+ inline virtual void copyDestAddrFrom(const LocIpcSender& otherSender) {}
};
class LocIpcRecver {
diff --git a/utils/LocLoggerBase.h b/utils/LocLoggerBase.h
new file mode 100644
index 0000000..867b6e2
--- /dev/null
+++ b/utils/LocLoggerBase.h
@@ -0,0 +1,39 @@
+/* Copyright (c) 2020 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 LOC_LOGGER_BASE_H
+#define LOC_LOGGER_BASE_H
+
+namespace loc_util {
+class LocLoggerBase {
+public:
+ virtual void log() {}
+};
+}
+
+#endif
diff --git a/utils/LocSharedLock.h b/utils/LocSharedLock.h
index a7af35e..1ef2c57 100644
--- a/utils/LocSharedLock.h
+++ b/utils/LocSharedLock.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015, 2020 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
@@ -49,9 +49,11 @@
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
+
+namespace loc_util {
+
+// 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,
@@ -74,4 +76,6 @@
inline void unlock() { pthread_mutex_unlock(&mMutex); }
};
+} //namespace loc_util
+
#endif //__LOC_SHARED_LOCK__
diff --git a/utils/LocThread.cpp b/utils/LocThread.cpp
index 568a6bb..3cac1f9 100644
--- a/utils/LocThread.cpp
+++ b/utils/LocThread.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015, 2020 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,194 +26,75 @@
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
+#include <sys/prctl.h>
#include <LocThread.h>
#include <string.h>
-#include <pthread.h>
+#include <string>
+#include <thread>
#include <loc_pla.h>
+using std::weak_ptr;
+using std::shared_ptr;
+using std::thread;
+using std::string;
+
+namespace loc_util {
+
class LocThreadDelegate {
- LocRunnable* mRunnable;
- bool mJoinable;
- pthread_t mThandle;
- pthread_mutex_t mMutex;
- int mRefCount;
- ~LocThreadDelegate();
- LocThreadDelegate(LocThread::tCreate creator, const char* threadName,
- LocRunnable* runnable, bool joinable);
- void destroy();
+ static const char defaultThreadName[];
+ weak_ptr<LocRunnable> mRunnable;
+ thread mThread;
+ LocThreadDelegate(const string tName, shared_ptr<LocRunnable> r);
public:
- static LocThreadDelegate* create(LocThread::tCreate creator,
- const char* threadName, LocRunnable* runnable, bool joinable);
- void stop();
- // bye() is for the parent thread to go away. if joinable,
- // parent must stop the spawned thread, join, and then
- // destroy(); if detached, the parent can go straight
- // ahead to destroy()
- inline void bye() { mJoinable ? stop() : destroy(); }
- inline bool isRunning() { return (NULL != mRunnable); }
- static void* threadMain(void* arg);
+ ~LocThreadDelegate() {
+ shared_ptr<LocRunnable> runnable = mRunnable.lock();
+ if (nullptr != runnable) {
+ runnable->interrupt();
+ }
+ }
+ inline static LocThreadDelegate* create(const char* tName, shared_ptr<LocRunnable> runnable);
};
-// it is important to note that internal members must be
-// initialized to values as if pthread_create succeeds.
-// This is to avoid the race condition between the threads,
-// once the thread is created, some of these values will
-// be check in the spawned thread, and must set correctly
-// then and there.
-// However, upon pthread_create failure, the data members
-// must be set to indicate failure, e.g. mRunnable, and
-// threashold approprietly for destroy(), e.g. mRefCount.
-LocThreadDelegate::LocThreadDelegate(LocThread::tCreate creator,
- const char* threadName, LocRunnable* runnable, bool joinable) :
- mRunnable(runnable), mJoinable(joinable), mThandle((pthread_t)NULL),
- mMutex(PTHREAD_MUTEX_INITIALIZER), mRefCount(2) {
+const char LocThreadDelegate::defaultThreadName[] = "LocThread";
- // set up thread name, if nothing is passed in
- if (!threadName) {
- threadName = "LocThread";
- }
+LocThreadDelegate* LocThreadDelegate::create(const char* tName, shared_ptr<LocRunnable> runnable) {
+ LocThreadDelegate* threadDelegate = nullptr;
- // create the thread here, then if successful
- // and a name is given, we set the thread name
- if (creator) {
- mThandle = creator(threadName, threadMain, this);
- } else if (pthread_create(&mThandle, NULL, threadMain, this)) {
- // pthread_create() failed
- mThandle = (pthread_t)NULL;
- }
+ if (nullptr != runnable) {
+ if (!tName) {
+ tName = defaultThreadName;
+ }
- if (mThandle) {
- // set thread name
char lname[16];
- int len = (sizeof(lname) > (strlen(threadName) + 1)) ?
- (strlen(threadName)):(sizeof(lname) - 1);
- memcpy(lname, threadName, len);
+ auto nameSize = strlen(tName) + 1;
+ int len = std::min(sizeof(lname), nameSize) - 1;
+ memcpy(lname, tName, len);
lname[len] = 0;
- // set the thread name here
- pthread_setname_np(mThandle, lname);
- // detach, if not joinable
- if (!joinable) {
- pthread_detach(mThandle);
- }
- } else {
- // must set these values upon failure
- mRunnable = NULL;
- mJoinable = false;
- mRefCount = 1;
- }
-}
-
-inline
-LocThreadDelegate::~LocThreadDelegate() {
- // at this point nothing should need done any more
-}
-
-// factory method so that we could return NULL upon failure
-LocThreadDelegate* LocThreadDelegate::create(LocThread::tCreate creator,
- const char* threadName, LocRunnable* runnable, bool joinable) {
- LocThreadDelegate* thread = NULL;
- if (runnable) {
- thread = new LocThreadDelegate(creator, threadName, runnable, joinable);
- if (thread && !thread->isRunning()) {
- thread->destroy();
- thread = NULL;
- }
+ threadDelegate = new LocThreadDelegate(lname, runnable);
}
- return thread;
+ return threadDelegate;
}
-// The order is importang
-// NULLing mRunnalbe stops the while loop in threadMain()
-// join() if mJoinble must come before destroy() call, as
-// the obj must remain alive at this time so that mThandle
-// remains valud.
-void LocThreadDelegate::stop() {
- // mRunnable and mJoinable are reset on different triggers.
- // mRunnable may get nulled on the spawned thread's way out;
- // or here.
- // mJouinable (if ever been true) gets falsed when client
- // thread triggers stop, with either a stop()
- // call or the client releases thread obj handle.
- if (mRunnable) {
- mRunnable = NULL;
- }
- if (mJoinable) {
- mJoinable = false;
- pthread_join(mThandle, NULL);
- }
- // call destroy() to possibly delete the obj
- destroy();
-}
-
-// method for clients to call to release the obj
-// when it is a detached thread, the client thread
-// and the spawned thread can both try to destroy()
-// asynchronously. And we delete this obj when
-// mRefCount becomes 0.
-void LocThreadDelegate::destroy() {
- // else case shouldn't happen, unless there is a
- // leaking obj. But only our code here has such
- // obj, so if we test our code well, else case
- // will never happen
- if (mRefCount > 0) {
- // we need a flag on the stack
- bool callDelete = false;
-
- // critical section between threads
- pthread_mutex_lock(&mMutex);
- // last destroy() call
- callDelete = (1 == mRefCount--);
- pthread_mutex_unlock(&mMutex);
-
- // upon last destroy() call we delete this obj
- if (callDelete) {
- delete this;
- }
- }
-}
-
-void* LocThreadDelegate::threadMain(void* arg) {
- LocThreadDelegate* locThread = (LocThreadDelegate*)(arg);
-
- if (locThread) {
- LocRunnable* runnable = locThread->mRunnable;
-
- if (runnable) {
- if (locThread->isRunning()) {
+LocThreadDelegate::LocThreadDelegate(const string tName, shared_ptr<LocRunnable> runnable) :
+ mRunnable(runnable),
+ mThread([tName, runnable] {
+ prctl(PR_SET_NAME, tName.c_str(), 0, 0, 0);
runnable->prerun();
- }
-
- while (locThread->isRunning() && runnable->run());
-
- if (locThread->isRunning()) {
+ while (runnable->run());
runnable->postrun();
- }
+ }) {
- // at this time, locThread->mRunnable may or may not be NULL
- // NULL it just to be safe and clean, as we want the field
- // in the released memory slot to be NULL.
- locThread->mRunnable = NULL;
- delete runnable;
- }
- locThread->destroy();
- }
-
- return NULL;
+ mThread.detach();
}
-LocThread::~LocThread() {
- if (mThread) {
- mThread->bye();
- mThread = NULL;
- }
-}
-bool LocThread::start(tCreate creator, const char* threadName, LocRunnable* runnable, bool joinable) {
+
+bool LocThread::start(const char* tName, shared_ptr<LocRunnable> runnable) {
bool success = false;
if (!mThread) {
- mThread = LocThreadDelegate::create(creator, threadName, runnable, joinable);
+ mThread = LocThreadDelegate::create(tName, runnable);
// true only if thread is created successfully
success = (NULL != mThread);
}
@@ -221,46 +102,10 @@
}
void LocThread::stop() {
- if (mThread) {
- mThread->stop();
- mThread = NULL;
+ if (nullptr != mThread) {
+ delete mThread;
+ mThread = nullptr;
}
}
-#ifdef __LOC_DEBUG__
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-class LocRunnableTest1 : public LocRunnable {
- int mID;
-public:
- LocRunnableTest1(int id) : LocRunnable(), mID(id) {}
- virtual bool run() {
- printf("LocRunnableTest1: %d\n", mID++);
- sleep(1);
- return true;
- }
-};
-
-// on linux command line:
-// compile: g++ -D__LOC_HOST_DEBUG__ -D__LOC_DEBUG__ -g -std=c++0x -I. -I../../../../vendor/qcom/proprietary/gps-internal/unit-tests/fakes_for_host -I../../../../system/core/include -lpthread LocThread.cpp
-// test detached thread: valgrind ./a.out 0
-// test joinable thread: valgrind ./a.out 1
-int main(int argc, char** argv) {
- LocRunnableTest1 test(10);
-
- LocThread thread;
- thread.start("LocThreadTest", test, atoi(argv[1]));
-
- sleep(10);
-
- thread.stop();
-
- sleep(5);
-
- return 0;
-}
-
-#endif
+} // loc_util
diff --git a/utils/LocThread.h b/utils/LocThread.h
index 2a65d8f..c7ece87 100644
--- a/utils/LocThread.h
+++ b/utils/LocThread.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015, 2020 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,14 +30,18 @@
#define __LOC_THREAD__
#include <stddef.h>
-#include <pthread.h>
+#include <memory>
+
+using std::shared_ptr;
+
+namespace loc_util {
// abstract class to be implemented by client to provide a runnable class
// which gets scheduled by LocThread
class LocRunnable {
public:
- inline LocRunnable() {}
- inline virtual ~LocRunnable() {}
+ inline LocRunnable() = default;
+ inline virtual ~LocRunnable() = default;
// The method to be implemented by thread clients
// and be scheduled by LocThread
@@ -52,6 +56,10 @@
// The method to be run after thread loop (conditionally repeatedly)
// calls run()
inline virtual void postrun() {}
+
+ // The method to wake up the potential blocking thread
+ // no op if not applicable
+ inline virtual void interrupt() = 0;
};
// opaque class to provide service implementation.
@@ -63,12 +71,11 @@
LocThreadDelegate* mThread;
public:
inline LocThread() : mThread(NULL) {}
- virtual ~LocThread();
+ inline virtual ~LocThread() { stop(); }
- typedef pthread_t (*tCreate)(const char* name, void* (*start)(void*), void* arg);
// client starts thread with a runnable, which implements
// the logics to fun in the created thread context.
- // The thread could be either joinable or detached.
+ // The thread is always detached.
// runnable is an obj managed by client. Client creates and
// frees it (but must be after stop() is called, or
// this LocThread obj is deleted).
@@ -76,17 +83,13 @@
// returns true. Else it is client's responsibility
// to delete the object
// Returns 0 if success; false if failure.
- bool start(tCreate creator, const char* threadName, LocRunnable* runnable, bool joinable = true);
- inline bool start(const char* threadName, LocRunnable* runnable, bool joinable = true) {
- return start(NULL, threadName, runnable, joinable);
- }
+ bool start(const char* threadName, shared_ptr<LocRunnable> runnable);
- // NOTE: if this is a joinable thread, this stop may block
- // for a while until the thread is joined.
void stop();
// thread status check
inline bool isRunning() { return NULL != mThread; }
};
+} // loc_util
#endif //__LOC_THREAD__
diff --git a/utils/LocTimer.cpp b/utils/LocTimer.cpp
index 93775d0..915cf54 100644
--- a/utils/LocTimer.cpp
+++ b/utils/LocTimer.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015, 2020 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
@@ -48,6 +48,8 @@
#define CLOCK_BOOTTIME_ALARM CLOCK_MONOTONIC
#endif
+namespace loc_util {
+
/*
There are implementations of 5 classes in this file:
LocTimer, LocTimerDelegate, LocTimerContainer, LocTimerPollTask, LocTimerWrapper
@@ -129,6 +131,21 @@
void expire();
};
+class TimerRunnable : public LocRunnable {
+ const int mFd;
+public:
+ inline TimerRunnable(const int fd) : mFd(fd) {}
+ // The method to be implemented by thread clients
+ // and be scheduled by LocThread
+ // This method will be repeated called until it returns false; or
+ // until thread is stopped.
+ virtual bool run() override;
+
+ // The method to wake up the potential blocking thread
+ // no op if not applicable
+ inline virtual void interrupt() { close(mFd); }
+};
+
// This class implements the polling thread that epolls imer / alarm fds.
// The LocRunnable::run() contains the actual polling. The other methods
// will be run in the caller's thread context to add / remove timer / alarm
@@ -140,19 +157,17 @@
// having 1 fd per container of timer / alarm is such that, we may not need
// to make a system call each time a timer / alarm is added / removed, unless
// that changes the "soonest" time out of that of all the timers / alarms.
-class LocTimerPollTask : public LocRunnable {
+class LocTimerPollTask {
// the epoll fd
const int mFd;
- // the thread that calls run() method
- LocThread* mThread;
- friend class LocThreadDelegate;
- // dtor
- ~LocTimerPollTask();
+ // the thread that calls TimerRunnable::run() method, where
+ // epoll_wait() is blocking and waiting for events..
+ LocThread mThread;
public:
// ctor
LocTimerPollTask();
- // this obj will be deleted once thread is deleted
- void destroy();
+ // dtor
+ ~LocTimerPollTask() = default;
// add a container of timers. Each contain has a unique device fd, i.e.
// either timer or alarm fd, and a heap of timers / alarms. It is expected
// that container would have written to the device fd with the soonest
@@ -164,9 +179,6 @@
// remove a fd that is assciated with a container. The expectation is that
// the atual timer would have been removed from the container.
void removePoll(LocTimerContainer& timerContainer);
- // The polling thread context will call this method. This is where
- // epoll_wait() is blocking and waiting for events..
- virtual bool run();
};
// Internal class of timer obj. It gets born when client calls LocTimer::start();
@@ -257,7 +269,7 @@
MsgTask* LocTimerContainer::getMsgTaskLocked() {
// it is cheap to check pointer first than locking mutext unconditionally
if (!mMsgTask) {
- mMsgTask = new MsgTask("LocTimerMsgTask", false);
+ mMsgTask = new MsgTask("LocTimerMsgTask");
}
return mMsgTask;
}
@@ -313,7 +325,6 @@
void LocTimerContainer::add(LocTimerDelegate& timer) {
struct MsgTimerPush : public LocMsg {
LocTimerContainer* mTimerContainer;
- LocHeapNode* mTree;
LocTimerDelegate* mTimer;
inline MsgTimerPush(LocTimerContainer& container, LocTimerDelegate& timer) :
LocMsg(), mTimerContainer(&container), mTimer(&timer) {}
@@ -398,39 +409,19 @@
inline
LocTimerPollTask::LocTimerPollTask()
- : mFd(epoll_create(2)), mThread(new LocThread()) {
+ : mFd(epoll_create(2)), mThread() {
// before a next call returens, a thread will be created. The run() method
// could already be running in parallel. Also, since each of the objs
// creates a thread, the container will make sure that there will be only
// one of such obj for our timer implementation.
- if (!mThread->start("LocTimerPollTask", this)) {
- delete mThread;
- mThread = NULL;
- }
-}
-
-inline
-LocTimerPollTask::~LocTimerPollTask() {
- // when fs is closed, epoll_wait() should fail run() should return false
- // and the spawned thread should exit.
- close(mFd);
-}
-
-void LocTimerPollTask::destroy() {
- if (mThread) {
- LocThread* thread = mThread;
- mThread = NULL;
- delete thread;
- } else {
- delete this;
- }
+ mThread.start("LocTimerPollTask", std::make_shared<TimerRunnable>(mFd));
}
void LocTimerPollTask::addPoll(LocTimerContainer& timerContainer) {
struct epoll_event ev;
memset(&ev, 0, sizeof(ev));
- ev.events = EPOLLIN | EPOLLWAKEUP;
+ ev.events = EPOLLIN;
ev.data.fd = timerContainer.getTimerFd();
// it is important that we set this context pointer with the input
// timer container this is how we know which container should handle
@@ -447,7 +438,7 @@
// The polling thread context will call this method. If run() method needs to
// be repetitvely called, it must return true from the previous call.
-bool LocTimerPollTask::run() {
+bool TimerRunnable::run() {
struct epoll_event ev[2];
// we have max 2 descriptors to poll from
@@ -621,6 +612,14 @@
}
};
+} // namespace loc_util
+
+//////////////////////////////////////////////////////////////////////////
+// This section below wraps for the C style APIs
+//////////////////////////////////////////////////////////////////////////
+
+using loc_util::LocTimerWrapper;
+
pthread_mutex_t LocTimerWrapper::mMutex = PTHREAD_MUTEX_INITIALIZER;
void* loc_timer_start(uint64_t msec, loc_timer_callback cb_func,
@@ -647,107 +646,3 @@
handle = NULL;
}
}
-
-//////////////////////////////////////////////////////////////////////////
-// This section above wraps for the C style APIs
-//////////////////////////////////////////////////////////////////////////
-
-#ifdef __LOC_DEBUG__
-
-double getDeltaSeconds(struct timespec from, struct timespec to) {
- return (double)to.tv_sec + (double)to.tv_nsec / 1000000000
- - from.tv_sec - (double)from.tv_nsec / 1000000000;
-}
-
-struct timespec getNow() {
- struct timespec now;
- clock_gettime(CLOCK_BOOTTIME, &now);
- return now;
-}
-
-class LocTimerTest : public LocTimer, public LocRankable {
- int mTimeOut;
- const struct timespec mTimeOfBirth;
- inline struct timespec getTimerWrapper(int timeout) {
- struct timespec now;
- clock_gettime(CLOCK_BOOTTIME, &now);
- now.tv_sec += timeout;
- return now;
- }
-public:
- inline LocTimerTest(int timeout) : LocTimer(), LocRankable(),
- mTimeOut(timeout), mTimeOfBirth(getTimerWrapper(0)) {}
- inline virtual int ranks(LocRankable& rankable) {
- LocTimerTest* timer = dynamic_cast<LocTimerTest*>(&rankable);
- return timer->mTimeOut - mTimeOut;
- }
- inline virtual void timeOutCallback() {
- printf("timeOutCallback() - ");
- deviation();
- }
- double deviation() {
- struct timespec now = getTimerWrapper(0);
- double delta = getDeltaSeconds(mTimeOfBirth, now);
- printf("%lf: %lf\n", delta, delta * 100 / mTimeOut);
- return delta / mTimeOut;
- }
-};
-
-// For Linux command line testing:
-// compilation:
-// g++ -D__LOC_HOST_DEBUG__ -D__LOC_DEBUG__ -g -I. -I../../../../system/core/include -o LocHeap.o LocHeap.cpp
-// g++ -D__LOC_HOST_DEBUG__ -D__LOC_DEBUG__ -g -std=c++0x -I. -I../../../../system/core/include -lpthread -o LocThread.o LocThread.cpp
-// g++ -D__LOC_HOST_DEBUG__ -D__LOC_DEBUG__ -g -I. -I../../../../system/core/include -o LocTimer.o LocTimer.cpp
-int main(int argc, char** argv) {
- struct timespec timeOfStart=getNow();
- srand(time(NULL));
- int tries = atoi(argv[1]);
- int checks = tries >> 3;
- LocTimerTest** timerArray = new LocTimerTest*[tries];
- memset(timerArray, NULL, tries);
-
- for (int i = 0; i < tries; i++) {
- int r = rand() % tries;
- LocTimerTest* timer = new LocTimerTest(r);
- if (timerArray[r]) {
- if (!timer->stop()) {
- printf("%lf:\n", getDeltaSeconds(timeOfStart, getNow()));
- printf("ERRER: %dth timer, id %d, not running when it should be\n", i, r);
- exit(0);
- } else {
- printf("stop() - %d\n", r);
- delete timer;
- timerArray[r] = NULL;
- }
- } else {
- if (!timer->start(r, false)) {
- printf("%lf:\n", getDeltaSeconds(timeOfStart, getNow()));
- printf("ERRER: %dth timer, id %d, running when it should not be\n", i, r);
- exit(0);
- } else {
- printf("stop() - %d\n", r);
- timerArray[r] = timer;
- }
- }
- }
-
- for (int i = 0; i < tries; i++) {
- if (timerArray[i]) {
- if (!timerArray[i]->stop()) {
- printf("%lf:\n", getDeltaSeconds(timeOfStart, getNow()));
- printf("ERRER: %dth timer, not running when it should be\n", i);
- exit(0);
- } else {
- printf("stop() - %d\n", i);
- delete timerArray[i];
- timerArray[i] = NULL;
- }
- }
- }
-
- delete[] timerArray;
-
- return 0;
-}
-
-#endif
diff --git a/utils/LocTimer.h b/utils/LocTimer.h
index abc7f64..c883de2 100644
--- a/utils/LocTimer.h
+++ b/utils/LocTimer.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015, 2020 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
@@ -33,6 +33,8 @@
#include <stddef.h>
#include <loc_pla.h>
+namespace loc_util {
+
// opaque class to provide service implementation.
class LocTimerDelegate;
class LocSharedLock;
@@ -71,4 +73,6 @@
virtual void timeOutCallback() = 0;
};
+} // namespace loc_util
+
#endif //__LOC_DELAY_H__
diff --git a/utils/LocUnorderedSetMap.h b/utils/LocUnorderedSetMap.h
index 8748134..7b25ad0 100644
--- a/utils/LocUnorderedSetMap.h
+++ b/utils/LocUnorderedSetMap.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015, 2017, 2020 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,8 +30,15 @@
#define __LOC_UNORDERDED_SETMAP_H__
#include <algorithm>
-#include <unordered_set>
-#include <unordered_map>
+#include <loc_pla.h>
+
+#ifdef NO_UNORDERED_SET_OR_MAP
+ #include <set>
+ #include <map>
+#else
+ #include <unordered_set>
+ #include <unordered_map>
+#endif
using std::unordered_set;
using std::unordered_map;
@@ -55,7 +62,7 @@
// *s1* and *s2* will be left with the intersect removed from them.
template <typename T>
static unordered_set<T> removeAndReturnInterset(unordered_set<T>& s1, unordered_set<T>& s2) {
- unordered_set<T> common(0);
+ unordered_set<T> common = {};
for (auto b = s2.begin(); b != s2.end(); b++) {
auto a = find(s1.begin(), s1.end(), *b);
if (a != s1.end()) {
@@ -73,7 +80,6 @@
class LocUnorderedSetMap {
unordered_map<KEY, unordered_set<VAL>> mMap;
-
// Trim the VALs pointed to by *iter*, with everything that also exist in *rVals*.
// If the set becomes empty, remove the map entry. *goneVals*, if not null, records
// the trimmed VALs.
@@ -89,7 +95,9 @@
public:
inline LocUnorderedSetMap() {}
- inline LocUnorderedSetMap(size_t size) : mMap(size) {}
+ inline LocUnorderedSetMap(size_t size) : LocUnorderedSetMap() {
+ mMap.get_allocator().allocate(size);
+ }
inline bool empty() { return mMap.empty(); }
@@ -104,12 +112,12 @@
// If the entry is not in the map, an empty set will be returned.
inline unordered_set<VAL> getValSet(const KEY& key) {
auto entry = mMap.find(key);
- return (entry != mMap.end()) ? entry->second : unordered_set<VAL>(0);
+ return (entry != mMap.end()) ? entry->second : unordered_set<VAL>{};
}
// This gets all the KEYs from the map
inline unordered_set<KEY> getKeys() {
- unordered_set<KEY> keys(0);
+ unordered_set<KEY> keys = {};
for (auto entry : mMap) {
keys.insert(entry.first);
}
@@ -128,6 +136,7 @@
unordered_set<KEY>* goneKeys, unordered_set<VAL>* goneVals) {
trimOrRemove(keys, rVals, goneKeys, goneVals);
}
+
inline void trimOrRemove(unordered_set<KEY>& keys, const unordered_set<VAL>& rVals,
unordered_set<KEY>* goneKeys, unordered_set<VAL>* goneVals) {
for (auto key : keys) {
@@ -161,6 +170,7 @@
unordered_set<KEY>* newKeys) {
add(keys, newVals, newKeys);
}
+
inline void add(const unordered_set<KEY>& keys, const unordered_set<VAL>& newVals,
unordered_set<KEY>* newKeys) {
for (auto key : keys) {
@@ -174,8 +184,7 @@
// in effect removed from the keyed VAL set in the map entry.
// This call would also remove those same VALs from *newVals*.
inline unordered_set<VAL> update(const KEY& key, unordered_set<VAL>& newVals) {
- unordered_set<VAL> goneVals(0);
-
+ unordered_set<VAL> goneVals = {};
if (newVals.empty()) {
mMap.erase(key);
} else {
diff --git a/utils/LogBuffer.cpp b/utils/LogBuffer.cpp
index 1bb6f0f..c280c82 100644
--- a/utils/LogBuffer.cpp
+++ b/utils/LogBuffer.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2019 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2019 - 2020 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
@@ -28,8 +28,13 @@
*/
#include "LogBuffer.h"
-#include <utils/Log.h>
+#ifdef USE_GLIB
+#include <execinfo.h>
+#endif
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
#define LOG_TAG "LocSvc_LogBuffer"
namespace loc_util {
@@ -131,7 +136,7 @@
void LogBuffer::registerSignalHandler() {
ALOGE("Singal handler registered");
mNewSigAction.sa_sigaction = &LogBuffer::signalHandler;
- mNewSigAction.sa_flags = SA_SIGINFO;
+ mNewSigAction.sa_flags = SA_SIGINFO | SA_RESTART;
sigemptyset(&mNewSigAction.sa_mask);
sigaction(SIGINT, &mNewSigAction, &mOriSigAction[SIGINT]);
@@ -145,6 +150,23 @@
void LogBuffer::signalHandler(const int code, siginfo_t *const si, void *const sc) {
ALOGE("[Gnss Log buffer]Singal handler, signal ID: %d", code);
+#ifdef USE_GLIB
+ int nptrs;
+ void *buffer[100];
+ char **strings;
+
+ nptrs = backtrace(buffer, sizeof(buffer)/sizeof(*buffer));
+ strings = backtrace_symbols(buffer, nptrs);
+ if (strings != NULL) {
+ timespec tv;
+ clock_gettime(CLOCK_BOOTTIME, &tv);
+ uint64_t elapsedTime = (uint64_t)tv.tv_sec + (uint64_t)tv.tv_nsec/1000000000;
+ for (int i = 0; i < nptrs; i++) {
+ string s(strings[i]);
+ mInstance->append(s, 0, elapsedTime);
+ }
+ }
+#endif
//Dump the log buffer to adb logcat
mInstance->dumpToAdbLogcat();
diff --git a/utils/Makefile.am b/utils/Makefile.am
index 72c7872..ada504c 100644
--- a/utils/Makefile.am
+++ b/utils/Makefile.am
@@ -31,7 +31,8 @@
loc_gps.h \
log_util.h \
LocSharedLock.h \
- LocUnorderedSetMap.h
+ LocUnorderedSetMap.h\
+ LocLoggerBase.h
libgps_utils_la_c_sources = \
linked_list.c \
diff --git a/utils/MsgTask.cpp b/utils/MsgTask.cpp
index 73a77fd..6ef689a 100644
--- a/utils/MsgTask.cpp
+++ b/utils/MsgTask.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2013, 2015, 2017The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, 2015, 2017, 2020 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,41 +36,33 @@
#include <loc_log.h>
#include <loc_pla.h>
+namespace loc_util {
+
+class MTRunnable : public LocRunnable {
+ const void* mQ;
+public:
+ inline MTRunnable(const void* q) : mQ(q) {}
+ virtual ~MTRunnable();
+ // Overrides of LocRunnable methods
+ // This method will be repeated called until it returns false; or
+ // until thread is stopped.
+ virtual bool run() override;
+
+ // The method to be run before thread loop (conditionally repeatedly)
+ // calls run()
+ virtual void prerun() override;
+
+ // to interrupt the run() method and come out of that
+ virtual void interrupt() override;
+};
+
static void LocMsgDestroy(void* msg) {
delete (LocMsg*)msg;
}
-MsgTask::MsgTask(LocThread::tCreate tCreator,
- const char* threadName, bool joinable) :
- mQ(msg_q_init2()), mThread(new LocThread()) {
- if (!mThread->start(tCreator, threadName, this, joinable)) {
- delete mThread;
- mThread = NULL;
- }
-}
-
-MsgTask::MsgTask(const char* threadName, bool joinable) :
- mQ(msg_q_init2()), mThread(new LocThread()) {
- if (!mThread->start(threadName, this, joinable)) {
- delete mThread;
- mThread = NULL;
- }
-}
-
-MsgTask::~MsgTask() {
- msg_q_flush((void*)mQ);
- msg_q_destroy((void**)&mQ);
-}
-
-void MsgTask::destroy() {
- LocThread* thread = mThread;
- msg_q_unblock((void*)mQ);
- if (thread) {
- mThread = NULL;
- delete thread;
- } else {
- delete this;
- }
+MsgTask::MsgTask(const char* threadName) :
+ mQ(msg_q_init2()), mThread() {
+ mThread.start(threadName, std::make_shared<MTRunnable>(mQ));
}
void MsgTask::sendMsg(const LocMsg* msg) const {
@@ -82,14 +74,27 @@
}
}
-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 */
+void MsgTask::sendMsg(const std::function<void()> runnable) const {
+ struct RunMsg : public LocMsg {
+ const std::function<void()> mRunnable;
+ public:
+ inline RunMsg(const std::function<void()> runnable) : mRunnable(runnable) {}
+ ~RunMsg() = default;
+ inline virtual void proc() const override { mRunnable(); }
+ };
+ sendMsg(new RunMsg(runnable));
}
-bool MsgTask::run() {
+void MTRunnable::interrupt() {
+ msg_q_unblock((void*)mQ);
+}
+
+void MTRunnable::prerun() {
+ // make sure we do not run in background scheduling group
+ set_sched_policy(gettid(), SP_FOREGROUND);
+}
+
+bool MTRunnable::run() {
LocMsg* msg;
msq_q_err_type result = msg_q_rcv((void*)mQ, (void **)&msg);
if (eMSG_Q_SUCCESS != result) {
@@ -106,3 +111,10 @@
return true;
}
+
+MTRunnable::~MTRunnable() {
+ msg_q_flush((void*)mQ);
+ msg_q_destroy((void**)&mQ);
+}
+
+} // namespace loc_util
diff --git a/utils/MsgTask.h b/utils/MsgTask.h
index 9eb1f56..a8cce9e 100644
--- a/utils/MsgTask.h
+++ b/utils/MsgTask.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2013,2015 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, 2015, 2020 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
@@ -29,8 +29,11 @@
#ifndef __MSG_TASK__
#define __MSG_TASK__
+#include <functional>
#include <LocThread.h>
+namespace loc_util {
+
struct LocMsg {
inline LocMsg() {}
inline virtual ~LocMsg() {}
@@ -38,30 +41,16 @@
inline virtual void log() const {}
};
-class MsgTask : public LocRunnable {
+class MsgTask {
const void* mQ;
- LocThread* mThread;
- friend class LocThreadDelegate;
-protected:
- virtual ~MsgTask();
+ LocThread mThread;
public:
- MsgTask(LocThread::tCreate tCreator, const char* threadName = NULL, bool joinable = true);
- MsgTask(const char* threadName = NULL, bool joinable = true);
- // this obj will be deleted once thread is deleted
- void destroy();
+ ~MsgTask() = default;
+ MsgTask(const char* threadName = NULL);
void sendMsg(const LocMsg* msg) const;
- // Overrides of LocRunnable methods
- // This method will be repeated called until it returns false; or
- // until thread is stopped.
- virtual bool run();
-
- // The method to be run before thread loop (conditionally repeatedly)
- // calls run()
- virtual void prerun();
-
- // The method to be run after thread loop (conditionally repeatedly)
- // calls run()
- inline virtual void postrun() {}
+ void sendMsg(const std::function<void()> runnable) const;
};
+} //
+
#endif //__MSG_TASK__
diff --git a/utils/gps_extended_c.h b/utils/gps_extended_c.h
index f4ad524..f368975 100644
--- a/utils/gps_extended_c.h
+++ b/utils/gps_extended_c.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2019 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2020 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
@@ -115,6 +115,9 @@
#define LOC_POS_TECH_MASK_AFLT ((LocPosTechMask)0x00000040)
#define LOC_POS_TECH_MASK_HYBRID ((LocPosTechMask)0x00000080)
#define LOC_POS_TECH_MASK_PPE ((LocPosTechMask)0x00000100)
+#define LOC_POS_TECH_MASK_VEH ((LocPosTechMask)0x00000200)
+#define LOC_POS_TECH_MASK_VIS ((LocPosTechMask)0x00000400)
+
enum loc_registration_mask_status {
LOC_REGISTRATION_MASK_ENABLED,
@@ -132,7 +135,11 @@
LOC_SUPPORTED_FEATURE_AGPM_V02, /**< Support AGPM feature */
LOC_SUPPORTED_FEATURE_XTRA_INTEGRITY, /**< Support XTRA integrity */
LOC_SUPPORTED_FEATURE_FDCL_2, /**< Support FDCL V2 */
- LOC_SUPPORTED_FEATURE_LOCATION_PRIVACY /**< Support location privacy */
+ LOC_SUPPORTED_FEATURE_LOCATION_PRIVACY, /**< Support location privacy */
+ LOC_SUPPORTED_FEATURE_NAVIC, /**< Support NAVIC constellation */
+ LOC_SUPPORTED_FEATURE_MEASUREMENTS_CORRECTION, /**< Support measurements correction */
+ LOC_SUPPORTED_FEATURE_ROBUST_LOCATION, /**< Support Robust Location feature */
+ LOC_SUPPORTED_FEATURE_EDGNSS /**< Support precise location dgnss */
} loc_supported_feature_enum;
typedef struct {
@@ -390,7 +397,30 @@
#define GPS_LOCATION_EXTENDED_HAS_OUTPUT_ENG_TYPE 0x2000000000
/** GpsLocationExtended has the engine mask that indicates the
* set of engines contribute to the fix. */
-#define GPS_LOCATION_EXTENDED_HAS_OUTPUT_ENG_MASK 0x4000000000
+#define GPS_LOCATION_EXTENDED_HAS_OUTPUT_ENG_MASK 0x4000000000
+/** GpsLocationExtended has dgnss correction source */
+#define GPS_LOCATION_EXTENDED_HAS_DGNSS_CORRECTION_SOURCE_TYPE 0x8000000000
+/** GpsLocationExtended has dgnss correction source ID */
+#define GPS_LOCATION_EXTENDED_HAS_DGNSS_CORRECTION_SOURCE_ID 0x10000000000
+/** GpsLocationExtended has dgnss constellation usage */
+#define GPS_LOCATION_EXTENDED_HAS_DGNSS_CONSTELLATION_USAGE 0x20000000000
+/** GpsLocationExtended has dgnss ref station Id */
+#define GPS_LOCATION_EXTENDED_HAS_DGNSS_REF_STATION_ID 0x40000000000
+/** GpsLocationExtended has dgnss data age */
+#define GPS_LOCATION_EXTENDED_HAS_DGNSS_DATA_AGE 0x80000000000
+ /** GpsLocationExtended has the conformityIndex computed from
+ * robust location feature. */
+#define GPS_LOCATION_EXTENDED_HAS_CONFORMITY_INDEX 0x100000000000
+ /** GpsLocationExtended has the llaVRPased. */
+#define GPS_LOCATION_EXTENDED_HAS_LLA_VRP_BASED 0x200000000000
+/** GpsLocationExtended has the velocityVRPased. */
+#define GPS_LOCATION_EXTENDED_HAS_ENU_VELOCITY_LLA_VRP_BASED 0x400000000000
+/** GpsLocationExtended has upperTriangleFullCovMatrix. */
+#define GPS_LOCATION_EXTENDED_HAS_UPPER_TRIANGLE_FULL_COV_MATRIX 0x800000000000
+/** GpsLocationExtended has drSolutionStatusMask. */
+#define GPS_LOCATION_EXTENDED_HAS_DR_SOLUTION_STATUS_MASK 0x1000000000000
+/** GpsLocationExtended has altitudeAssumed. */
+#define GPS_LOCATION_EXTENDED_HAS_ALTITUDE_ASSUMED 0x2000000000000
typedef uint32_t LocNavSolutionMask;
/* Bitmask to specify whether SBAS ionospheric correction is used */
@@ -409,6 +439,8 @@
#define LOC_NAV_MASK_PPP_CORRECTION ((LocNavSolutionMask)0x0040)
/**< Bitmask to specify whether Position Report is RTK fixed corrected */
#define LOC_NAV_MASK_RTK_FIXED_CORRECTION ((LocNavSolutionMask)0x0080)
+/**< Bitmask specifying whether only SBAS corrected SVs are used for the fix */
+#define LOC_NAV_MASK_ONLY_SBAS_CORRECTED_SV_USED ((LocNavSolutionMask)0x0100)
typedef uint32_t LocPosDataMask;
/* Bitmask to specify whether Navigation data has Forward Acceleration */
@@ -442,18 +474,29 @@
/** 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 SBAS_SV_PRN_MIN 120
+#define SBAS_SV_PRN_MAX 191
#define QZSS_SV_PRN_MIN 193
#define QZSS_SV_PRN_MAX 197
#define BDS_SV_PRN_MIN 201
-#define BDS_SV_PRN_MAX 237
+#define BDS_SV_PRN_MAX 263
#define GAL_SV_PRN_MIN 301
#define GAL_SV_PRN_MAX 336
#define NAVIC_SV_PRN_MIN 401
#define NAVIC_SV_PRN_MAX 414
+#define GLO_SV_PRN_SLOT_UNKNOWN 255
+
+/* Checking svIdOneBase can be set to the corresponding bit in mask */
+#define svFitsMask(mask, svIdOneBase) \
+ ((svIdOneBase) >= 1 && (svIdOneBase) <= (sizeof(mask) << 3))
+/* Setting svIdOneBase specific bit in the mask if the bit offset fits */
+#define setSvMask(mask, svIdOneBase) \
+ if (svFitsMask(mask, svIdOneBase)) mask |= (1ULL << ((svIdOneBase) - 1))
+
+#define isValInRangeInclusive(val, min, max) ((val) >= (min) && (val) <= (max))
+#define isGloSlotUnknown(val) ((val) == GLO_SV_PRN_SLOT_UNKNOWN)
typedef enum {
LOC_RELIABILITY_NOT_SET = 0,
@@ -573,6 +616,13 @@
#define CARRIER_PHASE_AMBIGUITY_RESOLUTION_FLOAT ((CarrierPhaseAmbiguityType)1)
#define CARRIER_PHASE_AMBIGUITY_RESOLUTION_FIXED ((CarrierPhaseAmbiguityType)2)
+
+typedef enum {
+ LOC_DGNSS_CORR_SOURCE_TYPE_INVALID = 0, /**< Invalid DGNSS correction source type \n */
+ LOC_DGNSS_CORR_SOURCE_TYPE_RTCM = 1, /**< DGNSS correction source type RTCM \n */
+ LOC_DGNSS_CORR_SOURCE_TYPE_3GPP = 2, /**< DGNSS correction source type 3GPP \n */
+}LocDgnssCorrectionSourceType;
+
typedef uint16_t GnssMeasUsageStatusBitMask;
/** Used in fix */
#define GNSS_MEAS_USED_IN_PVT ((GnssMeasUsageStatusBitMask)0x00000001ul)
@@ -613,7 +663,6 @@
#define GNSS_SV_POLY_DELETE_VALID_V02 ((GnssSvPolyStatusMaskValidity)0x04)
#define GNSS_SV_POLY_SRC_GAL_FNAV_OR_INAV_VALID_V02 ((GnssSvPolyStatusMaskValidity)0x08)
-
typedef struct {
/** Specifies GNSS signal type
Mandatory Field*/
@@ -621,13 +670,15 @@
/** Specifies GNSS Constellation Type
Mandatory Field*/
Gnss_LocSvSystemEnumType gnssConstellation;
- /** GNSS SV ID.
- For GPS: 1 to 32
- For GLONASS: 65 to 96. When slot-number to SV ID mapping is unknown, set as 255.
- For SBAS: 120 to 151
- For QZSS-L1CA:193 to 197
- For BDS: 201 to 237
- For GAL: 301 to 336 */
+ /** Unique SV Identifier.
+ * SV Range for supported constellation is specified as below:
+ * - For GPS: 1 to 32
+ * - For GLONASS: 65 to 96
+ * - For SBAS: 120 to 158 and 183 to 191
+ * - For QZSS: 193 to 197
+ * - For BDS: 201 to 263
+ * - For GAL: 301 to 336
+ * - For NAVIC: 401 to 414 */
uint16_t gnssSvId;
/** GLONASS frequency number + 7.
Valid only for a GLONASS system and
@@ -655,7 +706,7 @@
float carrierPhasAmbiguity;
} GpsMeasUsageInfo;
-
+#define COV_MATRIX_SIZE 12
/** Represents gps location extended. */
typedef struct {
/** set to sizeof(GpsLocationExtended) */
@@ -761,22 +812,74 @@
/** Sensor calibration confidence percent. Range: 0 - 100 */
uint8_t calibrationConfidence;
DrCalibrationStatusMask calibrationStatus;
- /* location engine type. When the fix. when the type is set to
+ /** location engine type. When the fix. when the type is set to
LOC_ENGINE_SRC_FUSED, the fix is the propagated/aggregated
reports from all engines running on the system (e.g.:
DR/SPE/PPE). To check which location engine contributes to
the fused output, check for locOutputEngMask. */
LocOutputEngineType locOutputEngType;
- /* when loc output eng type is set to fused, this field
+ /** when loc output eng type is set to fused, this field
indicates the set of engines contribute to the fix. */
PositioningEngineMask locOutputEngMask;
-} GpsLocationExtended;
-enum loc_sess_status {
- LOC_SESS_SUCCESS,
- LOC_SESS_INTERMEDIATE,
- LOC_SESS_FAILURE
-};
+ /** DGNSS Correction Source for position report: RTCM, 3GPP
+ * etc. */
+ LocDgnssCorrectionSourceType dgnssCorrectionSourceType;
+
+ /** If DGNSS is used, the SourceID is a 32bit number identifying
+ * the DGNSS source ID */
+ uint32_t dgnssCorrectionSourceID;
+
+ /** If DGNSS is used, which constellation was DGNSS used for to
+ * produce the pos report. */
+ GnssConstellationTypeMask dgnssConstellationUsage;
+
+ /** If DGNSS is used, DGNSS Reference station ID used for
+ * position report */
+ uint16_t dgnssRefStationId;
+
+ /** If DGNSS is used, DGNSS data age in milli-seconds */
+ uint32_t dgnssDataAgeMsec;
+
+ /** When robust location is enabled, this field
+ * will how well the various input data considered for
+ * navigation solution conform to expectations.
+ * Range: 0 (least conforming) to 1 (most conforming) */
+ float conformityIndex;
+ GnssLocationPositionDynamicsExt bodyFrameDataExt;
+ /** VRR-based latitude/longitude/altitude */
+ LLAInfo llaVRPBased;
+ /** VRR-based east, north, and up velocity */
+ float enuVelocityVRPBased[3];
+ /** Upper triangle elements of full matrix of position and
+ velocity estimate in ECEF
+
+ The full covariance matrix of PPE position
+ (x, y, z in ECEF, in the unit of meters) estimate is a 3x3 matrix
+ | px,x px,y px,z |
+ | py,x py,y py,z |
+ | pz,x pz,y pz,z |
+
+ The full covariance matrix of PPE velocity
+ (vx,vy, vz in ECEF, in the unit of m/s) estimate is a 3x3 matrix
+ | pvx,vx pvx,vy pvx,vz |
+ | pvy,vx pvy,vy pvy,vz |
+ | pvz,vx pvz,vy pvz,vz |
+
+ upperTriangleFullCovMatrix =
+ { px,x, px,y, px,z, py,y, py,z, pz,z, pvx,vx, pvx,vy, pvx,vz, pvy,vy, pvy,vz, pvz,vz}
+ Uint: px,x, px,y, px,z, py,y, py,z, pz,z is in meter
+ pvx,vx, pvx,vy, pvx,vz, pvy,vy, pvy,vz, pvz,vz is in meters/seconds
+ */
+ float upperTriangleFullCovMatrix[COV_MATRIX_SIZE];
+ DrSolutionStatusMask drSolutionStatusMask;
+ /** When this field is valid, it will indicates whether altitude
+ * is assumed or calculated.
+ * false: Altitude is calculated.
+ * true: Altitude is assumed; there may not be enough
+ * satellites to determine the precise altitude. */
+ bool altitudeAssumed;
+} GpsLocationExtended;
// struct that contains complete position info from engine
typedef struct {
@@ -818,6 +921,7 @@
#define LOC_NMEA_MASK_GQGSV_V02 ((NmeaSentenceTypesMask)0x10000000) /**< Enable GQGSV type */
#define LOC_NMEA_MASK_GIGSV_V02 ((NmeaSentenceTypesMask)0x20000000) /**< Enable GIGSV type */
#define LOC_NMEA_MASK_GNDTM_V02 ((NmeaSentenceTypesMask)0x40000000) /**< Enable GNDTM type */
+#define LOC_NMEA_MASK_TAGBLOCK_V02 ((NmeaSentenceTypesMask)0x80000000) /**< Enable TAGBLOCK type */
// all bitmasks of general supported NMEA sentenses - debug is not part of this
@@ -912,41 +1016,42 @@
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_LATENCY_INFORMATION_REPORT, // Latency information report
LOC_API_ADAPTER_EVENT_MAX
};
-#define LOC_API_ADAPTER_BIT_PARSED_POSITION_REPORT (1<<LOC_API_ADAPTER_REPORT_POSITION)
-#define LOC_API_ADAPTER_BIT_SATELLITE_REPORT (1<<LOC_API_ADAPTER_REPORT_SATELLITE)
-#define LOC_API_ADAPTER_BIT_NMEA_1HZ_REPORT (1<<LOC_API_ADAPTER_REPORT_NMEA_1HZ)
-#define LOC_API_ADAPTER_BIT_NMEA_POSITION_REPORT (1<<LOC_API_ADAPTER_REPORT_NMEA_POSITION)
-#define LOC_API_ADAPTER_BIT_NI_NOTIFY_VERIFY_REQUEST (1<<LOC_API_ADAPTER_REQUEST_NI_NOTIFY_VERIFY)
-#define LOC_API_ADAPTER_BIT_ASSISTANCE_DATA_REQUEST (1<<LOC_API_ADAPTER_REQUEST_ASSISTANCE_DATA)
-#define LOC_API_ADAPTER_BIT_LOCATION_SERVER_REQUEST (1<<LOC_API_ADAPTER_REQUEST_LOCATION_SERVER)
-#define LOC_API_ADAPTER_BIT_IOCTL_REPORT (1<<LOC_API_ADAPTER_REPORT_IOCTL)
-#define LOC_API_ADAPTER_BIT_STATUS_REPORT (1<<LOC_API_ADAPTER_REPORT_STATUS)
-#define LOC_API_ADAPTER_BIT_REQUEST_WIFI (1<<LOC_API_ADAPTER_REQUEST_WIFI)
-#define LOC_API_ADAPTER_BIT_SENSOR_STATUS (1<<LOC_API_ADAPTER_SENSOR_STATUS)
-#define LOC_API_ADAPTER_BIT_REQUEST_TIME_SYNC (1<<LOC_API_ADAPTER_REQUEST_TIME_SYNC)
-#define LOC_API_ADAPTER_BIT_REPORT_SPI (1<<LOC_API_ADAPTER_REPORT_SPI)
-#define LOC_API_ADAPTER_BIT_REPORT_NI_GEOFENCE (1<<LOC_API_ADAPTER_REPORT_NI_GEOFENCE)
-#define LOC_API_ADAPTER_BIT_GEOFENCE_GEN_ALERT (1<<LOC_API_ADAPTER_GEOFENCE_GEN_ALERT)
-#define LOC_API_ADAPTER_BIT_REPORT_GENFENCE_BREACH (1<<LOC_API_ADAPTER_REPORT_GENFENCE_BREACH)
-#define LOC_API_ADAPTER_BIT_BATCHED_GENFENCE_BREACH_REPORT (1<<LOC_API_ADAPTER_BATCHED_GENFENCE_BREACH_REPORT)
-#define LOC_API_ADAPTER_BIT_PEDOMETER_CTRL (1<<LOC_API_ADAPTER_PEDOMETER_CTRL)
-#define LOC_API_ADAPTER_BIT_MOTION_CTRL (1<<LOC_API_ADAPTER_MOTION_CTRL)
-#define LOC_API_ADAPTER_BIT_REQUEST_WIFI_AP_DATA (1<<LOC_API_ADAPTER_REQUEST_WIFI_AP_DATA)
-#define LOC_API_ADAPTER_BIT_BATCH_FULL (1<<LOC_API_ADAPTER_BATCH_FULL)
-#define LOC_API_ADAPTER_BIT_BATCHED_POSITION_REPORT (1<<LOC_API_ADAPTER_BATCHED_POSITION_REPORT)
-#define LOC_API_ADAPTER_BIT_GNSS_MEASUREMENT_REPORT (1<<LOC_API_ADAPTER_GNSS_MEASUREMENT_REPORT)
-#define LOC_API_ADAPTER_BIT_GNSS_SV_POLYNOMIAL_REPORT (1<<LOC_API_ADAPTER_GNSS_SV_POLYNOMIAL_REPORT)
-#define LOC_API_ADAPTER_BIT_GDT_UPLOAD_BEGIN_REQ (1<<LOC_API_ADAPTER_GDT_UPLOAD_BEGIN_REQ)
-#define LOC_API_ADAPTER_BIT_GDT_UPLOAD_END_REQ (1<<LOC_API_ADAPTER_GDT_UPLOAD_END_REQ)
-#define LOC_API_ADAPTER_BIT_GNSS_MEASUREMENT (1<<LOC_API_ADAPTER_GNSS_MEASUREMENT)
-#define LOC_API_ADAPTER_BIT_REQUEST_TIMEZONE (1<<LOC_API_ADAPTER_REQUEST_TIMEZONE)
-#define LOC_API_ADAPTER_BIT_REPORT_GENFENCE_DWELL (1<<LOC_API_ADAPTER_REPORT_GENFENCE_DWELL_REPORT)
-#define LOC_API_ADAPTER_BIT_REQUEST_SRN_DATA (1<<LOC_API_ADAPTER_REQUEST_SRN_DATA)
-#define LOC_API_ADAPTER_BIT_POSITION_INJECTION_REQUEST (1<<LOC_API_ADAPTER_REQUEST_POSITION_INJECTION)
-#define LOC_API_ADAPTER_BIT_BATCH_STATUS (1<<LOC_API_ADAPTER_BATCH_STATUS)
+#define LOC_API_ADAPTER_BIT_PARSED_POSITION_REPORT (1ULL<<LOC_API_ADAPTER_REPORT_POSITION)
+#define LOC_API_ADAPTER_BIT_SATELLITE_REPORT (1ULL<<LOC_API_ADAPTER_REPORT_SATELLITE)
+#define LOC_API_ADAPTER_BIT_NMEA_1HZ_REPORT (1ULL<<LOC_API_ADAPTER_REPORT_NMEA_1HZ)
+#define LOC_API_ADAPTER_BIT_NMEA_POSITION_REPORT (1ULL<<LOC_API_ADAPTER_REPORT_NMEA_POSITION)
+#define LOC_API_ADAPTER_BIT_NI_NOTIFY_VERIFY_REQUEST (1ULL<<LOC_API_ADAPTER_REQUEST_NI_NOTIFY_VERIFY)
+#define LOC_API_ADAPTER_BIT_ASSISTANCE_DATA_REQUEST (1ULL<<LOC_API_ADAPTER_REQUEST_ASSISTANCE_DATA)
+#define LOC_API_ADAPTER_BIT_LOCATION_SERVER_REQUEST (1ULL<<LOC_API_ADAPTER_REQUEST_LOCATION_SERVER)
+#define LOC_API_ADAPTER_BIT_IOCTL_REPORT (1ULL<<LOC_API_ADAPTER_REPORT_IOCTL)
+#define LOC_API_ADAPTER_BIT_STATUS_REPORT (1ULL<<LOC_API_ADAPTER_REPORT_STATUS)
+#define LOC_API_ADAPTER_BIT_REQUEST_WIFI (1ULL<<LOC_API_ADAPTER_REQUEST_WIFI)
+#define LOC_API_ADAPTER_BIT_SENSOR_STATUS (1ULL<<LOC_API_ADAPTER_SENSOR_STATUS)
+#define LOC_API_ADAPTER_BIT_REQUEST_TIME_SYNC (1ULL<<LOC_API_ADAPTER_REQUEST_TIME_SYNC)
+#define LOC_API_ADAPTER_BIT_REPORT_SPI (1ULL<<LOC_API_ADAPTER_REPORT_SPI)
+#define LOC_API_ADAPTER_BIT_REPORT_NI_GEOFENCE (1ULL<<LOC_API_ADAPTER_REPORT_NI_GEOFENCE)
+#define LOC_API_ADAPTER_BIT_GEOFENCE_GEN_ALERT (1ULL<<LOC_API_ADAPTER_GEOFENCE_GEN_ALERT)
+#define LOC_API_ADAPTER_BIT_REPORT_GENFENCE_BREACH (1ULL<<LOC_API_ADAPTER_REPORT_GENFENCE_BREACH)
+#define LOC_API_ADAPTER_BIT_BATCHED_GENFENCE_BREACH_REPORT (1ULL<<LOC_API_ADAPTER_BATCHED_GENFENCE_BREACH_REPORT)
+#define LOC_API_ADAPTER_BIT_PEDOMETER_CTRL (1ULL<<LOC_API_ADAPTER_PEDOMETER_CTRL)
+#define LOC_API_ADAPTER_BIT_MOTION_CTRL (1ULL<<LOC_API_ADAPTER_MOTION_CTRL)
+#define LOC_API_ADAPTER_BIT_REQUEST_WIFI_AP_DATA (1ULL<<LOC_API_ADAPTER_REQUEST_WIFI_AP_DATA)
+#define LOC_API_ADAPTER_BIT_BATCH_FULL (1ULL<<LOC_API_ADAPTER_BATCH_FULL)
+#define LOC_API_ADAPTER_BIT_BATCHED_POSITION_REPORT (1ULL<<LOC_API_ADAPTER_BATCHED_POSITION_REPORT)
+#define LOC_API_ADAPTER_BIT_GNSS_MEASUREMENT_REPORT (1ULL<<LOC_API_ADAPTER_GNSS_MEASUREMENT_REPORT)
+#define LOC_API_ADAPTER_BIT_GNSS_SV_POLYNOMIAL_REPORT (1ULL<<LOC_API_ADAPTER_GNSS_SV_POLYNOMIAL_REPORT)
+#define LOC_API_ADAPTER_BIT_GDT_UPLOAD_BEGIN_REQ (1ULL<<LOC_API_ADAPTER_GDT_UPLOAD_BEGIN_REQ)
+#define LOC_API_ADAPTER_BIT_GDT_UPLOAD_END_REQ (1ULL<<LOC_API_ADAPTER_GDT_UPLOAD_END_REQ)
+#define LOC_API_ADAPTER_BIT_GNSS_MEASUREMENT (1ULL<<LOC_API_ADAPTER_GNSS_MEASUREMENT)
+#define LOC_API_ADAPTER_BIT_REQUEST_TIMEZONE (1ULL<<LOC_API_ADAPTER_REQUEST_TIMEZONE)
+#define LOC_API_ADAPTER_BIT_REPORT_GENFENCE_DWELL (1ULL<<LOC_API_ADAPTER_REPORT_GENFENCE_DWELL_REPORT)
+#define LOC_API_ADAPTER_BIT_REQUEST_SRN_DATA (1ULL<<LOC_API_ADAPTER_REQUEST_SRN_DATA)
+#define LOC_API_ADAPTER_BIT_POSITION_INJECTION_REQUEST (1ULL<<LOC_API_ADAPTER_REQUEST_POSITION_INJECTION)
+#define LOC_API_ADAPTER_BIT_BATCH_STATUS (1ULL<<LOC_API_ADAPTER_BATCH_STATUS)
#define LOC_API_ADAPTER_BIT_FDCL_SERVICE_REQ (1ULL<<LOC_API_ADAPTER_FDCL_SERVICE_REQ)
#define LOC_API_ADAPTER_BIT_PARSED_UNPROPAGATED_POSITION_REPORT (1ULL<<LOC_API_ADAPTER_REPORT_UNPROPAGATED_POSITION)
#define LOC_API_ADAPTER_BIT_BS_OBS_DATA_SERVICE_REQ (1ULL<<LOC_API_ADAPTER_BS_OBS_DATA_SERVICE_REQ)
@@ -954,6 +1059,7 @@
#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)
+#define LOC_API_ADAPTER_BIT_LATENCY_INFORMATION (1ULL<<LOC_API_ADAPTER_LATENCY_INFORMATION_REPORT)
typedef uint64_t LOC_API_ADAPTER_EVENT_MASK_T;
@@ -977,11 +1083,11 @@
#define isGpsLockMT(lock) ((lock) & ((LOC_GPS_LOCK_MASK)2))
#define isGpsLockAll(lock) (((lock) & ((LOC_GPS_LOCK_MASK)3)) == 3)
-/*++ ***********************************************
+/* ***********************************************
** Satellite Measurement and Satellite Polynomial
-** Structure definitions
-** ***********************************************
---*/
+** structure definitions
+** ***********************************************
+*/
#define GNSS_SV_POLY_VELOCITY_COEF_MAX_SIZE 12
#define GNSS_SV_POLY_XYZ_0_TH_ORDER_COEFF_MAX_SIZE 3
#define GNSS_SV_POLY_XYZ_N_TH_ORDER_COEFF_MAX_SIZE 9
@@ -1173,20 +1279,26 @@
/**< Satellite Doppler measured */
GNSS_LOC_MEAS_STATUS_VELOCITY_FINE = 0x00000020,
/**< TRUE: Fine Doppler measured, FALSE: Coarse Doppler measured */
+ GNSS_LOC_MEAS_STATUS_LP_VALID = 0x00000040,
+ /**< TRUE/FALSE -- Lock Point is valid/invalid */
+ GNSS_LOC_MEAS_STATUS_LP_POS_VALID = 0x00000080,
+ /**< TRUE/FALSE -- Lock Point is positive/negative */
GNSS_LOC_MEAS_STATUS_FROM_RNG_DIFF = 0x00000200,
/**< Range update from Satellite differences */
GNSS_LOC_MEAS_STATUS_FROM_VE_DIFF = 0x00000400,
/**< Doppler update from Satellite differences */
GNSS_LOC_MEAS_STATUS_DONT_USE_X = 0x00000800,
/**< Don't use measurement if bit is set */
- GNSS_LOC_MEAS_STATUS_DONT_USE_M = 0x000001000,
+ GNSS_LOC_MEAS_STATUS_DONT_USE_M = 0x00001000,
/**< Don't use measurement if bit is set */
- GNSS_LOC_MEAS_STATUS_DONT_USE_D = 0x000002000,
+ GNSS_LOC_MEAS_STATUS_DONT_USE_D = 0x00002000,
/**< Don't use measurement if bit is set */
- GNSS_LOC_MEAS_STATUS_DONT_USE_S = 0x000004000,
+ GNSS_LOC_MEAS_STATUS_DONT_USE_S = 0x00004000,
/**< Don't use measurement if bit is set */
- GNSS_LOC_MEAS_STATUS_DONT_USE_P = 0x000008000
+ GNSS_LOC_MEAS_STATUS_DONT_USE_P = 0x00008000,
/**< Don't use measurement if bit is set */
+ GNSS_LOC_MEAS_STATUS_GNSS_FRESH_MEAS = 0x08000000
+ /**< TRUE -- Fresh GNSS measurement observed in last second */
}Gnss_LocSvMeasStatusMaskType;
typedef struct
@@ -1249,6 +1361,25 @@
/**< SV is being tracked */
}Gnss_LocSvSearchStatusEnumT;
+typedef uint32_t LocSvDgnssMeasStatusMask;
+#define LOC_MASK_DGNSS_EPOCH_TIME_VALID 0x1 /**< DGNSS Epoch time is valid */
+#define LOC_MASK_DGNSS_MEAS_STATUS_PR_VALID 0x2 /**< Pseudo Range correction is valid */
+#define LOC_MASK_DGNSS_MEAS_STATUS_PRR_VALID 0x4 /**< Pseudo Range rate correction is valid */
+
+typedef struct {
+ LocSvDgnssMeasStatusMask dgnssMeasStatus;
+ /**< Bitmask indicating the DGNSS SV measurement status. */
+
+ uint32_t diffDataEpochTimeMsec;
+ /**< Age of differential data in Milli Seconds with respect to the Measurement time. */
+
+ float prCorrMeters;
+ /**< Pseudo Range correction in meters. */
+
+ float prrCorrMetersPerSec;
+ /**< Pseudo Range rate correction in meters per second. */
+} Gnss_LocDgnssSVMeasurement;
+
typedef struct
{
uint32_t size;
@@ -1256,15 +1387,9 @@
// 0 signal type mask indicates invalid value
GnssSignalTypeMask gnssSignalTypeMask;
uint16_t gnssSvId;
- /**< GNSS SV ID.
- \begin{itemize1}
- \item Range: \begin{itemize1}
- \item For GPS: 1 to 32
- \item For GLONASS: 1 to 32
- \item For SBAS: 120 to 151
- \item For BDS: 201 to 237
- \end{itemize1} \end{itemize1}
- The GPS and GLONASS SVs can be disambiguated using the system field.
+ /** Unique SV Identifier.
+ * For SV Range of supported constellation, please refer to the
+ * comment section of gnssSvId in GpsMeasUsageInfo.
*/
uint8_t gloFrequency;
/**< GLONASS frequency number + 7 \n
@@ -1388,38 +1513,48 @@
float carrierPhaseUnc;
-
+ /** < DGNSS Measurements Report for SVs */
+ Gnss_LocDgnssSVMeasurement dgnssSvMeas;
} Gnss_SVMeasurementStructType;
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_GLO_SYSTEM_TIME_EXT 0x00040000
-#define GNSS_SV_MEAS_HEADER_HAS_GPSL1L5_TIME_BIAS 0x00080000
-#define GNSS_SV_MEAS_HEADER_HAS_GALE1E5A_TIME_BIAS 0x00100000
-#define GNSS_SV_MEAS_HEADER_HAS_GPS_NAVIC_INTER_SYSTEM_BIAS 0x00200000
-#define GNSS_SV_MEAS_HEADER_HAS_GAL_NAVIC_INTER_SYSTEM_BIAS 0x00400000
-#define GNSS_SV_MEAS_HEADER_HAS_GLO_NAVIC_INTER_SYSTEM_BIAS 0x00800000
-#define GNSS_SV_MEAS_HEADER_HAS_BDS_NAVIC_INTER_SYSTEM_BIAS 0x01000000
-#define GNSS_SV_MEAS_HEADER_HAS_NAVIC_SYSTEM_TIME 0x02000000
-#define GNSS_SV_MEAS_HEADER_HAS_NAVIC_SYSTEM_TIME_EXT 0x04000000
+#define GNSS_SV_MEAS_HEADER_HAS_LEAP_SECOND 0x000000001
+#define GNSS_SV_MEAS_HEADER_HAS_CLOCK_FREQ 0x000000002
+#define GNSS_SV_MEAS_HEADER_HAS_AP_TIMESTAMP 0x000000004
+#define GNSS_SV_MEAS_HEADER_HAS_GPS_GLO_INTER_SYSTEM_BIAS 0x000000008
+#define GNSS_SV_MEAS_HEADER_HAS_GPS_BDS_INTER_SYSTEM_BIAS 0x000000010
+#define GNSS_SV_MEAS_HEADER_HAS_GPS_GAL_INTER_SYSTEM_BIAS 0x000000020
+#define GNSS_SV_MEAS_HEADER_HAS_BDS_GLO_INTER_SYSTEM_BIAS 0x000000040
+#define GNSS_SV_MEAS_HEADER_HAS_GAL_GLO_INTER_SYSTEM_BIAS 0x000000080
+#define GNSS_SV_MEAS_HEADER_HAS_GAL_BDS_INTER_SYSTEM_BIAS 0x000000100
+#define GNSS_SV_MEAS_HEADER_HAS_GPS_SYSTEM_TIME 0x000000200
+#define GNSS_SV_MEAS_HEADER_HAS_GAL_SYSTEM_TIME 0x000000400
+#define GNSS_SV_MEAS_HEADER_HAS_BDS_SYSTEM_TIME 0x000000800
+#define GNSS_SV_MEAS_HEADER_HAS_QZSS_SYSTEM_TIME 0x000001000
+#define GNSS_SV_MEAS_HEADER_HAS_GLO_SYSTEM_TIME 0x000002000
+#define GNSS_SV_MEAS_HEADER_HAS_GPS_SYSTEM_TIME_EXT 0x000004000
+#define GNSS_SV_MEAS_HEADER_HAS_GAL_SYSTEM_TIME_EXT 0x000008000
+#define GNSS_SV_MEAS_HEADER_HAS_BDS_SYSTEM_TIME_EXT 0x000010000
+#define GNSS_SV_MEAS_HEADER_HAS_QZSS_SYSTEM_TIME_EXT 0x000020000
+#define GNSS_SV_MEAS_HEADER_HAS_GLO_SYSTEM_TIME_EXT 0x000040000
+#define GNSS_SV_MEAS_HEADER_HAS_GPSL1L5_TIME_BIAS 0x000080000
+#define GNSS_SV_MEAS_HEADER_HAS_GALE1E5A_TIME_BIAS 0x000100000
+#define GNSS_SV_MEAS_HEADER_HAS_BDSB1IB2A_TIME_BIAS 0x000200000
+#define GNSS_SV_MEAS_HEADER_HAS_GPS_NAVIC_INTER_SYSTEM_BIAS 0x000400000
+#define GNSS_SV_MEAS_HEADER_HAS_GAL_NAVIC_INTER_SYSTEM_BIAS 0x000800000
+#define GNSS_SV_MEAS_HEADER_HAS_GLO_NAVIC_INTER_SYSTEM_BIAS 0x001000000
+#define GNSS_SV_MEAS_HEADER_HAS_BDS_NAVIC_INTER_SYSTEM_BIAS 0x002000000
+#define GNSS_SV_MEAS_HEADER_HAS_NAVIC_SYSTEM_TIME 0x004000000
+#define GNSS_SV_MEAS_HEADER_HAS_NAVIC_SYSTEM_TIME_EXT 0x008000000
+#define GNSS_SV_MEAS_HEADER_HAS_DGNSS_CORRECTION_SOURCE_TYPE 0x010000000
+#define GNSS_SV_MEAS_HEADER_HAS_DGNSS_CORRECTION_SOURCE_ID 0x020000000
+#define GNSS_SV_MEAS_HEADER_HAS_DGNSS_REF_STATION_ID 0x040000000
+#define GNSS_SV_MEAS_HEADER_HAS_REF_COUNT_TICKS 0x080000000
+#define GNSS_SV_MEAS_HEADER_HAS_GPSL1L2C_TIME_BIAS 0x100000000
+#define GNSS_SV_MEAS_HEADER_HAS_GLOG1G2_TIME_BIAS 0x200000000
+#define GNSS_SV_MEAS_HEADER_HAS_BDSB1IB1C_TIME_BIAS 0x400000000
+#define GNSS_SV_MEAS_HEADER_HAS_GALE1E5B_TIME_BIAS 0x800000000
typedef struct
{
@@ -1445,6 +1580,11 @@
Gnss_InterSystemBiasStructType bdsNavicInterSystemBias;
Gnss_InterSystemBiasStructType gpsL1L5TimeBias;
Gnss_InterSystemBiasStructType galE1E5aTimeBias;
+ Gnss_InterSystemBiasStructType bdsB1iB2aTimeBias;
+ Gnss_InterSystemBiasStructType gpsL1L2cTimeBias;
+ Gnss_InterSystemBiasStructType gloG1G2TimeBias;
+ Gnss_InterSystemBiasStructType bdsB1iB1cTimeBias;
+ Gnss_InterSystemBiasStructType galE1E5bTimeBias;
GnssSystemTimeStructType gpsSystemTime;
GnssSystemTimeStructType galSystemTime;
@@ -1465,6 +1605,21 @@
Gnss_LocGnssTimeExtStructType gloSystemTimeExt;
/** NAVIC system RTC time information. */
Gnss_LocGnssTimeExtStructType navicSystemTimeExt;
+
+ /** Receiver tick at frame count */
+ uint64_t refCountTicks;
+
+ /** DGNSS corrections source type RTCM, 3GPP etc, if DGNSS was
+ * used for these measurements. */
+ LocDgnssCorrectionSourceType dgnssCorrectionSourceType;
+
+ /** DGNSS SourceID: 32bit number identifying the DGNSS source
+ * ID, if DGNSS was used for these measurements. */
+ uint32_t dgnssCorrectionSourceID;
+
+ /** DGNSS Ref station ID: 32bit number identifying the DGNSS
+ * ref station ID, if DGNSS was used for these measurements. */
+ uint16_t dgnssRefStationId;
} GnssSvMeasurementHeader;
typedef struct {
@@ -1503,19 +1658,17 @@
GNSS_SV_POLY_GLO_STR4 = 0x40
/**< GLONASS String 4 has been received */
-}Gnss_SvPolyStatusMaskType;
+} Gnss_SvPolyStatusMaskType;
-
-typedef struct
-{
+typedef struct {
uint32_t size;
uint16_t gnssSvId;
- /* GPS: 1-32, GLO: 65-96, 0: Invalid,
- SBAS: 120-151, BDS:201-237,GAL:301 to 336
- All others are reserved
+ /** Unique SV Identifier.
+ * For SV Range of supported constellation, please refer to the
+ * comment section of gnssSvId in GpsMeasUsageInfo.
*/
int8_t freqNum;
- /* Freq index, only valid if u_SysInd is GLO */
+ /** Freq index, only valid if u_SysInd is GLO */
GnssSvPolyStatusMaskValidity svPolyStatusMaskValidity;
GnssSvPolyStatusMask svPolyStatusMask;
@@ -1585,15 +1738,10 @@
typedef struct {
uint16_t gnssSvId;
- /**< GNSS SV ID.
- - Type: uint16
- \begin{itemize1}
- \item Range: \begin{itemize1}
- \item For GPS: 1 to 32
- \item For QZSS: 193 to 197
- \item For BDS: 201 to 237
- \item For GAL: 301 to 336
- \vspace{-0.18in} \end{itemize1} \end{itemize1} */
+ /** Unique SV Identifier.
+ * For SV Range of supported constellation, please refer to the
+ * comment section of gnssSvId in GpsMeasUsageInfo.
+ */
GnssEphAction updateAction;
/**< Specifies the action and source of ephemeris. \n
@@ -2163,6 +2311,20 @@
bool isCachedLocation;
} GnssNfwNotification;
+typedef uint16_t GnssMeasurementCorrectionsCapabilitiesMask;
+typedef enum {
+ GNSS_MEAS_CORR_LOS_SATS = 1 << 0,
+ GNSS_MEAS_CORR_EXCESS_PATH_LENGTH = 1 << 1,
+ GNSS_MEAS_CORR_REFLECTING_PLANE = 1 << 2,
+} GnssMeasurementCorrectionsCapabilities;
+
+/* Represents GNSS NMEA Report Rate Configuration */
+typedef enum {
+ GNSS_NMEA_REPORT_RATE_UNKNOWN = 0,
+ GNSS_NMEA_REPORT_RATE_1HZ = 1,
+ GNSS_NMEA_REPORT_RATE_NHZ = 2
+} GnssNMEARptRate;
+
/* ODCPI Request Info */
enum OdcpiRequestType {
ODCPI_REQUEST_TYPE_START,
@@ -2177,6 +2339,12 @@
/* Callback to send ODCPI request to framework */
typedef std::function<void(const OdcpiRequestInfo& request)> OdcpiRequestCallback;
+/* ODCPI callback priorities*/
+enum OdcpiPrioritytype {
+ ODCPI_HANDLER_PRIORITY_LOW,
+ ODCPI_HANDLER_PRIORITY_HIGH
+};
+
/*
* Callback with AGNSS(IpV4) status information.
*
@@ -2185,11 +2353,29 @@
typedef void (*AgnssStatusIpV4Cb)(AGnssExtStatusIpV4 status);
/*
+* Callback with AGNSS(IpV6) status information.
+*
+* @param status Will be of type AGnssExtStatusIpV6.
+*/
+typedef void (*AgnssStatusIpV6Cb)(AGnssExtStatusIpV6 status);
+
+/*
* Callback with NFW information.
*/
typedef void(*NfwStatusCb)(GnssNfwNotification notification);
typedef bool(*IsInEmergencySession)(void);
+enum AntennaInfoStatus {
+ ANTENNA_INFO_SUCCESS = 0,
+ ANTENNA_INFO_ERROR_ALREADY_INIT = 1,
+ ANTENNA_INFO_ERROR_GENERIC = 2
+};
+
+/*
+* Callback with Measurement corrections information.
+*/
+typedef void(*measCorrSetCapabilitiesCb)(GnssMeasurementCorrectionsCapabilitiesMask capabilities);
+
/*
* Callback with AGNSS(IpV6) status information.
*
@@ -2197,6 +2383,11 @@
*/
typedef void (*AgnssStatusIpV6Cb)(AGnssExtStatusIpV6 status);
+/*
+* Callback with Antenna information.
+*/
+typedef void(*antennaInfoCb)(std::vector<GnssAntennaInformation> gnssAntennaInformations);
+
/* Constructs for interaction with loc_net_iface library */
typedef void (*LocAgpsOpenResultCb)(bool isSuccess, AGpsExtType agpsType, const char* apn,
AGpsBearerType bearerType, void* userDataPtr);
@@ -2222,7 +2413,10 @@
#define EAP_LOC_CLIENT_DIR "/data/vendor/location/extap_locclient/"
#define LOC_CLIENT_NAME_PREFIX "toclient"
-#define LOC_INTAPI_NAME_PREFIX "toIntapiClient"
+// Please note that the socket name for all location hal daemon client need
+// to start with LOC_CLIENT_NAME_PREFIX so that upon hal daemon restarts,
+// every client can get the notification that hal daemon has restarted.
+#define LOC_INTAPI_NAME_PREFIX LOC_CLIENT_NAME_PREFIX "_intapi"
typedef uint64_t NetworkHandle;
#define NETWORK_HANDLE_UNKNOWN ~0
diff --git a/utils/loc_cfg.cpp b/utils/loc_cfg.cpp
index 432095e..a1e6b83 100644
--- a/utils/loc_cfg.cpp
+++ b/utils/loc_cfg.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2015, 2018 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2015, 2018-2020 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
@@ -89,6 +89,9 @@
const char LOC_PATH_APDR_CONF[] = LOC_PATH_APDR_CONF_STR;
const char LOC_PATH_XTWIFI_CONF[] = LOC_PATH_XTWIFI_CONF_STR;
const char LOC_PATH_QUIPC_CONF[] = LOC_PATH_QUIPC_CONF_STR;
+const char LOC_PATH_ANT_CORR[] = LOC_PATH_ANT_CORR_STR;
+const char LOC_PATH_SLIM_CONF[] = LOC_PATH_SLIM_CONF_STR;
+const char LOC_PATH_VPE_CONF[] = LOC_PATH_VPE_CONF_STR;
bool isVendorEnhanced() {
return sVendorEnhanced;
@@ -141,7 +144,9 @@
SIDE EFFECTS
N/A
===========================================================================*/
-int loc_set_config_entry(const loc_param_s_type* config_entry, loc_param_v_type* config_value)
+int loc_set_config_entry(const loc_param_s_type* config_entry,
+ loc_param_v_type* config_value,
+ uint16_t string_len = LOC_MAX_PARAM_STRING)
{
int ret=-1;
if(NULL == config_entry || NULL == config_value)
@@ -163,7 +168,7 @@
else {
strlcpy((char*) config_entry->param_ptr,
config_value->param_str_value,
- LOC_MAX_PARAM_STRING);
+ string_len);
}
/* Log INI values */
LOC_LOGD("%s: PARAM %s = %s", __FUNCTION__,
@@ -230,7 +235,8 @@
N/A
===========================================================================*/
int loc_fill_conf_item(char* input_buf,
- const loc_param_s_type* config_table, uint32_t table_length)
+ const loc_param_s_type* config_table,
+ uint32_t table_length, uint16_t string_len = LOC_MAX_PARAM_STRING)
{
int ret = 0;
@@ -243,7 +249,7 @@
config_value.param_name = strtok_r(input_buf, "=", &lasts);
/* skip lines that do not contain "=" */
if (config_value.param_name) {
- config_value.param_str_value = strtok_r(NULL, "=", &lasts);
+ config_value.param_str_value = strtok_r(NULL, "\0", &lasts);
/* skip lines that do not contain two operands */
if (config_value.param_str_value) {
@@ -267,7 +273,7 @@
for(uint32_t i = 0; NULL != config_table && i < table_length; i++)
{
- if(!loc_set_config_entry(&config_table[i], &config_value)) {
+ if(!loc_set_config_entry(&config_table[i], &config_value, string_len)) {
ret += 1;
}
}
@@ -279,7 +285,7 @@
}
/*===========================================================================
-FUNCTION loc_read_conf_r (repetitive)
+FUNCTION loc_read_conf_r_long (repetitive)
DESCRIPTION
Reads the specified configuration file and sets defined values based on
@@ -307,11 +313,13 @@
SIDE EFFECTS
N/A
===========================================================================*/
-int loc_read_conf_r(FILE *conf_fp, const loc_param_s_type* config_table, uint32_t table_length)
+int loc_read_conf_r_long(FILE *conf_fp, const loc_param_s_type* config_table,
+ uint32_t table_length, uint16_t string_len)
{
int ret=0;
-
+ char input_buf[string_len]; /* declare a char array */
unsigned int num_params=table_length;
+
if(conf_fp == NULL) {
LOC_LOGE("%s:%d]: ERROR: File pointer is NULL\n", __func__, __LINE__);
ret = -1;
@@ -327,17 +335,15 @@
}
}
- char input_buf[LOC_MAX_PARAM_LINE]; /* declare a char array */
-
LOC_LOGD("%s:%d]: num_params: %d\n", __func__, __LINE__, num_params);
while(num_params)
{
- if(!fgets(input_buf, LOC_MAX_PARAM_LINE, conf_fp)) {
+ if(!fgets(input_buf, string_len, conf_fp)) {
LOC_LOGD("%s:%d]: fgets returned NULL\n", __func__, __LINE__);
break;
}
- num_params -= loc_fill_conf_item(input_buf, config_table, table_length);
+ num_params -= loc_fill_conf_item(input_buf, config_table, table_length, string_len);
}
err:
@@ -345,7 +351,7 @@
}
/*===========================================================================
-FUNCTION loc_udpate_conf
+FUNCTION loc_update_conf_long
DESCRIPTION
Parses the passed in buffer for configuration items, and update the table
@@ -370,8 +376,9 @@
SIDE EFFECTS
N/A
===========================================================================*/
-int loc_update_conf(const char* conf_data, int32_t length,
- const loc_param_s_type* config_table, uint32_t table_length)
+int loc_update_conf_long(const char* conf_data, int32_t length,
+ const loc_param_s_type* config_table,
+ uint32_t table_length, uint16_t string_len)
{
int ret = -1;
@@ -394,7 +401,8 @@
LOC_LOGD("%s:%d]: num_params: %d\n", __func__, __LINE__, num_params);
while(num_params && input_buf) {
ret++;
- num_params -= loc_fill_conf_item(input_buf, config_table, table_length);
+ num_params -=
+ loc_fill_conf_item(input_buf, config_table, table_length, string_len);
input_buf = strtok_r(NULL, "\n", &saveptr);
}
free(conf_copy);
@@ -405,7 +413,7 @@
}
/*===========================================================================
-FUNCTION loc_read_conf
+FUNCTION loc_read_conf_long
DESCRIPTION
Reads the specified configuration file and sets defined values based on
@@ -426,8 +434,8 @@
SIDE EFFECTS
N/A
===========================================================================*/
-void loc_read_conf(const char* conf_file_name, const loc_param_s_type* config_table,
- uint32_t table_length)
+void loc_read_conf_long(const char* conf_file_name, const loc_param_s_type* config_table,
+ uint32_t table_length, uint16_t string_len)
{
FILE *conf_fp = NULL;
@@ -436,15 +444,16 @@
{
LOC_LOGD("%s: using %s", __FUNCTION__, conf_file_name);
if(table_length && config_table) {
- loc_read_conf_r(conf_fp, config_table, table_length);
+ loc_read_conf_r_long(conf_fp, config_table, table_length, string_len);
rewind(conf_fp);
}
- loc_read_conf_r(conf_fp, loc_param_table, loc_param_num);
+ loc_read_conf_r_long(conf_fp, loc_param_table, loc_param_num, string_len);
fclose(conf_fp);
}
/* Initialize logging mechanism with parsed data */
loc_logger_init(DEBUG_LEVEL, TIMESTAMP);
log_buffer_init(sLogBufferEnabled);
+ log_tag_level_map_init();
}
/*=============================================================================
@@ -617,14 +626,18 @@
UTIL_READ_CONF(conf_file_name, loc_feature_conf_table);
//Set service mask for GTP_MODE
- if(strcmp(conf.feature_gtp_mode, "DISABLED") == 0) {
+ if (strcmp(conf.feature_gtp_mode, "DISABLED") == 0) {
LOC_LOGD("%s:%d]: GTP MODE DISABLED", __func__, __LINE__);
}
- else if(strcmp(conf.feature_gtp_mode, "LEGACY_WWAN") == 0) {
+ else if (strcmp(conf.feature_gtp_mode, "LEGACY_WWAN") == 0) {
LOC_LOGD("%s:%d]: Setting GTP MODE to mode: LEGACY_WWAN", __func__, __LINE__);
loc_service_mask |= LOC_FEATURE_MASK_GTP_MODEM_CELL_BASIC;
}
- else if(strcmp(conf.feature_gtp_mode, "SDK") == 0) {
+ else if (strcmp(conf.feature_gtp_mode, "SDK") == 0) {
+ LOC_LOGD("%s:%d]: Setting GTP MODE to mode: SDK", __func__, __LINE__);
+ loc_service_mask |= LOC_FEATURE_MASK_GTP_WIFI_BASIC;
+ }
+ else if (strcmp(conf.feature_gtp_mode, "SDK_WIFI") == 0) {
LOC_LOGD("%s:%d]: Setting GTP MODE to mode: SDK", __func__, __LINE__);
loc_service_mask |= LOC_FEATURE_MASK_GTP_WIFI_BASIC;
}
@@ -634,11 +647,11 @@
" Setting GTP WIFI to default mode: DISABLED", __func__, __LINE__);
}
//Set service mask for GTP_WAA
- if(strcmp(conf.feature_gtp_waa, "BASIC") == 0) {
+ if (strcmp(conf.feature_gtp_waa, "BASIC") == 0) {
LOC_LOGD("%s:%d]: Setting GTP WAA to mode: BASIC", __func__, __LINE__);
loc_service_mask |= LOC_FEATURE_MASK_GTP_WAA_BASIC;
}
- else if(strcmp(conf.feature_gtp_waa, "DISABLED") == 0) {
+ else if (strcmp(conf.feature_gtp_waa, "DISABLED") == 0) {
LOC_LOGD("%s:%d]: GTP WAA DISABLED", __func__, __LINE__);
}
//conf file has a garbage value
@@ -648,19 +661,26 @@
}
//Set service mask for SAP
- if(strcmp(conf.feature_sap, "PREMIUM") == 0) {
+ if(strcmp(conf.feature_sap, "PREMIUM") == 0 ||
+ strcmp(conf.feature_sap, "PREMIUM_ENV_AIDING") == 0) {
LOC_LOGD("%s:%d]: Setting SAP to mode: PREMIUM", __func__, __LINE__);
loc_service_mask |= LOC_FEATURE_MASK_SAP_PREMIUM;
}
- else if(strcmp(conf.feature_sap, "BASIC") == 0) {
+ else if (strcmp(conf.feature_sap, "BASIC") == 0) {
LOC_LOGD("%s:%d]: Setting SAP to mode: BASIC", __func__, __LINE__);
loc_service_mask |= LOC_FEATURE_MASK_SAP_BASIC;
}
- else if(strcmp(conf.feature_sap, "MODEM_DEFAULT") == 0) {
+ else if (strcmp(conf.feature_sap, "MODEM_DEFAULT") == 0) {
LOC_LOGD("%s:%d]: Setting SAP to mode: MODEM_DEFAULT", __func__, __LINE__);
+ loc_service_mask |= LOC_FEATURE_MASK_SAP_BASIC;
}
- else if(strcmp(conf.feature_sap, "DISABLED") == 0) {
+ else if (strcmp(conf.feature_sap, "DISABLED") == 0) {
+#ifdef USE_GLIB
+ /* Enable slim_daemon even when SAP is set to DISABLED*/
+ loc_service_mask |= LOC_FEATURE_MASK_SAP_BASIC;
+#else
LOC_LOGD("%s:%d]: Setting SAP to mode: DISABLED", __func__, __LINE__);
+#endif
}
else {
LOC_LOGE("%s:%d]: Unrecognized value for SAP Mode."\
@@ -669,56 +689,56 @@
}
// Set service mask for ODCPI
- if(strcmp(conf.feature_odcpi, "BASIC") == 0) {
+ if (strcmp(conf.feature_odcpi, "BASIC") == 0) {
LOC_LOGD("%s:%d]: Setting ODCPI to mode: BASIC", __func__, __LINE__);
loc_service_mask |= LOC_FEATURE_MASK_ODCPI;
}
- else if(strcmp(conf.feature_odcpi, "DISABLED") == 0) {
+ else if (strcmp(conf.feature_odcpi, "DISABLED") == 0) {
LOC_LOGD("%s:%d]: Setting ODCPI to mode: DISABLED", __func__, __LINE__);
}
- else if(strcmp(conf.feature_odcpi, "PREMIUM") == 0) {
+ else if (strcmp(conf.feature_odcpi, "PREMIUM") == 0) {
LOC_LOGD("%s:%d]: Unrecognized value for ODCPI mode."\
"Setting ODCPI to default mode: BASIC", __func__, __LINE__);
loc_service_mask |= LOC_FEATURE_MASK_ODCPI;
}
// Set service mask for FREE_WIFI_SCAN_INJECT
- if(strcmp(conf.feature_free_wifi_scan_inject, "BASIC") == 0) {
+ if (strcmp(conf.feature_free_wifi_scan_inject, "BASIC") == 0) {
LOC_LOGD("%s:%d]: Setting FREE_WIFI_SCAN_INJECT to mode: BASIC", __func__, __LINE__);
loc_service_mask |= LOC_FEATURE_MASK_FREE_WIFI_SCAN_INJECT;
}
- else if(strcmp(conf.feature_free_wifi_scan_inject, "DISABLED") == 0) {
+ else if (strcmp(conf.feature_free_wifi_scan_inject, "DISABLED") == 0) {
LOC_LOGD("%s:%d]: Setting FREE_WIFI_SCAN_INJECT to mode: DISABLED", __func__, __LINE__);
}
- else if(strcmp(conf.feature_free_wifi_scan_inject, "PREMIUM") == 0) {
+ else if (strcmp(conf.feature_free_wifi_scan_inject, "PREMIUM") == 0) {
LOC_LOGD("%s:%d]: Unrecognized value for FREE_WIFI_SCAN_INJECT mode."\
"Setting FREE_WIFI_SCAN_INJECT to default mode: BASIC", __func__, __LINE__);
loc_service_mask |= LOC_FEATURE_MASK_FREE_WIFI_SCAN_INJECT;
}
// Set service mask for SUPL_WIFI
- if(strcmp(conf.feature_supl_wifi, "BASIC") == 0) {
+ if (strcmp(conf.feature_supl_wifi, "BASIC") == 0) {
LOC_LOGD("%s:%d]: Setting SUPL_WIFI to mode: BASIC", __func__, __LINE__);
loc_service_mask |= LOC_FEATURE_MASK_SUPL_WIFI;
}
- else if(strcmp(conf.feature_supl_wifi, "DISABLED") == 0) {
+ else if (strcmp(conf.feature_supl_wifi, "DISABLED") == 0) {
LOC_LOGD("%s:%d]: Setting SUPL_WIFI to mode: DISABLED", __func__, __LINE__);
}
- else if(strcmp(conf.feature_supl_wifi, "PREMIUM") == 0) {
+ else if (strcmp(conf.feature_supl_wifi, "PREMIUM") == 0) {
LOC_LOGD("%s:%d]: Unrecognized value for SUPL_WIFI mode."\
"Setting SUPL_WIFI to default mode: BASIC", __func__, __LINE__);
loc_service_mask |= LOC_FEATURE_MASK_SUPL_WIFI;
}
// Set service mask for WIFI_SUPPLICANT_INFO
- if(strcmp(conf.feature_wifi_supplicant_info, "BASIC") == 0) {
+ if (strcmp(conf.feature_wifi_supplicant_info, "BASIC") == 0) {
LOC_LOGD("%s:%d]: Setting WIFI_SUPPLICANT_INFO to mode: BASIC", __func__, __LINE__);
loc_service_mask |= LOC_FEATURE_MASK_WIFI_SUPPLICANT_INFO;
}
- else if(strcmp(conf.feature_wifi_supplicant_info, "DISABLED") == 0) {
+ else if (strcmp(conf.feature_wifi_supplicant_info, "DISABLED") == 0) {
LOC_LOGD("%s:%d]: Setting WIFI_SUPPLICANT_INFO to mode: DISABLED", __func__, __LINE__);
}
- else if(strcmp(conf.feature_wifi_supplicant_info, "PREMIUM") == 0) {
+ else if (strcmp(conf.feature_wifi_supplicant_info, "PREMIUM") == 0) {
LOC_LOGD("%s:%d]: Unrecognized value for WIFI_SUPPLICANT_INFO mode."\
"Setting LOC_FEATURE_MASK_WIFI_SUPPLICANT_INFO to default mode: BASIC", __func__, __LINE__);
loc_service_mask |= LOC_FEATURE_MASK_WIFI_SUPPLICANT_INFO;
@@ -801,13 +821,13 @@
continue;
}
- if(strcmp(conf.proc_status, "DISABLED") == 0) {
+ if (strcmp(conf.proc_status, "DISABLED") == 0) {
LOC_LOGD("%s:%d]: Process %s is disabled in conf file",
__func__, __LINE__, conf.proc_name);
child_proc[j].proc_status = DISABLED_FROM_CONF;
continue;
}
- else if(strcmp(conf.proc_status, "ENABLED") == 0) {
+ else if (strcmp(conf.proc_status, "ENABLED") == 0) {
LOC_LOGD("%s:%d]: Process %s is enabled in conf file",
__func__, __LINE__, conf.proc_name);
}
@@ -832,7 +852,7 @@
}
nstrings = loc_util_split_string(conf.platform_list, split_strings, MAX_NUM_STRINGS, ' ');
- if(strcmp("all", split_strings[0]) == 0) {
+ if (strcmp("all", split_strings[0]) == 0) {
if (nstrings == 1 || (nstrings == 2 && (strcmp("exclude", split_strings[1]) == 0))) {
LOC_LOGD("%s:%d]: Enabled for all targets\n", __func__, __LINE__);
config_mask |= CONFIG_MASK_TARGET_ALL;
@@ -840,7 +860,7 @@
else if (nstrings > 2 && (strcmp("exclude", split_strings[1]) == 0)) {
config_mask |= CONFIG_MASK_TARGET_FOUND;
for (i=2; i<nstrings; i++) {
- if(strcmp(platform_name, split_strings[i]) == 0) {
+ if (strcmp(platform_name, split_strings[i]) == 0) {
LOC_LOGD("%s:%d]: Disabled platform %s\n", __func__, __LINE__, platform_name);
config_mask &= ~CONFIG_MASK_TARGET_FOUND;
break;
@@ -850,7 +870,7 @@
}
else {
for(i=0; i<nstrings; i++) {
- if(strcmp(platform_name, split_strings[i]) == 0) {
+ if (strcmp(platform_name, split_strings[i]) == 0) {
LOC_LOGD("%s:%d]: Matched platform: %s\n",
__func__, __LINE__, split_strings[i]);
config_mask |= CONFIG_MASK_TARGET_FOUND;
@@ -888,7 +908,7 @@
}
nstrings = loc_util_split_string(conf.baseband, split_strings, MAX_NUM_STRINGS, ' ');
- if(strcmp("all", split_strings[0]) == 0) {
+ if (strcmp("all", split_strings[0]) == 0) {
if (nstrings == 1 || (nstrings == 2 && (strcmp("exclude", split_strings[1]) == 0))) {
LOC_LOGD("%s:%d]: Enabled for all basebands\n", __func__, __LINE__);
config_mask |= CONFIG_MASK_BASEBAND_ALL;
@@ -896,7 +916,7 @@
else if (nstrings > 2 && (strcmp("exclude", split_strings[1]) == 0)) {
config_mask |= CONFIG_MASK_BASEBAND_FOUND;
for (i=2; i<nstrings; i++) {
- if(strcmp(baseband_name, split_strings[i]) == 0) {
+ if (strcmp(baseband_name, split_strings[i]) == 0) {
LOC_LOGD("%s:%d]: Disabled band %s\n", __func__, __LINE__, baseband_name);
config_mask &= ~CONFIG_MASK_BASEBAND_FOUND;
break;
@@ -906,7 +926,7 @@
}
else {
for(i=0; i<nstrings; i++) {
- if(strcmp(baseband_name, split_strings[i]) == 0) {
+ if (strcmp(baseband_name, split_strings[i]) == 0) {
LOC_LOGD("%s:%d]: Matched baseband: %s\n",
__func__, __LINE__, split_strings[i]);
config_mask |= CONFIG_MASK_BASEBAND_FOUND;
@@ -924,13 +944,13 @@
}
nstrings = loc_util_split_string(conf.auto_platform, split_strings, MAX_NUM_STRINGS, ' ');
- if(strcmp("all", split_strings[0]) == 0) {
+ if (strcmp("all", split_strings[0]) == 0) {
LOC_LOGD("%s:%d]: Enabled for all auto platforms\n", __func__, __LINE__);
config_mask |= CONFIG_MASK_AUTOPLATFORM_ALL;
}
else {
for(i=0; i<nstrings; i++) {
- if(strcmp(autoplatform_name, split_strings[i]) == 0) {
+ if (strcmp(autoplatform_name, split_strings[i]) == 0) {
LOC_LOGD("%s:%d]: Matched auto platform: %s\n",
__func__, __LINE__, split_strings[i]);
config_mask |= CONFIG_MASK_AUTOPLATFORM_FOUND;
@@ -961,7 +981,7 @@
i = 0;
char* temp_arg = ('/' == child_proc[j].name[0][0]) ?
(strrchr(child_proc[j].name[0], '/') + 1) : child_proc[j].name[0];
- strlcpy (child_proc[j].args[i++], temp_arg, sizeof (child_proc[j].args[i++]));
+ strlcpy (child_proc[j].args[i++], temp_arg, sizeof (child_proc[j].args[0]));
if(conf.premium_feature) {
if(conf.loc_feature_mask & loc_service_mask) {
diff --git a/utils/loc_cfg.h b/utils/loc_cfg.h
index 5c77dc6..e87d632 100644
--- a/utils/loc_cfg.h
+++ b/utils/loc_cfg.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2015, 2018 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2015, 2018, 2020 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,14 +56,18 @@
#define LOC_PROCESS_MAX_ARG_STR_LENGTH 32
#define UTIL_UPDATE_CONF(conf_data, len, config_table) \
- loc_update_conf((conf_data), (len), (config_table), \
+ loc_update_conf((conf_data), (len), (&config_table[0]), \
sizeof(config_table) / sizeof(config_table[0]))
#define UTIL_READ_CONF_DEFAULT(filename) \
loc_read_conf((filename), NULL, 0);
#define UTIL_READ_CONF(filename, config_table) \
- loc_read_conf((filename), (config_table), sizeof(config_table) / sizeof(config_table[0]))
+ loc_read_conf((filename), (&config_table[0]), sizeof(config_table) / sizeof(config_table[0]))
+
+#define UTIL_READ_CONF_LONG(filename, config_table, rec_len) \
+ loc_read_conf_long((filename), (&config_table[0]), \
+ sizeof(config_table) / sizeof(config_table[0]), (rec_len))
/*=============================================================================
*
@@ -115,13 +119,30 @@
*============================================================================*/
bool isVendorEnhanced();
void setVendorEnhanced(bool vendorEnhanced);
-void loc_read_conf(const char* conf_file_name,
- const loc_param_s_type* config_table,
- uint32_t table_length);
-int loc_read_conf_r(FILE *conf_fp, const loc_param_s_type* config_table,
- uint32_t table_length);
-int loc_update_conf(const char* conf_data, int32_t length,
- const loc_param_s_type* config_table, uint32_t table_length);
+void loc_read_conf_long(const char* conf_file_name,
+ const loc_param_s_type* config_table,
+ uint32_t table_length, uint16_t string_len);
+int loc_read_conf_r_long(FILE *conf_fp, const loc_param_s_type* config_table,
+ uint32_t table_length, uint16_t string_len);
+int loc_update_conf_long(const char* conf_data, int32_t length,
+ const loc_param_s_type* config_table, uint32_t table_length,
+ uint16_t string_len);
+
+inline void loc_read_conf(const char* conf_file_name,
+ const loc_param_s_type* config_table, uint32_t table_length) {
+ loc_read_conf_long(conf_file_name, config_table, table_length, LOC_MAX_PARAM_STRING);
+}
+
+inline int loc_read_conf_r(FILE *conf_fp, const loc_param_s_type* config_table,
+ uint32_t table_length) {
+ return (loc_read_conf_r_long(conf_fp, config_table, table_length, LOC_MAX_PARAM_STRING));
+}
+
+inline int loc_update_conf(const char* conf_data, int32_t length,
+ const loc_param_s_type* config_table, uint32_t table_length) {
+ return (loc_update_conf_long(
+ conf_data, length, config_table, table_length, LOC_MAX_PARAM_STRING));
+}
// Below are the location conf file paths
extern const char LOC_PATH_GPS_CONF[];
@@ -132,6 +153,9 @@
extern const char LOC_PATH_APDR_CONF[];
extern const char LOC_PATH_XTWIFI_CONF[];
extern const char LOC_PATH_QUIPC_CONF[];
+extern const char LOC_PATH_ANT_CORR[];
+extern const char LOC_PATH_SLIM_CONF[];
+extern const char LOC_PATH_VPE_CONF[];
int loc_read_process_conf(const char* conf_file_name, uint32_t * process_count_ptr,
loc_process_info_s_type** process_info_table_ptr);
diff --git a/utils/loc_gps.h b/utils/loc_gps.h
index eae7383..90541c4 100644
--- a/utils/loc_gps.h
+++ b/utils/loc_gps.h
@@ -106,6 +106,8 @@
#define LOC_GPS_LOCATION_HAS_SPEED_ACCURACY 0x0100
/** LocGpsLocation has valid bearing accuracy */
#define LOC_GPS_LOCATION_HAS_BEARING_ACCURACY 0x0200
+/** LocGpsLocation has valid Real Time and Real Time Uncertainty */
+#define LOC_GPS_LOCATION_HAS_ELAPSED_REAL_TIME 0x0400
/** Spoof mask in LocGpsLocation */
typedef uint32_t LocGpsSpoofMask;
@@ -570,7 +572,11 @@
/** Represents the expected vertical uncertainity in meters*/
float vertUncertainity;
/** Timestamp for the location fix. */
- LocGpsUtcTime timestamp;
+ LocGpsUtcTime timestamp;
+ /** Elapsed RealTime in nanosends */
+ uint64_t elapsedRealTime;
+ /** Elapsed Real Time Uncertainty in nanosends */
+ uint64_t elapsedRealTimeUnc;
} LocGpsLocation;
/** Represents the status. */
diff --git a/utils/loc_log.cpp b/utils/loc_log.cpp
index 2c6a3fa..2110683 100644
--- a/utils/loc_log.cpp
+++ b/utils/loc_log.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, 2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2012, 2015, 2020, 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,8 +38,13 @@
#include "msg_q.h"
#include <loc_pla.h>
#include "LogBuffer.h"
-
+#include <unordered_map>
+#include <fstream>
+#include <algorithm>
+#include <string>
+#include <cctype>
#define BUFFER_SIZE 120
+#define LOG_TAG_LEVEL_CONF_FILE_PATH "/data/vendor/location/gps.prop"
// Logging Improvements
const char *loc_logger_boolStr[]={"False","True"};
@@ -52,38 +57,49 @@
const char ENTRY_TAG[] = "Entering";
const char EXIT_ERROR_TAG[] = "Exiting with error";
+int build_type_prop = BUILD_TYPE_PROP_NA;
+
+const string gEmptyStr = "";
+const string gUnknownStr = "UNKNOWN";
/* Logging Mechanism */
loc_logger_s_type loc_logger;
-/* Get names from value */
-const char* loc_get_name_from_mask(const loc_name_val_s_type table[], size_t table_size, long mask)
-{
- size_t i;
- for (i = 0; i < table_size; i++)
- {
- if (table[i].val & (long) mask)
- {
- return table[i].name;
- }
- }
- return UNKNOWN_STR;
+/* tag base logging control map*/
+static std::unordered_map<std::string, uint8_t> tag_level_map;
+static bool tag_map_inited = false;
+
+/* returns the least signification bit that is set in the mask
+ Param
+ mask - bit mask.
+ clearTheBit - if true, mask gets modified upon return.
+ returns 0 if mask is 0.
+*/
+uint64_t loc_get_least_bit(uint64_t& mask, bool clearTheBit) {
+ uint64_t bit = 0;
+
+ if (mask > 0) {
+ uint64_t less1 = mask - 1;
+ bit = mask & ~(less1);
+ if (clearTheBit) {
+ mask &= less1;
+ }
+ }
+
+ return bit;
}
-/* Get names from value */
-const char* loc_get_name_from_val(const loc_name_val_s_type table[], size_t table_size, long value)
-{
- size_t i;
- for (i = 0; i < table_size; i++)
- {
- if (table[i].val == (long) value)
- {
- return table[i].name;
- }
- }
- return UNKNOWN_STR;
+string loc_get_bit_defs(uint64_t mask, const NameValTbl& tbl) {
+ string out;
+ while (mask > 0) {
+ out += loc_get_name_from_tbl(tbl, loc_get_least_bit(mask));
+ if (mask > 0) {
+ out += " | ";
+ }
+ }
+ return out;
}
-static const loc_name_val_s_type loc_msg_q_status[] =
+DECLARE_TBL(loc_msg_q_status) =
{
NAME_VAL( eMSG_Q_SUCCESS ),
NAME_VAL( eMSG_Q_FAILURE_GENERAL ),
@@ -92,21 +108,15 @@
NAME_VAL( eMSG_Q_UNAVAILABLE_RESOURCE ),
NAME_VAL( eMSG_Q_INSUFFICIENT_BUFFER )
};
-static const size_t loc_msg_q_status_num = LOC_TABLE_SIZE(loc_msg_q_status);
/* Find msg_q status name */
const char* loc_get_msg_q_status(int status)
{
- return loc_get_name_from_val(loc_msg_q_status, loc_msg_q_status_num, (long) status);
-}
-
-const char* log_succ_fail_string(int is_succ)
-{
- return is_succ? "successful" : "failed";
+ return loc_get_name_from_val(loc_msg_q_status_tbl, (int64_t) status);
}
//Target names
-static const loc_name_val_s_type target_name[] =
+DECLARE_TBL(target_name) =
{
NAME_VAL(GNSS_NONE),
NAME_VAL(GNSS_MSM),
@@ -116,8 +126,6 @@
NAME_VAL(GNSS_UNKNOWN)
};
-static const size_t target_name_num = LOC_TABLE_SIZE(target_name);
-
/*===========================================================================
FUNCTION loc_get_target_name
@@ -133,21 +141,13 @@
===========================================================================*/
const char *loc_get_target_name(unsigned int target)
{
- int index = 0;
+ int64_t index = 0;
static char ret[BUFFER_SIZE];
- index = getTargetGnssType(target);
- if( index < 0 || (unsigned)index >= target_name_num )
- index = target_name_num - 1;
+ snprintf(ret, sizeof(ret), " %s with%s SSC",
+ loc_get_name_from_val(target_name_tbl, getTargetGnssType(target)),
+ ((target & HAS_SSC) == HAS_SSC) ? gEmptyStr.c_str() : "out");
- if( (target & HAS_SSC) == HAS_SSC ) {
- snprintf(ret, sizeof(ret), " %s with SSC",
- loc_get_name_from_val(target_name, target_name_num, (long)index) );
- }
- else {
- snprintf(ret, sizeof(ret), " %s without SSC",
- loc_get_name_from_val(target_name, target_name_num, (long)index) );
- }
return ret;
}
@@ -228,3 +228,55 @@
string ss = str;
loc_util::LogBuffer::getInstance()->append(ss, level, elapsedTime);
}
+
+void log_tag_level_map_init()
+{
+ if (tag_map_inited) {
+ return;
+ }
+
+ std::string filename = LOG_TAG_LEVEL_CONF_FILE_PATH;
+
+ std::ifstream s(filename);
+ if (!s.is_open()) {
+ ALOGE("cannot open file:%s", LOG_TAG_LEVEL_CONF_FILE_PATH);
+ } else {
+ std::string line;
+ while (std::getline(s, line)) {
+ line.erase(std::remove(line.begin(), line.end(), ' '), line.end());
+ int pos = line.find('=');
+ if (pos <= 0 || pos >= (line.size() - 1)) {
+ ALOGE("wrong format in gps.prop");
+ continue;
+ }
+ std::string tag = line.substr(0, pos);
+ std::string level = line.substr(pos+1, 1);
+ if (!std::isdigit(*(level.begin()))) {
+ ALOGE("wrong format in gps.prop");
+ continue;
+ }
+ tag_level_map[tag] = (uint8_t)std::stoul(level);
+ }
+ }
+ tag_map_inited = true;
+}
+
+int get_tag_log_level(const char* tag)
+{
+ if (!tag_map_inited) {
+ return -1;
+ }
+
+ // in case LOG_TAG isn't defined in a source file, use the global log level
+ if (tag == NULL) {
+ return loc_logger.DEBUG_LEVEL;
+ }
+ int log_level;
+ auto search = tag_level_map.find(std::string(tag));
+ if (tag_level_map.end() != search) {
+ log_level = search->second;
+ } else {
+ log_level = loc_logger.DEBUG_LEVEL;
+ }
+ return log_level;
+}
diff --git a/utils/loc_log.h b/utils/loc_log.h
index be492b1..b750932 100644
--- a/utils/loc_log.h
+++ b/utils/loc_log.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, 2015 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2012, 2015, 2020 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,42 +30,93 @@
#ifndef LOC_LOG_H
#define LOC_LOG_H
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
#include <ctype.h>
#include <stdlib.h>
+#include <unordered_map>
+#include <string>
#include "loc_target.h"
+#include "loc_misc_utils.h"
-typedef struct
-{
- const char *name;
- long val;
-} loc_name_val_s_type;
+using std::string;
+using std::unordered_map;
-#define NAME_VAL(x) {"" #x "", x }
+typedef unordered_map<int64_t, string> NameValTbl;
-#define UNKNOWN_STR "UNKNOWN"
+#define NAME_VAL(x) {x, "" #x ""}
+#define DECLARE_TBL(T) static const NameValTbl T##_tbl
+
+extern const string gEmptyStr;
+extern const string gUnknownStr;
#define CHECK_MASK(type, value, mask_var, mask) \
(((mask_var) & (mask)) ? (type) (value) : (type) (-1))
#define LOC_TABLE_SIZE(table) (sizeof(table)/sizeof((table)[0]))
+#define FIELDVAL_DEC(field) \
+ loc_put_tag_val(#field, to_string(field))
+#define FIELDVAL_DEC_ARR(field) \
+ loc_put_tag_val(#field, \
+ loc_parenthesize(loc_prim_arr_to_string(field, \
+ sizeof(field)/sizeof(field[0]))))
+#define FIELDVAL_HEX(field) \
+ loc_put_tag_val(#field, to_string_hex(field))
+#define FIELDVAL_HEX_ARR(field) \
+ loc_put_tag_val(#field, \
+ loc_parenthesize(loc_prim_arr_to_string(field, \
+ sizeof(field)/sizeof(field[0]), \
+ false)))
+#define FIELDVAL_ENUM(field, tbl) \
+ loc_put_tag_val(#field, \
+ loc_get_name_from_tbl(tbl, field, gUnknownStr))
+#define FIELDVAL_MASK(field, tbl) \
+ loc_put_tag_val(#field, \
+ to_string_hex((uint64_t)field) + " " + \
+ loc_parenthesize(loc_get_bit_defs(field, tbl)))
+
+/* get from a table of strings with index */
+/* tbl - map of <int, string> entries
+ key - key to the matching entry
+ defalt - default pointer in case of incorrect parameters
+ */
+inline static const string& loc_get_name_from_tbl(const NameValTbl& tbl, int64_t key,
+ const string& defalt = gEmptyStr) {
+ auto item = tbl.find(key);
+ if (item != tbl.end()) {
+ return item->second;
+ } else {
+ return defalt;
+ }
+}
+
+/* puts to string formatted "TAG: VAL" with option ending string, default to newline */
+inline string loc_put_tag_val(const string& tag, const string& val, const string& eol = "\n") {
+ return tag + ": " + val + eol;
+}
+
+inline string loc_parenthesize(const string& str) {
+ return "(" + str + ")";
+}
+
/* Get names from value */
-const char* loc_get_name_from_mask(const loc_name_val_s_type table[], size_t table_size, long mask);
-const char* loc_get_name_from_val(const loc_name_val_s_type table[], size_t table_size, long value);
+inline const char* loc_get_name_from_val(const NameValTbl& table, int64_t value) {
+ return loc_get_name_from_tbl(table, value, gUnknownStr).c_str();
+}
+
+inline const char* log_succ_fail_string(int is_succ) {
+ return is_succ? "successful" : "failed";
+}
+
+/* prints mask into a string with bit definitions from tbl */
+/* mask - bit mask, to be expanded into " BIT_NAMEx | BIT_NAMEy ... "
+ tbl - a table with defs for each bit, defined as <bit, name> entries
+ {{bit0, "BIT0_NAME"}, {bit1, "BIT1_NAME"}, .... {bitn, "BITn_NAME"} }
+ entries - number of strings in the table
+ */
+string loc_get_bit_defs(uint64_t mask, const NameValTbl& tbl);
+uint64_t loc_get_least_bit(uint64_t& mask, bool clearThebit = true);
const char* loc_get_msg_q_status(int status);
const char* loc_get_target_name(unsigned int target);
-
-extern const char* log_succ_fail_string(int is_succ);
-
-extern char *loc_get_time(char *time_string, size_t buf_size);
-
-#ifdef __cplusplus
-}
-#endif
+char *loc_get_time(char *time_string, size_t buf_size);
#endif /* LOC_LOG_H */
diff --git a/utils/loc_misc_utils.cpp b/utils/loc_misc_utils.cpp
index 70fdbc3..fbcaef4 100644
--- a/utils/loc_misc_utils.cpp
+++ b/utils/loc_misc_utils.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014, 2020 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,11 +30,19 @@
#define LOG_TAG "LocSvc_misc_utils"
#include <stdio.h>
#include <string.h>
+#include <inttypes.h>
#include <dlfcn.h>
+#include <math.h>
#include <log_util.h>
#include <loc_misc_utils.h>
#include <ctype.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#ifndef MSEC_IN_ONE_SEC
+#define MSEC_IN_ONE_SEC 1000ULL
+#endif
+#define GET_MSEC_FROM_TS(ts) ((ts.tv_sec * MSEC_IN_ONE_SEC) + (ts.tv_nsec + 500000)/1000000)
int loc_util_split_string(char *raw_string, char **split_strings_ptr,
int max_num_substrings, char delimiter)
@@ -57,8 +65,10 @@
end_string=1;
if((raw_string[raw_string_index] == delimiter) || end_string) {
raw_string[raw_string_index] = '\0';
- LOC_LOGD("%s:%d]: split string: %s\n",
- __func__, __LINE__, split_strings_ptr[num_split_strings]);
+ if (num_split_strings < max_num_substrings) {
+ LOC_LOGD("%s:%d]: split string: %s\n",
+ __func__, __LINE__, split_strings_ptr[num_split_strings]);
+ }
num_split_strings++;
if(((raw_string_index + 1) < raw_string_length) &&
(num_split_strings < max_num_substrings)) {
@@ -143,3 +153,199 @@
return sym;
}
+
+uint64_t getQTimerTickCount()
+{
+ uint64_t qTimerCount = 0;
+#if __aarch64__
+ asm volatile("mrs %0, cntvct_el0" : "=r" (qTimerCount));
+#elif defined (__i386__) || defined (__x86_64__)
+ /* Qtimer not supported in x86 architecture */
+ qTimerCount = 0;
+#else
+ asm volatile("mrrc p15, 1, %Q0, %R0, c14" : "=r" (qTimerCount));
+#endif
+
+ return qTimerCount;
+}
+
+uint64_t getQTimerDeltaNanos()
+{
+ char qtimer_val_string[100];
+ char *temp;
+ uint64_t local_qtimer = 0, remote_qtimer = 0;
+ int mdm_fd = -1, wlan_fd = -1, ret = 0;
+ uint64_t delta = 0;
+
+ memset(qtimer_val_string, '\0', sizeof(qtimer_val_string));
+
+ char devNode[] = "/sys/bus/mhi/devices/0306_00.01.00/time_us";
+ for (; devNode[27] < 3 && mdm_fd < 0; devNode[27]++) {
+ mdm_fd = ::open(devNode, O_RDONLY);
+ if (mdm_fd < 0) {
+ LOC_LOGe("MDM open file: %s error: %s", devNode, strerror(errno));
+ }
+ }
+ if (mdm_fd > 0) {
+ ret = read(mdm_fd, qtimer_val_string, sizeof(qtimer_val_string)-1);
+ ::close(mdm_fd);
+ if (ret < 0) {
+ LOC_LOGe("MDM read time_us file error: %s", strerror(errno));
+ } else {
+ temp = qtimer_val_string;
+ temp = strchr(temp, ':');
+ temp = temp + 2;
+ local_qtimer = atoll(temp);
+
+ temp = strchr(temp, ':');
+ temp = temp + 2;
+ remote_qtimer = atoll(temp);
+
+ if (local_qtimer >= remote_qtimer) {
+ delta = (local_qtimer - remote_qtimer) * 1000;
+ }
+ LOC_LOGv("qtimer values in microseconds: local:%" PRIi64 " remote:%" PRIi64 ""
+ " delta in nanoseconds:%" PRIi64 "",
+ local_qtimer, remote_qtimer, delta);
+ }
+ }
+ return delta;
+}
+
+uint64_t getQTimerFreq()
+{
+#if __aarch64__
+ uint64_t val = 0;
+ asm volatile("mrs %0, cntfrq_el0" : "=r" (val));
+#elif defined (__i386__) || defined (__x86_64__)
+ /* Qtimer not supported in x86 architecture */
+ uint64_t val = 0;
+#else
+ uint32_t val = 0;
+ asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (val));
+#endif
+ return val;
+}
+
+uint64_t getBootTimeMilliSec()
+{
+ struct timespec curTs;
+ clock_gettime(CLOCK_BOOTTIME, &curTs);
+ return (uint64_t)GET_MSEC_FROM_TS(curTs);
+}
+
+// Used for convert position/velocity from GSNS antenna based to VRP based
+void Matrix_MxV(float a[3][3], float b[3], float c[3]) {
+ int i, j;
+
+ for (i=0; i<3; i++) {
+ c[i] = 0.0f;
+ for (j=0; j<3; j++)
+ c[i] += a[i][j] * b[j];
+ }
+}
+
+// Used for convert position/velocity from GNSS antenna based to VRP based
+void Matrix_Skew(float a[3], float c[3][3]) {
+ c[0][0] = 0.0f;
+ c[0][1] = -a[2];
+ c[0][2] = a[1];
+ c[1][0] = a[2];
+ c[1][1] = 0.0f;
+ c[1][2] = -a[0];
+ c[2][0] = -a[1];
+ c[2][1] = a[0];
+ c[2][2] = 0.0f;
+}
+
+// Used for convert position/velocity from GNSS antenna based to VRP based
+void Euler2Dcm(float euler[3], float dcm[3][3]) {
+ float cr = 0.0, sr = 0.0, cp = 0.0, sp = 0.0, ch = 0.0, sh = 0.0;
+
+ cr = cosf(euler[0]);
+ sr = sinf(euler[0]);
+ cp = cosf(euler[1]);
+ sp = sinf(euler[1]);
+ ch = cosf(euler[2]);
+ sh = sinf(euler[2]);
+
+ dcm[0][0] = cp * ch;
+ dcm[0][1] = (sp*sr*ch) - (cr*sh);
+ dcm[0][2] = (cr*sp*ch) + (sh*sr);
+
+ dcm[1][0] = cp * sh;
+ dcm[1][1] = (sr*sp*sh) + (cr*ch);
+ dcm[1][2] = (cr*sp*sh) - (sr*ch);
+
+ dcm[2][0] = -sp;
+ dcm[2][1] = sr * cp;
+ dcm[2][2] = cr * cp;
+}
+
+// Used for convert position from GSNS based to VRP based
+// The converted position will be stored in the llaInfo parameter.
+#define A6DOF_WGS_A (6378137.0f)
+#define A6DOF_WGS_B (6335439.0f)
+#define A6DOF_WGS_E2 (0.00669437999014f)
+void loc_convert_lla_gnss_to_vrp(double lla[3], float rollPitchYaw[3],
+ float leverArm[3]) {
+ LOC_LOGv("lla: %f, %f, %f, lever arm: %f %f %f, "
+ "rollpitchyaw: %f %f %f",
+ lla[0], lla[1], lla[2],
+ leverArm[0], leverArm[1], leverArm[2],
+ rollPitchYaw[0], rollPitchYaw[1], rollPitchYaw[2]);
+
+ float cnb[3][3];
+ memset(cnb, 0, sizeof(cnb));
+ Euler2Dcm(rollPitchYaw, cnb);
+
+ float sl = sin(lla[0]);
+ float cl = cos(lla[0]);
+ float sf = 1.0f / (1.0f - A6DOF_WGS_E2 * sl* sl);
+ float sfr = sqrtf(sf);
+
+ float rn = A6DOF_WGS_B * sf * sfr + lla[2];
+ float re = A6DOF_WGS_A * sfr + lla[2];
+
+ float deltaNEU[3];
+
+ // gps_pos_lla = imu_pos_lla + Cbn*la_b .* [1/geo.Rn; 1/(geo.Re*geo.cL); -1];
+ Matrix_MxV(cnb, leverArm, deltaNEU);
+
+ // NED to lla conversion
+ lla[0] = lla[0] + deltaNEU[0] / rn;
+ lla[1] = lla[1] + deltaNEU[1] / (re * cl);
+ lla[2] = lla[2] + deltaNEU[2];
+}
+
+// Used for convert velocity from GSNS based to VRP based
+// The converted velocity will be stored in the enuVelocity parameter.
+void loc_convert_velocity_gnss_to_vrp(float enuVelocity[3], float rollPitchYaw[3],
+ float rollPitchYawRate[3], float leverArm[3]) {
+
+ LOC_LOGv("enu velocity: %f, %f, %f, lever arm: %f %f %f, roll pitch yaw: %f %f %f,"
+ "rollpitchyawRate: %f %f %f",
+ enuVelocity[0], enuVelocity[1], enuVelocity[2],
+ leverArm[0], leverArm[1], leverArm[2],
+ rollPitchYaw[0], rollPitchYaw[1], rollPitchYaw[2],
+ rollPitchYawRate[0], rollPitchYawRate[1], rollPitchYawRate[2]);
+
+ float cnb[3][3];
+ memset(cnb, 0, sizeof(cnb));
+ Euler2Dcm(rollPitchYaw, cnb);
+
+ float skewLA[3][3];
+ memset(skewLA, 0, sizeof(skewLA));
+ Matrix_Skew(leverArm, skewLA);
+
+ float tmp[3];
+ float deltaEnuVelocity[3];
+ memset(tmp, 0, sizeof(tmp));
+ memset(deltaEnuVelocity, 0, sizeof(deltaEnuVelocity));
+ Matrix_MxV(skewLA, rollPitchYawRate, tmp);
+ Matrix_MxV(cnb, tmp, deltaEnuVelocity);
+
+ enuVelocity[0] = enuVelocity[0] - deltaEnuVelocity[0];
+ enuVelocity[1] = enuVelocity[1] - deltaEnuVelocity[1];
+ enuVelocity[2] = enuVelocity[2] - deltaEnuVelocity[2];
+}
diff --git a/utils/loc_misc_utils.h b/utils/loc_misc_utils.h
index fad1b6d..2335e57 100644
--- a/utils/loc_misc_utils.h
+++ b/utils/loc_misc_utils.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014, 2020 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
@@ -28,11 +28,16 @@
*/
#ifndef _LOC_MISC_UTILS_H_
#define _LOC_MISC_UTILS_H_
+#include <stdint.h>
+#include <ios>
+#include <string>
+#include <sstream>
#ifdef __cplusplus
extern "C" {
#endif
-
+#include <stddef.h>
+#include <stdint.h>
/*===========================================================================
FUNCTION loc_split_string
@@ -120,8 +125,197 @@
===========================================================================*/
void* dlGetSymFromLib(void*& libHandle, const char* libName, const char* symName);
+/*===========================================================================
+FUNCTION getQTimerTickCount
+
+DESCRIPTION
+ This function is used to read the QTimer ticks count. This value is globally maintained and
+ must be the same across all processors on a target.
+
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ uint64_t QTimer tick count
+
+SIDE EFFECTS
+ N/A
+===========================================================================*/
+uint64_t getQTimerTickCount();
+
+/*===========================================================================
+FUNCTION getQTimerDeltaNanos
+
+DESCRIPTION
+This function is used to read the the difference in nanoseconds between
+Qtimer on AP side and Qtimer on MP side for dual-SoC architectures such as Kona
+
+DEPENDENCIES
+N/A
+
+RETURN VALUE
+uint64_t QTimer difference in nanoseconds
+
+SIDE EFFECTS
+N/A
+===========================================================================*/
+uint64_t getQTimerDeltaNanos();
+
+/*===========================================================================
+FUNCTION getQTimerFreq
+
+DESCRIPTION
+ This function is used to read the QTimer frequency in hz. This value is globally maintained and
+ must be the same across all processors on a target.
+
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ uint64_t QTimer frequency
+
+SIDE EFFECTS
+ N/A
+===========================================================================*/
+uint64_t getQTimerFreq();
+
+/*===========================================================================
+FUNCTION getBootTimeMilliSec
+
+DESCRIPTION
+ This function is used to get boot time in milliseconds.
+
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ uint64_t boot time in milliseconds
+
+SIDE EFFECTS
+ N/A
+===========================================================================*/
+uint64_t getBootTimeMilliSec();
+
#ifdef __cplusplus
}
#endif
+using std::hex;
+using std::string;
+using std::stringstream;
+
+/*===========================================================================
+FUNCTION to_string_hex
+
+DESCRIPTION
+ This function works similar to std::to_string, but puts only in hex format.
+
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ string, of input val in hex format
+
+SIDE EFFECTS
+ N/A
+===========================================================================*/
+template <typename T>
+string to_string_hex(T val) {
+ stringstream ss;
+ if (val < 0) {
+ val = -val;
+ ss << "-";
+ }
+ ss << hex << "0x" << val;
+ return ss.str();
+}
+
+/*===========================================================================
+FUNCTION loc_prim_arr_to_string
+
+DESCRIPTION
+ This function puts out primitive array in DEC or EHX format.
+
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ string, space separated string of values in the input array, either
+ in decimal or hex format, depending on the value of decIfTrue
+
+SIDE EFFECTS
+ N/A
+===========================================================================*/
+template <typename T>
+static string loc_prim_arr_to_string(T* arr, uint32_t size, bool decIfTrue = true) {
+ stringstream ss;
+ for (uint32_t i = 0; i < size; i++) {
+ ss << (decIfTrue ? to_string(arr[i]) : to_string_hex(arr[i]));
+ if (i != size - 1) {
+ ss << " ";
+ }
+ }
+ return ss.str();
+}
+
+/*===========================================================================
+FUNCTION qTimerTicksToNanos
+
+DESCRIPTION
+ Transform from ticks to nanoseconds, clock is 19.2 MHz
+ so the formula would be qtimer(ns) = (ticks * 1000000000) / 19200000
+ or simplified qtimer(ns) = (ticks * 10000) / 192.
+
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ Qtimer value in nanoseconds
+
+SIDE EFFECTS
+ N/A
+===========================================================================*/
+inline uint64_t qTimerTicksToNanos(double qTimer) {
+ return (uint64_t((qTimer * double(10000ull)) / (double)192ull));
+}
+
+/*===========================================================================
+FUNCTION loc_convert_lla_gnss_to_vrp
+
+DESCRIPTION
+ This function converts lat/long/altitude from GNSS antenna based
+ to vehicle reference point based.
+
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ The converted lat/long/altitude will be stored in the parameter of llaInfo.
+
+SIDE EFFECTS
+ N/A
+===========================================================================*/
+void loc_convert_lla_gnss_to_vrp(double lla[3], float rollPitchYaw[3],
+ float leverArm[3]);
+
+/*===========================================================================
+FUNCTION loc_convert_velocity_gnss_to_vrp
+
+DESCRIPTION
+ This function converts east/north/up velocity from GNSS antenna based
+ to vehicle reference point based.
+
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ The converted east/north/up velocity will be stored in the parameter of
+ enuVelocity.
+
+SIDE EFFECTS
+ N/A
+===========================================================================*/
+void loc_convert_velocity_gnss_to_vrp(float enuVelocity[3], float rollPitchYaw[3],
+ float rollPitchYawRate[3], float leverArm[3]);
+
#endif //_LOC_MISC_UTILS_H_
diff --git a/utils/loc_nmea.cpp b/utils/loc_nmea.cpp
index 9ee2716..3cd31cd 100644
--- a/utils/loc_nmea.cpp
+++ b/utils/loc_nmea.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2020, 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,11 +36,16 @@
#include <loc_cfg.h>
#define GLONASS_SV_ID_OFFSET 64
-#define QZSS_SV_ID_OFFSET (-192)
+#define SBAS_SV_ID_OFFSET (87)
+#define QZSS_SV_ID_OFFSET (192)
+#define BDS_SV_ID_OFFSET (200)
+#define GALILEO_SV_ID_OFFSET (300)
+#define NAVIC_SV_ID_OFFSET (400)
#define MAX_SV_COUNT_SUPPORTED_IN_ONE_CONSTELLATION 64
#define MAX_SATELLITES_IN_USE 12
#define MSEC_IN_ONE_WEEK 604800000ULL
#define UTC_GPS_OFFSET_MSECS 315964800000ULL
+#define MAX_TAG_BLOCK_GROUP_CODE (99999)
// GNSS system id according to NMEA spec
#define SYSTEM_ID_GPS 1
@@ -110,7 +115,7 @@
typedef struct loc_nmea_sv_meta_s
{
char talker[3];
- LocGnssConstellationType svType;
+ uint32_t svTypeMask;
uint64_t mask;
uint32_t svCount;
uint32_t totalSvUsedCount;
@@ -128,14 +133,18 @@
uint64_t bds_used_mask;
uint64_t navic_used_mask;
uint32_t gps_l1_count;
+ uint32_t gps_l2_count;
uint32_t gps_l5_count;
uint32_t glo_g1_count;
uint32_t glo_g2_count;
uint32_t gal_e1_count;
uint32_t gal_e5_count;
+ uint32_t gal_e5b_count;
uint32_t qzss_l1_count;
+ uint32_t qzss_l2_count;
uint32_t qzss_l5_count;
- uint32_t bds_b1_count;
+ uint32_t bds_b1i_count;
+ uint32_t bds_b1c_count;
uint32_t bds_b2_count;
uint32_t navic_l5_count;
float hdop;
@@ -285,6 +294,7 @@
switch (signalType) {
case GNSS_SIGNAL_GPS_L1CA:
+ case GNSS_SIGNAL_SBAS_L1:
signalId = SIGNAL_ID_GPS_L1CA;
break;
case GNSS_SIGNAL_GPS_L2:
@@ -397,7 +407,7 @@
bool needCombine)
{
memset(&sv_meta, 0, sizeof(sv_meta));
- sv_meta.svType = svType;
+ sv_meta.svTypeMask = (1 << svType);
switch (svType)
{
@@ -406,10 +416,17 @@
sv_meta.talker[1] = 'P';
sv_meta.mask = sv_cache_info.gps_used_mask;
sv_meta.systemId = SYSTEM_ID_GPS;
- if (GNSS_SIGNAL_GPS_L1CA == signalType) {
- sv_meta.svCount = sv_cache_info.gps_l1_count;
- } else if (GNSS_SIGNAL_GPS_L5 == signalType) {
- sv_meta.svCount = sv_cache_info.gps_l5_count;
+ sv_meta.svTypeMask |= (1 << GNSS_SV_TYPE_SBAS);
+ switch (signalType) {
+ case GNSS_SIGNAL_GPS_L1CA:
+ sv_meta.svCount = sv_cache_info.gps_l1_count;
+ break;
+ case GNSS_SIGNAL_GPS_L5:
+ sv_meta.svCount = sv_cache_info.gps_l5_count;
+ break;
+ case GNSS_SIGNAL_GPS_L2:
+ sv_meta.svCount = sv_cache_info.gps_l2_count;
+ break;
}
break;
case GNSS_SV_TYPE_GLONASS:
@@ -419,56 +436,83 @@
// GLONASS SV ids are from 65-96
sv_meta.svIdOffset = GLONASS_SV_ID_OFFSET;
sv_meta.systemId = SYSTEM_ID_GLONASS;
- if (GNSS_SIGNAL_GLONASS_G1 == signalType) {
- sv_meta.svCount = sv_cache_info.glo_g1_count;
- } else if (GNSS_SIGNAL_GLONASS_G2 == signalType) {
- sv_meta.svCount = sv_cache_info.glo_g2_count;
+ switch (signalType) {
+ case GNSS_SIGNAL_GLONASS_G1:
+ sv_meta.svCount = sv_cache_info.glo_g1_count;
+ break;
+ case GNSS_SIGNAL_GLONASS_G2:
+ sv_meta.svCount = sv_cache_info.glo_g2_count;
+ break;
}
break;
case GNSS_SV_TYPE_GALILEO:
sv_meta.talker[0] = 'G';
sv_meta.talker[1] = 'A';
sv_meta.mask = sv_cache_info.gal_used_mask;
+ // GALILEO SV ids are from 301-336, So keep svIdOffset 300
+ sv_meta.svIdOffset = GALILEO_SV_ID_OFFSET;
sv_meta.systemId = SYSTEM_ID_GALILEO;
- if (GNSS_SIGNAL_GALILEO_E1 == signalType) {
- sv_meta.svCount = sv_cache_info.gal_e1_count;
- } else if (GNSS_SIGNAL_GALILEO_E5A == signalType) {
- sv_meta.svCount = sv_cache_info.gal_e5_count;
+ switch (signalType) {
+ case GNSS_SIGNAL_GALILEO_E1:
+ sv_meta.svCount = sv_cache_info.gal_e1_count;
+ break;
+ case GNSS_SIGNAL_GALILEO_E5A:
+ sv_meta.svCount = sv_cache_info.gal_e5_count;
+ break;
+ case GNSS_SIGNAL_GALILEO_E5B:
+ sv_meta.svCount = sv_cache_info.gal_e5b_count;
+ break;
}
break;
case GNSS_SV_TYPE_QZSS:
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-199. So keep svIdOffset -192
+ // QZSS SV ids are from 193-199. So keep svIdOffset 192
sv_meta.svIdOffset = QZSS_SV_ID_OFFSET;
sv_meta.systemId = SYSTEM_ID_QZSS;
- if (GNSS_SIGNAL_QZSS_L1CA == signalType) {
- sv_meta.svCount = sv_cache_info.qzss_l1_count;
- } else if (GNSS_SIGNAL_QZSS_L5 == signalType) {
- sv_meta.svCount = sv_cache_info.qzss_l5_count;
+ switch (signalType) {
+ case GNSS_SIGNAL_QZSS_L1CA:
+ sv_meta.svCount = sv_cache_info.qzss_l1_count;
+ break;
+ case GNSS_SIGNAL_QZSS_L2:
+ sv_meta.svCount = sv_cache_info.qzss_l2_count;
+ break;
+ case GNSS_SIGNAL_QZSS_L5:
+ sv_meta.svCount = sv_cache_info.qzss_l5_count;
+ break;
}
break;
case GNSS_SV_TYPE_BEIDOU:
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
+ // BDS SV ids are from 201-237. So keep svIdOffset 200
+ sv_meta.svIdOffset = BDS_SV_ID_OFFSET;
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) {
- sv_meta.svCount = sv_cache_info.bds_b2_count;
+ switch (signalType) {
+ case GNSS_SIGNAL_BEIDOU_B1I:
+ sv_meta.svCount = sv_cache_info.bds_b1i_count;
+ break;
+ case GNSS_SIGNAL_BEIDOU_B1C:
+ sv_meta.svCount = sv_cache_info.bds_b1c_count;
+ break;
+ case GNSS_SIGNAL_BEIDOU_B2AI:
+ sv_meta.svCount = sv_cache_info.bds_b2_count;
+ break;
}
break;
case GNSS_SV_TYPE_NAVIC:
sv_meta.talker[0] = 'G';
sv_meta.talker[1] = 'I';
sv_meta.mask = sv_cache_info.navic_used_mask;
- // NAVIC SV ids are from 401-414. So keep svIdOffset 0
+ // NAVIC SV ids are from 401-414. So keep svIdOffset 400
+ sv_meta.svIdOffset = NAVIC_SV_ID_OFFSET;
sv_meta.systemId = SYSTEM_ID_NAVIC;
- if (GNSS_SIGNAL_NAVIC_L5 == signalType) {
- sv_meta.svCount = sv_cache_info.navic_l5_count;
+ switch (signalType) {
+ case GNSS_SIGNAL_NAVIC_L5:
+ sv_meta.svCount = sv_cache_info.navic_l5_count;
+ break;
}
break;
default:
@@ -523,23 +567,28 @@
N/A
===========================================================================*/
-static int loc_nmea_put_checksum(char *pNmea, int maxSize)
+static int loc_nmea_put_checksum(char *pNmea, int maxSize, bool isTagBlock)
{
uint8_t checksum = 0;
int length = 0;
+ int checksumLength = 0;
if(NULL == pNmea)
return 0;
- pNmea++; //skip the $
+ pNmea++; //skip the $ or / for Tag Block
while (*pNmea != '\0')
{
checksum ^= *pNmea++;
length++;
}
- // length now contains nmea sentence string length not including $ sign.
- int checksumLength = snprintf(pNmea,(maxSize-length-1),"*%02X\r\n", checksum);
-
+ if (isTagBlock) {
+ // length now contains tag block sentence string length not including / sign.
+ checksumLength = snprintf(pNmea, (maxSize-length-1), "*%02X\\", checksum);
+ } else {
+ // length now contains nmea sentence string length not including $ sign.
+ checksumLength = snprintf(pNmea, (maxSize-length-1), "*%02X\r\n", checksum);
+ }
// total length of nmea sentence is length of nmea sentence inc $ sign plus
// length of checksum (+1 is to cover the $ character in the length).
return (length + checksumLength + 1);
@@ -570,7 +619,8 @@
char* sentence,
int bufSize,
loc_nmea_sv_meta* sv_meta_p,
- std::vector<std::string> &nmeaArraystr)
+ std::vector<std::string> &nmeaArraystr,
+ bool isTagBlockGroupingEnabled)
{
if (!sentence || bufSize <= 0 || !sv_meta_p)
{
@@ -581,9 +631,14 @@
char* pMarker = sentence;
int lengthRemaining = bufSize;
int length = 0;
+ int lengthTagBlock = 0;
uint32_t svUsedCount = 0;
uint32_t svUsedList[64] = {0};
+ uint32_t sentenceCount = 0;
+ uint32_t sentenceNumber = 1;
+ size_t svNumber = 1;
+ static uint32_t code = 1;
char fixType = '\0';
@@ -591,7 +646,7 @@
uint32_t svIdOffset = sv_meta_p->svIdOffset;
uint64_t mask = sv_meta_p->mask;
- if(sv_meta_p->svType != GNSS_SV_TYPE_GLONASS) {
+ if (!(sv_meta_p->svTypeMask & (1 << GNSS_SV_TYPE_GLONASS))) {
svIdOffset = 0;
}
@@ -602,77 +657,98 @@
mask = mask >> 1;
}
- if (svUsedCount == 0)
+ if (svUsedCount == 0) {
return 0;
-
- if (sv_meta_p->totalSvUsedCount == 0)
- fixType = '1'; // no fix
- else if (sv_meta_p->totalSvUsedCount <= 3)
- fixType = '2'; // 2D fix
- else
- fixType = '3'; // 3D fix
-
- // Start printing the sentence
- // Format: $--GSA,a,x,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,p.p,h.h,v.v,s*cc
- // a : Mode : A : Automatic, allowed to automatically switch 2D/3D
- // x : Fixtype : 1 (no fix), 2 (2D fix), 3 (3D fix)
- // xx : 12 SV ID
- // p.p : Position DOP (Dilution of Precision)
- // h.h : Horizontal DOP
- // v.v : Vertical DOP
- // s : GNSS System Id
- // cc : Checksum value
- length = snprintf(pMarker, lengthRemaining, "$%sGSA,A,%c,", talker, fixType);
-
- if (length < 0 || length >= lengthRemaining)
- {
- LOC_LOGE("NMEA Error in string formatting");
- return 0;
+ } else {
+ sentenceNumber = 1;
+ sentenceCount = svUsedCount / 12 + (svUsedCount % 12 != 0);
+ svNumber = 1;
}
- pMarker += length;
- lengthRemaining -= length;
-
- // Add first 12 satellite IDs
- for (uint8_t i = 0; i < 12; i++)
- {
- if (i < svUsedCount)
- length = snprintf(pMarker, lengthRemaining, "%02d,", svUsedList[i]);
+ while (sentenceNumber <= sentenceCount) {
+ pMarker = sentence;
+ lengthRemaining = bufSize;
+ if (svUsedCount > 12 && isTagBlockGroupingEnabled) {
+ lengthTagBlock = snprintf(pMarker, lengthRemaining, "\\g:%d-%d-%d", sentenceNumber,
+ sentenceCount, code);
+ if (MAX_TAG_BLOCK_GROUP_CODE == code) {
+ code = 1;
+ }
+ lengthTagBlock = loc_nmea_put_checksum(sentence, bufSize, true);
+ pMarker += lengthTagBlock;
+ lengthRemaining -= lengthTagBlock;
+ }
+ if (sv_meta_p->totalSvUsedCount == 0)
+ fixType = '1'; // no fix
+ else if (sv_meta_p->totalSvUsedCount <= 3)
+ fixType = '2'; // 2D fix
else
- length = snprintf(pMarker, lengthRemaining, ",");
+ fixType = '3'; // 3D fix
- if (length < 0 || length >= lengthRemaining)
- {
+ // Start printing the sentence
+ // Format: $--GSA,a,x,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,p.p,h.h,v.v,s*cc
+ // a : Mode : A : Automatic, allowed to automatically switch 2D/3D
+ // x : Fixtype : 1 (no fix), 2 (2D fix), 3 (3D fix)
+ // xx : 12 SV ID
+ // p.p : Position DOP (Dilution of Precision)
+ // h.h : Horizontal DOP
+ // v.v : Vertical DOP
+ // s : GNSS System Id
+ // cc : Checksum value
+ length = snprintf(pMarker, lengthRemaining, "$%sGSA,A,%c,", talker, fixType);
+ if (length < 0 || length >= lengthRemaining) {
LOC_LOGE("NMEA Error in string formatting");
return 0;
}
pMarker += length;
lengthRemaining -= length;
+
+ // Add 12 satellite IDs
+ for (uint8_t i = 0; i < 12; i++, svNumber++)
+ {
+ if (svNumber <= svUsedCount)
+ length = snprintf(pMarker, lengthRemaining, "%02d,", svUsedList[svNumber - 1]);
+ else
+ length = snprintf(pMarker, lengthRemaining, ",");
+
+ if (length < 0 || length >= lengthRemaining) {
+ LOC_LOGE("NMEA Error in string formatting");
+ return 0;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+ }
+
+ // Add the position/horizontal/vertical DOP values
+ if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_DOP)
+ {
+ length = snprintf(pMarker, lengthRemaining, "%.1f,%.1f,%.1f,",
+ locationExtended.pdop,
+ locationExtended.hdop,
+ locationExtended.vdop);
+ }
+ else
+ { // no dop
+ length = snprintf(pMarker, lengthRemaining, ",,,");
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+
+ // system id
+ length = snprintf(pMarker, lengthRemaining, "%d", sv_meta_p->systemId);
+ pMarker += length;
+ lengthRemaining -= length;
+
+ /* Sentence is ready, add checksum and broadcast */
+ length = loc_nmea_put_checksum(sentence + lengthTagBlock, bufSize - lengthTagBlock, false);
+ nmeaArraystr.push_back(sentence);
+ sentenceNumber++;
+ if (!isTagBlockGroupingEnabled) {
+ break;
+ }
}
-
- // Add the position/horizontal/vertical DOP values
- if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_DOP)
- {
- length = snprintf(pMarker, lengthRemaining, "%.1f,%.1f,%.1f,",
- locationExtended.pdop,
- locationExtended.hdop,
- locationExtended.vdop);
+ if (svUsedCount > 12 && isTagBlockGroupingEnabled) {
+ code++;
}
- else
- { // no dop
- length = snprintf(pMarker, lengthRemaining, ",,,");
- }
- pMarker += length;
- lengthRemaining -= length;
-
- // system id
- length = snprintf(pMarker, lengthRemaining, "%d", sv_meta_p->systemId);
- pMarker += length;
- lengthRemaining -= length;
-
- /* Sentence is ready, add checksum and broadcast */
- length = loc_nmea_put_checksum(sentence, bufSize);
- nmeaArraystr.push_back(sentence);
-
return svUsedCount;
}
@@ -724,6 +800,9 @@
return;
}
+ if ((1 << GNSS_SV_TYPE_GLONASS) & sv_meta_p->svTypeMask) {
+ svIdOffset = 0;
+ }
svNumber = 1;
sentenceNumber = 1;
sentenceCount = svCount / 4 + (svCount % 4 != 0);
@@ -779,19 +858,23 @@
}
}
- if (sv_meta_p->svType == svNotify.gnssSvs[svNumber - 1].type &&
+ if ((sv_meta_p->svTypeMask & (1 << svNotify.gnssSvs[svNumber - 1].type)) &&
sv_meta_p->signalId == convert_signalType_to_signalId(signalType))
{
- uint16_t svId = svNotify.gnssSvs[svNumber - 1].svId;
- // For QZSS we adjusted SV id's in GnssAdapter, we need to re-adjust here
- if (GNSS_SV_TYPE_QZSS == svNotify.gnssSvs[svNumber - 1].type) {
- svId = svId - (QZSS_SV_PRN_MIN - 1);
+ if (GNSS_SV_TYPE_SBAS == svNotify.gnssSvs[svNumber - 1].type) {
+ svIdOffset = SBAS_SV_ID_OFFSET;
}
- length = snprintf(pMarker, lengthRemaining,",%02d,%02d,%03d,",
- svId + svIdOffset,
+ if (GNSS_SV_TYPE_GLONASS == svNotify.gnssSvs[svNumber - 1].type &&
+ GLO_SV_PRN_SLOT_UNKNOWN == svNotify.gnssSvs[svNumber - 1].svId) {
+ length = snprintf(pMarker, lengthRemaining, ",,%02d,%03d,",
(int)(0.5 + svNotify.gnssSvs[svNumber - 1].elevation), //float to int
(int)(0.5 + svNotify.gnssSvs[svNumber - 1].azimuth)); //float to int
-
+ } else {
+ length = snprintf(pMarker, lengthRemaining, ",%02d,%02d,%03d,",
+ svNotify.gnssSvs[svNumber - 1].svId - svIdOffset,
+ (int)(0.5 + svNotify.gnssSvs[svNumber - 1].elevation), //float to int
+ (int)(0.5 + svNotify.gnssSvs[svNumber - 1].azimuth)); //float to int
+ }
if (length < 0 || length >= lengthRemaining)
{
LOC_LOGE("NMEA Error in string formatting");
@@ -824,7 +907,7 @@
pMarker += length;
lengthRemaining -= length;
- length = loc_nmea_put_checksum(sentence, bufSize);
+ length = loc_nmea_put_checksum(sentence, bufSize, false);
nmeaArraystr.push_back(sentence);
sentenceNumber++;
@@ -857,7 +940,7 @@
int lengthRemaining = bufSize;
int length = 0;
int datum_type;
- char ref_datum[4] = {0};
+ char ref_datum[4] = {'W', '8', '4', '\0'};
char local_datum[4] = {0};
double lla_offset[3] = {0};
char latHem, longHem;
@@ -868,21 +951,15 @@
datum_type = loc_get_datum_type();
switch (datum_type) {
case LOC_GNSS_DATUM_WGS84:
- ref_datum[0] = 'W';
- ref_datum[1] = '8';
- ref_datum[2] = '4';
- local_datum[0] = 'P';
- local_datum[1] = '9';
- local_datum[2] = '0';
- break;
- case LOC_GNSS_DATUM_PZ90:
- ref_datum[0] = 'P';
- ref_datum[1] = '9';
- ref_datum[2] = '0';
local_datum[0] = 'W';
local_datum[1] = '8';
local_datum[2] = '4';
break;
+ case LOC_GNSS_DATUM_PZ90:
+ local_datum[0] = 'P';
+ local_datum[1] = '9';
+ local_datum[2] = '0';
+ break;
default:
break;
}
@@ -902,7 +979,7 @@
lla_offset[1] -= 360.0;
}
lla_offset[2] = local_lla.alt - ref_lla.alt;
- if (lla_offset[0] > 0.0) {
+ if (lla_offset[0] >= 0.0) {
latHem = 'N';
} else {
latHem = 'S';
@@ -933,7 +1010,7 @@
pMarker += length;
lengthRemaining -= length;
- length = loc_nmea_put_checksum(sentence, bufSize);
+ length = loc_nmea_put_checksum(sentence, bufSize, false);
}
/*===========================================================================
@@ -1036,24 +1113,15 @@
bool custom_gga_fix_quality,
char ggaGpsQuality[3],
char & rmcModeIndicator,
- char & vtgModeIndicator) {
+ char & vtgModeIndicator,
+ char gnsModeIndicator[7]) {
ggaGpsQuality[0] = '0'; // 0 means no fix
rmcModeIndicator = 'N'; // N means no fix
vtgModeIndicator = 'N'; // N means no fix
-
+ memset(gnsModeIndicator, 'N', 6); // N means no fix
+ gnsModeIndicator[6] = '\0';
do {
- // GGA fix quality is defined in NMEA spec as below:
- // https://www.trimble.com/OEM_ReceiverHelp/V4.44/en/NMEA-0183messages_GGA.html
- // Fix quality: 0 = invalid
- // 1 = GPS fix (SPS)
- // 2 = DGPS fix
- // 3 = PPS fix
- // 4 = Real Time Kinematic
- // 5 = Float RTK
- // 6 = estimated (dead reckoning) (2.3 feature)
- // 7 = Manual input mode
- // 8 = Simulation mode
if (!(location.gpsLocation.flags & LOC_GPS_LOCATION_HAS_LAT_LONG)){
break;
}
@@ -1063,28 +1131,88 @@
ggaGpsQuality[0] = '2'; // 2 means DGPS fix
rmcModeIndicator = 'P'; // P means precise
vtgModeIndicator = 'P'; // P means precise
+ if (locationExtended.gnss_sv_used_ids.gps_sv_used_ids_mask ? 1 : 0)
+ gnsModeIndicator[0] = 'P'; // P means precise
+ if (locationExtended.gnss_sv_used_ids.glo_sv_used_ids_mask ? 1 : 0)
+ gnsModeIndicator[1] = 'P'; // P means precise
+ if (locationExtended.gnss_sv_used_ids.gal_sv_used_ids_mask ? 1 : 0)
+ gnsModeIndicator[2] = 'P'; // P means precise
+ if (locationExtended.gnss_sv_used_ids.bds_sv_used_ids_mask ? 1 : 0)
+ gnsModeIndicator[3] = 'P'; // P means precise
+ if (locationExtended.gnss_sv_used_ids.qzss_sv_used_ids_mask ? 1 : 0)
+ gnsModeIndicator[4] = 'P'; // P means precise
+ if (locationExtended.gnss_sv_used_ids.navic_sv_used_ids_mask ? 1 : 0)
+ gnsModeIndicator[5] = 'P'; // P means precise
break;
} else if (LOC_NAV_MASK_RTK_FIXED_CORRECTION & locationExtended.navSolutionMask){
ggaGpsQuality[0] = '4'; // 4 means RTK Fixed fix
rmcModeIndicator = 'R'; // use R (RTK fixed)
vtgModeIndicator = 'D'; // use D (differential) as
// no RTK fixed defined for VTG in NMEA 183 spec
+ if (locationExtended.gnss_sv_used_ids.gps_sv_used_ids_mask ? 1 : 0)
+ gnsModeIndicator[0] = 'R'; // R means RTK fixed
+ if (locationExtended.gnss_sv_used_ids.glo_sv_used_ids_mask ? 1 : 0)
+ gnsModeIndicator[1] = 'R'; // R means RTK fixed
+ if (locationExtended.gnss_sv_used_ids.gal_sv_used_ids_mask ? 1 : 0)
+ gnsModeIndicator[2] = 'R'; // R means RTK fixed
+ if (locationExtended.gnss_sv_used_ids.bds_sv_used_ids_mask ? 1 : 0)
+ gnsModeIndicator[3] = 'R'; // R means RTK fixed
+ if (locationExtended.gnss_sv_used_ids.qzss_sv_used_ids_mask ? 1 : 0)
+ gnsModeIndicator[4] = 'R'; // R means RTK fixed
+ if (locationExtended.gnss_sv_used_ids.navic_sv_used_ids_mask ? 1 : 0)
+ gnsModeIndicator[5] = 'R'; // R means RTK fixed
break;
} else if (LOC_NAV_MASK_RTK_CORRECTION & locationExtended.navSolutionMask){
ggaGpsQuality[0] = '5'; // 5 means RTK float fix
rmcModeIndicator = 'F'; // F means RTK float fix
vtgModeIndicator = 'D'; // use D (differential) as
// no RTK float defined for VTG in NMEA 183 spec
+ if (locationExtended.gnss_sv_used_ids.gps_sv_used_ids_mask ? 1 : 0)
+ gnsModeIndicator[0] = 'F'; // F means RTK float fix
+ if (locationExtended.gnss_sv_used_ids.glo_sv_used_ids_mask ? 1 : 0)
+ gnsModeIndicator[1] = 'F'; // F means RTK float fix
+ if (locationExtended.gnss_sv_used_ids.gal_sv_used_ids_mask ? 1 : 0)
+ gnsModeIndicator[2] = 'F'; // F means RTK float fix
+ if (locationExtended.gnss_sv_used_ids.bds_sv_used_ids_mask ? 1 : 0)
+ gnsModeIndicator[3] = 'F'; // F means RTK float fix
+ if (locationExtended.gnss_sv_used_ids.qzss_sv_used_ids_mask ? 1 : 0)
+ gnsModeIndicator[4] = 'F'; // F means RTK float fix
+ if (locationExtended.gnss_sv_used_ids.navic_sv_used_ids_mask ? 1 : 0)
+ gnsModeIndicator[5] = 'F'; // F means RTK float fix
break;
} else if (LOC_NAV_MASK_DGNSS_CORRECTION & locationExtended.navSolutionMask){
ggaGpsQuality[0] = '2'; // 2 means DGPS fix
rmcModeIndicator = 'D'; // D means differential
vtgModeIndicator = 'D'; // D means differential
+ if (locationExtended.gnss_sv_used_ids.gps_sv_used_ids_mask ? 1 : 0)
+ gnsModeIndicator[0] = 'D'; // D means differential
+ if (locationExtended.gnss_sv_used_ids.glo_sv_used_ids_mask ? 1 : 0)
+ gnsModeIndicator[1] = 'D'; // D means differential
+ if (locationExtended.gnss_sv_used_ids.gal_sv_used_ids_mask ? 1 : 0)
+ gnsModeIndicator[2] = 'D'; // D means differential
+ if (locationExtended.gnss_sv_used_ids.bds_sv_used_ids_mask ? 1 : 0)
+ gnsModeIndicator[3] = 'D'; // D means differential
+ if (locationExtended.gnss_sv_used_ids.qzss_sv_used_ids_mask ? 1 : 0)
+ gnsModeIndicator[4] = 'D'; // D means differential
+ if (locationExtended.gnss_sv_used_ids.navic_sv_used_ids_mask ? 1 : 0)
+ gnsModeIndicator[5] = 'D'; // D means differential
break;
} else if (LOC_NAV_MASK_SBAS_CORRECTION_IONO & locationExtended.navSolutionMask){
ggaGpsQuality[0] = '2'; // 2 means DGPS fix
rmcModeIndicator = 'D'; // D means differential
vtgModeIndicator = 'D'; // D means differential
+ if (locationExtended.gnss_sv_used_ids.gps_sv_used_ids_mask ? 1 : 0)
+ gnsModeIndicator[0] = 'D'; // D means differential
+ if (locationExtended.gnss_sv_used_ids.glo_sv_used_ids_mask ? 1 : 0)
+ gnsModeIndicator[1] = 'D'; // D means differential
+ if (locationExtended.gnss_sv_used_ids.gal_sv_used_ids_mask ? 1 : 0)
+ gnsModeIndicator[2] = 'D'; // D means differential
+ if (locationExtended.gnss_sv_used_ids.bds_sv_used_ids_mask ? 1 : 0)
+ gnsModeIndicator[3] = 'D'; // D means differential
+ if (locationExtended.gnss_sv_used_ids.qzss_sv_used_ids_mask ? 1 : 0)
+ gnsModeIndicator[4] = 'D'; // D means differential
+ if (locationExtended.gnss_sv_used_ids.navic_sv_used_ids_mask ? 1 : 0)
+ gnsModeIndicator[5] = 'D'; // D means differential
break;
}
}
@@ -1094,11 +1222,24 @@
ggaGpsQuality[0] = '1'; // 1 means GPS
rmcModeIndicator = 'A'; // A means autonomous
vtgModeIndicator = 'A'; // A means autonomous
+ if (locationExtended.gnss_sv_used_ids.gps_sv_used_ids_mask ? 1 : 0)
+ gnsModeIndicator[0] = 'A'; // A means autonomous
+ if (locationExtended.gnss_sv_used_ids.glo_sv_used_ids_mask ? 1 : 0)
+ gnsModeIndicator[1] = 'A'; // A means autonomous
+ if (locationExtended.gnss_sv_used_ids.gal_sv_used_ids_mask ? 1 : 0)
+ gnsModeIndicator[2] = 'A'; // A means autonomous
+ if (locationExtended.gnss_sv_used_ids.bds_sv_used_ids_mask ? 1 : 0)
+ gnsModeIndicator[3] = 'A'; // A means autonomous
+ if (locationExtended.gnss_sv_used_ids.qzss_sv_used_ids_mask ? 1 : 0)
+ gnsModeIndicator[4] = 'A'; // A means autonomous
+ if (locationExtended.gnss_sv_used_ids.navic_sv_used_ids_mask ? 1 : 0)
+ gnsModeIndicator[5] = 'A'; // A means autonomous
break;
} else if (LOC_POS_TECH_MASK_SENSORS & locationExtended.tech_mask){
ggaGpsQuality[0] = '6'; // 6 means estimated (dead reckoning)
rmcModeIndicator = 'E'; // E means estimated (dead reckoning)
vtgModeIndicator = 'E'; // E means estimated (dead reckoning)
+ memset(gnsModeIndicator, 'E', 6); // E means estimated (dead reckoning)
break;
}
}
@@ -1184,10 +1325,13 @@
const LocationSystemInfo &systemInfo,
unsigned char generate_nmea,
bool custom_gga_fix_quality,
- std::vector<std::string> &nmeaArraystr)
+ std::vector<std::string> &nmeaArraystr,
+ int& indexOfGGA,
+ bool isTagBlockGroupingEnabled)
{
ENTRY_LOG();
+ indexOfGGA = -1;
LocGpsUtcTime utcPosTimestamp = 0;
bool inLsTransition = false;
@@ -1255,7 +1399,6 @@
if (generate_nmea) {
char talker[3] = {'G', 'P', '\0'};
- char modeIndicator[7] = {0};
uint32_t svUsedCount = 0;
uint32_t count = 0;
loc_nmea_sv_meta sv_meta;
@@ -1265,7 +1408,7 @@
count = loc_nmea_generate_GSA(locationExtended, sentence, sizeof(sentence),
loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_GPS,
- GNSS_SIGNAL_GPS_L1CA, true), nmeaArraystr);
+ GNSS_SIGNAL_GPS_L1CA, true), nmeaArraystr, isTagBlockGroupingEnabled);
if (count > 0)
{
svUsedCount += count;
@@ -1279,7 +1422,7 @@
count = loc_nmea_generate_GSA(locationExtended, sentence, sizeof(sentence),
loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_GLONASS,
- GNSS_SIGNAL_GLONASS_G1, true), nmeaArraystr);
+ GNSS_SIGNAL_GLONASS_G1, true), nmeaArraystr, isTagBlockGroupingEnabled);
if (count > 0)
{
svUsedCount += count;
@@ -1293,7 +1436,7 @@
count = loc_nmea_generate_GSA(locationExtended, sentence, sizeof(sentence),
loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_GALILEO,
- GNSS_SIGNAL_GALILEO_E1, true), nmeaArraystr);
+ GNSS_SIGNAL_GALILEO_E1, true), nmeaArraystr, isTagBlockGroupingEnabled);
if (count > 0)
{
svUsedCount += count;
@@ -1306,7 +1449,7 @@
// ----------------------------
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, true), nmeaArraystr);
+ GNSS_SIGNAL_BEIDOU_B1I, true), nmeaArraystr, isTagBlockGroupingEnabled);
if (count > 0)
{
svUsedCount += count;
@@ -1320,7 +1463,7 @@
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, true), nmeaArraystr);
+ GNSS_SIGNAL_QZSS_L1CA, true), nmeaArraystr, isTagBlockGroupingEnabled);
if (count > 0)
{
svUsedCount += count;
@@ -1332,15 +1475,16 @@
// in this case, generate an empty GSA sentence
if (svUsedCount == 0) {
strlcpy(sentence, "$GPGSA,A,1,,,,,,,,,,,,,,,,", sizeof(sentence));
- length = loc_nmea_put_checksum(sentence, sizeof(sentence));
+ length = loc_nmea_put_checksum(sentence, sizeof(sentence), false);
nmeaArraystr.push_back(sentence);
}
char ggaGpsQuality[3] = {'0', '\0', '\0'};
char rmcModeIndicator = 'N';
char vtgModeIndicator = 'N';
+ char gnsModeIndicator[7] = {'N', 'N', 'N', 'N', 'N', 'N', '\0'};
loc_nmea_get_fix_quality(location, locationExtended, custom_gga_fix_quality,
- ggaGpsQuality, rmcModeIndicator, vtgModeIndicator);
+ ggaGpsQuality, rmcModeIndicator, vtgModeIndicator, gnsModeIndicator);
// -------------------
// ------$--VTG-------
@@ -1354,7 +1498,7 @@
float magTrack = location.gpsLocation.bearing;
if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_MAG_DEV)
{
- float magTrack = location.gpsLocation.bearing - locationExtended.magneticDeviation;
+ magTrack = location.gpsLocation.bearing - locationExtended.magneticDeviation;
if (magTrack < 0.0)
magTrack += 360.0;
else if (magTrack > 360.0)
@@ -1398,7 +1542,7 @@
length = snprintf(pMarker, lengthRemaining, "%c", vtgModeIndicator);
- length = loc_nmea_put_checksum(sentence, sizeof(sentence));
+ length = loc_nmea_put_checksum(sentence, sizeof(sentence), false);
nmeaArraystr.push_back(sentence);
memset(&ecef_w84, 0, sizeof(ecef_w84));
@@ -1415,23 +1559,21 @@
convert_WGS84_to_PZ90(ecef_w84, ecef_p90);
convert_Ecef_to_Lla(ecef_p90, lla_p90);
+ ref_lla.lat = location.gpsLocation.latitude;
+ ref_lla.lon = location.gpsLocation.longitude;
+ ref_lla.alt = location.gpsLocation.altitude;
+
switch (datum_type) {
case LOC_GNSS_DATUM_WGS84:
- ref_lla.lat = location.gpsLocation.latitude;
- ref_lla.lon = location.gpsLocation.longitude;
- ref_lla.alt = location.gpsLocation.altitude;
- local_lla.lat = lla_p90.lat / M_PI * 180.0;
- local_lla.lon = lla_p90.lon / M_PI * 180.0;
- local_lla.alt = lla_p90.alt;
- break;
- case LOC_GNSS_DATUM_PZ90:
- ref_lla.lat = lla_p90.lat / M_PI * 180.0;
- ref_lla.lon = lla_p90.lon / M_PI * 180.0;
- ref_lla.alt = lla_p90.alt;
local_lla.lat = location.gpsLocation.latitude;
local_lla.lon = location.gpsLocation.longitude;
local_lla.alt = location.gpsLocation.altitude;
break;
+ case LOC_GNSS_DATUM_PZ90:
+ local_lla.lat = lla_p90.lat / M_PI * 180.0;
+ local_lla.lon = lla_p90.lon / M_PI * 180.0;
+ local_lla.alt = lla_p90.alt;
+ break;
default:
break;
}
@@ -1602,7 +1744,7 @@
// hardcode Navigation Status field to 'V'
length = snprintf(pMarker, lengthRemaining, ",%c", 'V');
- length = loc_nmea_put_checksum(sentence_RMC, sizeof(sentence_RMC));
+ length = loc_nmea_put_checksum(sentence_RMC, sizeof(sentence_RMC), false);
// -------------------
// ------$--GNS-------
@@ -1671,49 +1813,7 @@
pMarker += length;
lengthRemaining -= length;
- if(!(sv_cache_info.gps_used_mask ? 1 : 0))
- modeIndicator[0] = 'N';
- else if (LOC_NAV_MASK_SBAS_CORRECTION_IONO & locationExtended.navSolutionMask)
- modeIndicator[0] = 'D';
- else if (LOC_POS_TECH_MASK_SENSORS == locationExtended.tech_mask)
- modeIndicator[0] = 'E';
- else
- modeIndicator[0] = 'A';
- if(!(sv_cache_info.glo_used_mask ? 1 : 0))
- modeIndicator[1] = 'N';
- else if (LOC_POS_TECH_MASK_SENSORS == locationExtended.tech_mask)
- modeIndicator[1] = 'E';
- else
- modeIndicator[1] = 'A';
- if(!(sv_cache_info.gal_used_mask ? 1 : 0))
- modeIndicator[2] = 'N';
- else if (LOC_POS_TECH_MASK_SENSORS == locationExtended.tech_mask)
- modeIndicator[2] = 'E';
- else
- modeIndicator[2] = 'A';
- if(!(sv_cache_info.bds_used_mask ? 1 : 0))
- modeIndicator[3] = 'N';
- else if (LOC_POS_TECH_MASK_SENSORS == locationExtended.tech_mask)
- modeIndicator[3] = 'E';
- else
- modeIndicator[3] = 'A';
- if(!(sv_cache_info.qzss_used_mask ? 1 : 0))
- modeIndicator[4] = 'N';
- else if (LOC_POS_TECH_MASK_SENSORS == locationExtended.tech_mask)
- modeIndicator[4] = 'E';
- else
- modeIndicator[4] = 'A';
- if(!(sv_cache_info.navic_used_mask ? 1 : 0))
- modeIndicator[5] = 'N';
- else if (LOC_POS_TECH_MASK_SENSORS == locationExtended.tech_mask)
- modeIndicator[5] = 'E';
- else
- modeIndicator[5] = 'A';
- modeIndicator[6] = '\0';
- for(int index = 5; index > 0 && 'N' == modeIndicator[index]; index--) {
- modeIndicator[index] = '\0';
- }
- length = snprintf(pMarker, lengthRemaining,"%s,", modeIndicator);
+ length = snprintf(pMarker, lengthRemaining, "%s,", gnsModeIndicator);
pMarker += length;
lengthRemaining -= length;
@@ -1756,24 +1856,57 @@
if ((location.gpsLocation.flags & LOC_GPS_LOCATION_HAS_ALTITUDE) &&
(locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_ALTITUDE_MEAN_SEA_LEVEL))
{
- length = snprintf(pMarker, lengthRemaining, "%.1lf,,",
+ length = snprintf(pMarker, lengthRemaining, "%.1lf,",
ref_lla.alt - locationExtended.altitudeMeanSeaLevel);
}
else
{
- length = snprintf(pMarker, lengthRemaining,",,");
+ length = snprintf(pMarker, lengthRemaining, ",");
}
-
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
pMarker += length;
lengthRemaining -= length;
+ if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_DGNSS_DATA_AGE)
+ {
+ length = snprintf(pMarker, lengthRemaining, "%.1f,",
+ (float)locationExtended.dgnssDataAgeMsec / 1000);
+ }
+ else
+ {
+ length = snprintf(pMarker, lengthRemaining, ",");
+ }
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+
+ if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_DGNSS_REF_STATION_ID)
+ {
+ length = snprintf(pMarker, lengthRemaining, "%04d",
+ locationExtended.dgnssRefStationId);
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ 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));
-
+ length = loc_nmea_put_checksum(sentence_GNS, sizeof(sentence_GNS), false);
// -------------------
// ------$--GGA-------
@@ -1885,15 +2018,52 @@
if ((location.gpsLocation.flags & LOC_GPS_LOCATION_HAS_ALTITUDE) &&
(locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_ALTITUDE_MEAN_SEA_LEVEL))
{
- length = snprintf(pMarker, lengthRemaining, "%.1lf,M,,",
+ length = snprintf(pMarker, lengthRemaining, "%.1lf,M,",
ref_lla.alt - locationExtended.altitudeMeanSeaLevel);
}
else
{
- length = snprintf(pMarker, lengthRemaining,",,,");
+ length = snprintf(pMarker, lengthRemaining, ",,");
+ }
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+
+ if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_DGNSS_DATA_AGE)
+ {
+ length = snprintf(pMarker, lengthRemaining, "%.1f,",
+ (float)locationExtended.dgnssDataAgeMsec / 1000);
+ }
+ else
+ {
+ length = snprintf(pMarker, lengthRemaining, ",");
+ }
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+
+ if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_DGNSS_REF_STATION_ID)
+ {
+ length = snprintf(pMarker, lengthRemaining, "%04d",
+ locationExtended.dgnssRefStationId);
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
}
- length = loc_nmea_put_checksum(sentence_GGA, sizeof(sentence_GGA));
+ length = loc_nmea_put_checksum(sentence_GGA, sizeof(sentence_GGA), false);
// ------$--DTM-------
nmeaArraystr.push_back(sentence_DTM);
@@ -1911,32 +2081,32 @@
}
// ------$--GGA-------
nmeaArraystr.push_back(sentence_GGA);
-
+ indexOfGGA = static_cast<int>(nmeaArraystr.size() - 1);
}
//Send blank NMEA reports for non-final fixes
else {
strlcpy(sentence, "$GPGSA,A,1,,,,,,,,,,,,,,,,", sizeof(sentence));
- length = loc_nmea_put_checksum(sentence, sizeof(sentence));
+ length = loc_nmea_put_checksum(sentence, sizeof(sentence), false);
nmeaArraystr.push_back(sentence);
strlcpy(sentence, "$GPVTG,,T,,M,,N,,K,N", sizeof(sentence));
- length = loc_nmea_put_checksum(sentence, sizeof(sentence));
+ length = loc_nmea_put_checksum(sentence, sizeof(sentence), false);
nmeaArraystr.push_back(sentence);
strlcpy(sentence, "$GPDTM,,,,,,,,", sizeof(sentence));
- length = loc_nmea_put_checksum(sentence, sizeof(sentence));
+ length = loc_nmea_put_checksum(sentence, sizeof(sentence), false);
nmeaArraystr.push_back(sentence);
strlcpy(sentence, "$GPRMC,,V,,,,,,,,,,N,V", sizeof(sentence));
- length = loc_nmea_put_checksum(sentence, sizeof(sentence));
+ length = loc_nmea_put_checksum(sentence, sizeof(sentence), false);
nmeaArraystr.push_back(sentence);
strlcpy(sentence, "$GPGNS,,,,,,N,,,,,,,V", sizeof(sentence));
- length = loc_nmea_put_checksum(sentence, sizeof(sentence));
+ length = loc_nmea_put_checksum(sentence, sizeof(sentence), false);
nmeaArraystr.push_back(sentence);
strlcpy(sentence, "$GPGGA,,,,,,0,,,,,,,,", sizeof(sentence));
- length = loc_nmea_put_checksum(sentence, sizeof(sentence));
+ length = loc_nmea_put_checksum(sentence, sizeof(sentence), false);
nmeaArraystr.push_back(sentence);
}
@@ -1967,41 +2137,26 @@
ENTRY_LOG();
char sentence[NMEA_SENTENCE_MAX_LENGTH] = {0};
- int svCount = svNotify.count;
- int svNumber = 1;
loc_sv_cache_info sv_cache_info = {};
//Count GPS SVs for saparating GPS from GLONASS and throw others
- for(svNumber=1; svNumber <= svCount; svNumber++) {
- if (GNSS_SV_TYPE_GPS == svNotify.gnssSvs[svNumber - 1].type)
+ for (uint32_t svOffset = 0; svOffset < svNotify.count; svOffset++) {
+ if ((GNSS_SV_TYPE_GPS == svNotify.gnssSvs[svOffset].type) ||
+ (GNSS_SV_TYPE_SBAS == svNotify.gnssSvs[svOffset].type))
{
- // cache the used in fix mask, as it will be needed to send $GPGSA
- // during the position report
- if (GNSS_SV_OPTIONS_USED_IN_FIX_BIT ==
- (svNotify.gnssSvs[svNumber - 1].gnssSvOptionsMask &
- GNSS_SV_OPTIONS_USED_IN_FIX_BIT))
- {
- sv_cache_info.gps_used_mask |= (1ULL << (svNotify.gnssSvs[svNumber - 1].svId - 1));
- }
- if (GNSS_SIGNAL_GPS_L5 == svNotify.gnssSvs[svNumber - 1].gnssSignalTypeMask) {
+ if (GNSS_SIGNAL_GPS_L5 == svNotify.gnssSvs[svOffset].gnssSignalTypeMask) {
sv_cache_info.gps_l5_count++;
+ } else if (GNSS_SIGNAL_GPS_L2 == svNotify.gnssSvs[svOffset].gnssSignalTypeMask) {
+ sv_cache_info.gps_l2_count++;
} else {
- // GNSS_SIGNAL_GPS_L1CA or default
+ // GNSS_SIGNAL_GPS_L1CA, GNSS_SIGNAL_SBAS_L1 or default
// If no signal type in report, it means default L1
sv_cache_info.gps_l1_count++;
}
}
- else if (GNSS_SV_TYPE_GLONASS == svNotify.gnssSvs[svNumber - 1].type)
+ else if (GNSS_SV_TYPE_GLONASS == svNotify.gnssSvs[svOffset].type)
{
- // cache the used in fix mask, as it will be needed to send $GNGSA
- // during the position report
- if (GNSS_SV_OPTIONS_USED_IN_FIX_BIT ==
- (svNotify.gnssSvs[svNumber - 1].gnssSvOptionsMask &
- GNSS_SV_OPTIONS_USED_IN_FIX_BIT))
- {
- sv_cache_info.glo_used_mask |= (1ULL << (svNotify.gnssSvs[svNumber - 1].svId - 1));
- }
- if (GNSS_SIGNAL_GLONASS_G2 == svNotify.gnssSvs[svNumber - 1].gnssSignalTypeMask){
+ if (GNSS_SIGNAL_GLONASS_G2 == svNotify.gnssSvs[svOffset].gnssSignalTypeMask){
sv_cache_info.glo_g2_count++;
} else {
// GNSS_SIGNAL_GLONASS_G1 or default
@@ -2009,74 +2164,53 @@
sv_cache_info.glo_g1_count++;
}
}
- else if (GNSS_SV_TYPE_GALILEO == svNotify.gnssSvs[svNumber - 1].type)
+ else if (GNSS_SV_TYPE_GALILEO == svNotify.gnssSvs[svOffset].type)
{
- // cache the used in fix mask, as it will be needed to send $GAGSA
- // during the position report
- if (GNSS_SV_OPTIONS_USED_IN_FIX_BIT ==
- (svNotify.gnssSvs[svNumber - 1].gnssSvOptionsMask &
- GNSS_SV_OPTIONS_USED_IN_FIX_BIT))
- {
- sv_cache_info.gal_used_mask |= (1ULL << (svNotify.gnssSvs[svNumber - 1].svId - 1));
- }
- if(GNSS_SIGNAL_GALILEO_E5A == svNotify.gnssSvs[svNumber - 1].gnssSignalTypeMask){
+ if(GNSS_SIGNAL_GALILEO_E5A == svNotify.gnssSvs[svOffset].gnssSignalTypeMask){
sv_cache_info.gal_e5_count++;
+ } else if (GNSS_SIGNAL_GALILEO_E5B == svNotify.gnssSvs[svOffset].gnssSignalTypeMask) {
+ sv_cache_info.gal_e5b_count++;
} else {
// GNSS_SIGNAL_GALILEO_E1 or default
// If no signal type in report, it means default E1
sv_cache_info.gal_e1_count++;
}
}
- else if (GNSS_SV_TYPE_QZSS == svNotify.gnssSvs[svNumber - 1].type)
+ else if (GNSS_SV_TYPE_QZSS == svNotify.gnssSvs[svOffset].type)
{
- // cache the used in fix mask, as it will be needed to send $PQGSA
- // during the position report
- if (GNSS_SV_OPTIONS_USED_IN_FIX_BIT ==
- (svNotify.gnssSvs[svNumber - 1].gnssSvOptionsMask &
- GNSS_SV_OPTIONS_USED_IN_FIX_BIT))
- {
- // For QZSS we adjusted SV id's in GnssAdapter, we need to re-adjust here
- sv_cache_info.qzss_used_mask |=
- (1ULL << (svNotify.gnssSvs[svNumber - 1].svId - (QZSS_SV_PRN_MIN - 1) - 1));
- }
- if (GNSS_SIGNAL_QZSS_L5 == svNotify.gnssSvs[svNumber - 1].gnssSignalTypeMask) {
+ if (GNSS_SIGNAL_QZSS_L5 == svNotify.gnssSvs[svOffset].gnssSignalTypeMask) {
sv_cache_info.qzss_l5_count++;
+ } else if (GNSS_SIGNAL_QZSS_L2 == svNotify.gnssSvs[svOffset].gnssSignalTypeMask) {
+ sv_cache_info.qzss_l2_count++;
} else {
// GNSS_SIGNAL_QZSS_L1CA or default
// If no signal type in report, it means default L1
sv_cache_info.qzss_l1_count++;
}
}
- else if (GNSS_SV_TYPE_BEIDOU == svNotify.gnssSvs[svNumber - 1].type)
+ else if (GNSS_SV_TYPE_BEIDOU == svNotify.gnssSvs[svOffset].type)
{
// cache the used in fix mask, as it will be needed to send $PQGSA
// during the position report
if (GNSS_SV_OPTIONS_USED_IN_FIX_BIT ==
- (svNotify.gnssSvs[svNumber - 1].gnssSvOptionsMask &
+ (svNotify.gnssSvs[svOffset].gnssSvOptionsMask &
GNSS_SV_OPTIONS_USED_IN_FIX_BIT))
{
- sv_cache_info.bds_used_mask |= (1ULL << (svNotify.gnssSvs[svNumber - 1].svId - 1));
+ setSvMask(sv_cache_info.bds_used_mask, svNotify.gnssSvs[svOffset].svId);
}
- if ((GNSS_SIGNAL_BEIDOU_B2AI == svNotify.gnssSvs[svNumber - 1].gnssSignalTypeMask) ||
- (GNSS_SIGNAL_BEIDOU_B2AQ == svNotify.gnssSvs[svNumber - 1].gnssSignalTypeMask)) {
+ if ((GNSS_SIGNAL_BEIDOU_B2AI == svNotify.gnssSvs[svOffset].gnssSignalTypeMask) ||
+ (GNSS_SIGNAL_BEIDOU_B2AQ == svNotify.gnssSvs[svOffset].gnssSignalTypeMask)) {
sv_cache_info.bds_b2_count++;
+ } else if (GNSS_SIGNAL_BEIDOU_B1C == svNotify.gnssSvs[svOffset].gnssSignalTypeMask) {
+ sv_cache_info.bds_b1c_count++;
} else {
// GNSS_SIGNAL_BEIDOU_B1I or default
// If no signal type in report, it means default B1I
- sv_cache_info.bds_b1_count++;
+ sv_cache_info.bds_b1i_count++;
}
}
- else if (GNSS_SV_TYPE_NAVIC == svNotify.gnssSvs[svNumber - 1].type)
+ else if (GNSS_SV_TYPE_NAVIC == svNotify.gnssSvs[svOffset].type)
{
- // cache the used in fix mask, as it will be needed to send $PQGSA
- // during the position report
- if (GNSS_SV_OPTIONS_USED_IN_FIX_BIT ==
- (svNotify.gnssSvs[svNumber - 1].gnssSvOptionsMask &
- GNSS_SV_OPTIONS_USED_IN_FIX_BIT))
- {
- sv_cache_info.navic_used_mask |=
- (1ULL << (svNotify.gnssSvs[svNumber - 1].svId - 1));
- }
// GNSS_SIGNAL_NAVIC_L5 is the only signal type for NAVIC
sv_cache_info.navic_l5_count++;
}
@@ -2098,6 +2232,14 @@
loc_nmea_generate_GSV(svNotify, sentence, sizeof(sentence),
loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_GPS,
GNSS_SIGNAL_GPS_L5, false), nmeaArraystr);
+
+ // ---------------------
+ // ------$GPGSV:L2------
+ // ---------------------
+ loc_nmea_generate_GSV(svNotify, sentence, sizeof(sentence),
+ loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_GPS,
+ GNSS_SIGNAL_GPS_L2, false), nmeaArraystr);
+
// ---------------------
// ------$GLGSV:G1------
// ---------------------
@@ -2129,8 +2271,15 @@
loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_GALILEO,
GNSS_SIGNAL_GALILEO_E5A, false), nmeaArraystr);
+ // -------------------------
+ // ------$GAGSV:E5B---------
+ // -------------------------
+ loc_nmea_generate_GSV(svNotify, sentence, sizeof(sentence),
+ loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_GALILEO,
+ GNSS_SIGNAL_GALILEO_E5B, false), nmeaArraystr);
+
// -----------------------------
- // ------$PQGSV (QZSS):L1CA-----
+ // ------$GQGSV (QZSS):L1CA-----
// -----------------------------
loc_nmea_generate_GSV(svNotify, sentence, sizeof(sentence),
@@ -2138,27 +2287,45 @@
GNSS_SIGNAL_QZSS_L1CA, false), nmeaArraystr);
// -----------------------------
- // ------$PQGSV (QZSS):L5-------
+ // ------$GQGSV (QZSS):L5-------
// -----------------------------
loc_nmea_generate_GSV(svNotify, sentence, sizeof(sentence),
loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_QZSS,
GNSS_SIGNAL_QZSS_L5, false), nmeaArraystr);
+
// -----------------------------
- // ------$PQGSV (BEIDOU:B1I)----
+ // ------$GQGSV (QZSS):L2-------
+ // -----------------------------
+
+ loc_nmea_generate_GSV(svNotify, sentence, sizeof(sentence),
+ loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_QZSS,
+ GNSS_SIGNAL_QZSS_L2, false), nmeaArraystr);
+
+
+ // -----------------------------
+ // ------$GBGSV (BEIDOU:B1I)----
// -----------------------------
loc_nmea_generate_GSV(svNotify, 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, false), nmeaArraystr);
// -----------------------------
- // ------$PQGSV (BEIDOU:B2AI)---
+ // ------$GBGSV (BEIDOU:B1C)----
// -----------------------------
loc_nmea_generate_GSV(svNotify, sentence, sizeof(sentence),
loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_BEIDOU,
- GNSS_SIGNAL_BEIDOU_B2AI,false), nmeaArraystr);
+ GNSS_SIGNAL_BEIDOU_B1C, false), nmeaArraystr);
+
+ // -----------------------------
+ // ------$GBGSV (BEIDOU:B2AI)---
+ // -----------------------------
+
+ loc_nmea_generate_GSV(svNotify, sentence, sizeof(sentence),
+ loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_BEIDOU,
+ GNSS_SIGNAL_BEIDOU_B2AI, false), nmeaArraystr);
// -----------------------------
// ------$GIGSV (NAVIC:L5)------
diff --git a/utils/loc_nmea.h b/utils/loc_nmea.h
index a9cafb7..2d98f42 100644
--- a/utils/loc_nmea.h
+++ b/utils/loc_nmea.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, 2015-2017 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, 2015-2020 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
@@ -80,7 +80,9 @@
const LocationSystemInfo &systemInfo,
unsigned char generate_nmea,
bool custom_gga_fix_quality,
- std::vector<std::string> &nmeaArraystr);
+ std::vector<std::string> &nmeaArraystr,
+ int& indexOfGGA,
+ bool isTagBlockGroupingEnabled);
#define DEBUG_NMEA_MINSIZE 6
#define DEBUG_NMEA_MAXSIZE 4096
diff --git a/utils/log_util.h b/utils/log_util.h
index 13c08bc..33aa6e2 100644
--- a/utils/log_util.h
+++ b/utils/log_util.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2014 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2014, 2020 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,7 +31,7 @@
#define __LOG_UTIL_H__
#include <stdbool.h>
-
+#include <loc_pla.h>
#if defined (USE_ANDROID_LOGGING) || defined (ANDROID)
// Android and LE targets with logcat support
#include <utils/Log.h>
@@ -52,7 +52,7 @@
#endif /* LOG_TAG */
// LE targets with no logcat support
-#ifdef FEATURE_EXTERNAL_AP
+#if defined(FEATURE_EXTERNAL_AP) || defined(USE_SYSLOG_LOGGING)
#include <syslog.h>
#define ALOGE(...) syslog(LOG_ERR, "LOC_LOGE: " __VA_ARGS__);
#define ALOGW(...) syslog(LOG_WARNING, "LOC_LOGW: " __VA_ARGS__);
@@ -119,6 +119,12 @@
extern const char ENTRY_TAG[];
extern const char EXIT_ERROR_TAG[];
+#define BUILD_TYPE_PROP_NA 0
+#define BUILD_TYPE_PROP_USER 1
+#define BUILD_TYPE_PROP_USERDEBUG 2
+#define BUILD_TYPE_PROP_INVALID 3
+extern int build_type_prop;
+
/*=============================================================================
*
* MODULE EXPORTED FUNCTIONS
@@ -126,23 +132,37 @@
*============================================================================*/
inline void loc_logger_init(unsigned long debug, unsigned long timestamp)
{
- loc_logger.DEBUG_LEVEL = debug;
-#ifdef TARGET_BUILD_VARIANT_USER
- // force user builds to 2 or less
- if (loc_logger.DEBUG_LEVEL > 2) {
- loc_logger.DEBUG_LEVEL = 2;
- }
-#endif
- loc_logger.TIMESTAMP = timestamp;
+ loc_logger.DEBUG_LEVEL = debug;
+
+ if (BUILD_TYPE_PROP_NA == build_type_prop) {
+ char value[PROPERTY_VALUE_MAX] = "NA";
+ property_get("ro.build.type", value, "userdebug");
+ if (0 == strcmp(value, "user")) {
+ build_type_prop = BUILD_TYPE_PROP_USER;
+ } else if (0 == strcmp(value, "userdebug")) {
+ build_type_prop = BUILD_TYPE_PROP_USERDEBUG;
+ } else {
+ build_type_prop = BUILD_TYPE_PROP_INVALID;
+ }
+ }
+
+ if (BUILD_TYPE_PROP_USER == build_type_prop) {
+ // force user builds to 2 or less
+ if (loc_logger.DEBUG_LEVEL > 2) {
+ loc_logger.DEBUG_LEVEL = 2;
+ }
+ }
+
+ loc_logger.TIMESTAMP = timestamp;
}
inline void log_buffer_init(bool enabled) {
loc_logger.LOG_BUFFER_ENABLE = enabled;
}
-
+extern void log_tag_level_map_init();
+extern int get_tag_log_level(const char* tag);
extern char* get_timestamp(char* str, unsigned long buf_size);
extern void log_buffer_insert(char *str, unsigned long buf_size, int level);
-
/*=============================================================================
*
* LOGGING BUFFER MACROS
@@ -175,11 +195,28 @@
if that value remains unchanged, it means gps.conf did not
provide a value and we default to the initial value to use
Android's logging levels*/
-#define IF_LOC_LOGE if((loc_logger.DEBUG_LEVEL >= 1) && (loc_logger.DEBUG_LEVEL <= 5))
-#define IF_LOC_LOGW if((loc_logger.DEBUG_LEVEL >= 2) && (loc_logger.DEBUG_LEVEL <= 5))
-#define IF_LOC_LOGI if((loc_logger.DEBUG_LEVEL >= 3) && (loc_logger.DEBUG_LEVEL <= 5))
-#define IF_LOC_LOGD if((loc_logger.DEBUG_LEVEL >= 4) && (loc_logger.DEBUG_LEVEL <= 5))
-#define IF_LOC_LOGV if((loc_logger.DEBUG_LEVEL >= 5) && (loc_logger.DEBUG_LEVEL <= 5))
+
+
+/* Tag based logging control MACROS */
+/* The logic is like this:
+ * 1, LOCAL_LOG_LEVEL is defined as a static variable in log_util.h,
+ * then all source files which includes log_util.h will have its own LOCAL_LOG_LEVEL variable;
+ * 2, For each source file,
+ * 2.1, First time when LOC_LOG* is invoked(its LOCAL_LOG_LEVEL == -1),
+ * Set the tag based log level according to the <tag, level> map;
+ * If this tag isn't found in map, set local debug level as global loc_logger.DEBUG_LEVEL;
+ * 2.2, If not the first time, use its LOCAL_LOG_LEVEL as the debug level of this tag.
+*/
+static int LOCAL_LOG_LEVEL = -1;
+#define IF_LOC_LOG(x) \
+ if (((LOCAL_LOG_LEVEL == -1 && (LOCAL_LOG_LEVEL = get_tag_log_level(LOG_TAG)) >= x) ||\
+ LOCAL_LOG_LEVEL >= x) && LOCAL_LOG_LEVEL <= 5)
+
+#define IF_LOC_LOGE IF_LOC_LOG(1)
+#define IF_LOC_LOGW IF_LOC_LOG(2)
+#define IF_LOC_LOGI IF_LOC_LOG(3)
+#define IF_LOC_LOGD IF_LOC_LOG(4)
+#define IF_LOC_LOGV IF_LOC_LOG(5)
#define LOC_LOGE(...) IF_LOC_LOGE { ALOGE(__VA_ARGS__); INSERT_BUFFER(LOG_NDEBUG, 0, __VA_ARGS__);}
#define LOC_LOGW(...) IF_LOC_LOGW { ALOGW(__VA_ARGS__); INSERT_BUFFER(LOG_NDEBUG, 1, __VA_ARGS__);}