From 5fd60608691a083e61394d4495d26c56f856ffb2 Mon Sep 17 00:00:00 2001 From: OdSazib Date: Mon, 1 Mar 2021 03:45:09 +0600 Subject: [PATCH] sdm660-common: Checkout gps hal from LA.UM.9.6.2.r1-03300-89xx.0 --- gps/Android.bp | 45 + gps/Android.mk | 45 +- gps/android/1.0/Gnss.cpp | 10 +- gps/android/1.0/GnssConfiguration.cpp | 38 +- gps/android/1.0/GnssConfiguration.h | 2 +- .../1.0/location_api/BatchingAPIClient.h | 1 + .../1.0/location_api/GeofenceAPIClient.h | 2 + .../1.0/location_api/GnssAPIClient.cpp | 6 +- gps/android/1.0/location_api/LocationUtil.cpp | 10 + .../1.0/location_api/MeasurementAPIClient.h | 1 + gps/android/1.1/Gnss.cpp | 10 +- gps/android/1.1/GnssConfiguration.cpp | 38 +- gps/android/1.1/GnssConfiguration.h | 2 +- .../1.1/location_api/GeofenceAPIClient.h | 5 +- .../1.1/location_api/GnssAPIClient.cpp | 6 +- gps/android/1.1/location_api/GnssAPIClient.h | 1 + gps/android/1.1/location_api/LocationUtil.cpp | 10 + gps/android/2.0/Android.mk | 10 +- gps/android/2.0/Gnss.cpp | 40 +- gps/android/2.0/Gnss.h | 3 +- gps/android/2.0/GnssConfiguration.cpp | 37 +- gps/android/2.0/GnssConfiguration.h | 2 +- gps/android/2.0/GnssMeasurement.cpp | 22 +- gps/android/2.0/GnssMeasurement.h | 1 + .../1.0 => 2.0}/GnssVisibilityControl.cpp | 0 .../1.0 => 2.0}/GnssVisibilityControl.h | 0 .../1.0 => 2.0}/MeasurementCorrections.cpp | 6 +- .../1.0 => 2.0}/MeasurementCorrections.h | 7 +- .../android.hardware.gnss@2.0-service-qti.xml | 1 - .../2.0/location_api/BatchingAPIClient.h | 1 + .../2.0/location_api/GeofenceAPIClient.h | 1 + .../2.0/location_api/GnssAPIClient.cpp | 27 +- gps/android/2.0/location_api/GnssAPIClient.h | 3 +- gps/android/2.0/location_api/LocationUtil.cpp | 85 +- .../2.0/location_api/MeasurementAPIClient.cpp | 116 +- .../2.0/location_api/MeasurementAPIClient.h | 2 +- gps/android/2.0/service.cpp | 27 +- gps/android/2.1/AGnss.cpp | 209 +++ gps/android/2.1/AGnss.h | 78 + gps/android/2.1/AGnssRil.cpp | 133 ++ gps/android/2.1/AGnssRil.h | 84 + gps/android/2.1/Android.mk | 116 ++ gps/android/2.1/Gnss.cpp | 800 +++++++++ gps/android/2.1/Gnss.h | 193 +++ gps/android/2.1/GnssAntennaInfo.cpp | 202 +++ gps/android/2.1/GnssAntennaInfo.h | 90 + gps/android/2.1/GnssBatching.cpp | 163 ++ gps/android/2.1/GnssBatching.h | 84 + gps/android/2.1/GnssConfiguration.cpp | 408 +++++ gps/android/2.1/GnssConfiguration.h | 88 + gps/android/2.1/GnssDebug.cpp | 299 ++++ gps/android/2.1/GnssDebug.h | 62 + gps/android/2.1/GnssGeofencing.cpp | 141 ++ gps/android/2.1/GnssGeofencing.h | 91 + gps/android/2.1/GnssMeasurement.cpp | 211 +++ gps/android/2.1/GnssMeasurement.h | 93 + gps/android/2.1/GnssNi.cpp | 85 + gps/android/2.1/GnssNi.h | 75 + gps/android/2.1/GnssVisibilityControl.cpp | 169 ++ gps/android/2.1/GnssVisibilityControl.h | 90 + gps/android/2.1/MeasurementCorrections.cpp | 199 +++ gps/android/2.1/MeasurementCorrections.h | 106 ++ .../android.hardware.gnss@2.1-service-qti.rc | 4 + .../android.hardware.gnss@2.1-service-qti.xml | 36 + .../2.1/location_api/BatchingAPIClient.cpp | 250 +++ .../2.1/location_api/BatchingAPIClient.h | 82 + .../2.1/location_api/GeofenceAPIClient.cpp | 275 +++ .../2.1/location_api/GeofenceAPIClient.h | 77 + .../2.1/location_api/GnssAPIClient.cpp | 863 ++++++++++ gps/android/2.1/location_api/GnssAPIClient.h | 118 ++ gps/android/2.1/location_api/LocationUtil.cpp | 492 ++++++ gps/android/2.1/location_api/LocationUtil.h | 69 + .../2.1/location_api/MeasurementAPIClient.cpp | 706 ++++++++ .../2.1/location_api/MeasurementAPIClient.h | 96 ++ gps/android/2.1/service.cpp | 81 + gps/android/Android.mk | 15 +- gps/android/utils/Android.bp | 37 + gps/android/utils/Android.mk | 41 - gps/android/utils/battery_listener.cpp | 28 +- gps/batching/Android.bp | 31 + gps/batching/Android.mk | 39 - gps/batching/BatchingAdapter.cpp | 9 +- gps/batching/Makefile.am | 3 +- gps/batching/configure.ac | 4 - gps/build/target_specific_features.mk | 73 - gps/core/Android.bp | 56 + gps/core/Android.mk | 62 - gps/core/ContextBase.cpp | 37 +- gps/core/ContextBase.h | 9 +- gps/core/EngineHubProxyBase.h | 10 +- gps/core/LocAdapterBase.cpp | 17 +- gps/core/LocApiBase.cpp | 73 +- gps/core/LocApiBase.h | 44 +- gps/core/LocContext.cpp | 21 +- gps/core/LocContext.h | 12 +- gps/core/SystemStatus.cpp | 10 +- gps/core/SystemStatus.h | 36 +- gps/core/SystemStatusOsObserver.cpp | 46 +- gps/core/SystemStatusOsObserver.h | 31 +- gps/core/observer/IFrameworkActionReq.h | 9 +- gps/core/observer/IOsObserver.h | 6 +- gps/etc/Android.bp | 49 + gps/etc/Android.mk | 21 - gps/etc/apdr.conf | 205 --- gps/etc/flp.conf | 2 +- gps/etc/gnss_antenna_info.conf | 134 ++ gps/etc/gps.conf | 80 +- gps/etc/izat.conf | 275 --- gps/etc/lowi.conf | 27 - gps/etc/sap.conf | 161 -- gps/etc/seccomp_policy/gnss@2.0-base.policy | 95 ++ .../gnss@2.0-xtra-daemon.policy | 48 + .../gnss@2.0-xtwifi-client.policy | 45 + .../gnss@2.0-xtwifi-inet-agent.policy | 33 + gps/etc/xtwifi.conf | 78 - gps/geofence/Android.bp | 31 + gps/geofence/Android.mk | 38 - gps/geofence/GeofenceAdapter.cpp | 22 +- gps/gnss/Agps.h | 4 +- gps/gnss/Android.bp | 34 + gps/gnss/Android.mk | 49 - gps/gnss/GnssAdapter.cpp | 1519 ++++++++++++++--- gps/gnss/GnssAdapter.h | 116 +- gps/gnss/XtraSystemStatusObserver.cpp | 65 +- gps/gnss/XtraSystemStatusObserver.h | 24 +- gps/gnss/location_gnss.cpp | 153 +- gps/gps_vendor_product.mk | 46 +- gps/location/Android.bp | 36 + gps/location/Android.mk | 44 - gps/location/ILocationAPI.h | 84 +- gps/location/LocationAPI.cpp | 59 +- gps/location/LocationAPI.h | 93 +- gps/location/LocationAPIClientBase.cpp | 14 +- gps/location/LocationAPIClientBase.h | 2 +- gps/location/LocationDataTypes.h | 537 ++++-- gps/location/location_interface.h | 24 +- gps/pla/Android.bp | 7 + gps/pla/Android.mk | 30 - gps/pla/android/loc_pla.h | 32 +- gps/pla/oe/loc_pla.h | 50 + gps/utils/Android.bp | 54 + gps/utils/Android.mk | 69 - gps/utils/LocHeap.cpp | 84 +- gps/utils/LocHeap.h | 6 +- gps/utils/LocIpc.cpp | 32 +- gps/utils/LocIpc.h | 51 +- gps/utils/LocLoggerBase.h | 39 + gps/utils/LocSharedLock.h | 10 +- gps/utils/LocThread.cpp | 251 +-- gps/utils/LocThread.h | 29 +- gps/utils/LocTimer.cpp | 179 +- gps/utils/LocTimer.h | 6 +- gps/utils/LogBuffer.cpp | 28 +- gps/utils/Makefile.am | 3 +- gps/utils/MsgTask.cpp | 80 +- gps/utils/MsgTask.h | 33 +- gps/utils/gps_extended_c.h | 229 ++- gps/utils/loc_cfg.cpp | 60 +- gps/utils/loc_cfg.h | 44 +- gps/utils/loc_gps.h | 8 +- gps/utils/loc_log.cpp | 65 +- gps/utils/loc_misc_utils.cpp | 198 ++- gps/utils/loc_misc_utils.h | 114 ++ gps/utils/loc_nmea.cpp | 102 +- gps/utils/loc_nmea.h | 5 +- gps/utils/log_util.h | 73 +- sdm660.mk | 10 +- 167 files changed, 12125 insertions(+), 2903 deletions(-) create mode 100644 gps/Android.bp rename gps/android/{visibility_control/1.0 => 2.0}/GnssVisibilityControl.cpp (100%) rename gps/android/{visibility_control/1.0 => 2.0}/GnssVisibilityControl.h (100%) rename gps/android/{measurement_corrections/1.0 => 2.0}/MeasurementCorrections.cpp (90%) rename gps/android/{measurement_corrections/1.0 => 2.0}/MeasurementCorrections.h (92%) create mode 100644 gps/android/2.1/AGnss.cpp create mode 100644 gps/android/2.1/AGnss.h create mode 100644 gps/android/2.1/AGnssRil.cpp create mode 100644 gps/android/2.1/AGnssRil.h create mode 100644 gps/android/2.1/Android.mk create mode 100644 gps/android/2.1/Gnss.cpp create mode 100644 gps/android/2.1/Gnss.h create mode 100644 gps/android/2.1/GnssAntennaInfo.cpp create mode 100644 gps/android/2.1/GnssAntennaInfo.h create mode 100644 gps/android/2.1/GnssBatching.cpp create mode 100644 gps/android/2.1/GnssBatching.h create mode 100644 gps/android/2.1/GnssConfiguration.cpp create mode 100644 gps/android/2.1/GnssConfiguration.h create mode 100644 gps/android/2.1/GnssDebug.cpp create mode 100644 gps/android/2.1/GnssDebug.h create mode 100644 gps/android/2.1/GnssGeofencing.cpp create mode 100644 gps/android/2.1/GnssGeofencing.h create mode 100644 gps/android/2.1/GnssMeasurement.cpp create mode 100644 gps/android/2.1/GnssMeasurement.h create mode 100644 gps/android/2.1/GnssNi.cpp create mode 100644 gps/android/2.1/GnssNi.h create mode 100644 gps/android/2.1/GnssVisibilityControl.cpp create mode 100644 gps/android/2.1/GnssVisibilityControl.h create mode 100644 gps/android/2.1/MeasurementCorrections.cpp create mode 100644 gps/android/2.1/MeasurementCorrections.h create mode 100644 gps/android/2.1/android.hardware.gnss@2.1-service-qti.rc create mode 100755 gps/android/2.1/android.hardware.gnss@2.1-service-qti.xml create mode 100755 gps/android/2.1/location_api/BatchingAPIClient.cpp create mode 100755 gps/android/2.1/location_api/BatchingAPIClient.h create mode 100755 gps/android/2.1/location_api/GeofenceAPIClient.cpp create mode 100755 gps/android/2.1/location_api/GeofenceAPIClient.h create mode 100644 gps/android/2.1/location_api/GnssAPIClient.cpp create mode 100755 gps/android/2.1/location_api/GnssAPIClient.h create mode 100644 gps/android/2.1/location_api/LocationUtil.cpp create mode 100644 gps/android/2.1/location_api/LocationUtil.h create mode 100644 gps/android/2.1/location_api/MeasurementAPIClient.cpp create mode 100644 gps/android/2.1/location_api/MeasurementAPIClient.h create mode 100755 gps/android/2.1/service.cpp create mode 100644 gps/android/utils/Android.bp delete mode 100644 gps/android/utils/Android.mk create mode 100644 gps/batching/Android.bp delete mode 100644 gps/batching/Android.mk delete mode 100644 gps/build/target_specific_features.mk create mode 100644 gps/core/Android.bp delete mode 100644 gps/core/Android.mk create mode 100644 gps/etc/Android.bp delete mode 100644 gps/etc/Android.mk delete mode 100644 gps/etc/apdr.conf create mode 100644 gps/etc/gnss_antenna_info.conf delete mode 100644 gps/etc/izat.conf delete mode 100644 gps/etc/lowi.conf delete mode 100644 gps/etc/sap.conf create mode 100644 gps/etc/seccomp_policy/gnss@2.0-base.policy create mode 100644 gps/etc/seccomp_policy/gnss@2.0-xtra-daemon.policy create mode 100644 gps/etc/seccomp_policy/gnss@2.0-xtwifi-client.policy create mode 100644 gps/etc/seccomp_policy/gnss@2.0-xtwifi-inet-agent.policy delete mode 100644 gps/etc/xtwifi.conf create mode 100644 gps/geofence/Android.bp delete mode 100644 gps/geofence/Android.mk create mode 100644 gps/gnss/Android.bp delete mode 100644 gps/gnss/Android.mk create mode 100644 gps/location/Android.bp delete mode 100644 gps/location/Android.mk create mode 100644 gps/pla/Android.bp delete mode 100644 gps/pla/Android.mk create mode 100644 gps/utils/Android.bp delete mode 100644 gps/utils/Android.mk create mode 100644 gps/utils/LocLoggerBase.h diff --git a/gps/Android.bp b/gps/Android.bp new file mode 100644 index 00000000..ea0d991c --- /dev/null +++ b/gps/Android.bp @@ -0,0 +1,45 @@ +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 regression testing */ +GNSS_SANITIZE = { +/* address: true,*/ + cfi: true, + misc_undefined: [ + "bounds", + "null", + "unreachable", + "integer", + ], +} + +/* 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/gps/Android.mk b/gps/Android.mk index f1088a43..77d61c99 100644 --- a/gps/Android.mk +++ b/gps/Android.mk @@ -1,5 +1,44 @@ 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 := cfi bounds null unreachable integer +# Activate the following two lines for regression testing +#GNSS_SANITIZE += address +#GNSS_SANITIZE_DIAG := $(GNSS_SANITIZE) + +endif # ifneq ($(BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE),) diff --git a/gps/android/1.0/Gnss.cpp b/gps/android/1.0/Gnss.cpp index 06a94d48..308cc7cf 100644 --- a/gps/android/1.0/Gnss.cpp +++ b/gps/android/1.0/Gnss.cpp @@ -43,6 +43,7 @@ void Gnss::GnssDeathRecipient::serviceDied(uint64_t cookie, const wp& who LOC_LOGE("%s] service died. cookie: %llu, who: %p", __FUNCTION__, static_cast(cookie), &who); if (mGnss != nullptr) { + mGnss->getGnssInterface()->resetNetworkInfo(); mGnss->stop(); mGnss->cleanup(); } @@ -110,7 +111,7 @@ const GnssInterface* Gnss::getGnssInterface() { if (nullptr == getter) { getGnssInterfaceFailed = true; } else { - mGnssInterface = (GnssInterface*)(*getter)(); + mGnssInterface = (const GnssInterface*)(*getter)(); } } return mGnssInterface; @@ -175,7 +176,7 @@ Return Gnss::updateConfiguration(GnssConfig& gnssConfig) { } 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; @@ -254,11 +255,6 @@ Return Gnss::injectLocation(double latitudeDegrees, Return Gnss::injectTime(int64_t timeMs, int64_t timeReferenceMs, int32_t uncertaintyMs) { - ENTRY_LOG_CALLFLOW(); - const GnssInterface* gnssInterface = getGnssInterface(); - if ((nullptr != gnssInterface) && (gnssInterface->isSS5HWEnabled())) { - gnssInterface->injectTime(timeMs, timeReferenceMs, uncertaintyMs); - } return true; } diff --git a/gps/android/1.0/GnssConfiguration.cpp b/gps/android/1.0/GnssConfiguration.cpp index 73c9d5c2..a7f64fa4 100644 --- a/gps/android/1.0/GnssConfiguration.cpp +++ b/gps/android/1.0/GnssConfiguration.cpp @@ -80,7 +80,6 @@ Return GnssConfiguration::setSuplVersion(uint32_t version) { default: LOC_LOGE("%s]: invalid version: 0x%x.", __FUNCTION__, version); return false; - break; } return mGnss->updateConfiguration(config); @@ -112,39 +111,33 @@ Return GnssConfiguration::setSuplMode(uint8_t mode) { default: LOC_LOGE("%s]: invalid mode: %d.", __FUNCTION__, mode); return false; - break; } return mGnss->updateConfiguration(config); } -Return GnssConfiguration::setLppProfile(uint8_t lppProfile) { +Return 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 @@ Return GnssConfiguration::setGpsLock(uint8_t lock) { default: LOC_LOGE("%s]: invalid lock: %d.", __FUNCTION__, lock); return false; - break; } return mGnss->updateConfiguration(config); diff --git a/gps/android/1.0/GnssConfiguration.h b/gps/android/1.0/GnssConfiguration.h index 1629e06e..d0e2ba8d 100644 --- a/gps/android/1.0/GnssConfiguration.h +++ b/gps/android/1.0/GnssConfiguration.h @@ -53,7 +53,7 @@ struct GnssConfiguration : public IGnssConfiguration { Return setSuplVersion(uint32_t version) override; Return setSuplMode(uint8_t mode) override; Return setSuplEs(bool enabled) override; - Return setLppProfile(uint8_t lppProfile) override; + Return setLppProfile(uint8_t lppProfileMask) override; Return setGlonassPositioningProtocol(uint8_t protocol) override; Return setEmergencySuplPdn(bool enable) override; Return setGpsLock(uint8_t lock) override; diff --git a/gps/android/1.0/location_api/BatchingAPIClient.h b/gps/android/1.0/location_api/BatchingAPIClient.h index f98726f7..c3b0a7b6 100644 --- a/gps/android/1.0/location_api/BatchingAPIClient.h +++ b/gps/android/1.0/location_api/BatchingAPIClient.h @@ -61,6 +61,7 @@ public: private: ~BatchingAPIClient(); + sp mGnssBatchingCbIface; uint32_t mDefaultId; LocationCapabilitiesMask mLocationCapabilitiesMask; diff --git a/gps/android/1.0/location_api/GeofenceAPIClient.h b/gps/android/1.0/location_api/GeofenceAPIClient.h index 94aada70..b6a009b3 100644 --- a/gps/android/1.0/location_api/GeofenceAPIClient.h +++ b/gps/android/1.0/location_api/GeofenceAPIClient.h @@ -46,6 +46,7 @@ class GeofenceAPIClient : public LocationAPIClientBase { public: GeofenceAPIClient(const sp& 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); @@ -64,6 +65,7 @@ public: private: virtual ~GeofenceAPIClient() = default; + sp mGnssGeofencingCbIface; }; diff --git a/gps/android/1.0/location_api/GnssAPIClient.cpp b/gps/android/1.0/location_api/GnssAPIClient.cpp index 27be0fcc..235e6336 100644 --- a/gps/android/1.0/location_api/GnssAPIClient.cpp +++ b/gps/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 @@ -110,9 +110,7 @@ void GnssAPIClient::gnssUpdateCallbacks(const sp& gpsCb, 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) { diff --git a/gps/android/1.0/location_api/LocationUtil.cpp b/gps/android/1.0/location_api/LocationUtil.cpp index d14cdac5..7bbc0648 100644 --- a/gps/android/1.0/location_api/LocationUtil.cpp +++ b/gps/android/1.0/location_api/LocationUtil.cpp @@ -168,6 +168,11 @@ void convertGnssSvid(GnssSv& in, int16_t& out) case GNSS_SV_TYPE_GALILEO: out = in.svId - GAL_SV_PRN_MIN + 1; break; + case GNSS_SV_TYPE_NAVIC: + /*Android doesn't define Navic svid range yet, use Naviv svid [1, 14] now + will update this once Android give Navic svid definiitons */ + out = in.svId - NAVIC_SV_PRN_MIN + 1; + break; default: out = in.svId; break; @@ -199,6 +204,11 @@ void convertGnssSvid(GnssMeasurementsData& in, int16_t& out) case GNSS_SV_TYPE_GALILEO: out = in.svId - GAL_SV_PRN_MIN + 1; break; + case GNSS_SV_TYPE_NAVIC: + /*Android doesn't define Navic svid range yet, use Naviv svid [1, 14] now + will update this once Android give Navic svid definiitons */ + out = in.svId - NAVIC_SV_PRN_MIN + 1; + break; default: out = in.svId; break; diff --git a/gps/android/1.0/location_api/MeasurementAPIClient.h b/gps/android/1.0/location_api/MeasurementAPIClient.h index 1b322513..225deaca 100644 --- a/gps/android/1.0/location_api/MeasurementAPIClient.h +++ b/gps/android/1.0/location_api/MeasurementAPIClient.h @@ -63,6 +63,7 @@ public: private: virtual ~MeasurementAPIClient(); + std::mutex mMutex; sp mGnssMeasurementCbIface; diff --git a/gps/android/1.1/Gnss.cpp b/gps/android/1.1/Gnss.cpp index 0babbc4f..537f6a62 100644 --- a/gps/android/1.1/Gnss.cpp +++ b/gps/android/1.1/Gnss.cpp @@ -84,6 +84,7 @@ void Gnss::GnssDeathRecipient::serviceDied(uint64_t cookie, const wp& who LOC_LOGE("%s] service died. cookie: %llu, who: %p", __FUNCTION__, static_cast(cookie), &who); if (mGnss != nullptr) { + mGnss->getGnssInterface()->resetNetworkInfo(); mGnss->stop(); mGnss->cleanup(); } @@ -151,7 +152,7 @@ const GnssInterface* Gnss::getGnssInterface() { if (nullptr == getter) { getGnssInterfaceFailed = true; } else { - mGnssInterface = (GnssInterface*)(*getter)(); + mGnssInterface = (const GnssInterface*)(*getter)(); } } return mGnssInterface; @@ -216,7 +217,7 @@ Return Gnss::updateConfiguration(GnssConfig& gnssConfig) { } 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; @@ -295,11 +296,6 @@ Return Gnss::injectLocation(double latitudeDegrees, Return Gnss::injectTime(int64_t timeMs, int64_t timeReferenceMs, int32_t uncertaintyMs) { - ENTRY_LOG_CALLFLOW(); - const GnssInterface* gnssInterface = getGnssInterface(); - if ((nullptr != gnssInterface) && (gnssInterface->isSS5HWEnabled())) { - gnssInterface->injectTime(timeMs, timeReferenceMs, uncertaintyMs); - } return true; } diff --git a/gps/android/1.1/GnssConfiguration.cpp b/gps/android/1.1/GnssConfiguration.cpp index 708e2c1a..ad255d1e 100644 --- a/gps/android/1.1/GnssConfiguration.cpp +++ b/gps/android/1.1/GnssConfiguration.cpp @@ -80,7 +80,6 @@ Return GnssConfiguration::setSuplVersion(uint32_t version) { default: LOC_LOGE("%s]: invalid version: 0x%x.", __FUNCTION__, version); return false; - break; } return mGnss->updateConfiguration(config); @@ -112,39 +111,33 @@ Return GnssConfiguration::setSuplMode(uint8_t mode) { default: LOC_LOGE("%s]: invalid mode: %d.", __FUNCTION__, mode); return false; - break; } return mGnss->updateConfiguration(config); } -Return GnssConfiguration::setLppProfile(uint8_t lppProfile) { +Return 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 @@ Return GnssConfiguration::setGpsLock(uint8_t lock) { default: LOC_LOGE("%s]: invalid lock: %d.", __FUNCTION__, lock); return false; - break; } return mGnss->updateConfiguration(config); diff --git a/gps/android/1.1/GnssConfiguration.h b/gps/android/1.1/GnssConfiguration.h index 96681b61..daea1595 100644 --- a/gps/android/1.1/GnssConfiguration.h +++ b/gps/android/1.1/GnssConfiguration.h @@ -53,7 +53,7 @@ struct GnssConfiguration : public IGnssConfiguration { Return setSuplVersion(uint32_t version) override; Return setSuplMode(uint8_t mode) override; Return setSuplEs(bool enabled) override; - Return setLppProfile(uint8_t lppProfile) override; + Return setLppProfile(uint8_t lppProfileMask) override; Return setGlonassPositioningProtocol(uint8_t protocol) override; Return setEmergencySuplPdn(bool enable) override; Return setGpsLock(uint8_t lock) override; diff --git a/gps/android/1.1/location_api/GeofenceAPIClient.h b/gps/android/1.1/location_api/GeofenceAPIClient.h index 3df50bbb..0ffff91a 100644 --- a/gps/android/1.1/location_api/GeofenceAPIClient.h +++ b/gps/android/1.1/location_api/GeofenceAPIClient.h @@ -46,6 +46,7 @@ class GeofenceAPIClient : public LocationAPIClientBase { public: GeofenceAPIClient(const sp& 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); @@ -63,9 +64,9 @@ public: void onResumeGeofencesCb(size_t count, LocationError* errors, uint32_t* ids) final; private: - virtual ~GeofenceAPIClient() = default; + virtual ~GeofenceAPIClient() = default; - sp mGnssGeofencingCbIface; + sp mGnssGeofencingCbIface; }; } // namespace implementation diff --git a/gps/android/1.1/location_api/GnssAPIClient.cpp b/gps/android/1.1/location_api/GnssAPIClient.cpp index 7aa573b6..42c05ccc 100644 --- a/gps/android/1.1/location_api/GnssAPIClient.cpp +++ b/gps/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 @@ -110,9 +110,7 @@ void GnssAPIClient::gnssUpdateCallbacks(const sp& gpsCb, 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) { diff --git a/gps/android/1.1/location_api/GnssAPIClient.h b/gps/android/1.1/location_api/GnssAPIClient.h index 1c8737f6..3829265c 100644 --- a/gps/android/1.1/location_api/GnssAPIClient.h +++ b/gps/android/1.1/location_api/GnssAPIClient.h @@ -92,6 +92,7 @@ public: private: virtual ~GnssAPIClient(); + sp mGnssCbIface; sp mGnssNiCbIface; std::mutex mMutex; diff --git a/gps/android/1.1/location_api/LocationUtil.cpp b/gps/android/1.1/location_api/LocationUtil.cpp index 459150fd..e0c1849a 100644 --- a/gps/android/1.1/location_api/LocationUtil.cpp +++ b/gps/android/1.1/location_api/LocationUtil.cpp @@ -168,6 +168,11 @@ void convertGnssSvid(GnssSv& in, int16_t& out) case GNSS_SV_TYPE_GALILEO: out = in.svId - GAL_SV_PRN_MIN + 1; break; + case GNSS_SV_TYPE_NAVIC: + /*Android doesn't define Navic svid range yet, use Naviv svid [1, 14] now + will update this once Android give Navic svid definiitons */ + out = in.svId - NAVIC_SV_PRN_MIN + 1; + break; default: out = in.svId; break; @@ -199,6 +204,11 @@ void convertGnssSvid(GnssMeasurementsData& in, int16_t& out) case GNSS_SV_TYPE_GALILEO: out = in.svId - GAL_SV_PRN_MIN + 1; break; + case GNSS_SV_TYPE_NAVIC: + /*Android doesn't define Navic svid range yet, use Naviv svid [1, 14] now + will update this once Android give Navic svid definiitons */ + out = in.svId - NAVIC_SV_PRN_MIN + 1; + break; default: out = in.svId; break; diff --git a/gps/android/2.0/Android.mk b/gps/android/2.0/Android.mk index b6790c5d..c0b91aeb 100644 --- a/gps/android/2.0/Android.mk +++ b/gps/android/2.0/Android.mk @@ -17,8 +17,8 @@ LOCAL_SRC_FILES := \ 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 +33,8 @@ LOCAL_CFLAGS += \ 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 +54,7 @@ LOCAL_SHARED_LIBRARIES := \ 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 diff --git a/gps/android/2.0/Gnss.cpp b/gps/android/2.0/Gnss.cpp index 28352d25..823ef6ec 100644 --- a/gps/android/2.0/Gnss.cpp +++ b/gps/android/2.0/Gnss.cpp @@ -34,7 +34,7 @@ typedef const GnssInterface* (getLocationInterface)(); #define IMAGES_INFO_FILE "/sys/devices/soc0/images" #define DELIMITER ";" -#define MAX_GNSS_ACCURACY_ALLOWED 10000 + namespace android { namespace hardware { namespace gnss { @@ -84,6 +84,7 @@ void Gnss::GnssDeathRecipient::serviceDied(uint64_t cookie, const wp& who LOC_LOGE("%s] service died. cookie: %llu, who: %p", __FUNCTION__, static_cast(cookie), &who); if (mGnss != nullptr) { + mGnss->getGnssInterface()->resetNetworkInfo(); mGnss->cleanup(); } } @@ -97,7 +98,6 @@ void location_on_battery_status_changed(bool charging) { Gnss::Gnss() { ENTRY_LOG_CALLFLOW(); sGnss = this; - mIsGnssClient = true; // initilize gnss interface at first in case needing notify battery status sGnss->getGnssInterface()->initialize(); // register health client to listen on battery change @@ -191,7 +191,6 @@ Return Gnss::setCallback(const sp& callback) { GnssAPIClient* api = getApi(); if (api != nullptr) { - mIsGnssClient = true; api->gnssUpdateCallbacks(mGnssCbIface, mGnssNiCbIface); api->gnssEnable(LOCATION_TECHNOLOGY_TYPE_GNSS); api->requestCapabilities(); @@ -239,7 +238,7 @@ Return Gnss::updateConfiguration(GnssConfig& gnssConfig) { } 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; @@ -323,11 +322,6 @@ Return Gnss::injectLocation(double latitudeDegrees, Return Gnss::injectTime(int64_t timeMs, int64_t timeReferenceMs, int32_t uncertaintyMs) { - ENTRY_LOG_CALLFLOW(); - const GnssInterface* gnssInterface = getGnssInterface(); - if ((nullptr != gnssInterface) && (gnssInterface->isSS5HWEnabled())) { - gnssInterface->injectTime(timeMs, timeReferenceMs, uncertaintyMs); - } return true; } @@ -340,28 +334,6 @@ Return Gnss::deleteAidingData(V1_0::IGnss::GnssAidingData aidingDataFlags) return Void(); } -void Gnss::updateCallbacksByAccuracy(uint32_t preferredAccuracyMeters, GnssAPIClient* api) { - if (preferredAccuracyMeters >= MAX_GNSS_ACCURACY_ALLOWED && mIsGnssClient) { - // Swith to timebased FLP client, if request accuracy is very low - LOC_LOGd("Swith to timebased FlpClient due to low accuracy(m): %d", - preferredAccuracyMeters); - mIsGnssClient = false; - api->gnssUpdateFlpCallbacks(); - } else if (preferredAccuracyMeters < MAX_GNSS_ACCURACY_ALLOWED && !mIsGnssClient) { - LOC_LOGd("Swith to timebased GnssClient accuracy(m):%d", preferredAccuracyMeters); - mIsGnssClient = true; - if (mGnssCbIface_2_0 != nullptr) { - api->gnssUpdateCallbacks_2_0(mGnssCbIface_2_0); - } else if (mGnssCbIface_1_1 != nullptr) { - api->gnssUpdateCallbacks(mGnssCbIface_1_1, mGnssNiCbIface); - } else if (mGnssCbIface != nullptr) { - api->gnssUpdateCallbacks(mGnssCbIface, mGnssNiCbIface); - } else { - LOC_LOGe("All client callbacks are null..."); - } - } -} - Return Gnss::setPositionMode(V1_0::IGnss::GnssPositionMode mode, V1_0::IGnss::GnssPositionRecurrence recurrence, uint32_t minIntervalMs, @@ -371,8 +343,7 @@ Return Gnss::setPositionMode(V1_0::IGnss::GnssPositionMode mode, bool retVal = false; GnssAPIClient* api = getApi(); if (api) { - updateCallbacksByAccuracy(preferredAccuracyMeters, api); - retVal = api->gnssSetPositionMode(mode, recurrence, minIntervalMs, + retVal = api->gnssSetPositionMode(mode, recurrence, minIntervalMs, preferredAccuracyMeters, preferredTimeMs); } return retVal; @@ -480,7 +451,6 @@ Return Gnss::setCallback_1_1(const sp& callback) { GnssAPIClient* api = getApi(); if (api != nullptr) { - mIsGnssClient = true; api->gnssUpdateCallbacks(mGnssCbIface_1_1, mGnssNiCbIface); api->gnssEnable(LOCATION_TECHNOLOGY_TYPE_GNSS); api->requestCapabilities(); @@ -499,7 +469,6 @@ Return Gnss::setPositionMode_1_1(V1_0::IGnss::GnssPositionMode mode, bool retVal = false; GnssAPIClient* api = getApi(); if (api) { - updateCallbacksByAccuracy(preferredAccuracyMeters, api); GnssPowerMode powerMode = lowPowerMode? GNSS_POWER_MODE_M4 : GNSS_POWER_MODE_M2; retVal = api->gnssSetPositionMode(mode, recurrence, minIntervalMs, @@ -615,7 +584,6 @@ Return Gnss::setCallback_2_0(const sp& callback) { GnssAPIClient* api = getApi(); if (api != nullptr) { - mIsGnssClient = true; api->gnssUpdateCallbacks_2_0(mGnssCbIface_2_0); api->gnssEnable(LOCATION_TECHNOLOGY_TYPE_GNSS); api->requestCapabilities(); diff --git a/gps/android/2.0/Gnss.h b/gps/android/2.0/Gnss.h index 24c7f201..a403d613 100644 --- a/gps/android/2.0/Gnss.h +++ b/gps/android/2.0/Gnss.h @@ -142,7 +142,7 @@ struct Gnss : public IGnss { // Callback for ODCPI request void odcpiRequestCb(const OdcpiRequestInfo& request); - void updateCallbacksByAccuracy(uint32_t preferredAccuracyMeters, GnssAPIClient* api); + private: struct GnssDeathRecipient : hidl_death_recipient { GnssDeathRecipient(sp gnss) : mGnss(gnss) { @@ -174,7 +174,6 @@ struct Gnss : public IGnss { GnssAPIClient* mApi = nullptr; GnssConfig mPendingConfig; const GnssInterface* mGnssInterface = nullptr; - bool mIsGnssClient; }; extern "C" V1_0::IGnss* HIDL_FETCH_IGnss(const char* name); diff --git a/gps/android/2.0/GnssConfiguration.cpp b/gps/android/2.0/GnssConfiguration.cpp index 764a0705..55a70dcd 100644 --- a/gps/android/2.0/GnssConfiguration.cpp +++ b/gps/android/2.0/GnssConfiguration.cpp @@ -39,7 +39,7 @@ GnssConfiguration::GnssConfiguration(Gnss* gnss) : mGnss(gnss) { } // Methods from ::android::hardware::gps::V1_0::IGnssConfiguration follow. -Return GnssConfiguration::setSuplEs(bool /*enabled*/) { +Return GnssConfiguration::setSuplEs(bool enabled) { // deprecated function. Must return false to pass VTS return false; } @@ -70,7 +70,6 @@ Return GnssConfiguration::setSuplVersion(uint32_t version) { default: LOC_LOGE("%s]: invalid version: 0x%x.", __FUNCTION__, version); return false; - break; } return mGnss->updateConfiguration(config); @@ -102,13 +101,12 @@ Return GnssConfiguration::setSuplMode(uint8_t mode) { default: LOC_LOGE("%s]: invalid mode: %d.", __FUNCTION__, mode); return false; - break; } return mGnss->updateConfiguration(config); } -Return GnssConfiguration::setLppProfile(uint8_t lppProfile) { +Return GnssConfiguration::setLppProfile(uint8_t lppProfileMask) { if (mGnss == nullptr) { LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__); return false; @@ -117,23 +115,19 @@ Return GnssConfiguration::setLppProfile(uint8_t lppProfile) { 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 @@ Return GnssConfiguration::setGpsLock(uint8_t lock) { default: LOC_LOGE("%s]: invalid lock: %d.", __FUNCTION__, lock); return false; - break; } mGnss->updateConfiguration(config); diff --git a/gps/android/2.0/GnssConfiguration.h b/gps/android/2.0/GnssConfiguration.h index 202a9fda..c3de2c9d 100644 --- a/gps/android/2.0/GnssConfiguration.h +++ b/gps/android/2.0/GnssConfiguration.h @@ -52,7 +52,7 @@ struct GnssConfiguration : public V2_0::IGnssConfiguration { Return setSuplVersion(uint32_t version) override; Return setSuplMode(uint8_t mode) override; Return setSuplEs(bool enabled) override; - Return setLppProfile(uint8_t lppProfile) override; + Return setLppProfile(uint8_t lppProfileMask) override; Return setGlonassPositioningProtocol(uint8_t protocol) override; Return setEmergencySuplPdn(bool enable) override; Return setGpsLock(uint8_t lock) override; diff --git a/gps/android/2.0/GnssMeasurement.cpp b/gps/android/2.0/GnssMeasurement.cpp index b21b0047..6cb55ca0 100644 --- a/gps/android/2.0/GnssMeasurement.cpp +++ b/gps/android/2.0/GnssMeasurement.cpp @@ -71,18 +71,15 @@ Return GnssMeasurement::setCallback( return ret; } + clearInterfaces(); + mGnssMeasurementCbIface = callback; mGnssMeasurementCbIface->linkToDeath(mGnssMeasurementDeathRecipient, 0); return mApi->measurementSetCallback(callback); } -Return 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 @@ Return GnssMeasurement::close() { mGnssMeasurementCbIface_2_0->unlinkToDeath(mGnssMeasurementDeathRecipient); mGnssMeasurementCbIface_2_0 = nullptr; } +} + +Return GnssMeasurement::close() { + if (mApi == nullptr) { + LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__); + return Void(); + } + + clearInterfaces(); mApi->measurementClose(); return Void(); @@ -120,6 +126,8 @@ Return GnssMeasurement::setCallback_1_1( return ret; } + clearInterfaces(); + mGnssMeasurementCbIface_1_1 = callback; mGnssMeasurementCbIface_1_1->linkToDeath(mGnssMeasurementDeathRecipient, 0); @@ -149,6 +157,8 @@ Return GnssMeasurement::setCallba return ret; } + clearInterfaces(); + mGnssMeasurementCbIface_2_0 = callback; mGnssMeasurementCbIface_2_0->linkToDeath(mGnssMeasurementDeathRecipient, 0); diff --git a/gps/android/2.0/GnssMeasurement.h b/gps/android/2.0/GnssMeasurement.h index 000b00f4..7fa66b40 100644 --- a/gps/android/2.0/GnssMeasurement.h +++ b/gps/android/2.0/GnssMeasurement.h @@ -75,6 +75,7 @@ struct GnssMeasurement : public V2_0::IGnssMeasurement { sp mGnssMeasurementCbIface_1_1 = nullptr; sp mGnssMeasurementCbIface_2_0 = nullptr; MeasurementAPIClient* mApi; + void clearInterfaces(); }; } // namespace implementation diff --git a/gps/android/visibility_control/1.0/GnssVisibilityControl.cpp b/gps/android/2.0/GnssVisibilityControl.cpp similarity index 100% rename from gps/android/visibility_control/1.0/GnssVisibilityControl.cpp rename to gps/android/2.0/GnssVisibilityControl.cpp diff --git a/gps/android/visibility_control/1.0/GnssVisibilityControl.h b/gps/android/2.0/GnssVisibilityControl.h similarity index 100% rename from gps/android/visibility_control/1.0/GnssVisibilityControl.h rename to gps/android/2.0/GnssVisibilityControl.h diff --git a/gps/android/measurement_corrections/1.0/MeasurementCorrections.cpp b/gps/android/2.0/MeasurementCorrections.cpp similarity index 90% rename from gps/android/measurement_corrections/1.0/MeasurementCorrections.cpp rename to gps/android/2.0/MeasurementCorrections.cpp index 2c93cb3a..bb750733 100644 --- a/gps/android/measurement_corrections/1.0/MeasurementCorrections.cpp +++ b/gps/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() { MeasurementCorrections::~MeasurementCorrections() { } -Return MeasurementCorrections::setCorrections(const ::android::hardware::gnss::measurement_corrections::V1_0::MeasurementCorrections& /*corrections*/) { +Return MeasurementCorrections::setCorrections( + const ::android::hardware::gnss::measurement_corrections:: + V1_0::MeasurementCorrections& /*corrections*/) { return true; } diff --git a/gps/android/measurement_corrections/1.0/MeasurementCorrections.h b/gps/android/2.0/MeasurementCorrections.h similarity index 92% rename from gps/android/measurement_corrections/1.0/MeasurementCorrections.h rename to gps/android/2.0/MeasurementCorrections.h index ad534dc1..96b1120c 100644 --- a/gps/android/measurement_corrections/1.0/MeasurementCorrections.h +++ b/gps/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 @@ struct MeasurementCorrections : public IMeasurementCorrections { ~MeasurementCorrections(); // Methods from ::android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrections follow. -Return setCorrections(const ::android::hardware::gnss::measurement_corrections::V1_0::MeasurementCorrections& corrections) override; +Return setCorrections( + const ::android::hardware::gnss::measurement_corrections:: + V1_0::MeasurementCorrections& corrections) override; Return setCallback(const sp& callback) override; - }; diff --git a/gps/android/2.0/android.hardware.gnss@2.0-service-qti.xml b/gps/android/2.0/android.hardware.gnss@2.0-service-qti.xml index de82c60e..ff9fb2c9 100644 --- a/gps/android/2.0/android.hardware.gnss@2.0-service-qti.xml +++ b/gps/android/2.0/android.hardware.gnss@2.0-service-qti.xml @@ -29,7 +29,6 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. android.hardware.gnss hwbinder - @1.0::IGnss/gnss_vendor @1.1::IGnss/default @2.0::IGnss/default diff --git a/gps/android/2.0/location_api/BatchingAPIClient.h b/gps/android/2.0/location_api/BatchingAPIClient.h index a249b587..d2d9b4ae 100644 --- a/gps/android/2.0/location_api/BatchingAPIClient.h +++ b/gps/android/2.0/location_api/BatchingAPIClient.h @@ -66,6 +66,7 @@ public: private: void setCallbacks(); ~BatchingAPIClient(); + std::mutex mMutex; sp mGnssBatchingCbIface; uint32_t mDefaultId; diff --git a/gps/android/2.0/location_api/GeofenceAPIClient.h b/gps/android/2.0/location_api/GeofenceAPIClient.h index 83025a92..5bce4767 100644 --- a/gps/android/2.0/location_api/GeofenceAPIClient.h +++ b/gps/android/2.0/location_api/GeofenceAPIClient.h @@ -46,6 +46,7 @@ class GeofenceAPIClient : public LocationAPIClientBase { public: GeofenceAPIClient(const sp& 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); diff --git a/gps/android/2.0/location_api/GnssAPIClient.cpp b/gps/android/2.0/location_api/GnssAPIClient.cpp index 74fe0366..c588978b 100644 --- a/gps/android/2.0/location_api/GnssAPIClient.cpp +++ b/gps/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 @@ -105,24 +105,13 @@ void GnssAPIClient::initLocationOptions() mTrackingOptions.mode = GNSS_SUPL_MODE_STANDALONE; } -void GnssAPIClient::setFlpCallbacks() { - LOC_LOGd("Going to set Flp Callbacks..."); - LocationCallbacks locationCallbacks; - memset(&locationCallbacks, 0, sizeof(LocationCallbacks)); - locationCallbacks.size = sizeof(LocationCallbacks); - - locationCallbacks.trackingCb = [this](Location location) { - onTrackingCb(location); - }; - locAPISetCallbacks(locationCallbacks); -} - void GnssAPIClient::setCallbacks() { LocationCallbacks locationCallbacks; memset(&locationCallbacks, 0, sizeof(LocationCallbacks)); locationCallbacks.size = sizeof(LocationCallbacks); + locationCallbacks.trackingCb = nullptr; locationCallbacks.trackingCb = [this](Location location) { onTrackingCb(location); }; @@ -134,9 +123,7 @@ void GnssAPIClient::setCallbacks() 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) { @@ -145,10 +132,12 @@ void GnssAPIClient::setCallbacks() } } + locationCallbacks.gnssSvCb = nullptr; locationCallbacks.gnssSvCb = [this](GnssSvNotification gnssSvNotification) { onGnssSvCb(gnssSvNotification); }; + locationCallbacks.gnssNmeaCb = nullptr; locationCallbacks.gnssNmeaCb = [this](GnssNmeaNotification gnssNmeaNotification) { onGnssNmeaCb(gnssNmeaNotification); }; @@ -187,12 +176,6 @@ void GnssAPIClient::gnssUpdateCallbacks_2_0(const sp& gpsCb } } -void GnssAPIClient::gnssUpdateFlpCallbacks() { - if (mGnssCbIface_2_0 != nullptr || mGnssCbIface != nullptr) { - setFlpCallbacks(); - } -} - bool GnssAPIClient::gnssStart() { LOC_LOGD("%s]: ()", __FUNCTION__); diff --git a/gps/android/2.0/location_api/GnssAPIClient.h b/gps/android/2.0/location_api/GnssAPIClient.h index d6190a9b..cfa78c7d 100644 --- a/gps/android/2.0/location_api/GnssAPIClient.h +++ b/gps/android/2.0/location_api/GnssAPIClient.h @@ -57,7 +57,6 @@ public: void gnssUpdateCallbacks(const sp& gpsCb, const sp& niCb); void gnssUpdateCallbacks_2_0(const sp& gpsCb); - void gnssUpdateFlpCallbacks(); bool gnssStart(); bool gnssStop(); bool gnssSetPositionMode(V1_0::IGnss::GnssPositionMode mode, @@ -94,8 +93,8 @@ public: private: virtual ~GnssAPIClient(); + void setCallbacks(); - void setFlpCallbacks(); void initLocationOptions(); sp mGnssCbIface; sp mGnssNiCbIface; diff --git a/gps/android/2.0/location_api/LocationUtil.cpp b/gps/android/2.0/location_api/LocationUtil.cpp index 97cc2cf4..fe8d22cd 100644 --- a/gps/android/2.0/location_api/LocationUtil.cpp +++ b/gps/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 @@ -31,6 +31,7 @@ #include #include #include +#include namespace android { namespace hardware { @@ -39,6 +40,7 @@ namespace V2_0 { 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; @@ -129,31 +131,62 @@ void convertGnssLocation(Location& in, V2_0::GnssLocation& out) 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); - // the max trusted propagation time 100ms for ageTimeNanos to avoid user setting - //wrong time, it will affect elapsedRealtimeNanos - if (ageTimeNanos <= 100000000) { + if (in.flags & LOCATION_HAS_ELAPSED_REAL_TIME) { + uint64_t qtimerDiff = 0; + uint64_t qTimerTickCount = getQTimerTickCount(); + if (qTimerTickCount >= in.elapsedRealTime) { + qtimerDiff = qTimerTickCount - in.elapsedRealTime; + } + LOC_LOGv("sinceBootTimeNanos:%" PRIi64 " in.elapsedRealTime=%" PRIi64 "" + " qTimerTickCount=%" PRIi64 " qtimerDiff=%" PRIi64 "", + sinceBootTimeNanos, in.elapsedRealTime, 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; + } + } + + if (sinceBootTimeNanos >= qTimerDiffNanos) { out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIMESTAMP_NS; - out.elapsedRealtime.timestampNs = sinceBootTimeNanos - ageTimeNanos; + out.elapsedRealtime.timestampNs = sinceBootTimeNanos - qTimerDiffNanos; out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS; - // time uncertainty is the max value between abs(AP_UTC - MP_UTC) and 100ms, to - //verify if user change the sys time - out.elapsedRealtime.timeUncertaintyNs = - std::max(ageTimeNanos, (int64_t)100000000); - LOC_LOGD("%s]: timestampNs:%" PRIi64 ")", - __FUNCTION__, out.elapsedRealtime.timestampNs); + out.elapsedRealtime.timeUncertaintyNs = in.elapsedRealTimeUnc; + } + } else { + int64_t currentTimeNanos = currentTime.tv_sec*1000000000 + currentTime.tv_nsec; + int64_t locationTimeNanos = in.timestamp*1000000; + LOC_LOGv("sinceBootTimeNanos:%" PRIi64 " currentTimeNanos:%" PRIi64 "" + " locationTimeNanos:%" PRIi64 "", + sinceBootTimeNanos, currentTimeNanos, locationTimeNanos); + if (currentTimeNanos >= locationTimeNanos) { + int64_t ageTimeNanos = currentTimeNanos - locationTimeNanos; + LOC_LOGv("ageTimeNanos:%" PRIi64 ")", ageTimeNanos); + // the max trusted propagation time 100ms for ageTimeNanos to avoid user setting + // wrong time, it will affect elapsedRealtimeNanos + if (ageTimeNanos <= 100000000) { + out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIMESTAMP_NS; + out.elapsedRealtime.timestampNs = sinceBootTimeNanos - ageTimeNanos; + out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS; + // time uncertainty is the max value between abs(AP_UTC - MP_UTC) and 100ms, to + // verify if user change the sys time + out.elapsedRealtime.timeUncertaintyNs = + std::max(ageTimeNanos, (int64_t)100000000); + } } } - } else { - LOC_LOGe("Failed to calculate elapsedRealtimeNanos timestamp"); } + LOC_LOGv("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) @@ -282,6 +315,11 @@ void convertGnssSvid(GnssSv& in, int16_t& out) case GNSS_SV_TYPE_GALILEO: out = in.svId - GAL_SV_PRN_MIN + 1; break; + case GNSS_SV_TYPE_NAVIC: + /*Android doesn't define Navic svid range yet, use Naviv svid [1, 14] now + will update this once Android give Navic svid definiitons */ + out = in.svId - NAVIC_SV_PRN_MIN + 1; + break; default: out = in.svId; break; @@ -313,6 +351,11 @@ void convertGnssSvid(GnssMeasurementsData& in, int16_t& out) case GNSS_SV_TYPE_GALILEO: out = in.svId - GAL_SV_PRN_MIN + 1; break; + case GNSS_SV_TYPE_NAVIC: + /*Android doesn't define Navic svid range yet, use Naviv svid [1, 14] now + will update this once Android give Navic svid definiitons */ + out = in.svId - NAVIC_SV_PRN_MIN + 1; + break; default: out = in.svId; break; diff --git a/gps/android/2.0/location_api/MeasurementAPIClient.cpp b/gps/android/2.0/location_api/MeasurementAPIClient.cpp index f41fe94c..a32b1cd9 100644 --- a/gps/android/2.0/location_api/MeasurementAPIClient.cpp +++ b/gps/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 namespace android { namespace hardware { @@ -57,6 +58,8 @@ static void convertGnssMeasurement(GnssMeasurementsData& in, 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 @@ MeasurementAPIClient::~MeasurementAPIClient() LOC_LOGD("%s]: ()", __FUNCTION__); } +void MeasurementAPIClient::clearInterfaces() +{ + mGnssMeasurementCbIface = nullptr; + mGnssMeasurementCbIface_1_1 = nullptr; + mGnssMeasurementCbIface_2_0 = nullptr; +} + // for GpsInterface Return MeasurementAPIClient::measurementSetCallback(const sp& callback) @@ -79,6 +89,7 @@ MeasurementAPIClient::measurementSetCallback(const sp= in.clock.elapsedRealTime) { + qtimerDiff = qTimerTickCount - in.clock.elapsedRealTime; + } + LOC_LOGv("sinceBootTimeNanos:%" PRIi64 " in.clock.elapsedRealTime=%" PRIi64 "" + " qTimerTickCount=%" PRIi64 " qtimerDiff=%" PRIi64 "", + sinceBootTimeNanos, in.clock.elapsedRealTime, qTimerTickCount, qtimerDiff); + uint64_t qTimerDiffNanos = qTimerTicksToNanos(double(qtimerDiff)); - 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); - // the max trusted propagation time 100ms for ageTimeNanos to avoid user setting - //wrong time, it will affect elapsedRealtimeNanos - if (ageTimeNanos <= 100000000) { - out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIMESTAMP_NS; - out.elapsedRealtime.timestampNs = sinceBootTimeNanos - ageTimeNanos; - out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS; - // time uncertainty is the max value between abs(AP_UTC - MP_UTC) and 100ms, to - //verify if user change the sys time - out.elapsedRealtime.timeUncertaintyNs = - std::max(ageTimeNanos, (int64_t)100000000); - LOC_LOGd("timestampNs:%" PRIi64 ") timeUncertaintyNs:%" PRIi64 ")", - out.elapsedRealtime.timestampNs, - out.elapsedRealtime.timeUncertaintyNs); + /* 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; + } + } + + if (sinceBootTimeNanos >= qTimerDiffNanos) { + elapsedRealtime.flags |= V2_0::ElapsedRealtimeFlags::HAS_TIMESTAMP_NS; + elapsedRealtime.timestampNs = sinceBootTimeNanos - qTimerDiffNanos; + elapsedRealtime.flags |= V2_0::ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS; + elapsedRealtime.timeUncertaintyNs = in.clock.elapsedRealTimeUnc; + } + } else { + const uint32_t UTC_TO_GPS_SECONDS = 315964800; + + if (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_LOGv("sinceBootTimeNanos:%" PRIi64 " currentTimeNanos:%" PRIi64 "" + " measTimeNanos:%" PRIi64 "", + sinceBootTimeNanos, currentTimeNanos, measTimeNanos); + if (currentTimeNanos >= measTimeNanos) { + int64_t ageTimeNanos = currentTimeNanos - measTimeNanos; + LOC_LOGv("ageTimeNanos:%" PRIi64 ")", ageTimeNanos); + // the max trusted propagation time 100ms for ageTimeNanos to avoid user + // setting wrong time, it will affect elapsedRealtimeNanos + if (ageTimeNanos <= 100000000) { + elapsedRealtime.flags |= V2_0::ElapsedRealtimeFlags::HAS_TIMESTAMP_NS; + elapsedRealtime.timestampNs = sinceBootTimeNanos - ageTimeNanos; + elapsedRealtime.flags |= + V2_0::ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS; + // time uncertainty is the max value between abs(AP_UTC - MP_UTC) and 100ms, + // to verify if user change the sys time + elapsedRealtime.timeUncertaintyNs = + std::max(ageTimeNanos, (int64_t)100000000); + } + } + } else { + LOC_LOGe("Failed to calculate elapsedRealtimeNanos timestamp"); } } - } else { - LOC_LOGe("Failed to calculate elapsedRealtimeNanos timestamp"); } + LOC_LOGv("elapsedRealtime.timestampNs=%" PRIi64 "" + " elapsedRealtime.timeUncertaintyNs=%" PRIi64 " elapsedRealtime.flags=0x%X", + elapsedRealtime.timestampNs, + elapsedRealtime.timeUncertaintyNs, elapsedRealtime.flags); } static void convertGnssMeasurementsCodeType(GnssMeasurementsCodeType& in, diff --git a/gps/android/2.0/location_api/MeasurementAPIClient.h b/gps/android/2.0/location_api/MeasurementAPIClient.h index 67f17aed..6c2d38d2 100644 --- a/gps/android/2.0/location_api/MeasurementAPIClient.h +++ b/gps/android/2.0/location_api/MeasurementAPIClient.h @@ -78,8 +78,8 @@ private: sp mGnssMeasurementCbIface; sp mGnssMeasurementCbIface_1_1; sp mGnssMeasurementCbIface_2_0; - bool mTracking; + void clearInterfaces(); }; } // namespace implementation diff --git a/gps/android/2.0/service.cpp b/gps/android/2.0/service.cpp index e484a16d..f7efb187 100644 --- a/gps/android/2.0/service.cpp +++ b/gps/android/2.0/service.cpp @@ -60,28 +60,19 @@ int main() { status = registerPassthroughServiceImplementation(); 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 - } else { - status = registerPassthroughServiceImplementation("gnss_vendor"); - if (status != OK) { - ALOGE("Error while registering gnss_vendor service: %d", status); - } + 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.0 service: %d", status); } diff --git a/gps/android/2.1/AGnss.cpp b/gps/android/2.1/AGnss.cpp new file mode 100644 index 00000000..c759492c --- /dev/null +++ b/gps/android/2.1/AGnss.cpp @@ -0,0 +1,209 @@ +/* + * 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 +#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) { + spAGnss = this; +} + +AGnss::~AGnss() { + spAGnss = nullptr; +} + +void AGnss::agnssStatusIpV4Cb(AGnssExtStatusIpV4 status) { + if (nullptr != spAGnss) { + spAGnss->statusCb(status.type, status.status); + } +} + +void AGnss::statusCb(AGpsExtType type, LocAGpsStatusValue status) { + + V2_0::IAGnssCallback::AGnssType aType; + IAGnssCallback::AGnssStatusValue aStatus; + + switch (type) { + case LOC_AGPS_TYPE_SUPL: + aType = IAGnssCallback::AGnssType::SUPL; + break; + case LOC_AGPS_TYPE_SUPL_ES: + aType = IAGnssCallback::AGnssType::SUPL_EIMS; + break; + default: + LOC_LOGE("invalid type: %d", type); + return; + } + + switch (status) { + case LOC_GPS_REQUEST_AGPS_DATA_CONN: + aStatus = IAGnssCallback::AGnssStatusValue::REQUEST_AGNSS_DATA_CONN; + break; + case LOC_GPS_RELEASE_AGPS_DATA_CONN: + aStatus = IAGnssCallback::AGnssStatusValue::RELEASE_AGNSS_DATA_CONN; + break; + case LOC_GPS_AGPS_DATA_CONNECTED: + aStatus = IAGnssCallback::AGnssStatusValue::AGNSS_DATA_CONNECTED; + break; + case LOC_GPS_AGPS_DATA_CONN_DONE: + aStatus = IAGnssCallback::AGnssStatusValue::AGNSS_DATA_CONN_DONE; + break; + case LOC_GPS_AGPS_DATA_CONN_FAILED: + aStatus = IAGnssCallback::AGnssStatusValue::AGNSS_DATA_CONN_FAILED; + break; + default: + LOC_LOGE("invalid status: %d", status); + return; + } + + if (mAGnssCbIface != nullptr) { + auto r = mAGnssCbIface->agnssStatusCb(aType, aStatus); + if (!r.isOk()) { + LOC_LOGw("Error invoking AGNSS status cb %s", r.description().c_str()); + } + } + else { + LOC_LOGw("setCallback has not been called yet"); + } +} + +Return AGnss::setCallback(const sp& 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 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 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 AGnss::dataConnOpen(uint64_t /*networkHandle*/, const hidl_string& apn, + V2_0::IAGnss::ApnIpType apnIpType) { + + if(mGnss == nullptr || mGnss->getGnssInterface() == nullptr){ + LOC_LOGE("Null GNSS interface"); + return false; + } + + /* Validate */ + if(apn.empty()){ + LOC_LOGE("Invalid APN"); + return false; + } + + LOC_LOGD("dataConnOpen APN name = [%s]", apn.c_str()); + + AGpsBearerType bearerType; + switch (apnIpType) { + case IAGnss::ApnIpType::IPV4: + bearerType = AGPS_APN_BEARER_IPV4; + break; + case IAGnss::ApnIpType::IPV6: + bearerType = AGPS_APN_BEARER_IPV6; + break; + case IAGnss::ApnIpType::IPV4V6: + bearerType = AGPS_APN_BEARER_IPV4V6; + break; + default: + bearerType = AGPS_APN_BEARER_IPV4; + break; + } + + mGnss->getGnssInterface()->agpsDataConnOpen( + LOC_AGPS_TYPE_SUPL, apn.c_str(), apn.size(), (int)bearerType); + return true; +} + +Return 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(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/gps/android/2.1/AGnss.h b/gps/android/2.1/AGnss.h new file mode 100644 index 00000000..f6ea9971 --- /dev/null +++ b/gps/android/2.1/AGnss.h @@ -0,0 +1,78 @@ +/* + * 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 +#include +#include + +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 setCallback(const sp& callback) override; + + Return dataConnClosed() override; + + Return dataConnFailed() override; + + Return dataConnOpen(uint64_t networkHandle, const hidl_string& apn, + V2_0::IAGnss::ApnIpType apnIpType) override; + + Return 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 mAGnssCbIface = nullptr; +}; + +} // namespace implementation +} // namespace V2_1 +} // namespace gnss +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_GNSS_V2_0_AGNSS_H diff --git a/gps/android/2.1/AGnssRil.cpp b/gps/android/2.1/AGnssRil.cpp new file mode 100644 index 00000000..65fb3005 --- /dev/null +++ b/gps/android/2.1/AGnssRil.cpp @@ -0,0 +1,133 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include "Gnss.h" +#include "AGnssRil.h" +#include + +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 AGnssRil::updateNetworkState(bool connected, NetworkType type, bool /*roaming*/) { + ENTRY_LOG_CALLFLOW(); + // Extra NetworkTypes not available in IAgnssRil enums + const int NetworkType_BLUETOOTH = 7; + const int NetworkType_ETHERNET = 9; + const int NetworkType_PROXY = 16; + + // for XTRA + if (nullptr != mGnss && ( nullptr != mGnss->getGnssInterface() )) { + int8_t typeout = loc_core::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, false, typeout, 0); + } + return true; +} +Return AGnssRil::updateNetworkState_2_0(const V2_0::IAGnssRil::NetworkAttributes& attributes) { + ENTRY_LOG_CALLFLOW(); + + 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; + } + mGnss->getGnssInterface()->updateConnectionStatus(attributes.isConnected, + typeout, roaming, (NetworkHandle) attributes.networkHandle); + } + return true; +} + +} // namespace implementation +} // namespace V2_1 +} // namespace gnss +} // namespace hardware +} // namespace android diff --git a/gps/android/2.1/AGnssRil.h b/gps/android/2.1/AGnssRil.h new file mode 100644 index 00000000..2bf61568 --- /dev/null +++ b/gps/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 +#include +#include + +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 setCallback(const sp& /*callback*/) override { + return Void(); + } + Return setRefLocation(const V1_0::IAGnssRil::AGnssRefLocation& /*agnssReflocation*/) override { + return Void(); + } + Return setSetId(V1_0::IAGnssRil::SetIDType /*type*/, const hidl_string& /*setid*/) override { + return false; + } + Return updateNetworkAvailability(bool /*available*/, + const hidl_string& /*apn*/) override { + return false; + } + Return updateNetworkState(bool connected, V1_0::IAGnssRil::NetworkType type, bool roaming) override; + + // Methods from ::android::hardware::gnss::V2_0::IAGnssRil follow + Return 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/gps/android/2.1/Android.mk b/gps/android/2.1/Android.mk new file mode 100644 index 00000000..a947e414 --- /dev/null +++ b/gps/android/2.1/Android.mk @@ -0,0 +1,116 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) +LOCAL_MODULE := android.hardware.gnss@2.1-impl-qti +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_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_SANITIZE += $(GNSS_SANITIZE) +# 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/gps/android/2.1/Gnss.cpp b/gps/android/2.1/Gnss.cpp new file mode 100644 index 00000000..37e1cc5a --- /dev/null +++ b/gps/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 +#include +#include +#include +#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 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& who) { + LOC_LOGE("%s] service died. cookie: %llu, who: %p", + __FUNCTION__, static_cast(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 Gnss::setCallback(const sp& 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 Gnss::setGnssNiCb(const sp& callback) { + ENTRY_LOG_CALLFLOW(); + mGnssNiCbIface = callback; + GnssAPIClient* api = getApi(); + if (api != nullptr) { + api->gnssUpdateCallbacks(mGnssCbIface, mGnssNiCbIface); + } + return true; +} + +Return 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 Gnss::start() { + ENTRY_LOG_CALLFLOW(); + bool retVal = false; + GnssAPIClient* api = getApi(); + if (api) { + retVal = api->gnssStart(); + } + return retVal; +} + +Return Gnss::stop() { + ENTRY_LOG_CALLFLOW(); + bool retVal = false; + GnssAPIClient* api = getApi(); + if (api) { + retVal = api->gnssStop(); + } + return retVal; +} + +Return Gnss::cleanup() { + ENTRY_LOG_CALLFLOW(); + + if (mApi != nullptr) { + mApi->gnssStop(); + mApi->gnssDisable(); + } + + return Void(); +} + +Return 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 Gnss::injectTime(int64_t timeMs, int64_t timeReferenceMs, + int32_t uncertaintyMs) { + return true; +} + +Return Gnss::deleteAidingData(V1_0::IGnss::GnssAidingData aidingDataFlags) { + ENTRY_LOG_CALLFLOW(); + GnssAPIClient* api = getApi(); + if (api) { + api->gnssDeleteAidingData(aidingDataFlags); + } + return Void(); +} + +Return 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> Gnss::getExtensionAGnss() { + ENTRY_LOG_CALLFLOW(); + // deprecated function. Must return nullptr to pass VTS + return nullptr; +} + +Return> Gnss::getExtensionGnssNi() { + ENTRY_LOG_CALLFLOW(); + // deprecated function. Must return nullptr to pass VTS + return nullptr; +} + +Return> Gnss::getExtensionGnssMeasurement() { + ENTRY_LOG_CALLFLOW(); + if (mGnssMeasurement == nullptr) { + mGnssMeasurement = new GnssMeasurement(); + } + return mGnssMeasurement; +} + +Return> Gnss::getExtensionGnssConfiguration() { + ENTRY_LOG_CALLFLOW(); + if (mGnssConfig == nullptr) { + mGnssConfig = new GnssConfiguration(this); + } + return mGnssConfig; +} + +Return> Gnss::getExtensionGnssGeofencing() { + ENTRY_LOG_CALLFLOW(); + if (mGnssGeofencingIface == nullptr) { + mGnssGeofencingIface = new GnssGeofencing(); + } + return mGnssGeofencingIface; +} + +Return> Gnss::getExtensionGnssBatching() { + ENTRY_LOG_CALLFLOW(); + if (mGnssBatching == nullptr) { + mGnssBatching = new GnssBatching(); + } + return mGnssBatching; +} + +Return> Gnss::getExtensionGnssDebug() { + ENTRY_LOG_CALLFLOW(); + if (mGnssDebug == nullptr) { + mGnssDebug = new GnssDebug(this); + } + return mGnssDebug; +} + +Return> Gnss::getExtensionAGnssRil() { + ENTRY_LOG_CALLFLOW(); + if (mGnssRil == nullptr) { + mGnssRil = new AGnssRil(this); + } + return mGnssRil; +} + +// Methods from ::android::hardware::gnss::V1_1::IGnss follow. +Return Gnss::setCallback_1_1(const sp& 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 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> 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> Gnss::getExtensionGnssConfiguration_1_1() { + ENTRY_LOG_CALLFLOW(); + if (mGnssConfig == nullptr) + mGnssConfig = new GnssConfiguration(this); + return mGnssConfig; +} + +Return 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 Gnss::setCallback_2_0(const sp& 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> Gnss::getExtensionAGnss_2_0() { + ENTRY_LOG_CALLFLOW(); + if (mAGnssIface_2_0 == nullptr) { + mAGnssIface_2_0 = new AGnss(this); + } + return mAGnssIface_2_0; +} +Return> Gnss::getExtensionAGnssRil_2_0() { + + if (mGnssRil == nullptr) { + mGnssRil = new AGnssRil(this); + } + return mGnssRil; +} + +Return> Gnss::getExtensionGnssConfiguration_2_0() { + ENTRY_LOG_CALLFLOW(); + if (mGnssConfig == nullptr) { + mGnssConfig = new GnssConfiguration(this); + } + return mGnssConfig; +} +Return> 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> + Gnss::getExtensionMeasurementCorrections() { + ENTRY_LOG_CALLFLOW(); + if (mGnssMeasCorr == nullptr) { + mGnssMeasCorr = new MeasurementCorrections(this); + } + return mGnssMeasCorr; +} + +Return> + Gnss::getExtensionMeasurementCorrections_1_1() { + ENTRY_LOG_CALLFLOW(); + if (mGnssMeasCorr == nullptr) { + mGnssMeasCorr = new MeasurementCorrections(this); + } + return mGnssMeasCorr; +} + +Return> + Gnss::getExtensionVisibilityControl() { + ENTRY_LOG_CALLFLOW(); + if (mVisibCtrl == nullptr) { + mVisibCtrl = new GnssVisibilityControl(this); + } + return mVisibCtrl; +} + +Return 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> Gnss::getExtensionGnssDebug_2_0() { + ENTRY_LOG_CALLFLOW(); + if (mGnssDebug == nullptr) { + mGnssDebug = new GnssDebug(this); + } + return mGnssDebug; +} + +Return> Gnss::getExtensionGnssBatching_2_0() { + return nullptr; +} + +// Methods from ::android::hardware::gnss::V2_1::IGnss follow. +Return Gnss::setCallback_2_1(const sp& 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> Gnss::getExtensionGnssMeasurement_2_1() { + ENTRY_LOG_CALLFLOW(); + if (mGnssMeasurement == nullptr) { + mGnssMeasurement = new GnssMeasurement(); + } + return mGnssMeasurement; +} +Return> Gnss::getExtensionGnssConfiguration_2_1() { + ENTRY_LOG_CALLFLOW(); + if (mGnssConfig == nullptr) { + mGnssConfig = new GnssConfiguration(this); + } + return mGnssConfig; +} + +Return> 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/gps/android/2.1/Gnss.h b/gps/android/2.1/Gnss.h new file mode 100644 index 00000000..c3838822 --- /dev/null +++ b/gps/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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#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 setCallback(const sp& callback) override; + Return start() override; + Return stop() override; + Return cleanup() override; + Return injectLocation(double latitudeDegrees, + double longitudeDegrees, + float accuracyMeters) override; + Return injectTime(int64_t timeMs, + int64_t timeReferenceMs, + int32_t uncertaintyMs) override; + Return deleteAidingData(V1_0::IGnss::GnssAidingData aidingDataFlags) override; + Return setPositionMode(V1_0::IGnss::GnssPositionMode mode, + V1_0::IGnss::GnssPositionRecurrence recurrence, + uint32_t minIntervalMs, + uint32_t preferredAccuracyMeters, + uint32_t preferredTimeMs) override; + Return> getExtensionAGnss() override; + Return> getExtensionGnssNi() override; + Return> getExtensionGnssMeasurement() override; + Return> getExtensionGnssConfiguration() override; + Return> getExtensionGnssGeofencing() override; + Return> getExtensionGnssBatching() override; + + Return> getExtensionAGnssRil() override; + + inline Return> getExtensionGnssNavigationMessage() override { + return nullptr; + } + + inline Return> getExtensionXtra() override { + return nullptr; + } + + Return> getExtensionGnssDebug() override; + + // Methods from ::android::hardware::gnss::V1_1::IGnss follow. + Return setCallback_1_1(const sp& callback) override; + Return 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> getExtensionGnssMeasurement_1_1() override; + Return> getExtensionGnssConfiguration_1_1() override; + Return injectBestLocation(const GnssLocation& location) override; + + // Methods from ::android::hardware::gnss::V2_0::IGnss follow. + Return setCallback_2_0(const sp& callback) override; + Return> getExtensionAGnss_2_0() override; + Return> getExtensionAGnssRil_2_0() override; + + Return> getExtensionGnssConfiguration_2_0() override; + Return> getExtensionMeasurementCorrections() override; + Return> getExtensionMeasurementCorrections_1_1() override; + Return> getExtensionGnssMeasurement_2_0() override; + + Return injectBestLocation_2_0( + const ::android::hardware::gnss::V2_0::GnssLocation& location) override; + + Return> getExtensionGnssBatching_2_0() override; + Return> getExtensionGnssDebug_2_0() override; + Return> + getExtensionVisibilityControl() override; + + // Methods from ::android::hardware::gnss::V2_1::IGnss follow. + Return setCallback_2_1(const sp& callback) override; + Return> getExtensionGnssMeasurement_2_1() override; + Return> getExtensionGnssConfiguration_2_1() override; + Return> getExtensionGnssAntennaInfo() override; + + // These methods are not part of the IGnss base class. + GnssAPIClient* getApi(); + Return setGnssNiCb(const sp& niCb); + Return updateConfiguration(GnssConfig& gnssConfig); + const GnssInterface* getGnssInterface(); + + // Callback for ODCPI request + void odcpiRequestCb(const OdcpiRequestInfo& request); + + private: + struct GnssDeathRecipient : hidl_death_recipient { + GnssDeathRecipient(sp gnss) : mGnss(gnss) { + } + ~GnssDeathRecipient() = default; + virtual void serviceDied(uint64_t cookie, const wp& who) override; + sp mGnss; + }; + + private: + sp mGnssDeathRecipient = nullptr; + + sp mGnssNi = nullptr; + sp mGnssGeofencingIface = nullptr; + sp mAGnssIface = nullptr; + sp mGnssCbIface = nullptr; + sp mGnssNiCbIface = nullptr; + sp mGnssCbIface_1_1 = nullptr; + sp mAGnssIface_2_0 = nullptr; + sp mGnssRil = nullptr; + sp mGnssBatching = nullptr; + sp mGnssDebug = nullptr; + sp mGnssCbIface_2_0 = nullptr; + sp mGnssCbIface_2_1 = nullptr; + sp mGnssMeasurement = nullptr; + sp mGnssConfig = nullptr; + sp mGnssAntennaInfo = nullptr; + sp mGnssMeasCorr = nullptr; + sp 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/gps/android/2.1/GnssAntennaInfo.cpp b/gps/android/2.1/GnssAntennaInfo.cpp new file mode 100644 index 00000000..62c4cc7e --- /dev/null +++ b/gps/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 +#include "Gnss.h" +#include "GnssAntennaInfo.h" +#include + +namespace android { +namespace hardware { +namespace gnss { +namespace V2_1 { +namespace implementation { + +static GnssAntennaInfo* spGnssAntennaInfo = nullptr; + +static void convertGnssAntennaInfo(std::vector& in, + hidl_vec& antennaInfos); + +void GnssAntennaInfo::GnssAntennaInfoDeathRecipient::serviceDied(uint64_t cookie, + const wp& who) { + LOC_LOGE("%s] service died. cookie: %llu, who: %p", + __FUNCTION__, static_cast(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& in, + hidl_vec& 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::setCallback(const sp& 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 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 gnssAntennaInformations) { + if (nullptr != spGnssAntennaInfo) { + spGnssAntennaInfo->gnssAntennaInfoCb(gnssAntennaInformations); + } +} + +void GnssAntennaInfo::gnssAntennaInfoCb + (std::vector gnssAntennaInformations) { + + if (mGnssAntennaInfoCbIface != nullptr) { + hidl_vec 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/gps/android/2.1/GnssAntennaInfo.h b/gps/android/2.1/GnssAntennaInfo.h new file mode 100644 index 00000000..02ddd28a --- /dev/null +++ b/gps/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 +#include + +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 + setCallback(const sp& callback) override; + Return close(void) override; + + void gnssAntennaInfoCb(std::vector gnssAntennaInformations); + + static void aiGnssAntennaInfoCb(std::vector gnssAntennaInformations); + + private: + struct GnssAntennaInfoDeathRecipient : hidl_death_recipient { + GnssAntennaInfoDeathRecipient(sp gnssAntennaInfo) : + mGnssAntennaInfo(gnssAntennaInfo) { + } + ~GnssAntennaInfoDeathRecipient() = default; + virtual void serviceDied(uint64_t cookie, const wp& who) override; + sp mGnssAntennaInfo; + }; + + private: + sp mGnssAntennaInfoDeathRecipient = nullptr; + sp 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/gps/android/2.1/GnssBatching.cpp b/gps/android/2.1/GnssBatching.cpp new file mode 100644 index 00000000..73e3532f --- /dev/null +++ b/gps/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 +#include +#include "GnssBatching.h" + +namespace android { +namespace hardware { +namespace gnss { +namespace V2_1 { +namespace implementation { + +void GnssBatching::GnssBatchingDeathRecipient::serviceDied( + uint64_t cookie, const wp& who) { + LOC_LOGE("%s] service died. cookie: %llu, who: %p", + __FUNCTION__, static_cast(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 GnssBatching::init(const sp& 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 GnssBatching::getBatchSize() { + uint16_t ret = 0; + if (mApi == nullptr) { + LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__); + } else { + ret = mApi->getBatchSize(); + } + return ret; +} + +Return 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 GnssBatching::flush() { + if (mApi == nullptr) { + LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__); + } else { + mApi->flushBatchedLocations(); + } + return Void(); +} + +Return GnssBatching::stop() { + bool ret = false; + if (mApi == nullptr) { + LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__); + } else { + ret = mApi->stopSession(); + } + return ret; +} + +Return 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 GnssBatching::init_2_0(const sp& 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/gps/android/2.1/GnssBatching.h b/gps/android/2.1/GnssBatching.h new file mode 100644 index 00000000..908748f0 --- /dev/null +++ b/gps/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 +#include + + +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 init(const sp& callback) override; + Return getBatchSize() override; + Return start(const IGnssBatching::Options& options ) override; + Return flush() override; + Return stop() override; + Return cleanup() override; + + // Methods from ::android::hardware::gnss::V2_0::IGnssBatching follow. + Return init_2_0(const sp& callback) override; + + private: + struct GnssBatchingDeathRecipient : hidl_death_recipient { + GnssBatchingDeathRecipient(sp gnssBatching) : + mGnssBatching(gnssBatching) { + } + ~GnssBatchingDeathRecipient() = default; + virtual void serviceDied(uint64_t cookie, const wp& who) override; + sp mGnssBatching; + }; + + private: + sp mGnssBatchingDeathRecipient = nullptr; + sp mGnssBatchingCbIface = nullptr; + BatchingAPIClient* mApi = nullptr; + sp 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/gps/android/2.1/GnssConfiguration.cpp b/gps/android/2.1/GnssConfiguration.cpp new file mode 100644 index 00000000..b6077aea --- /dev/null +++ b/gps/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 +#include "Gnss.h" +#include "GnssConfiguration.h" +#include "ContextBase.h" +#include + +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 GnssConfiguration::setSuplEs(bool enabled) { + // deprecated function. Must return false to pass VTS + return false; +} + +Return 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 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 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 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 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 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 GnssConfiguration::setBlacklist( + const hidl_vec& 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 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 GnssConfiguration::setBlacklist_2_1( + const hidl_vec& 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/gps/android/2.1/GnssConfiguration.h b/gps/android/2.1/GnssConfiguration.h new file mode 100644 index 00000000..f000dbda --- /dev/null +++ b/gps/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 +#include + +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 setSuplVersion(uint32_t version) override; + Return setSuplMode(uint8_t mode) override; + Return setSuplEs(bool enabled) override; + Return setLppProfile(uint8_t lppProfileMask) override; + Return setGlonassPositioningProtocol(uint8_t protocol) override; + Return setEmergencySuplPdn(bool enable) override; + Return setGpsLock(uint8_t lock) override; + + // Methods from ::android::hardware::gnss::V1_1::IGnssConfiguration follow. + Return setBlacklist( + const hidl_vec& blacklist) override; + + // Methods from ::android::hardware::gnss::V2_0::IGnssConfiguration follow. + Return setEsExtensionSec(uint32_t emergencyExtensionSeconds) override; + // Methods from ::android::hardware::gnss::V2_1::IGnssConfiguration follow. + Return setBlacklist_2_1( + const hidl_vec& 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/gps/android/2.1/GnssDebug.cpp b/gps/android/2.1/GnssDebug.cpp new file mode 100644 index 00000000..27ff964d --- /dev/null +++ b/gps/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 +#include +#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 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 s_array; + + for (uint32_t i=0; i 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 s_array; + + for (uint32_t i=0; i +#include + +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 getDebugData(getDebugData_cb _hidl_cb) override; + // Methods from ::android::hardware::gnss::V2_0::IGnssDebug follow. + Return 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/gps/android/2.1/GnssGeofencing.cpp b/gps/android/2.1/GnssGeofencing.cpp new file mode 100644 index 00000000..0ca3e6da --- /dev/null +++ b/gps/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 +#include +#include "GnssGeofencing.h" + +namespace android { +namespace hardware { +namespace gnss { +namespace V2_1 { +namespace implementation { + +void GnssGeofencing::GnssGeofencingDeathRecipient::serviceDied( + uint64_t cookie, const wp& who) { + LOC_LOGE("%s] service died. cookie: %llu, who: %p", + __FUNCTION__, static_cast(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 GnssGeofencing::setCallback(const sp& 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 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(lastTransition), + monitorTransitions, + notificationResponsivenessMs, + unknownTimerMs); + } + return Void(); +} + +Return GnssGeofencing::pauseGeofence(int32_t geofenceId) { + if (mApi == nullptr) { + LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__); + } else { + mApi->geofencePause(geofenceId); + } + return Void(); +} + +Return 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 GnssGeofencing::removeGeofence(int32_t geofenceId) { + if (mApi == nullptr) { + LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__); + } else { + mApi->geofenceRemove(geofenceId); + } + return Void(); +} + +Return 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/gps/android/2.1/GnssGeofencing.h b/gps/android/2.1/GnssGeofencing.h new file mode 100644 index 00000000..1cdca12e --- /dev/null +++ b/gps/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 +#include + +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 setCallback(const sp& callback) override; + Return addGeofence(int32_t geofenceId, + double latitudeDegrees, + double longitudeDegrees, + double radiusMeters, + IGnssGeofenceCallback::GeofenceTransition lastTransition, + int32_t monitorTransitions, + uint32_t notificationResponsivenessMs, + uint32_t unknownTimerMs) override; + + Return pauseGeofence(int32_t geofenceId) override; + Return resumeGeofence(int32_t geofenceId, int32_t monitorTransitions) override; + Return 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 removeAllGeofences(); + + private: + struct GnssGeofencingDeathRecipient : hidl_death_recipient { + GnssGeofencingDeathRecipient(sp gnssGeofencing) : + mGnssGeofencing(gnssGeofencing) { + } + ~GnssGeofencingDeathRecipient() = default; + virtual void serviceDied(uint64_t cookie, const wp& who) override; + sp mGnssGeofencing; + }; + + private: + sp mGnssGeofencingDeathRecipient = nullptr; + sp 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/gps/android/2.1/GnssMeasurement.cpp b/gps/android/2.1/GnssMeasurement.cpp new file mode 100644 index 00000000..af758028 --- /dev/null +++ b/gps/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 +#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& who) { + LOC_LOGE("%s] service died. cookie: %llu, who: %p", + __FUNCTION__, static_cast(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::setCallback( + const sp& callback) { + + Return 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 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::setCallback_1_1( + const sp& callback, bool enableFullTracking) { + + Return 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 GnssMeasurement::setCallback_2_0( + const sp& callback, + bool enableFullTracking) { + + Return 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 GnssMeasurement::setCallback_2_1( + const sp<::android::hardware::gnss::V2_1::IGnssMeasurementCallback>& callback, + bool enableFullTracking) { + Return 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/gps/android/2.1/GnssMeasurement.h b/gps/android/2.1/GnssMeasurement.h new file mode 100644 index 00000000..2ac45c61 --- /dev/null +++ b/gps/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 +#include +#include + +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 setCallback( + const sp& callback) override; + Return close() override; + + // Methods from ::android::hardware::gnss::V1_1::IGnssMeasurement follow. + Return setCallback_1_1( + const sp& callback, + bool enableFullTracking) override; + + // Methods from ::android::hardware::gnss::V2_0::IGnssMeasurement follow. + Return setCallback_2_0( + const sp& callback, + bool enableFullTracking) override; + // Methods from ::android::hardware::gnss::V2_1::IGnssMeasurement follow. + Return setCallback_2_1( + const sp<::android::hardware::gnss::V2_1::IGnssMeasurementCallback>& callback, + bool enableFullTracking) override; + + private: + struct GnssMeasurementDeathRecipient : hidl_death_recipient { + GnssMeasurementDeathRecipient(sp gnssMeasurement) : + mGnssMeasurement(gnssMeasurement) { + } + ~GnssMeasurementDeathRecipient() = default; + virtual void serviceDied(uint64_t cookie, const wp& who) override; + sp mGnssMeasurement; + }; + + private: + sp mGnssMeasurementDeathRecipient = nullptr; + sp mGnssMeasurementCbIface = nullptr; + sp mGnssMeasurementCbIface_1_1 = nullptr; + sp mGnssMeasurementCbIface_2_0 = nullptr; + sp 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/gps/android/2.1/GnssNi.cpp b/gps/android/2.1/GnssNi.cpp new file mode 100644 index 00000000..ba5e8d93 --- /dev/null +++ b/gps/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 +#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& who) { + LOC_LOGE("%s] service died. cookie: %llu, who: %p", + __FUNCTION__, static_cast(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 GnssNi::setCallback(const sp& 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 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/gps/android/2.1/GnssNi.h b/gps/android/2.1/GnssNi.h new file mode 100644 index 00000000..9a8fb693 --- /dev/null +++ b/gps/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 +#include + +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 setCallback(const sp& callback) override; + Return respond(int32_t notifId, + IGnssNiCallback::GnssUserResponseType userResponse) override; + + private: + struct GnssNiDeathRecipient : hidl_death_recipient { + GnssNiDeathRecipient(sp gnssNi) : mGnssNi(gnssNi) { + } + ~GnssNiDeathRecipient() = default; + virtual void serviceDied(uint64_t cookie, const wp& who) override; + sp mGnssNi; + }; + + private: + sp mGnssNiDeathRecipient = nullptr; + sp 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/gps/android/2.1/GnssVisibilityControl.cpp b/gps/android/2.1/GnssVisibilityControl.cpp new file mode 100644 index 00000000..5a8c697a --- /dev/null +++ b/gps/android/2.1/GnssVisibilityControl.cpp @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include "GnssVisibilityControl.h" +#include + +namespace android { +namespace hardware { +namespace gnss { +namespace visibility_control { +namespace V1_0 { +namespace implementation { + +using ::android::hardware::hidl_array; +using ::android::hardware::hidl_memory; +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::sp; + +static GnssVisibilityControl* spGnssVisibilityControl = nullptr; + +static void convertGnssNfwNotification(GnssNfwNotification& in, + IGnssVisibilityControlCallback::NfwNotification& out); + +GnssVisibilityControl::GnssVisibilityControl(Gnss* gnss) : mGnss(gnss) { + spGnssVisibilityControl = this; +} +GnssVisibilityControl::~GnssVisibilityControl() { + spGnssVisibilityControl = nullptr; +} + +void GnssVisibilityControl::nfwStatusCb(GnssNfwNotification notification) { + if (nullptr != spGnssVisibilityControl) { + spGnssVisibilityControl->statusCb(notification); + } +} + +bool GnssVisibilityControl::isInEmergencySession() { + if (nullptr != spGnssVisibilityControl) { + return spGnssVisibilityControl->isE911Session(); + } + return false; +} + +static void convertGnssNfwNotification(GnssNfwNotification& in, + IGnssVisibilityControlCallback::NfwNotification& out) +{ + memset(&out, 0, sizeof(IGnssVisibilityControlCallback::NfwNotification)); + out.proxyAppPackageName = in.proxyAppPackageName; + out.protocolStack = (IGnssVisibilityControlCallback::NfwProtocolStack)in.protocolStack; + out.otherProtocolStackName = in.otherProtocolStackName; + out.requestor = (IGnssVisibilityControlCallback::NfwRequestor)in.requestor; + out.requestorId = in.requestorId; + out.responseType = (IGnssVisibilityControlCallback::NfwResponseType)in.responseType; + out.inEmergencyMode = in.inEmergencyMode; + out.isCachedLocation = in.isCachedLocation; +} + +void GnssVisibilityControl::statusCb(GnssNfwNotification notification) { + + if (mGnssVisibilityControlCbIface != nullptr) { + IGnssVisibilityControlCallback::NfwNotification nfwNotification; + + // Convert from one structure to another + convertGnssNfwNotification(notification, nfwNotification); + + auto r = mGnssVisibilityControlCbIface->nfwNotifyCb(nfwNotification); + if (!r.isOk()) { + LOC_LOGw("Error invoking NFW status cb %s", r.description().c_str()); + } + } else { + LOC_LOGw("setCallback has not been called yet"); + } +} + +bool GnssVisibilityControl::isE911Session() { + + if (mGnssVisibilityControlCbIface != nullptr) { + auto r = mGnssVisibilityControlCbIface->isInEmergencySession(); + if (!r.isOk()) { + LOC_LOGw("Error invoking NFW status cb %s", r.description().c_str()); + return false; + } else { + return (r); + } + } else { + LOC_LOGw("setCallback has not been called yet"); + return false; + } +} + +// Methods from ::android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControl follow. +Return GnssVisibilityControl::enableNfwLocationAccess(const hidl_vec<::android::hardware::hidl_string>& proxyApps) { + + if (nullptr == mGnss || nullptr == mGnss->getGnssInterface()) { + LOC_LOGe("Null GNSS interface"); + return false; + } + + /* If the vector is empty we need to disable all NFW clients + If there is at least one app in the vector we need to enable + all NFW clients */ + if (0 == proxyApps.size()) { + mGnss->getGnssInterface()->enableNfwLocationAccess(false); + } else { + mGnss->getGnssInterface()->enableNfwLocationAccess(true); + } + + return true; +} +/** + * Registers the callback for HAL implementation to use. + * + * @param callback Handle to IGnssVisibilityControlCallback interface. + */ +Return GnssVisibilityControl::setCallback(const ::android::sp<::android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControlCallback>& callback) { + + if (nullptr == mGnss || nullptr == mGnss->getGnssInterface()) { + LOC_LOGe("Null GNSS interface"); + return false; + } + mGnssVisibilityControlCbIface = callback; + + NfwCbInfo cbInfo = {}; + cbInfo.visibilityControlCb = (void*)nfwStatusCb; + cbInfo.isInEmergencySession = (void*)isInEmergencySession; + + mGnss->getGnssInterface()->nfwInit(cbInfo); + + return true; +} + +} // namespace implementation +} // namespace V1_0 +} // namespace visibility_control +} // namespace gnss +} // namespace hardware +} // namespace android diff --git a/gps/android/2.1/GnssVisibilityControl.h b/gps/android/2.1/GnssVisibilityControl.h new file mode 100644 index 00000000..6794a646 --- /dev/null +++ b/gps/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 +#include +#include + +#include +#include +#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 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 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 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/gps/android/2.1/MeasurementCorrections.cpp b/gps/android/2.1/MeasurementCorrections.cpp new file mode 100644 index 00000000..f8f0803f --- /dev/null +++ b/gps/android/2.1/MeasurementCorrections.cpp @@ -0,0 +1,199 @@ +/* + * 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_MeasurementCorrectionsInterface" + +#include +#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& who) { + LOC_LOGe("service died. cookie: %llu, who: %p", static_cast(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) { + + if (mMeasurementCorrectionsCbIface != 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 = mMeasurementCorrectionsCbIface->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 MeasurementCorrections::setCorrections( + const MeasurementCorrectionsV1_0& corrections) { + + GnssMeasurementCorrections gnssMeasurementCorrections = {}; + + V2_1::implementation::convertMeasurementCorrections(corrections, gnssMeasurementCorrections); + + return mGnss->getGnssInterface()->measCorrSetCorrections(gnssMeasurementCorrections); +} + +Return 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 MeasurementCorrections::setCallback( + const sp& callback) { + + if (nullptr == mGnss || nullptr == mGnss->getGnssInterface()) { + LOC_LOGe("Null GNSS interface"); + return false; + } + mMeasurementCorrectionsCbIface = callback; + + return mGnss->getGnssInterface()->measCorrInit(measCorrSetCapabilitiesCb); +} + +} // namespace implementation +} // namespace V1_1 +} // namespace measurement_corrections +} // namespace gnss +} // namespace hardware +} // namespace android diff --git a/gps/android/2.1/MeasurementCorrections.h b/gps/android/2.1/MeasurementCorrections.h new file mode 100644 index 00000000..92fcc6a1 --- /dev/null +++ b/gps/android/2.1/MeasurementCorrections.h @@ -0,0 +1,106 @@ +/* + * 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_V1_1_MeasurementCorrections_H +#define ANDROID_HARDWARE_GNSS_V1_1_MeasurementCorrections_H + +#include +#include +#include +#include + +#include +#include +#include "Gnss.h" +#include + +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 setCorrections(const MeasurementCorrectionsV1_0& corrections) override; + + // Methods from + // ::android::hardware::gnss::measurement_corrections::V1_1::IMeasurementCorrections follow. + Return setCorrections_1_1(const MeasurementCorrectionsV1_1& corrections); + + Return setCallback(const sp& callback) override; + + void setCapabilitiesCb(GnssMeasurementCorrectionsCapabilitiesMask capabilities); + + /* Data call setup callback passed down to GNSS HAL implementation */ + static void measCorrSetCapabilitiesCb(GnssMeasurementCorrectionsCapabilitiesMask capabilities); + +private: + struct GnssMeasurementCorrectionsDeathRecipient : hidl_death_recipient { + GnssMeasurementCorrectionsDeathRecipient( + sp gnssMeasurementCorrections) : + mGnssMeasurementCorrections(gnssMeasurementCorrections) { + } + ~GnssMeasurementCorrectionsDeathRecipient() = default; + virtual void serviceDied(uint64_t cookie, const wp& who) override; + sp mGnssMeasurementCorrections; + }; + Gnss* mGnss = nullptr; + sp mGnssMeasurementCorrectionsDeathRecipient = + nullptr; + sp 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/gps/android/2.1/android.hardware.gnss@2.1-service-qti.rc b/gps/android/2.1/android.hardware.gnss@2.1-service-qti.rc new file mode 100644 index 00000000..19e32c4a --- /dev/null +++ b/gps/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 vendor_qti_diag diff --git a/gps/android/2.1/android.hardware.gnss@2.1-service-qti.xml b/gps/android/2.1/android.hardware.gnss@2.1-service-qti.xml new file mode 100755 index 00000000..842fb6ee --- /dev/null +++ b/gps/android/2.1/android.hardware.gnss@2.1-service-qti.xml @@ -0,0 +1,36 @@ + + + + android.hardware.gnss + hwbinder + @1.1::IGnss/default + @2.1::IGnss/default + + + diff --git a/gps/android/2.1/location_api/BatchingAPIClient.cpp b/gps/android/2.1/location_api/BatchingAPIClient.cpp new file mode 100755 index 00000000..f1f1fe43 --- /dev/null +++ b/gps/android/2.1/location_api/BatchingAPIClient.cpp @@ -0,0 +1,250 @@ +/* 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_BatchingAPIClient" + +#include +#include + +#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& 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& 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() +{ + LOC_LOGD("%s]: ()", __FUNCTION__); + return locAPIGetBatchSize(); +} + +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& callback) +{ + mMutex.lock(); + mGnssBatchingCbIface = callback; + mMutex.unlock(); + + if (mGnssBatchingCbIface != nullptr) { + setCallbacks(); + } +} + +void BatchingAPIClient::gnssUpdateCallbacks_2_0(const sp& callback) +{ + mMutex.lock(); + mGnssBatchingCbIface_2_0 = callback; + mMutex.unlock(); + + if (mGnssBatchingCbIface_2_0 != nullptr) { + setCallbacks(); + } +} + +int BatchingAPIClient::startSession(const IGnssBatching::Options& opts) +{ + LOC_LOGD("%s]: (%lld %d)", __FUNCTION__, + static_cast(opts.periodNanos), static_cast(opts.flags)); + int retVal = -1; + LocationOptions options; + convertBatchOption(opts, options, mLocationCapabilitiesMask); + uint32_t mode = 0; + if (opts.flags == static_cast(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(opts.periodNanos), static_cast(opts.flags)); + int retVal = -1; + LocationOptions options; + convertBatchOption(opts, options, mLocationCapabilitiesMask); + + uint32_t mode = 0; + if (opts.flags == static_cast(IGnssBatching::Flag::WAKEUP_ON_FIFO_FULL)) { + mode = SESSION_MODE_ON_FULL; + } + if (locAPIUpdateSessionOptions(mDefaultId, mode, options) == LOCATION_ERROR_SUCCESS) { + retVal = 1; + } + return retVal; +} + +int BatchingAPIClient::stopSession() +{ + LOC_LOGD("%s]: ", __FUNCTION__); + int retVal = -1; + if (locAPIStopSession(mDefaultId) == LOCATION_ERROR_SUCCESS) { + retVal = 1; + } + return retVal; +} + +void BatchingAPIClient::getBatchedLocation(int last_n_locations) +{ + LOC_LOGD("%s]: (%d)", __FUNCTION__, last_n_locations); + locAPIGetBatchedLocations(mDefaultId, last_n_locations); +} + +void BatchingAPIClient::flushBatchedLocations() +{ + LOC_LOGD("%s]: ()", __FUNCTION__); + locAPIGetBatchedLocations(mDefaultId, SIZE_MAX); +} + +void BatchingAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask) +{ + LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask); + mLocationCapabilitiesMask = capabilitiesMask; +} + +void BatchingAPIClient::onBatchingCb(size_t count, Location* location, + BatchingOptions /*batchOptions*/) +{ + mMutex.lock(); + auto gnssBatchingCbIface(mGnssBatchingCbIface); + auto gnssBatchingCbIface_2_0(mGnssBatchingCbIface_2_0); + mMutex.unlock(); + + LOC_LOGD("%s]: (count: %zu)", __FUNCTION__, count); + if (gnssBatchingCbIface_2_0 != nullptr && count > 0) { + hidl_vec locationVec; + locationVec.resize(count); + for (size_t i = 0; i < count; i++) { + convertGnssLocation(location[i], locationVec[i]); + } + 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 && count > 0) { + hidl_vec locationVec; + locationVec.resize(count); + for (size_t i = 0; i < count; i++) { + convertGnssLocation(location[i], locationVec[i]); + } + auto r = gnssBatchingCbIface->gnssLocationBatchCb(locationVec); + if (!r.isOk()) { + LOC_LOGE("%s] Error from gnssLocationBatchCb 1.0 description=%s", + __func__, r.description().c_str()); + } + } +} + +static void convertBatchOption(const IGnssBatching::Options& in, LocationOptions& out, + LocationCapabilitiesMask mask) +{ + memset(&out, 0, sizeof(LocationOptions)); + out.size = sizeof(LocationOptions); + out.minInterval = (uint32_t)(in.periodNanos / 1000000L); + out.minDistance = 0; + out.mode = GNSS_SUPL_MODE_STANDALONE; + if (mask & LOCATION_CAPABILITIES_GNSS_MSA_BIT) + out.mode = GNSS_SUPL_MODE_MSA; + if (mask & LOCATION_CAPABILITIES_GNSS_MSB_BIT) + out.mode = GNSS_SUPL_MODE_MSB; +} + +} // namespace implementation +} // namespace V2_1 +} // namespace gnss +} // namespace hardware +} // namespace android diff --git a/gps/android/2.1/location_api/BatchingAPIClient.h b/gps/android/2.1/location_api/BatchingAPIClient.h new file mode 100755 index 00000000..08d7d237 --- /dev/null +++ b/gps/android/2.1/location_api/BatchingAPIClient.h @@ -0,0 +1,82 @@ +/* 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 +#include +#include +#include + +#include + +namespace android { +namespace hardware { +namespace gnss { +namespace V2_1 { +namespace implementation { + +class BatchingAPIClient : public LocationAPIClientBase +{ +public: + BatchingAPIClient(const sp& callback); + BatchingAPIClient(const sp& callback); + void gnssUpdateCallbacks(const sp& callback); + void gnssUpdateCallbacks_2_0(const sp& 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 mGnssBatchingCbIface; + uint32_t mDefaultId; + LocationCapabilitiesMask mLocationCapabilitiesMask; + sp mGnssBatchingCbIface_2_0; +}; + +} // namespace implementation +} // namespace V2_1 +} // namespace gnss +} // namespace hardware +} // namespace android +#endif // BATCHING_API_CLINET_H diff --git a/gps/android/2.1/location_api/GeofenceAPIClient.cpp b/gps/android/2.1/location_api/GeofenceAPIClient.cpp new file mode 100755 index 00000000..6e63465b --- /dev/null +++ b/gps/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 +#include + +#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& 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(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/gps/android/2.1/location_api/GeofenceAPIClient.h b/gps/android/2.1/location_api/GeofenceAPIClient.h new file mode 100755 index 00000000..9ed289f1 --- /dev/null +++ b/gps/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 +#include + +namespace android { +namespace hardware { +namespace gnss { +namespace V2_1 { +namespace implementation { + +using ::android::sp; + +class GeofenceAPIClient : public LocationAPIClientBase +{ +public: + GeofenceAPIClient(const sp& 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 mGnssGeofencingCbIface; +}; + +} // namespace implementation +} // namespace V2_1 +} // namespace gnss +} // namespace hardware +} // namespace android +#endif // GEOFENCE_API_CLINET_H diff --git a/gps/android/2.1/location_api/GnssAPIClient.cpp b/gps/android/2.1/location_api/GnssAPIClient.cpp new file mode 100644 index 00000000..09c83dfb --- /dev/null +++ b/gps/android/2.1/location_api/GnssAPIClient.cpp @@ -0,0 +1,863 @@ +/* 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 +#include + +#include "LocationUtil.h" +#include "GnssAPIClient.h" +#include + +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& out); +static void convertGnssSvStatus(GnssSvNotification& in, + hidl_vec& out); + +GnssAPIClient::GnssAPIClient(const sp& gpsCb, + const sp& 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& 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& 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& gpsCb, + const sp& 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& 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& 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(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]: (%02x)", __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 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 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(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(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(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(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(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(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& 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(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& 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(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/gps/android/2.1/location_api/GnssAPIClient.h b/gps/android/2.1/location_api/GnssAPIClient.h new file mode 100755 index 00000000..c4dbe9a9 --- /dev/null +++ b/gps/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 +#include +#include +#include + +namespace android { +namespace hardware { +namespace gnss { +namespace V2_1 { +namespace implementation { + +using ::android::sp; + +class GnssAPIClient : public LocationAPIClientBase +{ +public: + GnssAPIClient(const sp& gpsCb, + const sp& niCb); + GnssAPIClient(const sp& gpsCb); + GnssAPIClient(const sp& gpsCb); + GnssAPIClient(const GnssAPIClient&) = delete; + GnssAPIClient& operator=(const GnssAPIClient&) = delete; + + // for GpsInterface + void gnssUpdateCallbacks(const sp& gpsCb, + const sp& niCb); + void gnssUpdateCallbacks_2_0(const sp& gpsCb); + void gnssUpdateCallbacks_2_1(const sp& 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 mGnssCbIface; + sp mGnssNiCbIface; + std::mutex mMutex; + LocationAPIControlClient* mControlClient; + LocationCapabilitiesMask mLocationCapabilitiesMask; + bool mLocationCapabilitiesCached; + TrackingOptions mTrackingOptions; + bool mTracking; + sp mGnssCbIface_2_0; + sp mGnssCbIface_2_1; +}; + +} // namespace implementation +} // namespace V2_1 +} // namespace gnss +} // namespace hardware +} // namespace android +#endif // GNSS_API_CLINET_H diff --git a/gps/android/2.1/location_api/LocationUtil.cpp b/gps/android/2.1/location_api/LocationUtil.cpp new file mode 100644 index 00000000..43711199 --- /dev/null +++ b/gps/android/2.1/location_api/LocationUtil.cpp @@ -0,0 +1,492 @@ +/* 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 +#include +#include +#include +#include + +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(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)) { + if (in.flags & LOCATION_HAS_ELAPSED_REAL_TIME) { + uint64_t qtimerDiff = 0; + uint64_t qTimerTickCount = getQTimerTickCount(); + if (qTimerTickCount >= in.elapsedRealTime) { + qtimerDiff = qTimerTickCount - in.elapsedRealTime; + } + LOC_LOGd("sinceBootTimeNanos:%" PRIi64 " in.elapsedRealTime=%" PRIi64 "" + " qTimerTickCount=%" PRIi64 " qtimerDiff=%" PRIi64 "", + sinceBootTimeNanos, in.elapsedRealTime, 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; + } + } + + if (sinceBootTimeNanos >= qTimerDiffNanos) { + out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIMESTAMP_NS; + out.elapsedRealtime.timestampNs = sinceBootTimeNanos - qTimerDiffNanos; + out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS; + out.elapsedRealtime.timeUncertaintyNs = in.elapsedRealTimeUnc; + } + } else { + int64_t currentTimeNanos = currentTime.tv_sec*1000000000 + currentTime.tv_nsec; + int64_t locationTimeNanos = in.timestamp*1000000; + LOC_LOGd("sinceBootTimeNanos:%" PRIi64 " currentTimeNanos:%" PRIi64 "" + " locationTimeNanos:%" PRIi64 "", + sinceBootTimeNanos, currentTimeNanos, locationTimeNanos); + if (currentTimeNanos >= locationTimeNanos) { + int64_t ageTimeNanos = currentTimeNanos - locationTimeNanos; + LOC_LOGd("ageTimeNanos:%" PRIi64 ")", ageTimeNanos); + // the max trusted propagation time 100ms for ageTimeNanos to avoid user setting + // wrong time, it will affect elapsedRealtimeNanos + if (ageTimeNanos <= 100000000) { + out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIMESTAMP_NS; + out.elapsedRealtime.timestampNs = sinceBootTimeNanos - ageTimeNanos; + out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS; + // time uncertainty is the max value between abs(AP_UTC - MP_UTC) and 100ms, to + // verify if user change the sys time + out.elapsedRealtime.timeUncertaintyNs = + std::max(ageTimeNanos, (int64_t)100000000); + } + } + } + } + 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(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: + out = in.svId - GLO_SV_PRN_MIN + 1; + 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: + /*Android doesn't define Navic svid range yet, use Naviv svid [1, 14] now + will update this once Android give Navic svid definiitons */ + 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 (in.svId != 255) { // 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: + /*Android doesn't define Navic svid range yet, use Naviv svid [1, 14] now + will update this once Android give Navic svid definiitons */ + 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/gps/android/2.1/location_api/LocationUtil.h b/gps/android/2.1/location_api/LocationUtil.h new file mode 100644 index 00000000..fde15950 --- /dev/null +++ b/gps/android/2.1/location_api/LocationUtil.h @@ -0,0 +1,69 @@ +/* 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 +#include +#include +#include + +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); +bool getCurrentTime(struct timespec& currentTime, int64_t& sinceBootTimeNanos); +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/gps/android/2.1/location_api/MeasurementAPIClient.cpp b/gps/android/2.1/location_api/MeasurementAPIClient.cpp new file mode 100644 index 00000000..58697744 --- /dev/null +++ b/gps/android/2.1/location_api/MeasurementAPIClient.cpp @@ -0,0 +1,706 @@ +/* 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 +#include +#include + +#include "LocationUtil.h" +#include "MeasurementAPIClient.h" +#include + +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 + & out); +static void convertGnssMeasurementsState(GnssMeasurementsStateMask& in, + ::android::hardware::hidl_bitfield + & 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 +MeasurementAPIClient::measurementSetCallback(const sp& callback) +{ + LOC_LOGD("%s]: (%p)", __FUNCTION__, &callback); + + mMutex.lock(); + clearInterfaces(); + mGnssMeasurementCbIface = callback; + mMutex.unlock(); + + return startTracking(); +} + +Return +MeasurementAPIClient::measurementSetCallback_1_1( + const sp& 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 +MeasurementAPIClient::measurementSetCallback_2_0( + const sp& 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 MeasurementAPIClient::measurementSetCallback_2_1( + const sp& 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 +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 gnssMeasurementCbIface = nullptr; + sp gnssMeasurementCbIface_1_1 = nullptr; + sp gnssMeasurementCbIface_2_0 = nullptr; + sp 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(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(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(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(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 + & 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 + & 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) +{ + struct timespec currentTime; + int64_t sinceBootTimeNanos; + + if (getCurrentTime(currentTime, sinceBootTimeNanos)) { + if (in.clock.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_ELAPSED_REAL_TIME_BIT) { + uint64_t qtimerDiff = 0; + uint64_t qTimerTickCount = getQTimerTickCount(); + if (qTimerTickCount >= in.clock.elapsedRealTime) { + qtimerDiff = qTimerTickCount - in.clock.elapsedRealTime; + } + LOC_LOGv("sinceBootTimeNanos:%" PRIi64 " in.clock.elapsedRealTime=%" PRIi64 "" + " qTimerTickCount=%" PRIi64 " qtimerDiff=%" PRIi64 "", + sinceBootTimeNanos, in.clock.elapsedRealTime, 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; + } + } + + if (sinceBootTimeNanos >= qTimerDiffNanos) { + elapsedRealtime.flags |= V2_0::ElapsedRealtimeFlags::HAS_TIMESTAMP_NS; + elapsedRealtime.timestampNs = sinceBootTimeNanos - qTimerDiffNanos; + elapsedRealtime.flags |= V2_0::ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS; + elapsedRealtime.timeUncertaintyNs = in.clock.elapsedRealTimeUnc; + } + } else { + const uint32_t UTC_TO_GPS_SECONDS = 315964800; + + if (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_LOGv("sinceBootTimeNanos:%" PRIi64 " currentTimeNanos:%" PRIi64 "" + " measTimeNanos:%" PRIi64 "", + sinceBootTimeNanos, currentTimeNanos, measTimeNanos); + if (currentTimeNanos >= measTimeNanos) { + int64_t ageTimeNanos = currentTimeNanos - measTimeNanos; + LOC_LOGv("ageTimeNanos:%" PRIi64 ")", ageTimeNanos); + // the max trusted propagation time 100ms for ageTimeNanos to avoid user + // setting wrong time, it will affect elapsedRealtimeNanos + if (ageTimeNanos <= 100000000) { + elapsedRealtime.flags |= V2_0::ElapsedRealtimeFlags::HAS_TIMESTAMP_NS; + elapsedRealtime.timestampNs = sinceBootTimeNanos - ageTimeNanos; + elapsedRealtime.flags |= + V2_0::ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS; + // time uncertainty is 1 ms since it is calculated from utc time that + // is in ms + // time uncertainty is the max value between abs(AP_UTC - MP_UTC) and 100ms, + // to verify if user change the sys time + elapsedRealtime.timeUncertaintyNs = + std::max(ageTimeNanos, (int64_t)100000000); + } + } + } else { + LOC_LOGe("Failed to calculate elapsedRealtimeNanos timestamp"); + } + } + } + LOC_LOGv("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/gps/android/2.1/location_api/MeasurementAPIClient.h b/gps/android/2.1/location_api/MeasurementAPIClient.h new file mode 100644 index 00000000..3e8805b0 --- /dev/null +++ b/gps/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 +#include +//#include +#include +#include +#include +#include + +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 measurementSetCallback( + const sp& callback); + Return measurementSetCallback_1_1( + const sp& callback, + GnssPowerMode powerMode = GNSS_POWER_MODE_INVALID, + uint32_t timeBetweenMeasurement = GPS_DEFAULT_FIX_INTERVAL_MS); + Return measurementSetCallback_2_0( + const sp& callback, + GnssPowerMode powerMode = GNSS_POWER_MODE_INVALID, + uint32_t timeBetweenMeasurement = GPS_DEFAULT_FIX_INTERVAL_MS); + Return measurementSetCallback_2_1( + const sp& callback, + GnssPowerMode powerMode = GNSS_POWER_MODE_INVALID, + uint32_t timeBetweenMeasurement = GPS_DEFAULT_FIX_INTERVAL_MS); + void measurementClose(); + Return 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 mGnssMeasurementCbIface; + sp mGnssMeasurementCbIface_1_1; + sp mGnssMeasurementCbIface_2_0; + sp 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/gps/android/2.1/service.cpp b/gps/android/2.1/service.cpp new file mode 100755 index 00000000..c5f040b0 --- /dev/null +++ b/gps/android/2.1/service.cpp @@ -0,0 +1,81 @@ +/* + * 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 +#include +#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(); + 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/gps/android/Android.mk b/gps/android/Android.mk index 3b5c01fe..aa2f4b59 100644 --- a/gps/android/Android.mk +++ b/gps/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/gps/android/utils/Android.bp b/gps/android/utils/Android.bp new file mode 100644 index 00000000..c3dc17ae --- /dev/null +++ b/gps/android/utils/Android.bp @@ -0,0 +1,37 @@ +cc_library_static { + + name: "liblocbatterylistener", + vendor: true, + + sanitize: GNSS_SANITIZE, + + 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/gps/android/utils/Android.mk b/gps/android/utils/Android.mk deleted file mode 100644 index 9cb6f7ba..00000000 --- a/gps/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/gps/android/utils/battery_listener.cpp b/gps/android/utils/battery_listener.cpp index 170159a7..9cbfabdc 100644 --- a/gps/android/utils/battery_listener.cpp +++ b/gps/android/utils/battery_listener.cpp @@ -34,7 +34,8 @@ #define LOG_NDEBUG 0 #include -#include +#include +#include #include #include #include @@ -44,10 +45,9 @@ using android::hardware::interfacesEqual; 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 @@ namespace android { #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 cb_fn_t; BatteryListenerImpl(cb_fn_t cb); virtual ~BatteryListenerImpl (); virtual hardware::Return healthInfoChanged( - const hardware::health::V2_0::HealthInfo& info); + const hardware::health::V2_0::HealthInfo& info); + virtual hardware::Return healthInfoChanged_2_1( + const hardware::health::V2_1::HealthInfo& info); virtual void serviceDied(uint64_t cookie, const wp& who); bool isCharging() { @@ -72,7 +74,7 @@ struct BatteryListenerImpl : public hardware::health::V2_0::IHealthInfoCallback, return statusToBool(mStatus); } private: - sp mHealth; + sp mHealth; status_t init(); BatteryStatus mStatus; cb_fn_t mCb; @@ -94,7 +96,7 @@ status_t BatteryListenerImpl::init() 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); @@ -229,6 +231,13 @@ Return BatteryListenerImpl::healthInfoChanged( return Void(); } +Return 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 batteryListener; bool batteryPropertiesListenerIsCharging() { @@ -253,6 +262,7 @@ status_t batteryPropertiesListenerDeinit() { } // 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/gps/batching/Android.bp b/gps/batching/Android.bp new file mode 100644 index 00000000..9182a0a0 --- /dev/null +++ b/gps/batching/Android.bp @@ -0,0 +1,31 @@ + +cc_library_shared { + + name: "libbatching", + vendor: true, + + sanitize: GNSS_SANITIZE, + + 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/gps/batching/Android.mk b/gps/batching/Android.mk deleted file mode 100644 index f3e8fe4d..00000000 --- a/gps/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/gps/batching/BatchingAdapter.cpp b/gps/batching/BatchingAdapter.cpp index 135f0ed9..d9f7945b 100644 --- a/gps/batching/BatchingAdapter.cpp +++ b/gps/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 @@ -37,12 +37,7 @@ using namespace loc_core; BatchingAdapter::BatchingAdapter() : - LocAdapterBase(0, - LocContext::getLocContext( - NULL, - NULL, - LocContext::mLocationHalName, - false)), + LocAdapterBase(0, LocContext::getLocContext(LocContext::mLocationHalName)), mOngoingTripDistance(0), mOngoingTripTBFInterval(0), mTripWithOngoingTBFDropped(false), diff --git a/gps/batching/Makefile.am b/gps/batching/Makefile.am index ef8011e9..d5cba39a 100644 --- a/gps/batching/Makefile.am +++ b/gps/batching/Makefile.am @@ -22,8 +22,7 @@ libbatching_la_SOURCES = \ 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/gps/batching/configure.ac b/gps/batching/configure.ac index e77e4972..4ca49985 100644 --- a/gps/batching/configure.ac +++ b/gps/batching/configure.ac @@ -37,10 +37,6 @@ PKG_CHECK_MODULES([LOCCORE], [loc-core]) AC_SUBST([LOCCORE_CFLAGS]) AC_SUBST([LOCCORE_LIBS]) -PKG_CHECK_MODULES([GEOFENCE], [location-geofence]) -AC_SUBST([GEOFENCE_CFLAGS]) -AC_SUBST([GEOFENCE_LIBS]) - AC_ARG_WITH([locpla_includes], AC_HELP_STRING([--with-locpla-includes=@<:@dir@:>@], [specify the path to locpla-includes in loc-pla_git.bb]), diff --git a/gps/build/target_specific_features.mk b/gps/build/target_specific_features.mk deleted file mode 100644 index 5b13125d..00000000 --- a/gps/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-reorder-ctor \ - -Wno-error=missing-braces \ - -Wno-error=self-assign \ - -Wno-enum-conversion \ - -Wno-error=logical-op-parentheses \ - -Wno-error=null-arithmetic \ - -Wno-error=null-conversion \ - -Wno-error=parentheses-equality \ - -Wno-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_2_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 - -ifneq (,$(filter $(GNSS_HIDL_2_0_TARGET_LIST),$(TARGET_BOARD_PLATFORM))) -GNSS_HIDL_VERSION = 2.0 -endif -ifneq (,$(filter $(GNSS_HIDL_1_0_TARGET_LIST),$(TARGET_BOARD_PLATFORM))) -GNSS_HIDL_VERSION = 1.0 -endif -ifneq (,$(filter $(GNSS_HIDL_1_1_TARGET_LIST),$(TARGET_BOARD_PLATFORM))) -GNSS_HIDL_VERSION = 1.1 -endif - -GNSS_HIDL_LEGACY_MEASURMENTS_TARGET_LIST := msm8937 -GNSS_HIDL_LEGACY_MEASURMENTS_TARGET_LIST += msm8953 -GNSS_HIDL_LEGACY_MEASURMENTS_TARGET_LIST += msm8998 -GNSS_HIDL_LEGACY_MEASURMENTS_TARGET_LIST += apq8098_latv -GNSS_HIDL_LEGACY_MEASURMENTS_TARGET_LIST += sdm710 -GNSS_HIDL_LEGACY_MEASURMENTS_TARGET_LIST += qcs605 -GNSS_HIDL_LEGACY_MEASURMENTS_TARGET_LIST += sdm845 -GNSS_HIDL_LEGACY_MEASURMENTS_TARGET_LIST += sdm660 - -ifneq (,$(filter $(GNSS_HIDL_LEGACY_MEASURMENTS_TARGET_LIST),$(TARGET_BOARD_PLATFORM))) -GNSS_HIDL_LEGACY_MEASURMENTS = true -endif - -# 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/gps/core/Android.bp b/gps/core/Android.bp new file mode 100644 index 00000000..ee8e8077 --- /dev/null +++ b/gps/core/Android.bp @@ -0,0 +1,56 @@ + +cc_library_shared { + + name: "libloc_core", + vendor: true, + + sanitize: GNSS_SANITIZE, + + 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/gps/core/Android.mk b/gps/core/Android.mk deleted file mode 100644 index ce5d6a8e..00000000 --- a/gps/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/gps/core/ContextBase.cpp b/gps/core/ContextBase.cpp index d12f5530..411c9900 100644 --- a/gps/core/ContextBase.cpp +++ b/gps/core/ContextBase.cpp @@ -49,6 +49,7 @@ bool ContextBase::sIsEngineCapabilitiesKnown = false; uint64_t ContextBase::sSupportedMsgMask = 0; bool ContextBase::sGnssMeasurementSupported = false; uint8_t ContextBase::sFeaturesSupported[MAX_FEATURE_LENGTH]; +GnssNMEARptRate ContextBase::sNmeaReportRate = GNSS_NMEA_REPORT_RATE_NHZ; const loc_param_s_type ContextBase::mGps_conf_table[] = { @@ -64,8 +65,8 @@ const loc_param_s_type ContextBase::mGps_conf_table[] = {"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'}, @@ -135,8 +136,6 @@ void ContextBase::readConfig() 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*/ @@ -200,6 +199,12 @@ void ContextBase::readConfig() 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"))); @@ -328,6 +333,32 @@ void ContextBase::setEngineCapabilities(uint64_t supportedMsgMask, (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/gps/core/ContextBase.h b/gps/core/ContextBase.h index 1a003c86..026ab49d 100644 --- a/gps/core/ContextBase.h +++ b/gps/core/ContextBase.h @@ -49,12 +49,12 @@ typedef struct loc_gps_cfg_s 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; @@ -79,13 +79,13 @@ typedef struct loc_gps_cfg_s uint32_t ENABLE_NMEA_PRINT; } 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; @@ -110,6 +110,8 @@ typedef struct double VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY; } loc_sap_cfg_s_type; +using namespace loc_util; + namespace loc_core { class LocAdapterBase; @@ -157,6 +159,7 @@ public: static uint64_t sSupportedMsgMask; static uint8_t sFeaturesSupported[MAX_FEATURE_LENGTH]; static bool sGnssMeasurementSupported; + static GnssNMEARptRate sNmeaReportRate; void readConfig(); static uint32_t getCarrierCapabilities(); diff --git a/gps/core/EngineHubProxyBase.h b/gps/core/EngineHubProxyBase.h index d46bca25..13a1cd75 100644 --- a/gps/core/EngineHubProxyBase.h +++ b/gps/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 @@ -31,6 +31,8 @@ namespace loc_core { +using namespace loc_util; + class EngineHubProxyBase { public: inline EngineHubProxyBase() { @@ -106,6 +108,12 @@ public: (void) configInfo; return false; } + + inline virtual bool configDeadReckoningEngineParams( + const DeadReckoningEngineConfig& dreConfig) { + (void) dreConfig; + return false; + } }; typedef std::function diff --git a/gps/core/LocAdapterBase.cpp b/gps/core/LocAdapterBase.cpp index a8b10d7a..5ada84b7 100644 --- a/gps/core/LocAdapterBase.cpp +++ b/gps/core/LocAdapterBase.cpp @@ -88,8 +88,8 @@ void LocAdapterBase:: const GpsLocationExtended& locationExtended, enum loc_sess_status status, LocPosTechMask loc_technology_mask, - GnssDataNotification* /*pDataNotify*/, - int /*msInWeek*/) + GnssDataNotification* pDataNotify, + int msInWeek) { if (mLocAdapterProxyBase != NULL) { mLocAdapterProxyBase->reportPositionEvent((UlpLocation&)location, @@ -162,7 +162,7 @@ DEFAULT_IMPL(false) bool LocAdapterBase:: requestNiNotifyEvent(const GnssNiNotification &/*notify*/, const void* /*data*/, - const LocInEmergency /*emergencyState*/) + const LocInEmergency emergencyState) DEFAULT_IMPL(false) void LocAdapterBase:: @@ -313,6 +313,15 @@ LocAdapterBase::getCapabilities() 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__); } @@ -335,7 +344,7 @@ LocAdapterBase::updateClientsEventMask() DEFAULT_IMPL() void -LocAdapterBase::stopClientSessions(LocationAPI* /*client*/) +LocAdapterBase::stopClientSessions(LocationAPI* client) DEFAULT_IMPL() void diff --git a/gps/core/LocApiBase.cpp b/gps/core/LocApiBase.cpp index 60bfdd21..0044d07d 100644 --- a/gps/core/LocApiBase.cpp +++ b/gps/core/LocApiBase.cpp @@ -160,7 +160,7 @@ LocApiBase::LocApiBase(LOC_API_ADAPTER_EVENT_MASK_T excludedMask, android_atomic_inc(&mMsgTaskRefCount); if (nullptr == mMsgTask) { - mMsgTask = new MsgTask("LocApiMsgTask", false); + mMsgTask = new MsgTask("LocApiMsgTask"); } } @@ -330,7 +330,7 @@ void LocApiBase::reportPosition(UlpLocation& location, "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 +340,8 @@ void LocApiBase::reportPosition(UlpLocation& location, 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,21 +407,22 @@ void LocApiBase::reportSv(GnssSvNotification& svNotify) // 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 - LOC_LOGV(" %03zu: %*s %02d %f %f %f %f 0x%02X 0x%2X", + LOC_LOGV(" %03zu: %*s %02d %f %f %f %f %f 0x%02X 0x%2X", i, 13, constellationString[svNotify.gnssSvs[i].type], svNotify.gnssSvs[i].svId, svNotify.gnssSvs[i].cN0Dbhz, + svNotify.gnssSvs[i].basebandCarrierToNoiseDbHz, svNotify.gnssSvs[i].elevation, svNotify.gnssSvs[i].azimuth, svNotify.gnssSvs[i].carrierFrequencyHz, @@ -539,9 +541,10 @@ void LocApiBase::reportGnssSvIdConfig(const GnssSvIdConfig& config) { // 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)); @@ -616,7 +619,8 @@ void LocApiBase:: DEFAULT_IMPL() void LocApiBase:: - injectPosition(double /*latitude*/, double /*longitude*/, float /*accuracy*/) + injectPosition(double /*latitude*/, double /*longitude*/, float /*accuracy*/, + bool /*onDemandCpi*/) DEFAULT_IMPL() void LocApiBase:: @@ -631,10 +635,6 @@ void LocApiBase:: 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*/, @@ -666,7 +666,7 @@ enum loc_api_adapter_err LocApiBase:: DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS) LocationError LocApiBase:: - setLPPConfigSync(GnssConfigLppProfile /*profile*/) + setLPPConfigSync(GnssConfigLppProfileMask /*profileMask*/) DEFAULT_IMPL(LOCATION_ERROR_SUCCESS) @@ -711,9 +711,6 @@ DEFAULT_IMPL(LOCATION_ERROR_SUCCESS) 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) @@ -724,6 +721,10 @@ LocationError LocApiBase::setEmergencyExtensionWindowSync( const uint32_t /*emergencyExtensionSeconds*/) DEFAULT_IMPL(LOCATION_ERROR_SUCCESS) +void LocApiBase::setMeasurementCorrections( + const GnssMeasurementCorrections& /*gnssMeasurementCorrections*/) +DEFAULT_IMPL() + void LocApiBase:: getWwanZppFix() DEFAULT_IMPL() @@ -740,12 +741,6 @@ void LocApiBase:: 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) @@ -753,7 +748,8 @@ DEFAULT_IMPL(LOCATION_ERROR_SUCCESS) 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() @@ -781,8 +777,8 @@ void LocApiBase:: 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*/, @@ -892,4 +888,29 @@ 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() } // namespace loc_core diff --git a/gps/core/LocApiBase.h b/gps/core/LocApiBase.h index 1e8337c5..fd0f1d21 100644 --- a/gps/core/LocApiBase.h +++ b/gps/core/LocApiBase.h @@ -37,6 +37,8 @@ #include #include +using namespace loc_util; + namespace loc_core { class ContextBase; @@ -59,13 +61,6 @@ int decodeAddress(char *addr_string, int string_size, #define TO_1ST_HANDLING_ADAPTER(adapters, call) \ for (int i = 0; i destroy(); + delete mMsgTask; mMsgTask = nullptr; } } @@ -195,8 +192,8 @@ public: void reportDeleteAidingDataEvent(GnssAidingData& aidingData); void reportKlobucharIonoModel(GnssKlobucharIonoModel& ionoModel); void reportGnssAdditionalSystemInfo(GnssAdditionalSystemInfo& additionalSystemInfo); - void reportGnssConfig(uint32_t sessionId, const GnssConfig& gnssConfig); void sendNfwNotification(GnssNfwNotification& notification); + void reportGnssConfig(uint32_t sessionId, const GnssConfig& gnssConfig); void geofenceBreach(size_t count, uint32_t* hwIds, Location& location, GeofenceBreachType breachType, uint64_t timestamp); @@ -215,12 +212,12 @@ public: 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); @@ -229,7 +226,7 @@ public: 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, @@ -245,21 +242,21 @@ public: 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); @@ -272,7 +269,7 @@ public: 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* adapterResponseData); @@ -319,9 +316,22 @@ public: 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); }; typedef LocApiBase* (getLocApi_t)(LOC_API_ADAPTER_EVENT_MASK_T exMask, diff --git a/gps/core/LocContext.cpp b/gps/core/LocContext.cpp index 18d3f2d1..272c08c8 100644 --- a/gps/core/LocContext.cpp +++ b/gps/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 @@ const char* LocContext::mLBSLibName = "liblbs_core.so.1"; 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/gps/core/LocContext.h b/gps/core/LocContext.h index fb7d009d..628ed938 100644 --- a/gps/core/LocContext.h +++ b/gps/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 @@ namespace loc_core { 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 @@ public: 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/gps/core/SystemStatus.cpp b/gps/core/SystemStatus.cpp index 393eead1..891a8e65 100644 --- a/gps/core/SystemStatus.cpp +++ b/gps/core/SystemStatus.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 @@ -1287,6 +1287,14 @@ void SystemStatus::destroyInstance() mInstance = NULL; } +void SystemStatus::resetNetworkInfo() { + for (int i=0; i(curInfo)).mAllTypes; - uint64_t networkHandle = - (static_cast(curInfo)).mNetworkHandle; - int32_t type = (static_cast(curInfo)).mType; // Replace current with cached table for now and then update memcpy(mAllNetworkHandles, (static_cast(curInfo)).getNetworkHandle(), @@ -542,18 +538,21 @@ public: ++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; @@ -910,6 +909,7 @@ public: bool eventConnectionStatus(bool connected, int8_t type, bool roaming, NetworkHandle networkHandle); bool updatePowerConnectState(bool charging); + void resetNetworkInfo(); }; } // namespace loc_core diff --git a/gps/core/SystemStatusOsObserver.cpp b/gps/core/SystemStatusOsObserver.cpp index 98f5f742..8fd95642 100644 --- a/gps/core/SystemStatusOsObserver.cpp +++ b/gps/core/SystemStatusOsObserver.cpp @@ -452,61 +452,73 @@ void SystemStatusOsObserver::turnOff(DataItemId dit) } #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_LOGi("HandleConnectBackhaul::enter"); - mFwkActionReqObj->connectBackhaul(); + 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_LOGi("HandleDisconnectBackhaul::enter"); - mFwkActionReqObj->disconnectBackhaul(); + 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; diff --git a/gps/core/SystemStatusOsObserver.h b/gps/core/SystemStatusOsObserver.h index fd606063..c0f56d8c 100644 --- a/gps/core/SystemStatusOsObserver.h +++ b/gps/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 ClientToDataItems; typedef LocUnorderedSetMap DataItemToClients; typedef unordered_map DataItemIdToCore; typedef unordered_map DataItemIdToInt; +#ifdef USE_GLIB +// Cache details of backhaul client requests +typedef unordered_set ClientBackhaulReqCache; +#endif struct ObserverContext { IDataItemSubscription* mSubscriptionObj; @@ -83,12 +87,7 @@ public: 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 @@ public: 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 @@ public: 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 @@ private: const list& l, IDataItemObserver* client); #ifdef USE_GLIB // Cache the framework action request for connect/disconnect - int mBackHaulConnectReqCount; + ClientBackhaulReqCache mBackHaulConnReqCache; #endif void subscribe(const list& l, IDataItemObserver* client, bool toRequestData); diff --git a/gps/core/observer/IFrameworkActionReq.h b/gps/core/observer/IFrameworkActionReq.h index 4be947ff..138508c7 100644 --- a/gps/core/observer/IFrameworkActionReq.h +++ b/gps/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 #include +using namespace std; + namespace loc_core { @@ -77,7 +80,7 @@ public: * * @param None */ - virtual bool connectBackhaul() = 0; + virtual bool connectBackhaul(const string& clientName) = 0; /** * @brief Disconnects the WWANbackhaul @@ -85,7 +88,7 @@ public: * * @param None */ - virtual bool disconnectBackhaul() = 0; + virtual bool disconnectBackhaul(const string& clientName) = 0; #endif /** diff --git a/gps/core/observer/IOsObserver.h b/gps/core/observer/IOsObserver.h index f6618281..a25bb9fb 100644 --- a/gps/core/observer/IOsObserver.h +++ b/gps/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 @@ public: 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/gps/etc/Android.bp b/gps/etc/Android.bp new file mode 100644 index 00000000..897c3f33 --- /dev/null +++ b/gps/etc/Android.bp @@ -0,0 +1,49 @@ + +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/gps/etc/Android.mk b/gps/etc/Android.mk deleted file mode 100644 index 22ca2f71..00000000 --- a/gps/etc/Android.mk +++ /dev/null @@ -1,21 +0,0 @@ - -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) - diff --git a/gps/etc/apdr.conf b/gps/etc/apdr.conf deleted file mode 100644 index ce5ba783..00000000 --- a/gps/etc/apdr.conf +++ /dev/null @@ -1,205 +0,0 @@ -# AP DR SENSOR Configuration file -# -# SENSOR_SERVICE options are one of below -# accel,gyro,vehicle_accel,vehicle_gyro,pedometer,vehicle_odometry,accel_temp, -# gyro_temp,baro,mag_calib,mag_uncalib,amd,rmd. -# -# SENSOR_PROVIDER options is one of -- default,native,ssc,samlite. -# -# SENSOR_RATE = 1~100 (Hz) -# -# SENSOR_SAMPLES = 1~N -# -# SENSOR_STATISTIC_ENABLED -# bit 0: Diag Print Enabled -# bit 1: Adb Print Enabled -# SENSOR_STATISTIC_PRINT_COUNT -# Skip Number of Print -# -# QDR_DYNAMIC_LOADING = 1~3 -# Configure QDR library to be loaded -# 1: QDR3 -# 2: QDR2-GYRO -# 3: QDR2-DWT -# -# - - -###################################### -# # -# Default Configuration # -# (GNSS only,QDR Disabled) # -# # -# For QDR enablement, comment # -# this section and enabled # -# either QDR3 OR # -# QDR2-DWT OR QDR2-Gyro related # -# configuration section in below. # -# # -###################################### - -SENSOR_SERVICE = accel -SENSOR_PROVIDER = native -SENSOR_RATE = 100 -SENSOR_SAMPLES = 1 - -SENSOR_SERVICE = gyro -SENSOR_PROVIDER = native -SENSOR_RATE = 100 -SENSOR_SAMPLES = 1 - -SENSOR_SERVICE = vehicle_gear -SENSOR_PROVIDER = native -SENSOR_RATE = 100 -SENSOR_SAMPLES = 1 - - -###################################### -# # -# QDR3 Configuration # -# # -# For QDR3, # -# comment default configuration above# -# and # -# uncomment below configuration # -# settings. # -# # -###################################### -# -#SENSOR_SERVICE = accel -#SENSOR_PROVIDER = native -#SENSOR_RATE = 10 -#SENSOR_SAMPLES = 10 -# -#SENSOR_SERVICE = vehicle_speed -#SENSOR_PROVIDER = native -#SENSOR_RATE = 100 -#SENSOR_SAMPLES = 1 -# -#SENSOR_SERVICE = gyro -#SENSOR_PROVIDER = native -#SENSOR_RATE = 10 -#SENSOR_SAMPLES = 10 -# -#SENSOR_SERVICE = vehicle_gear -#SENSOR_PROVIDER = native -#SENSOR_RATE = 100 -#SENSOR_SAMPLES = 1 -# -# -##Enable/disable sensor data flashback feature -#QDR_FLASHBACK_ENABLED = 0 -##Configure QDR library to be loaded 1: QDR3 2: QDR2-GYRO 3: QDR2-DWS -#QDR_DYNAMIC_LOADING = 1 -##Enable/disable sensor data batching feature -#QDR_BATCHING_ENABLED = 2 -##Reporting offset before PPS boundary -#QDR_REPORTING_OFFSET = 0 -##Sensor dispatch threshold declaration -#QDR_SENSDISPATCH_MS = 30 -# - -###################################### -# # -# QDR2-DWT Configuration # -# # -# For QDR2-DWT, # -# comment default configuration above# -# and # -# uncomment below configuration # -# settings. # -# # -###################################### -# -#SENSOR_SERVICE = vehicle_speed -#SENSOR_PROVIDER = native -#SENSOR_RATE = 100 -#SENSOR_SAMPLES = 1 -#SENSOR_STATISTIC_ENABLED = 3 -#SENSOR_STATISTIC_PRINT_COUNT = 50 -# -#SENSOR_SERVICE = vehicle_dws -#SENSOR_PROVIDER = native -#SENSOR_RATE = 100 -#SENSOR_SAMPLES = 1 -#SENSOR_STATISTIC_ENABLED = 3 -#SENSOR_STATISTIC_PRINT_COUNT = 50 -# -#SENSOR_SERVICE = vehicle_gear -#SENSOR_PROVIDER = native -#SENSOR_RATE = 100 -#SENSOR_SAMPLES = 1 -#SENSOR_STATISTIC_ENABLED = 3 -#SENSOR_STATISTIC_PRINT_COUNT = 50 -# -#GNSS_POS_STATISTIC_ENABLED = 3 -#GNSS_POS_STATISTIC_PRNTCNT = 10 -#GNSS_MSR_STATISTIC_ENABLED = 3 -#GNSS_MSR_STATISTIC_PRNTCNT = 10 -# -##Enable/disable sensor data flashback feature -#QDR_FLASHBACK_ENABLED = 0 -##Configure QDR library to be loaded 1: QDR3 2: QDR2-GYRO 3: QDR2-DWS -#QDR_DYNAMIC_LOADING = 3 -##Enable/disable sensor data batching feature -#QDR_BATCHING_ENABLED = 0 -##Reporting offset before PPS boundary -#QDR_REPORTING_OFFSET = 0 -##Sensor dispatch threshold declaration -#QDR_SENSDISPATCH_MS = 30 -##QDR_ENABLE_QG shall be set as 1 -#QDR_ENABLE_QG = 1 -##Select Wheel set (E.g.: Front two wheels, Rear two wheels OR All four wheels) -##To be used for differential wheel tick OR speed service. -##This configuration is applicable when QDR_CAN_TYPE configured as -##ODO_DWS(3) or ODO_DWT(2). -##Value "0": Use Front two wheels -##Value "1": Use Rear two wheels -##Value "2": Use All four wheels -#QG_DRIVE_WHEEL_FW_RW_AW = 2 -##Max Wheel tick value above which wheel tick rolls over -##This configuration is applicable when QDR_CAN_TYPE configured as ODO_DWT(2) -#QG_DWT_MAX_WHEEL_TICK_COUNT = 255.0 -##Configure Wheel constant for DWT based below equation -##(2 * pi * WHEEL_RADIUS / Pulses Per revolution) -##This configuration is applicable when QDR_CAN_TYPE configured as ODO_DWT(2) -#QG_DWT_WHEEL_CONSTANT = 0.044 - -###################################### -# # -# QDR2-GYRO Configuration # -# # -# For QDR2-GYRO, # -# comment default configuration above# -# and # -# uncomment below configuration # -# settings. # -# # -###################################### -# -#SENSOR_SERVICE = vehicle_speed -#SENSOR_PROVIDER = native -#SENSOR_RATE = 100 -#SENSOR_SAMPLES = 1 -# -#SENSOR_SERVICE = vehicle_gyro -#SENSOR_PROVIDER = native -#SENSOR_RATE = 100 -#SENSOR_SAMPLES = 1 -# -#SENSOR_SERVICE = vehicle_gear -#SENSOR_PROVIDER = native -#SENSOR_RATE = 100 -#SENSOR_SAMPLES = 1 -# -##Enable/disable sensor data flashback feature -#QDR_FLASHBACK_ENABLED = 0 -##Configure QDR library to be loaded 1: QDR3 2: QDR2-GYRO 3: QDR2-DWS -#QDR_DYNAMIC_LOADING = 2 -##Enable/disable sensor data batching feature -#QDR_BATCHING_ENABLED = 0 -##Reporting offset before PPS boundary -#QDR_REPORTING_OFFSET = 0 -##Sensor dispatch threshold declaration -#QDR_SENSDISPATCH_MS = 30 -# diff --git a/gps/etc/flp.conf b/gps/etc/flp.conf index 19851b5e..fc2469c2 100644 --- a/gps/etc/flp.conf +++ b/gps/etc/flp.conf @@ -12,7 +12,7 @@ # of batched locations that can be allocated, # which is limited by memory. The default # batch size defined as 20 as below. -BATCH_SIZE=40 +BATCH_SIZE=30 ################################### # FLP OUTDOOR TRIP BATCH SIZE diff --git a/gps/etc/gnss_antenna_info.conf b/gps/etc/gnss_antenna_info.conf new file mode 100644 index 00000000..79a2aefb --- /dev/null +++ b/gps/etc/gnss_antenna_info.conf @@ -0,0 +1,134 @@ +################################### +##### 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 = 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/gps/etc/gps.conf b/gps/etc/gps.conf index d18ef65e..644eec9a 100644 --- a/gps/etc/gps.conf +++ b/gps/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 @@ -19,7 +12,7 @@ XTRA_CA_PATH=/usr/lib/ssl-1.1/certs # DEBUG LEVELS: 0 - none, 1 - Error, 2 - Warning, 3 - Info # 4 - Debug, 5 - Verbose # If DEBUG_LEVEL is commented, Android's logging levels will be used -DEBUG_LEVEL = 2 +DEBUG_LEVEL = 3 # Intermediate position report, 1=enable, 0=disable INTERMEDIATE_POS=0 @@ -81,10 +74,12 @@ CAPABILITIES=0x17 #################################### # 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 #################################### @@ -124,6 +119,15 @@ NMEA_PROVIDER=0 # 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 +188,6 @@ AGPS_CONFIG_INJECT = 1 # 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 ##################################### @@ -344,3 +338,45 @@ D_LEVEL_MAX_CAPACITY = 300 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/gps/etc/izat.conf b/gps/etc/izat.conf deleted file mode 100644 index f6fda33b..00000000 --- a/gps/etc/izat.conf +++ /dev/null @@ -1,275 +0,0 @@ -######################################### -# Log verbosity control for izat modules -######################################### -# OFF = 0, ERROR = 1, WARNING = 2, INFO = 3, DEBUG = 4, VERBOSE = 5 -IZAT_DEBUG_LEVEL = 2 - -################################################## -# Select WIFI Wait Timeout value in seconds for SUPL -################################################## -WIFI_WAIT_TIMEOUT_SELECT = 0 - -################################################## -# Time interval of injecting SRN scan data to modem -# time in seconds. -# Note: recommended value is between 1-5 sec -################################################## -LPPE_SRN_DATA_SCAN_INJECT_TIME=2 - -################################ -# NLP Settings -################################ -# NLP_MODE 1: OSNLP Only, 2: QNP Only, 3: Combo, 4: QNP preferred -# For Automotive products, please use NLP_MODE = 4 only. -# NLP_TOLERANCE_TIME_FIRST: Time in ms used in Combo mode -# to determine how much Tolerance for first position -# NLP_TOLERANCE_TIME_AFTER: Time in ms used in Combo mode -# to determine how much Tolerance for positions after first -# NLP_THRESHOLD: Sets how many failures needed before -# switching preferred NLP in Combo mode -# NLP_ACCURACY_MULTIPLE: Determines how far off the accuracy -# must be, in multiples, between two NLP location reports to -# be considered much worse accuracy. Used in switching logic -# NLP COMBO MODE USES QNP WITH NO EULA CONSENT: Determines -# whether or not to still send network location requests to -# QNP when the EULA is not consented to by the user. QNP can -# still return ZPP locations or injected locations even -# without EULA consent, but the uncertainty can be high. -# QNP preferred mode prefers QNP when there is EULA consent, -# otherwise OSNLP is used. -NLP_MODE = 1 -NLP_MODE_EMERGENCY = 2 -NLP_TOLERANCE_TIME_FIRST = 5000 -NLP_TOLERANCE_TIME_AFTER = 20000 -NLP_THRESHOLD = 3 -NLP_ACCURACY_MULTIPLE = 2 -NLP_COMBO_MODE_USES_QNP_WITH_NO_EULA_CONSENT = 1 - -######################################### -# NLP PACKAGE SETTINGS -######################################### -# OSNLP_PACKAGE: name of default NLP package -OSNLP_PACKAGE = com.google.android.gms -# REGION_OSNLP_PACKAGE: -# This value will be used as alternative -# for particular region where default NLP is not functional. -#REGION_OSNLP_PACKAGE = - -################################### -# GEOFENCE SERVICES -################################### -# If set to one of the defined values below, it will override -# the responsiveness for geofence services, which implements -# the Proximity Alert API. If not set to a value defined below, -# which is default, it will not override the responsivness. -# The geofence HAL API is unaffected by this value. -# GEOFENCE_SERVICES_RESPONSIVENESS_OVERRIDE Values: -# 1: LOW responsiveness -# 2: MEDIUM responsiveness -# 3: HIGH responsiveness -GEOFENCE_SERVICES_RESPONSIVENESS_OVERRIDE = 0 - -##################################### -#GTP Opt-In app -##################################### - -#GTP privacy policy version url -#https support is required -GTP_PRIVACY_VERSION_URL = https://info.izatcloud.net/privacy/version.html - -#GTP privacy policy version download retry interval -#unit is second. default is 86400 -GTP_PRIVACY_RETRY_INTERVAL = 86400 - -##################################### -# IZAT PREMIUM FEATURE SETTINGS -##################################### -#Possible states of a feature: -#DISABLED -#BASIC -#PREMIUM - -#GTP_MODE valid modes: -# DISABLED -# LEGACY_WWAN -# SDK (WWAN not available for Modems before LocTech 10.0) -GTP_MODE=DISABLED - -#GTP_WAA valid modes: -# DISABLED -# BASIC -GTP_WAA=DISABLED - -#SAP valid modes: -# DISABLED -# BASIC -# PREMIUM -# MODEM_DEFAULT -SAP=MODEM_DEFAULT - -#FREE_WIFI_SCAN_INJECT valid modes: -#DISABLED -#BASIC -FREE_WIFI_SCAN_INJECT=BASIC - -#SUPL_WIFI valid modes: -#DISABLED -#BASIC -SUPL_WIFI=BASIC - -#WIFI_SUPPLICANT_INFO valid modes: -#DISABLED -#BASIC -WIFI_SUPPLICANT_INFO=BASIC - -##################################### -# Location process launcher settings -##################################### - -# DO NOT MODIFY -# Modifying below attributes without -# caution can have serious implications. - -#Values for PROCESS_STATE: -# ENABLED -# DISABLED - -#Values for LOW_RAM_TARGETS: -# ENABLED -# DISABLED -# Property to enable/disable processes for low ram targets. Uses ro.config.low_ram property -# to identify low ram targets. - -#PROCESS_NAME -# Name of the executable file. - -#FEATURE MASKS: -# GTP-WIFI 0X03 -# GTP-MP-CELL 0xc00 -# GTP-WAA 0x100 -# SAP 0Xc0 -# ODCPI 0x1000 -# FREE_WIFI_SCAN_INJECT 0x2000 -# SUPL_WIFI 0x4000 -# WIFI_SUPPLICANT_INFO 0x8000 - -#Values for PLATFORMS can be: -#1. Any valid values obtained from ro.board.platform separated by single space. For example: msm8960 msm8226 -#2. 'all' or 'all exclude' -> for All platforms -#3. 'all exclude XXXX' -> All platforms exclude XXXX. For example: all exclude msm8937 - -#Values for SOC_IDS can be: -#1. Any valid values obtained from soc_id node separated by single space. For example: 339 386 436 -## soc_id value can be obtained from any one of below node: -## - /sys/devices/soc0/soc_id -## - /sys/devices/system/soc/soc0/id -#2. 'all' or 'all exclude' -> for All soc id's -#3. 'all exclude XXXX' -> All soc id's exclude XXXX. For example: all exclude 339 386 - -#Values for BASEBAND can be: -#1. Any valid values obtained from ro.baseband separated by single space. For example: sglte sglte2 -#2. 'all' or 'all exclude' -> for all basebands -#3. 'all exclude XXXX' -> All basebands exclude XXXX. For example: all exclude sglte -PROCESS_NAME=lowi-server -PROCESS_ARGUMENT= -PROCESS_STATE=ENABLED -PROCESS_GROUPS=gps wifi inet oem_2901 -PREMIUM_FEATURE=0 -IZAT_FEATURE_MASK=0xf303 -PLATFORMS=all -SOC_IDS=all -BASEBAND=all -LOW_RAM_TARGETS=DISABLED -HARDWARE_TYPE=all -VENDOR_ENHANCED_PROCESS=0 - -PROCESS_NAME=xtwifi-inet-agent -PROCESS_ARGUMENT= -PROCESS_STATE=DISABLED -PROCESS_GROUPS=inet gps -PREMIUM_FEATURE=1 -IZAT_FEATURE_MASK=0xc03 -PLATFORMS=all -SOC_IDS=all exclude 386 436 -BASEBAND=all -LOW_RAM_TARGETS=DISABLED -HARDWARE_TYPE=all -VENDOR_ENHANCED_PROCESS=1 - -PROCESS_NAME=xtwifi-client -PROCESS_ARGUMENT= -PROCESS_STATE=DISABLED -PROCESS_GROUPS=wifi inet gps system oem_2904 -PREMIUM_FEATURE=1 -IZAT_FEATURE_MASK=0xd03 -PLATFORMS=all -SOC_IDS=all exclude 386 436 -BASEBAND=all -LOW_RAM_TARGETS=DISABLED -HARDWARE_TYPE=all -VENDOR_ENHANCED_PROCESS=1 - -PROCESS_NAME=slim_daemon -PROCESS_ARGUMENT= -PROCESS_STATE=ENABLED -PROCESS_GROUPS=gps oem_2901 can plugdev diag sensors -PREMIUM_FEATURE=1 -IZAT_FEATURE_MASK=0xf0 -PLATFORMS=all -SOC_IDS=all exclude 386 436 -BASEBAND=all -LOW_RAM_TARGETS=DISABLED -HARDWARE_TYPE=all -VENDOR_ENHANCED_PROCESS=1 - -PROCESS_NAME=xtra-daemon -PROCESS_ARGUMENT= -PROCESS_STATE=ENABLED -PROCESS_GROUPS=inet gps system -PREMIUM_FEATURE=0 -IZAT_FEATURE_MASK=0 -PLATFORMS=all -SOC_IDS=all -BASEBAND=all -LOW_RAM_TARGETS=ENABLED -HARDWARE_TYPE=all -VENDOR_ENHANCED_PROCESS=0 - -######################################## -# Engine Service which host DRE module # -# To enable DRE engine service, change # -# PROCESS_STATE=ENABLED # -######################################## -PROCESS_NAME=engine-service -PROCESS_ARGUMENT=DRE-INT libloc_epDr.so -PROCESS_STATE=DISABLED -PROCESS_GROUPS=gps diag inet qwes oem_2901 system -PREMIUM_FEATURE=0 -IZAT_FEATURE_MASK=0 -PLATFORMS=all -SOC_IDS=all -BASEBAND=all -LOW_RAM_TARGETS=DISABLED -HARDWARE_TYPE=all -VENDOR_ENHANCED_PROCESS=1 - -######################################## -# Engine Service which host PPE module # -# To enable PPE engine service, change # -# PROCESS_STATE=ENABLED # -# and update process arugements # -# with PPE library name # -#PROCESS_ARGUMENT=PPE libepsimulator.so# -######################################## -PROCESS_NAME=engine-service -PROCESS_ARGUMENT=PPE libepsimulator.so -PROCESS_STATE=DISABLED -PROCESS_GROUPS=gps diag inet oem_2901 -PREMIUM_FEATURE=0 -IZAT_FEATURE_MASK=0 -PLATFORMS=all -SOC_IDS=all -BASEBAND=all -LOW_RAM_TARGETS=DISABLED -HARDWARE_TYPE=all -VENDOR_ENHANCED_PROCESS=1 diff --git a/gps/etc/lowi.conf b/gps/etc/lowi.conf deleted file mode 100644 index ed8b09ab..00000000 --- a/gps/etc/lowi.conf +++ /dev/null @@ -1,27 +0,0 @@ -#*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* -# -# LOWI Config file -# -# GENERAL DESCRIPTION -# This file contains the config params for LOWI -# -# Copyright (c) 2019 Qualcomm Technologies, Inc. -# All Rights Reserved. -# Confidential and Proprietary - Qualcomm Technologies, Inc. -# -# 2012-2013 Qualcomm Atheros, Inc. -# All Rights Reserved. -# Qualcomm Atheros Confidential and Proprietary. -# -# Export of this technology or software is regulated by the U.S. Government. -# Diversion contrary to U.S. law prohibited. -#=============================================================================*/ - -# X86 ONLY - UBUNTU: -# Copy this file in the same directory where the executable is - -# Log level -# EL_LOG_OFF = 0, EL_ERROR = 1, EL_WARNING = 2, EL_INFO = 3, EL_DEBUG = 4, EL_VERBOSE = 5, EL_LOG_ALL = 100 -LOWI_LOG_LEVEL = 2 -LOWI_USE_LOWI_LP = 0 - diff --git a/gps/etc/sap.conf b/gps/etc/sap.conf deleted file mode 100644 index 0f717941..00000000 --- a/gps/etc/sap.conf +++ /dev/null @@ -1,161 +0,0 @@ -################################ -# Sensor Settings -################################ -#The following parameters are optional. -#Internal defaults support MEMS sensors -#native to most handset devices. -#Device specific sensor characterization -#for improved performance is possible as -#described in SAP application notes. -#GYRO_BIAS_RANDOM_WALK= -#ACCEL_RANDOM_WALK_SPECTRAL_DENSITY= -#ANGLE_RANDOM_WALK_SPECTRAL_DENSITY= -#RATE_RANDOM_WALK_SPECTRAL_DENSITY= -#VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY= - -# Sensor Sampling Rate Parameters for Low-Data Rate Filter (should be greater than 0) -# used in loc_eng_reinit -SENSOR_ACCEL_BATCHES_PER_SEC=2 -SENSOR_ACCEL_SAMPLES_PER_BATCH=5 -SENSOR_GYRO_BATCHES_PER_SEC=2 -SENSOR_GYRO_SAMPLES_PER_BATCH=5 -# Sensor Sampling Rate Parameters for High-Data Rate Filter (should be greater than 0) -SENSOR_ACCEL_BATCHES_PER_SEC_HIGH=4 -SENSOR_ACCEL_SAMPLES_PER_BATCH_HIGH=25 -SENSOR_GYRO_BATCHES_PER_SEC_HIGH=4 -SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH=25 - -# Sensor Control Mode (0=AUTO, 1=FORCE_ON, 2=MODEM_DEFAULT) -# used in loc_eng_reinit -SENSOR_CONTROL_MODE=2 - -# Bit mask used to define which sensor algorithms are used. -# Setting each bit has the following definition: -# 0x1 - DISABLE_INS_POSITIONING_FILTER -# 0x0 - ENABLE_INS_POSITIONING_FILTER -SENSOR_ALGORITHM_CONFIG_MASK=0x0 - -#Vehicle Network Provider configuration - -#Service configuration strings -#The number before colon in VN_X items defines version of the format of the rest of the string -#VN_ACCEL_CFG=0:5 -#VN_GYRO_CFG=0:5.5 -#VN_ODOMETRY_CFG=0:2,4.5 - -################################################ -# QDR3 configurations # -################################################ -VN_SPEED_CFG=1:131,5,8,1,2,3,1,1,9,2,14,2 -VN_GEAR_CFG=1:422,20,4,0,4,1,9,0,1,2,3,4,5,6,7,8 - -################################################ -# QDR2-Gyro configurations # -################################################ -#VN_GYRO_CFG=1:555,0,1,0,0,0,0,-6.5,6.6066,-6.5,-1.00,2,6.607,6.6068,0,0,16,0.0002,0,16,0.0002,0,16,0.0002 -#VN_SPEED_CFG=1:555,0,0,1,2,1,0.01,0,56,8,48,8 -#VN_GEAR_CFG=1:555,16,4,0,1,1,9,0,1,2,3,4,5,6,7,8 - -################################################ -# QDR2-DWT configurations # -################################################ -#VN_SPEED_CFG=1:555,22,1,2,1,1,1,0,8,8,23,1,2,0,1,0,8,8,23,1 -#VN_GEAR_CFG=1:555,12,4,16,14,16,8,1,2,3,4,5,6,7,8 -#VN_DWS_CFG=1:555,0,0,1,3,1,1,0,0,8,0,0,8,8,0,0,16,8,0,0,24,8,0,0 -#VN_GYRO_CFG=1:555,40,16,1.0,40,16,1.0,40,16,1.0 - -##################################################################################### -# VNW service batching configuration strings # -# VNW provider will initialize default type as Time based batching # -# Each service batch value is configured to be 100 # -# VN_ACCEL_CFG_BATCH_VALUE will be treated as time in Ms if VN_CFG_BATCH_TYPE # -# is set to time based batching # -# VN_ACCEL_CFG_BATCH_VALUE will be treated as sample count if VN_CFG_BATCH_TYPE # -# is set to count based batching # -# Uncomment and update batch time /sample count as per selected batching type # -##################################################################################### -# Batching type -# 1 - Time based (default) -# 2 - Count based -#VN_CFG_BATCH_TYPE=1 - -#Vehicle Accel batching value, it can either accept time in milli seconds or sample count -#VN_ACCEL_CFG_BATCH_VALUE=100 - -#Vehicle Gyro batching value, it can either accept time in milli seconds or sample count -#VN_GYRO_CFG_BATCH_VALUE=100 - -#Vehicle Odo batching value, it can either accept time in milli seconds or sample count -#VN_ODOMETRY_CFG_BATCH_VALUE=100 - -#Vehicle Speed batching value, it can either accept time in milli seconds or sample count -#VN_SPEED_CFG_BATCH_VALUE=100 - -#Vehicle Gear batching value, it can either accept time in milli seconds or sample count -#VN_GEAR_CFG_BATCH_VALUE=100 - -#Vehicle DWS batching value, it can either accept time in milli seconds or sample count -#VN_DWS_CFG_BATCH_VALUE=100 -#################################################################################### - -#Procesors clock ratio: AP and CAN bus microcontroller -################################################ -# QDR3 configurations # -################################################ -VN_PROC_CLOCK_RATIO=1.0 - -################################################ -# QDR2-DWT OR QDR2-Gyro configurations # -################################################ -#VN_PROC_CLOCK_RATIO = 1.0 - -# Time source used by Sensor HAL -# Setting this value controls accuracy of location sensor services. -# 0 - Unknown -# 1 - CLOCK_BOOTTIME -# 2 - CLOCK_MONOTONIC -# 3 - CLOCK_REALTIME -# 4 - CLOCK_BOOTTIME using Alarm timer interface -NDK_PROVIDER_TIME_SOURCE=1 - -# Sensor Batching Configuration -# 0 - Time based -# 1 - Fixed count based -# 2 - Variable count based -COUNT_BASED_BATCHING=1 -SYNC_ONCE=0 - -#Sensor HAL Provider Configuration HAL Library name including path -################################################ -# # -# Configuration for BMI 160 Sensor # -# # -################################################ -SENSOR_TYPE=2 -SENSOR_HAL_LIB_PATH=/usr/lib/libbmi160sensors.so.1 - -################################################ -# # -# Configuration for ASM330 Sensor # -# # -################################################ -#SENSOR_TYPE=1 -#SENSOR_HAL_LIB_PATH=/usr/lib/libasm330sensors.so.1 - - -################################################ -# # -# Configuration for IAM20680 Sensor # -# # -################################################ -#SENSOR_TYPE=3 -#SENSOR_HAL_LIB_PATH=/usr/lib/libiam20680sensors.so.1 - - -################################################ -# # -# Configuration for SMI130 Sensor # -# # -################################################ -#SENSOR_TYPE=4 -#SENSOR_HAL_LIB_PATH=/usr/lib/libsmi130sensors.so.1 diff --git a/gps/etc/seccomp_policy/gnss@2.0-base.policy b/gps/etc/seccomp_policy/gnss@2.0-base.policy new file mode 100644 index 00000000..7b930374 --- /dev/null +++ b/gps/etc/seccomp_policy/gnss@2.0-base.policy @@ -0,0 +1,95 @@ +#******************************************************************************* +# 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 + diff --git a/gps/etc/seccomp_policy/gnss@2.0-xtra-daemon.policy b/gps/etc/seccomp_policy/gnss@2.0-xtra-daemon.policy new file mode 100644 index 00000000..19b67bbc --- /dev/null +++ b/gps/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/gps/etc/seccomp_policy/gnss@2.0-xtwifi-client.policy b/gps/etc/seccomp_policy/gnss@2.0-xtwifi-client.policy new file mode 100644 index 00000000..17df31a8 --- /dev/null +++ b/gps/etc/seccomp_policy/gnss@2.0-xtwifi-client.policy @@ -0,0 +1,45 @@ + +#******************************************************************************* +# 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: arg1 == _IOC(_IOC_NONE || arg1 == _IOC(_IOC_READ || arg1 == VSOC_MAYBE_SEND_INTERRUPT_TO_HOST +lseek: 1 +madvise: 1 +mkdirat: 1 +pwrite64: 1 + +timerfd_create: 1 +timerfd_settime: 1 +epoll_create1: 1 +epoll_pwait: 1 +epoll_ctl: 1 diff --git a/gps/etc/seccomp_policy/gnss@2.0-xtwifi-inet-agent.policy b/gps/etc/seccomp_policy/gnss@2.0-xtwifi-inet-agent.policy new file mode 100644 index 00000000..00df6c72 --- /dev/null +++ b/gps/etc/seccomp_policy/gnss@2.0-xtwifi-inet-agent.policy @@ -0,0 +1,33 @@ + +#******************************************************************************* +# 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 diff --git a/gps/etc/xtwifi.conf b/gps/etc/xtwifi.conf deleted file mode 100644 index 5d7df9e2..00000000 --- a/gps/etc/xtwifi.conf +++ /dev/null @@ -1,78 +0,0 @@ -#GTP AP Project client core config file -# -#GENERAL DESCRIPTION -#This is used by client core -# -#Copyright (c) 2012-2014 Qualcomm Atheros, Inc. -#All Rights Reserved. -#Qualcomm Atheros Confidential and Proprietary. -# -#Copyright (c) 2017 Qualcomm Technologies, Inc. -#All Rights Reserved. -#Confidential and Proprietary - Qualcomm Technologies, Inc. - -############################################################################## -# non-IOT devices configuration items # -# For non-IOT devices, configure below configuration items # -# according to the app note: 80-NK218-1 and remove the configuration items # -# in section of "IOT devices configuration items". # -############################################################################## - -# ASN URI v2 to be used by some GTP AP modules that -# need to run with ASN URI v2 protocol. -XT_SERVER_ROOT_URL = https://gtp1.izatcloud.net:443/uds/v2 - -# ASN URI v3 to be used by GTP AP modules that -# can support ASN URI v3 protocol. -XT_SERVER_ROOT_URL_V3 = https://gtp1.izatcloud.net:443/uds/v3 - -# size, in bytes, of the cache on device -SIZE_BYTE_TOTAL_CACHE = 5000000 - -############################################################################## -# IOT devices configuration items # -# For IOT devices, configure below configuration items # -# according to the app note and remove the configuration items in section of # -# "non-IOT devices configuration items". # -############################################################################## - -# ASN URI v3 to be used by GTP AP modules that -# can support ASN URI v3 protocol. -# XT_SERVER_ROOT_URL_V3 = https://gtpma1.izatcloud.net:443/uds/v3 - -# 3: Wi-Fi APDB injection via Izat SDK. GTP server is not accessed -# for any GTP requests, instead notification is sent to Izat SDK. -# WiFi crowdsourcing module is disabled. -# 4: Wi-Fi APDB injection via Izat SDK. GTP server is not accessed -# for any GTP requests, instead notification is sent to Izat SDK. -# WiFi crowdsourcing module is active, also accessed via Izat SDK. -# GTP_AP_MODE = 4 - -# 1: MP cell features relies on GTP AP for either download or upload -# 0: MP cell features does not rely on GTP AP -# GTP_AP_NEEDED_BY_MP_CELL = 1 - -############################################################################## -# Configuration items applicable to all devices # -############################################################################## - -# Log verbosity control for most of the GTP WiFi system, including native and -# Java componenets -# OFF = 0, ERROR = 1, WARNING = 2, INFO = 3, DEBUG = 4, VERBOSE = 5, ALL = 100 -DEBUG_GLOBAL_LOG_LEVEL = 2 - -# this is used at the server side to distinguish uploads from different maker/model -# default "Qualcomm" -OEM_ID_IN_REQUEST_TO_SERVER = "Qualcomm" - -# this is used at the server side to distinguish uploads from different maker/model -# default "UNKNOWN" -MODEL_ID_IN_REQUEST_TO_SERVER = "UNKNOWN" - -############################################################################## -# Qualcomm Network Location Provider config # -############################################################################## - -# Accuracy Threshold for NLP position. Position exceeds thsi threshold will be filtered out. -# Default is 25000 meters. -LARGE_ACCURACY_THRESHOLD_TO_FILTER_NLP_POSITION = 25000 diff --git a/gps/geofence/Android.bp b/gps/geofence/Android.bp new file mode 100644 index 00000000..4801eb8a --- /dev/null +++ b/gps/geofence/Android.bp @@ -0,0 +1,31 @@ + + +cc_library_shared { + + name: "libgeofencing", + vendor: true, + + sanitize: GNSS_SANITIZE, + + 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/gps/geofence/Android.mk b/gps/geofence/Android.mk deleted file mode 100644 index 133d4080..00000000 --- a/gps/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/gps/geofence/GeofenceAdapter.cpp b/gps/geofence/GeofenceAdapter.cpp index d51bd047..f024e3f5 100644 --- a/gps/geofence/GeofenceAdapter.cpp +++ b/gps/geofence/GeofenceAdapter.cpp @@ -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 @@ -37,12 +37,8 @@ using namespace loc_core; GeofenceAdapter::GeofenceAdapter() : LocAdapterBase(0, - LocContext::getLocContext( - NULL, - NULL, - LocContext::mLocationHalName, - false), - true /*isMaster*/) + LocContext::getLocContext(LocContext::mLocationHalName), + true /*isMaster*/) { LOC_LOGD("%s]: Constructor", __func__); } @@ -167,7 +163,7 @@ GeofenceAdapter::restartGeofences() if (LOCATION_ERROR_SUCCESS == err) { if (true == object.paused) { mLocApi->pauseGeofence(data.hwId, object.key.id, - new LocApiResponse(*getContext(), [] (LocationError /*err*/) {})); + new LocApiResponse(*getContext(), [] (LocationError err ) {})); } saveGeofenceItem(object.key.client, object.key.id, data.hwId, options, info); } @@ -245,7 +241,7 @@ GeofenceAdapter::addGeofencesCommand(LocationAPI* client, size_t count, Geofence mApi.addToCallQueue(new LocApiResponse(*mAdapter.getContext(), [&mAdapter = mAdapter, mCount = mCount, mClient = mClient, mOptions = mOptions, mInfos = mInfos, mIds = mIds, &mApi = mApi, - errs, i] (LocationError /*err*/) { + errs, i] (LocationError err ) { mApi.addGeofence(mIds[i], mOptions[i], mInfos[i], new LocApiResponseData(*mAdapter.getContext(), [&mAdapter = mAdapter, mOptions = mOptions, mClient = mClient, @@ -346,7 +342,7 @@ GeofenceAdapter::removeGeofencesCommand(LocationAPI* client, size_t count, uint3 for (size_t i=0; i < mCount; ++i) { mApi.addToCallQueue(new LocApiResponse(*mAdapter.getContext(), [&mAdapter = mAdapter, mCount = mCount, mClient = mClient, mIds = mIds, - &mApi = mApi, errs, i] (LocationError /*err*/) { + &mApi = mApi, errs, i] (LocationError err ) { uint32_t hwId = 0; errs[i] = mAdapter.getHwIdFromClient(mClient, mIds[i], hwId); if (LOCATION_ERROR_SUCCESS == errs[i]) { @@ -422,7 +418,7 @@ GeofenceAdapter::pauseGeofencesCommand(LocationAPI* client, size_t count, uint32 for (size_t i=0; i < mCount; ++i) { mApi.addToCallQueue(new LocApiResponse(*mAdapter.getContext(), [&mAdapter = mAdapter, mCount = mCount, mClient = mClient, mIds = mIds, - &mApi = mApi, errs, i] (LocationError /*err*/) { + &mApi = mApi, errs, i] (LocationError err ) { uint32_t hwId = 0; errs[i] = mAdapter.getHwIdFromClient(mClient, mIds[i], hwId); if (LOCATION_ERROR_SUCCESS == errs[i]) { @@ -497,7 +493,7 @@ GeofenceAdapter::resumeGeofencesCommand(LocationAPI* client, size_t count, uint3 for (size_t i=0; i < mCount; ++i) { mApi.addToCallQueue(new LocApiResponse(*mAdapter.getContext(), [&mAdapter = mAdapter, mCount = mCount, mClient = mClient, mIds = mIds, - &mApi = mApi, errs, i] (LocationError /*err*/) { + &mApi = mApi, errs, i] (LocationError err ) { uint32_t hwId = 0; errs[i] = mAdapter.getHwIdFromClient(mClient, mIds[i], hwId); if (LOCATION_ERROR_SUCCESS == errs[i]) { @@ -580,7 +576,7 @@ GeofenceAdapter::modifyGeofencesCommand(LocationAPI* client, size_t count, uint3 } else { mApi.addToCallQueue(new LocApiResponse(*mAdapter.getContext(), [&mAdapter = mAdapter, mCount = mCount, mClient = mClient, mIds = mIds, - &mApi = mApi, mOptions = mOptions, errs, i] (LocationError /*err*/) { + &mApi = mApi, mOptions = mOptions, errs, i] (LocationError err ) { uint32_t hwId = 0; errs[i] = mAdapter.getHwIdFromClient(mClient, mIds[i], hwId); if (LOCATION_ERROR_SUCCESS == errs[i]) { diff --git a/gps/gnss/Agps.h b/gps/gnss/Agps.h index d559377a..6b43bf57 100644 --- a/gps/gnss/Agps.h +++ b/gps/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 #include +using namespace loc_util; + /* ATL callback function pointers * Passed in by Adapter to AgpsManager */ typedef std::function #include #include +#include +#include #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,18 @@ static void agpsOpenResultCb (bool isSuccess, AGpsExtType agpsType, const char* AGpsBearerType bearerType, void* userDataPtr); static void agpsCloseResultCb (bool isSuccess, AGpsExtType agpsType, void* userDataPtr); +typedef const CdfwInterface* (*getCdfwInterface)(); + + 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 +96,7 @@ GnssAdapter::GnssAdapter() : mAfwControlId(0), mNmeaMask(0), mGnssSvIdConfig(), + mGnssSeconaryBandConfig(), mGnssSvTypeConfig(), mGnssSvTypeConfigCb(nullptr), mLocConfigInfo{}, @@ -102,7 +121,13 @@ GnssAdapter::GnssAdapter() : 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) { LOC_LOGD("%s]: Constructor %p", __func__, this); mLocPositionMode.mode = LOC_POSITION_MODE_INVALID; @@ -179,6 +204,7 @@ GnssAdapter::convertOptions(LocPosMode& out, const TrackingOptions& trackingOpti 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. @@ -203,8 +229,7 @@ GnssAdapter::checkAndSetSPEToRunforNHz(TrackingOptions & out) { 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); @@ -241,24 +266,57 @@ GnssAdapter::convertLocation(Location& out, const UlpLocation& ulpLocation, 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 @@ -408,6 +466,8 @@ GnssAdapter::convertLocationInfo(GnssLocationInfoNotification& out, 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, @@ -420,6 +480,8 @@ GnssAdapter::convertLocationInfo(GnssLocationInfoNotification& out, 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++) { @@ -435,10 +497,6 @@ GnssAdapter::convertLocationInfo(GnssLocationInfoNotification& out, 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 & @@ -453,46 +511,88 @@ GnssAdapter::convertLocationInfo(GnssLocationInfoNotification& out, 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. @@ -532,10 +632,26 @@ GnssAdapter::convertLocationInfo(GnssLocationInfoNotification& out, 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; + } } - - inline uint32_t GnssAdapter::convertSuplVersion(const GnssConfigSuplVersion suplVersion) { @@ -552,22 +668,6 @@ GnssAdapter::convertSuplVersion(const GnssConfigSuplVersion suplVersion) } } -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) { @@ -719,7 +819,9 @@ GnssAdapter::setSuplHostServer(const char* server, int port, LocServerType type) } 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) { @@ -794,12 +896,9 @@ GnssAdapter::setConfig() 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 = @@ -830,8 +929,6 @@ GnssAdapter::setConfig() 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) { @@ -895,7 +992,10 @@ GnssAdapter::setConfig() sapConf.SENSOR_GYRO_BATCHES_PER_SEC_HIGH, sapConf.SENSOR_ALGORITHM_CONFIG_MASK); } )); - + // deal with Measurement Corrections + if (true == mIsMeasCorrInterfaceOpen) { + initMeasCorr(true); + } } std::vector GnssAdapter::gnssUpdateConfig(const std::string& oldMoServerUrl, @@ -1008,7 +1108,7 @@ std::vector GnssAdapter::gnssUpdateConfig(const std::string& oldM 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; } @@ -1084,11 +1184,23 @@ std::vector GnssAdapter::gnssUpdateConfig(const std::string& oldM } 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; @@ -1134,19 +1246,26 @@ GnssAdapter::gnssUpdateConfigCommand(GnssConfig config) 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 { @@ -1163,6 +1282,7 @@ GnssAdapter::gnssUpdateConfigCommand(GnssConfig config) sessionIds.assign(mIds, mIds + mCount); std::vector 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; @@ -1216,8 +1336,8 @@ GnssAdapter::gnssUpdateConfigCommand(GnssConfig config) 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) { @@ -1262,6 +1382,14 @@ GnssAdapter::gnssUpdateConfigCommand(GnssConfig config) 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 errs) { @@ -1278,6 +1406,10 @@ GnssAdapter::gnssUpdateConfigCommand(GnssConfig config) configCollectiveResponse->returnToSender(errsList); })); + + if (needSuspendResume == true) { + mAdapter.restartSessions(); + } } }; @@ -1311,11 +1443,10 @@ void GnssAdapter::gnssSvIdConfigUpdate() { LOC_LOGd("blacklist bds 0x%" PRIx64 ", glo 0x%" PRIx64 - ", qzss 0x%" PRIx64 ", gal 0x%" PRIx64 ", sbas 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.sbasBlacklistSvMask, mGnssSvIdConfig.navicBlacklistSvMask); // Now set required blacklisted SVs mLocApi->setBlacklistSv(mGnssSvIdConfig); } @@ -1337,15 +1468,28 @@ LocationError GnssAdapter::gnssSvIdConfigUpdateSync() { LOC_LOGd("blacklist bds 0x%" PRIx64 ", glo 0x%" PRIx64 - ", qzss 0x%" PRIx64 ", gal 0x%" PRIx64 ", sbas 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.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) { @@ -1392,21 +1536,27 @@ GnssAdapter::gnssGetConfigCommand(GnssConfigFlagsMask configMask) { mAdapter(adapter), mApi(api), mConfigMask(configMask), - mIds(ids), - mCount(count) {} + mIds(nullptr), + mCount(count) { + 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()) { @@ -1496,7 +1646,7 @@ GnssAdapter::gnssGetConfigCommand(GnssConfigFlagsMask configMask) { } if (mConfigMask & GNSS_CONFIG_FLAGS_ROBUST_LOCATION_BIT) { uint32_t sessionId = *(mIds+index); - LocApiResponse* locApiResponse = + LocApiResponse* locApiResponse = new LocApiResponse(*mAdapter.getContext(), [this, sessionId] (LocationError err) { mAdapter.reportResponse(err, sessionId);}); @@ -1508,6 +1658,35 @@ GnssAdapter::gnssGetConfigCommand(GnssConfigFlagsMask configMask) { } } + 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; @@ -1537,6 +1716,7 @@ GnssAdapter::convertToGnssSvIdConfig( 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 @@ -1565,24 +1745,27 @@ GnssAdapter::convertToGnssSvIdConfig( // SBAS does not support enable/disable whole constellation // so do not set up svTypeMask for SBAS svMaskPtr = &config.sbasBlacklistSvMask; - // SBAS currently has two ranges - // range of SV id: 120 to 158 and 183 to 191 + // 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 of 183 to 191 + // 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 to 158 + // 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; } @@ -1608,16 +1791,17 @@ GnssAdapter::convertToGnssSvIdConfig( 0 != config.bdsBlacklistSvMask || 0 != config.galBlacklistSvMask || 0 != config.qzssBlacklistSvMask || - 0 != config.sbasBlacklistSvMask) { + 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, - config.bdsBlacklistSvMask, config.gloBlacklistSvMask, - config.qzssBlacklistSvMask, config.galBlacklistSvMask, - config.sbasBlacklistSvMask); + ", 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; } @@ -1647,9 +1831,26 @@ void GnssAdapter::convertFromGnssSvIdConfig( GNSS_SV_CONFIG_QZSS_INITIAL_SV_ID, GNSS_SV_TYPE_QZSS); } 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( - svConfig.sbasBlacklistSvMask, blacklistedSvIds, + 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); } } @@ -1725,10 +1926,10 @@ void GnssAdapter::reportGnssSvIdConfig(const GnssSvIdConfig& svIdConfig) 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, + "qzss 0x%" PRIx64 ", gal 0x%" PRIx64 ", sbas 0x%" PRIx64 ", navic 0x%" PRIx64, svIdConfig.bdsBlacklistSvMask, svIdConfig.gloBlacklistSvMask, svIdConfig.qzssBlacklistSvMask, svIdConfig.galBlacklistSvMask, - svIdConfig.sbasBlacklistSvMask); + svIdConfig.sbasBlacklistSvMask, svIdConfig.navicBlacklistSvMask); // use 0 session id to indicate that receiver does not yet care about session id mControlCallbacks.gnssConfigCb(0, config); } else { @@ -1792,10 +1993,16 @@ GnssAdapter::gnssSvTypeConfigUpdate(bool sendReset) mGnssSvTypeConfig.enabledSvTypesMask, sendReset); LOC_LOGd("blacklist bds 0x%" PRIx64 ", glo 0x%" PRIx64 - ", qzss 0x%" PRIx64 ", gal 0x%" PRIx64 ", sbas 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.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)) { @@ -1820,6 +2027,9 @@ GnssAdapter::gnssSvTypeConfigUpdate(bool sendReset) 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 @@ -1935,10 +2145,19 @@ void GnssAdapter::reportGnssSvTypeConfig(const GnssSvTypeConfig& config) } 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 @@ -1961,14 +2180,23 @@ GnssAdapter::gnssDeleteAidingDataCommand(GnssAidingData& data) 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); + } } }; @@ -2009,35 +2237,38 @@ GnssAdapter::injectLocationCommand(double latitude, double longitude, float accu 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 @@ -2309,6 +2540,9 @@ GnssAdapter::handleEngineUpEvent() mAdapter.gnssSvIdConfigUpdate(); mAdapter.gnssSvTypeConfigUpdate(); mAdapter.updateSystemPowerState(mAdapter.getSystemPowerState()); + mAdapter.gnssSecondaryBandConfigUpdate(); + // start CDFW service + mAdapter.initCDFWService(); // restart sessions mAdapter.restartSessions(true); for (auto msg: mAdapter.mPendingMsgs) { @@ -2335,6 +2569,22 @@ GnssAdapter::restartSessions(bool modemSSR) // 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(); + } + + checkAndRestartSPESession(); +} + +void GnssAdapter::checkAndRestartSPESession() +{ + LOC_LOGD("%s]: ", __func__); + + // SPE will be restarted now, so set this variable to false. + mSPEAlreadyRunningAtHighestInterval = false; + checkAndRestartTimeBasedSession(); for (auto it = mDistanceBasedTrackingSessions.begin(); @@ -2443,7 +2693,8 @@ GnssAdapter::hasCallbacksToStartTracking(LocationAPI* client) 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") @@ -2475,15 +2726,15 @@ GnssAdapter::reportPowerStateIfChanged() } void -GnssAdapter::getPowerStateChangesCommand(void* powerStateCb) +GnssAdapter::getPowerStateChangesCommand(std::function powerStateCb) { LOC_LOGD("%s]: ", __func__); struct MsgReportLocation : public LocMsg { GnssAdapter& mAdapter; - powerStateCallback mPowerStateCb; + std::function mPowerStateCb; inline MsgReportLocation(GnssAdapter& adapter, - powerStateCallback powerStateCb) : + std::function powerStateCb) : LocMsg(), mAdapter(adapter), mPowerStateCb(powerStateCb) {} @@ -2493,7 +2744,7 @@ GnssAdapter::getPowerStateChangesCommand(void* powerStateCb) } }; - sendMsg(new MsgReportLocation(*this, (powerStateCallback)powerStateCb)); + sendMsg(new MsgReportLocation(*this, powerStateCb)); } void @@ -2508,6 +2759,7 @@ GnssAdapter::saveTrackingSession(LocationAPI* client, uint32_t sessionId, mTimeBasedTrackingSessions[key] = options; } reportPowerStateIfChanged(); + checkUpdateDgnssNtrip(false); } void @@ -2524,6 +2776,13 @@ GnssAdapter::eraseTrackingSession(LocationAPI* client, uint32_t sessionId) } } reportPowerStateIfChanged(); + + if (mSendNmeaConsent && mStartDgnssNtripParams.ntripParams.requiresNmeaLocation) { + LOC_LOGd("requiresNmeaLocation"); + mDgnssState &= ~DGNSS_STATE_NO_NMEA_PENDING; + mStartDgnssNtripParams.nmea.clear(); + } + stopDgnssNtrip(); } @@ -2672,6 +2931,8 @@ GnssAdapter::startTimeBasedTrackingMultiplex(LocationAPI* client, uint32_t sessi 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; @@ -2725,12 +2986,12 @@ GnssAdapter::startTimeBasedTracking(LocationAPI* client, uint32_t sessionId, 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 @@ -2759,9 +3020,11 @@ GnssAdapter::updateTracking(LocationAPI* client, uint32_t sessionId, { 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 @@ -3067,7 +3330,6 @@ GnssAdapter::stopTimeBasedTrackingMultiplex(LocationAPI* client, uint32_t id) // else part: no QMI call is made, need to report back to client right away } } - return reportToClientWithNoWait; } @@ -3294,6 +3556,63 @@ GnssAdapter::disableCommand(uint32_t id) } +// 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, @@ -3305,85 +3624,94 @@ GnssAdapter::reportPositionEvent(const UlpLocation& ulpLocation, // 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 @@ -3453,6 +3781,41 @@ GnssAdapter::isFlpClient(LocationCallbacks& locationCallbacks) 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; +} + +// 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, @@ -3465,7 +3828,7 @@ GnssAdapter::reportPosition(const UlpLocation& ulpLocation, if (reportToGnssClient || reportToFlpClient) { GnssLocationInfoNotification locationInfo = {}; convertLocationInfo(locationInfo, locationExtended); - convertLocation(locationInfo.location, ulpLocation, locationExtended, techMask); + convertLocation(locationInfo.location, ulpLocation, locationExtended); for (auto it=mClientData.begin(); it != mClientData.end(); ++it) { if ((reportToFlpClient && isFlpClient(it->second)) || @@ -3503,7 +3866,7 @@ GnssAdapter::reportPosition(const UlpLocation& ulpLocation, // if PACE is enabled if ((true == mLocConfigInfo.paceConfigInfo.isValid) && - (true == mLocConfigInfo.paceConfigInfo.enable)) { + (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) && @@ -3517,8 +3880,8 @@ GnssAdapter::reportPosition(const UlpLocation& ulpLocation, } } - 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) && @@ -3527,14 +3890,24 @@ GnssAdapter::reportPosition(const UlpLocation& ulpLocation, 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); std::vector nmeaArraystr; + int indexOfGGA = -1; loc_nmea_generate_pos(ulpLocation, locationExtended, mLocSystemInfo, - generate_nmea, custom_nmea_gga, nmeaArraystr); + generate_nmea, custom_nmea_gga, nmeaArraystr, indexOfGGA); 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); + } } } @@ -3566,8 +3939,7 @@ GnssAdapter::reportEnginePositions(unsigned int count, convertLocationInfo(locationInfo[i], engLocation->locationExtended); convertLocation(locationInfo[i].location, engLocation->location, - engLocation->locationExtended, - engLocation->location.tech_mask); + engLocation->locationExtended); } } @@ -3807,6 +4179,8 @@ GnssAdapter::reportNmeaEvent(const char* nmea, size_t length) if (false == ret) { // forward NMEA message to upper layer mAdapter.reportNmea(mNmea, mLength); + // DgnssNtrip + mAdapter.reportGGAToNtrip(mNmea); } } }; @@ -3847,15 +4221,15 @@ GnssAdapter::reportDataEvent(const GnssDataNotification& dataNotify, 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); } @@ -4194,6 +4568,9 @@ GnssAdapter::reportGnssMeasurementsEvent(const GnssMeasurements& gnssMeasurement sendMsg(new MsgReportGnssMeasurementData(*this, gnssMeasurements, msInWeek)); } mEngHubProxy->gnssReportSvMeasurement(gnssMeasurements.gnssSvMeasurementSet); + if (mDGnssNeedReport) { + reportDGnssDataUsable(gnssMeasurements.gnssSvMeasurementSet); + } } void @@ -4206,6 +4583,27 @@ GnssAdapter::reportGnssMeasurementData(const GnssMeasurementsNotification& measu } } +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) { @@ -4663,7 +5061,8 @@ void GnssAdapter::dataConnOpenCommand( }; // 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 <= 0 || apnLen > MAX_APN_LEN || + (strlen(apnName) != (unsigned)apnLen)) { LOC_LOGe("%s]: incorrect apnlen length or incorrect apnName", __func__); mAgpsManager.reportAtlClosed(agpsType); } else { @@ -5328,42 +5727,54 @@ GnssAdapter::setPositionAssistedClockEstimatorCommand(bool enable) { 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; + // handle blacklisted SV settings + mGnssSvIdConfig = blacklistSvConfig; + // process blacklist svs info mBlacklistedSvIds.clear(); - convertFromGnssSvIdConfig(svIdConfig, mBlacklistedSvIds); - - // Send blacklist info - mLocApi->setBlacklistSv(mGnssSvIdConfig); - - // Send only enabled constellation config - GnssSvTypeConfig svTypeConfigCopy = {sizeof(GnssSvTypeConfig), 0, 0}; - svTypeConfigCopy.enabledSvTypesMask = mGnssSvTypeConfig.enabledSvTypesMask; + // 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(); @@ -5372,78 +5783,115 @@ uint32_t GnssAdapter::gnssUpdateSvConfigCommand( 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) { - // Clear blacklisting - memset(&mGnssSvIdConfig, 0, sizeof(GnssSvIdConfig)); - mGnssSvIdConfig.size = sizeof(mGnssSvIdConfig); - mBlacklistedSvIds.clear(); - gnssSvIdConfigUpdate(); - - // Reset constellation config, including mGnssSvTypeConfig - // when size is set to 0, upon subsequent modem restart, sv type - // config will not be sent down to modem - gnssSetSvTypeConfig({sizeof(GnssSvTypeConfig), 0, 0}); - - 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; } @@ -5478,6 +5926,13 @@ GnssAdapter::configLeverArmCommand(const LeverArmConfigInfo& configInfo) { mSessionId(sessionId), mConfigInfo(configInfo) {} inline virtual void proc() const { + // save the lever ARM config info for translate 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); } }; @@ -5486,6 +5941,113 @@ GnssAdapter::configLeverArmCommand(const LeverArmConfigInfo& configInfo) { 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, @@ -5495,9 +6057,6 @@ GnssAdapter::configRobustLocation(uint32_t sessionId, mLocConfigInfo.robustLocationConfigInfo.enable = enable; mLocConfigInfo.robustLocationConfigInfo.enableFor911 = enableForE911; - // suspend all tracking sessions so modem can take the E911 configure - suspendSessions(); - LocApiResponse* locApiResponse = nullptr; if (sessionId != 0) { locApiResponse = @@ -5509,9 +6068,6 @@ GnssAdapter::configRobustLocation(uint32_t sessionId, } } mLocApi->configRobustLocation(enable, enableForE911, locApiResponse); - - // resume all tracking sessions after the E911 configure - restartSessions(false); } uint32_t GnssAdapter::configRobustLocationCommand( @@ -5545,6 +6101,86 @@ uint32_t GnssAdapter::configRobustLocationCommand( 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; +} + void GnssAdapter::reportGnssConfigEvent(uint32_t sessionId, const GnssConfig& gnssConfig) { struct MsgReportGnssConfig : public LocMsg { @@ -5623,9 +6259,14 @@ GnssAdapter::initEngHubProxy() { } } - // 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 @@ -5672,7 +6313,7 @@ GnssAdapter::initEngHubProxy() { if (mNHzNeeded != nHzNeeded) { mNHzNeeded = nHzNeeded; - checkAndRestartTimeBasedSession(); + checkAndRestartSPESession(); } }; @@ -5704,3 +6345,327 @@ GnssAdapter::initEngHubProxy() { firstTime = false; return engHubLoadSuccessful; } + +std::vector +GnssAdapter::parseDoublesString(char* dString) { + std::vector 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 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 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)); + } + 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 + + 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("isInSession %d mDgnssState 0x%x", isInSession(), mDgnssState); + + 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) && + params.requiresNmeaLocation == params.requiresNmeaLocation) { + 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() { + mStartDgnssNtripParams.clear(); + mDgnssState &= ~DGNSS_STATE_ENABLE_NTRIP_COMMAND; + mDgnssState |= DGNSS_STATE_NO_NMEA_PENDING; + stopDgnssNtrip(); +} + +void GnssAdapter::checkUpdateDgnssNtrip(bool 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() { + if (mDgnssState & DGNSS_STATE_NTRIP_SESSION_STARTED) { + mDgnssState &= ~DGNSS_STATE_NTRIP_SESSION_STARTED; + mXtraObserver.stopDgnssSource(); + } else { + LOC_LOGd("isInSession %d mDgnssState 0x%x", + isInSession(), mDgnssState); + } +} + +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/gps/gnss/GnssAdapter.h b/gps/gnss/GnssAdapter.h index 48db26b5..20064e60 100644 --- a/gps/gnss/GnssAdapter.h +++ b/gps/gnss/GnssAdapter.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2020, 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,7 @@ #include #include #include +#include #define MAX_URL_LEN 256 #define NMEA_SENTENCE_MAX_LENGTH 200 @@ -46,7 +47,7 @@ #define LOC_NI_NO_RESPONSE_TIME 20 #define LOC_GPS_NI_RESPONSE_IGNORE 4 #define ODCPI_EXPECTED_INJECTION_TIME_MS 10000 -#define IS_SS5_HW_ENABLED (1) +#define DELETE_AIDING_DATA_EXPECTED_TIME_MS 5000 class GnssAdapter; @@ -145,6 +146,7 @@ typedef struct { TuncConfigInfo tuncConfigInfo; PaceConfigInfo paceConfigInfo; RobustLocationConfigInfo robustLocationConfigInfo; + LeverArmConfigInfo leverArmConfigInfo; } LocIntegrationConfigInfo; using namespace loc_core; @@ -157,7 +159,23 @@ typedef std::function GnssEnergyConsumedCallback; -typedef void (*powerStateCallback)(bool on); +typedef void* QDgnssListenerHDL; +typedef std::function 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 GnssAdapter : public LocAdapterBase { @@ -179,7 +197,9 @@ class GnssAdapter : public LocAdapterBase { LocationControlCallbacks mControlCallbacks; uint32_t mAfwControlId; uint32_t mNmeaMask; + uint64_t mPrevNmeaRptTimeNsec; GnssSvIdConfig mGnssSvIdConfig; + GnssSvTypeConfig mGnssSeconaryBandConfig; GnssSvTypeConfig mGnssSvTypeConfig; GnssSvTypeConfigCallback mGnssSvTypeConfigCb; bool mSupportNfwControl; @@ -201,6 +221,19 @@ class GnssAdapter : public LocAdapterBase { 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; @@ -209,6 +242,9 @@ class GnssAdapter : public LocAdapterBase { OdcpiRequestInfo mOdcpiRequest; void odcpiTimerExpire(); + /* ==== DELETEAIDINGDATA =============================================================== */ + int64_t mLastDeleteAidingDataTime; + /* === SystemStatus ===================================================================== */ SystemStatus* mSystemStatus; std::string mServerUrl; @@ -225,13 +261,12 @@ class GnssAdapter : public LocAdapterBase { /* === Misc callback from QMI LOC API ============================================== */ GnssEnergyConsumedCallback mGnssEnergyConsumedCb; - powerStateCallback mPowerStateCb; + std::function 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); static uint16_t getNumSvUsed(uint64_t svUsedIdsMask, @@ -242,6 +277,14 @@ class GnssAdapter : public LocAdapterBase { 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 ========================================================================= */ @@ -259,6 +302,7 @@ public: /* ======== UTILITIES ================================================================== */ void restartSessions(bool modemSSR = false); void checkAndRestartTimeBasedSession(); + void checkAndRestartSPESession(); void suspendSessions(); /* ==== CLIENT ========================================================================= */ @@ -301,13 +345,17 @@ public: 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); - inline bool isSS5HWEnabled() - { return ((mContext != NULL) && (IS_SS5_HW_ENABLED == mContext->mGps_conf.GNSS_DEPLOYMENT)); } + void configMinGpsWeek(uint32_t sessionId, uint16_t minGpsWeek); /* ==== NI ============================================================================= */ /* ======== COMMANDS ====(Called from Client Thread)==================================== */ @@ -326,7 +374,7 @@ public: 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); @@ -356,6 +404,7 @@ public: inline GnssSvTypeConfigCallback gnssGetSvTypeConfigCallback() { return mGnssSvTypeConfigCb; } void setConfig(); + void gnssSecondaryBandConfigUpdate(LocApiResponse* locApiResponse= nullptr); /* ========= AGPS ====================================================================== */ /* ======== COMMANDS ====(Called from Client Thread)==================================== */ @@ -371,11 +420,20 @@ public: 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); /* ========= ODCPI ===================================================================== */ /* ======== COMMANDS ====(Called from Client Thread)==================================== */ @@ -393,6 +451,7 @@ public: virtual bool isInSession() { return !mTimeBasedTrackingSessions.empty(); } void initDefaultAgps(); bool initEngHubProxy(); + void initCDFWService(); void odcpiTimerExpireEvent(); /* ==== REPORTS ======================================================================== */ @@ -435,6 +494,8 @@ public: 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, @@ -449,6 +510,7 @@ public: 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); @@ -469,6 +531,8 @@ public: void reportSvPolynomial(const GnssSvPolynomial &svPolynomial); + std::vector parseDoublesString(char* dString); + void reportGnssAntennaInformation(const antennaInfoCb antennaInfoCallback); /*======== GNSSDEBUG ================================================================*/ bool getDebugReport(GnssDebugReport& report); @@ -484,7 +548,6 @@ public: /*==== 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); @@ -501,6 +564,8 @@ public: static void convertGnssSvIdMaskToList( uint64_t svIdMask, std::vector& 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); @@ -511,10 +576,11 @@ public: /* ==== MISCELLANEOUS ================================================================== */ /* ======== COMMANDS ====(Called from Client Thread)==================================== */ - void getPowerStateChangesCommand(void* powerStateCb); + void getPowerStateChangesCommand(std::function powerStateCb); /* ======== UTILITIES ================================================================== */ void reportPowerStateIfChanged(); - void savePowerStateCallback(powerStateCallback powerStateCb){ mPowerStateCb = powerStateCb; } + void savePowerStateCallback(std::function powerStateCb){ + mPowerStateCb = powerStateCb; } bool getPowerState() { return mPowerOn; } inline PowerStateType getSystemPowerState() { return mSystemPowerState; } @@ -524,10 +590,22 @@ public: void notifyClientOfCachedLocationSystemInfo(LocationAPI* client, const LocationCallbacks& callbacks); 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)) ? - (true) : (false)); + 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/gps/gnss/XtraSystemStatusObserver.cpp b/gps/gnss/XtraSystemStatusObserver.cpp index 0f48a44d..d65622f0 100644 --- a/gps/gnss/XtraSystemStatusObserver.cpp +++ b/gps/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 @@ -65,16 +65,20 @@ public: inline XtraIpcListener(IOsObserver* observer, const MsgTask* msgTask, XtraSystemStatusObserver& xsso) : mSystemStatusObsrvr(observer), mMsgTask(msgTask), mXSSO(xsso) {} - virtual void onReceive(const char* data, uint32_t /*length*/, - const LocIpcRecver* /*recver*/) override { + virtual void onReceive(const char* data, uint32_t length, + const LocIpcRecver* recver) override { #define STRNCMP(str, constStr) strncmp(str, constStr, sizeof(constStr)-1) if (!STRNCMP(data, "ping")) { 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 @@ public: 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 @@ inline bool XtraSystemStatusObserver::onStatusRequested(int32_t xtraStatusUpdate 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/gps/gnss/XtraSystemStatusObserver.h b/gps/gnss/XtraSystemStatusObserver.h index 3a5259d4..56a3a9c1 100644 --- a/gps/gnss/XtraSystemStatusObserver.h +++ b/gps/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 #include #include +#include using namespace std; using namespace loc_util; @@ -40,6 +41,22 @@ using loc_core::IOsObserver; 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 @@ public : 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 @@ private: bool mReqStatusReceived; bool mIsConnectivityStatusKnown; shared_ptr mSender; + string mNtripParamsString; class DelayLocTimer : public LocTimer { LocIpcSender& mSender; diff --git a/gps/gnss/location_gnss.cpp b/gps/gnss/location_gnss.cpp index 4c2120a4..d0978f44 100644 --- a/gps/gnss/location_gnss.cpp +++ b/gps/gnss/location_gnss.cpp @@ -50,7 +50,7 @@ static void gnssUpdateXtraThrottle(const bool enabled); 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); @@ -71,7 +71,7 @@ static void updateConnectionStatus(bool connected, int8_t type, bool roaming = f 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 powerStateCb); static void odcpiInit(const OdcpiRequestCallback& callback, OdcpiPrioritytype priority); static void odcpiInject(const Location& location); @@ -83,12 +83,26 @@ static void updateSystemPowerState(PowerStateType systemPowerState); 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 bool isSS5HWEnabled(); +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 const GnssInterface gGnssInterface = { sizeof(GnssInterface), @@ -132,10 +146,21 @@ static const GnssInterface gGnssInterface = { setConstrainedTunc, setPositionAssistedClockEstimator, gnssUpdateSvConfig, - gnssResetSvConfig, configLeverArm, + measCorrInit, + measCorrSetCorrections, + measCorrClose, + antennaInfoInit, + antennaInfoClose, configRobustLocation, - isSS5HWEnabled, + configMinGpsWeek, + configDeadReckoningEngineParams, + updateNTRIPGGAConsent, + enablePPENtripStream, + disablePPENtripStream, + gnssUpdateSecondaryBandConfig, + gnssGetSecondaryBandConfig, + resetNetworkInfo }; #ifndef DEBUG_X86 @@ -240,7 +265,7 @@ static void disable(uint32_t id) } } -static uint32_t* gnssUpdateConfig(GnssConfig config) +static uint32_t* gnssUpdateConfig(const GnssConfig& config) { if (NULL != gGnssAdapter) { return gGnssAdapter->gnssUpdateConfigCommand(config); @@ -390,7 +415,8 @@ static void nfwInit(const NfwCbInfo& cbInfo) { gGnssAdapter->initNfwCommand(cbInfo); } } -static void getPowerStateChanges(void* powerStateCb) + +static void getPowerStateChanges(std::function powerStateCb) { if (NULL != gGnssAdapter) { gGnssAdapter->getPowerStateChangesCommand(powerStateCb); @@ -410,6 +436,12 @@ static void updateBatteryStatus(bool charging) { } } +static void resetNetworkInfo() { + if (NULL != gGnssAdapter) { + gGnssAdapter->getSystemStatus()->resetNetworkInfo(); + } +} + static void updateSystemPowerState(PowerStateType systemPowerState) { if (NULL != gGnssAdapter) { gGnssAdapter->updateSystemPowerStateCommand(systemPowerState); @@ -433,19 +465,11 @@ static uint32_t setPositionAssistedClockEstimator(bool enable) { } 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; } @@ -459,11 +483,40 @@ static uint32_t configLeverArm(const LeverArmConfigInfo& configInfo){ } } -static bool isSS5HWEnabled() { +static bool measCorrInit(const measCorrSetCapabilitiesCb setCapabilitiesCb) { if (NULL != gGnssAdapter) { - return gGnssAdapter->isSS5HWEnabled(); + return gGnssAdapter->openMeasCorrCommand(setCapabilitiesCb); + } else { + return false; } - 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){ @@ -473,3 +526,57 @@ static uint32_t configRobustLocation(bool enable, bool enableForE911){ 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(); + } +} diff --git a/gps/gps_vendor_product.mk b/gps/gps_vendor_product.mk index 6e938b35..0e578e80 100644 --- a/gps/gps_vendor_product.mk +++ b/gps/gps_vendor_product.mk @@ -1,14 +1,44 @@ # 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 += 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/gps/location/Android.bp b/gps/location/Android.bp new file mode 100644 index 00000000..8532a085 --- /dev/null +++ b/gps/location/Android.bp @@ -0,0 +1,36 @@ + +cc_library_shared { + + name: "liblocation_api", + vendor: true, + + sanitize: GNSS_SANITIZE, + + 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/gps/location/Android.mk b/gps/location/Android.mk deleted file mode 100644 index 2a595414..00000000 --- a/gps/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/gps/location/ILocationAPI.h b/gps/location/ILocationAPI.h index b53e41ea..96076e9e 100644 --- a/gps/location/ILocationAPI.h +++ b/gps/location/ILocationAPI.h @@ -179,7 +179,7 @@ public: 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 @@ public: 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 @@ public: 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. @@ -303,7 +311,7 @@ public: */ virtual uint32_t configLeverArm(const LeverArmConfigInfo& configInfo) = 0; - /** @brief + /** @brief Configure the robust location setting. @param @@ -323,6 +331,38 @@ public: 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; }; #endif /* ILOCATIONAPI_H */ diff --git a/gps/location/LocationAPI.cpp b/gps/location/LocationAPI.cpp index c591223c..06c1e46c 100644 --- a/gps/location/LocationAPI.cpp +++ b/gps/location/LocationAPI.cpp @@ -80,12 +80,25 @@ static const T1* loadLocationInterface(const char* library, const char* name) { } } +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.gnssSvCb != nullptr || + locationCallbacks.gnssNmeaCb != nullptr || + locationCallbacks.gnssDataCb != nullptr || locationCallbacks.gnssMeasurementsCb != nullptr || locationCallbacks.locationSystemInfoCb != nullptr); } @@ -677,7 +690,7 @@ LocationControlAPI::disable(uint32_t id) } uint32_t* -LocationControlAPI::gnssUpdateConfig(GnssConfig config) +LocationControlAPI::gnssUpdateConfig(const GnssConfig& config) { uint32_t* ids = NULL; pthread_mutex_lock(&gDataMutex); @@ -725,12 +738,15 @@ LocationControlAPI::gnssDeleteAidingData(GnssAidingData& data) 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"); } @@ -739,15 +755,13 @@ uint32_t LocationControlAPI::resetConstellationConfig() { 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"); } @@ -814,3 +828,32 @@ uint32_t LocationControlAPI::configRobustLocation(bool enable, bool enableForE91 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; +} diff --git a/gps/location/LocationAPI.h b/gps/location/LocationAPI.h index c949fcc7..21a3a1fa 100644 --- a/gps/location/LocationAPI.h +++ b/gps/location/LocationAPI.h @@ -235,8 +235,11 @@ public: 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 +253,10 @@ public: 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 +269,17 @@ public: 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 +289,26 @@ public: 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. @@ -395,6 +409,39 @@ public: 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; }; #endif /* LOCATIONAPI_H */ diff --git a/gps/location/LocationAPIClientBase.cpp b/gps/location/LocationAPIClientBase.cpp index c2416607..4865a16e 100644 --- a/gps/location/LocationAPIClientBase.cpp +++ b/gps/location/LocationAPIClientBase.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2020 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 @@ -158,6 +158,7 @@ uint32_t LocationAPIControlClient::locAPIGnssUpdateConfig(GnssConfig config) } mRequestQueues[CTRL_REQUEST_CONFIG_UPDATE].push(new GnssUpdateConfigRequest(*this)); retVal = LOCATION_ERROR_SUCCESS; + delete [] idArray; } } } @@ -180,6 +181,7 @@ uint32_t LocationAPIControlClient::locAPIGnssGetConfig(GnssConfigFlagsMask mask) } mRequestQueues[CTRL_REQUEST_CONFIG_GET].push(new GnssGetConfigRequest(*this)); retVal = LOCATION_ERROR_SUCCESS; + delete [] idArray; } } pthread_mutex_unlock(&mMutex); @@ -342,6 +344,7 @@ LocationAPIClientBase::~LocationAPIClientBase() { pthread_mutex_destroy(&mMutex); } + void LocationAPIClientBase::onLocationApiDestroyCompleteCb() { LOC_LOGD("LocationAPIClientBase::onLocationApiDestroyCompleteCb()"); @@ -396,12 +399,11 @@ void LocationAPIClientBase::locAPIUpdateTrackingOptions(TrackingOptions& options if (mLocationAPI) { uint32_t session = 0; session = mRequestQueues[REQUEST_TRACKING].getSession(); - // Not allowing to update the tracking options for stopped session - if (session > 0 && mTracking) { + if (session > 0) { mRequestQueues[REQUEST_TRACKING].push(new UpdateTrackingOptionsRequest(*this)); mLocationAPI->updateTrackingOptions(session, options); } else { - LOC_LOGe("invalid or stopped session: %d.", session); + LOC_LOGE("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__, session); } } pthread_mutex_unlock(&mMutex); @@ -818,7 +820,9 @@ void LocationAPIClientBase::locAPIResumeGeofences( void LocationAPIClientBase::locAPIRemoveAllGeofences() { std::vector 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/gps/location/LocationAPIClientBase.h b/gps/location/LocationAPIClientBase.h index 591775af..ac1ebe61 100644 --- a/gps/location/LocationAPIClientBase.h +++ b/gps/location/LocationAPIClientBase.h @@ -426,10 +426,10 @@ private: public: StopTrackingRequest(LocationAPIClientBase& API) : mAPI(API) {} inline void onResponse(LocationError error, uint32_t id) { + mAPI.onStopTrackingCb(error); if (error == LOCATION_ERROR_SUCCESS) { mAPI.removeSession(id); } - mAPI.onStopTrackingCb(error); } LocationAPIClientBase& mAPI; }; diff --git a/gps/location/LocationDataTypes.h b/gps/location/LocationDataTypes.h index f987c75f..9fc40aff 100644 --- a/gps/location/LocationDataTypes.h +++ b/gps/location/LocationDataTypes.h @@ -34,6 +34,7 @@ #include #include #include +#include #define GNSS_NI_REQUESTOR_MAX (256) #define GNSS_NI_MESSAGE_ID_MAX (2048) @@ -75,14 +76,25 @@ typedef enum { 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 +114,26 @@ typedef enum { 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,40 +153,63 @@ typedef enum { 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 - GNSS_LOCATION_INFO_CONFORMITY_INDEX_BIT = (1<<29), // valid conformity index + // 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), // DR solution status } GnssLocationInfoFlagBits; typedef enum { @@ -229,6 +261,12 @@ typedef enum { 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), } LocationCapabilitiesBits; typedef enum { @@ -253,12 +291,14 @@ typedef enum { } 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; @@ -320,6 +360,9 @@ typedef enum { 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 { @@ -462,6 +505,11 @@ typedef enum { 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; @@ -486,6 +534,15 @@ typedef enum { 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, @@ -503,6 +560,7 @@ typedef enum { 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; @@ -530,7 +588,9 @@ typedef enum { 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; @@ -660,10 +720,12 @@ typedef uint32_t PositioningEngineMask; 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) typedef uint64_t GnssDataMask; typedef enum { @@ -713,11 +775,17 @@ typedef struct { 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; @@ -747,14 +815,18 @@ typedef struct { 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 { @@ -763,6 +835,7 @@ typedef enum { 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; @@ -910,6 +983,18 @@ typedef struct { float pitchUnc; // Uncertainty of Body pitch } 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; @@ -999,6 +1084,16 @@ typedef struct { 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; + typedef struct { uint32_t size; // set to sizeof(GnssLocationInfo) Location location; // basic locaiton info, latitude, longitude, and etc @@ -1026,7 +1121,6 @@ typedef struct { 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,17 +1134,23 @@ typedef struct { // 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) */ + // 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; } GnssLocationInfoNotification; typedef struct { @@ -1096,17 +1196,18 @@ typedef struct { // - For GLONASS: 65 to 96 // - For SBAS: 120 to 158 and 183 to 191 // - For QZSS: 193 to 197 - // - For BDS: 201 to 237 + // - For BDS: 201 to 263 // - For GAL: 301 to 336 - // - For NAVIC: 401 to 41 + // - For NAVIC: 401 to 414 uint16_t svId; - GnssSvType type; // type of SV (GPS, SBAS, GLONASS, QZSS, BEIDOU, GALILEO) + 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 } GnssSv; struct GnssConfigSetAssistanceServer { @@ -1155,9 +1256,57 @@ typedef struct { 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 satCorrections; + bool hasEnvironmentBearing; + float environmentBearingDegrees; + float environmentBearingUncertaintyDegrees; +} GnssMeasurementCorrections; + typedef struct { uint32_t size; // set to sizeof(GnssMeasurementsClock) GnssMeasurementsClockFlagsMask flags; // bitwise OR of GnssMeasurementsClockFlagsBits @@ -1170,6 +1319,9 @@ typedef struct { double driftNsps; double driftUncertaintyNsps; uint32_t hwClockDiscontinuityCount; + GnssMeasurementsSignalType referenceSignalTypeForIsb; + uint64_t elapsedRealTime; // in ns + uint64_t elapsedRealTimeUnc; // in ns } GnssMeasurementsClock; typedef struct { @@ -1215,7 +1367,7 @@ inline bool operator ==(GnssSvIdSource const& left, GnssSvIdSource const& right) } #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 @@ -1240,16 +1392,45 @@ typedef struct { #define GNSS_SV_CONFIG_SBAS_INITIAL_SV_LENGTH 39 #define GNSS_SV_CONFIG_SBAS_INITIAL2_SV_ID 183 uint64_t sbasBlacklistSvMask; -} GnssSvIdConfig; -// Specify the valid mask for robust location configure that -// will be returned via LocConfigGetMinGpsWeekCb when invoking -// getRobustLocationConfig. */ + //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 @@ -1257,24 +1438,57 @@ 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.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) GnssConfigFlagsMask flags; // bitwise OR of GnssConfigFlagsBits to mark which params are valid GnssConfigGpsLock gpsLock; GnssConfigSuplVersion suplVersion; GnssConfigSetAssistanceServer assistanceServer; - GnssConfigLppProfile lppProfile; + GnssConfigLppProfileMask lppProfileMask; GnssConfigLppeControlPlaneMask lppeControlPlaneMask; GnssConfigLppeUserPlaneMask lppeUserPlaneMask; GnssConfigAGlonassPositionProtocolMask aGlonassPositionProtocolMask; @@ -1284,13 +1498,16 @@ struct GnssConfig{ std::vector 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 && @@ -1299,7 +1516,10 @@ struct GnssConfig{ suplModeMask == config.suplModeMask && blacklistedSvIds == config.blacklistedSvIds && emergencyExtensionSeconds == config.emergencyExtensionSeconds && - robustLocationConfig.equals(config.robustLocationConfig)) { + robustLocationConfig.equals(config.robustLocationConfig) && + minGpsWeek == config.minGpsWeek && + minSvElevation == config.minSvElevation && + secondaryBandConfig.equals(config.secondaryBandConfig)) { return true; } return false; @@ -1399,26 +1619,6 @@ struct LocationSystemInfo { 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 parameters related to lever arm struct LeverArmParams { // Offset along the vehicle forward axis @@ -1459,6 +1659,103 @@ struct LeverArmConfigInfo { 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> phaseCenterVariationCorrectionMillimeters; + std::vector> phaseCenterVariationCorrectionUncertaintyMillimeters; + std::vector> signalGainCorrectionDbi; + std::vector> 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; #endif /* LOCATIONDATATYPES_H */ diff --git a/gps/location/location_interface.h b/gps/location/location_interface.h index 019bf09f..53b71415 100644 --- a/gps/location/location_interface.h +++ b/gps/location/location_interface.h @@ -31,6 +31,7 @@ #include #include +#include /* Used for callback to deliver GNSS energy consumed */ /** @fn @@ -62,7 +63,7 @@ struct GnssInterface { 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); @@ -85,18 +86,29 @@ struct GnssInterface { void (*getGnssEnergyConsumed)(GnssEnergyConsumedCallback energyConsumedCb); void (*enableNfwLocationAccess)(bool enable); void (*nfwInit)(const NfwCbInfo& cbInfo); - void (*getPowerStateChanges)(void* powerStateCb); + void (*getPowerStateChanges)(std::function 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); - bool (*isSS5HWEnabled)(); + 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)(); }; struct BatchingInterface { diff --git a/gps/pla/Android.bp b/gps/pla/Android.bp new file mode 100644 index 00000000..5f240eb3 --- /dev/null +++ b/gps/pla/Android.bp @@ -0,0 +1,7 @@ + +cc_library_headers { + + name: "libloc_pla_headers", + export_include_dirs: ["android"], + vendor: true, +} diff --git a/gps/pla/Android.mk b/gps/pla/Android.mk deleted file mode 100644 index bb37f898..00000000 --- a/gps/pla/Android.mk +++ /dev/null @@ -1,30 +0,0 @@ -GNSS_CFLAGS := \ - -Werror \ - -Wno-error=unused-parameter \ - -Wno-error=macro-redefined \ - -Wno-error=reorder \ - -Wno-reorder-ctor \ - -Wno-error=missing-braces \ - -Wno-error=self-assign \ - -Wno-enum-conversion \ - -Wno-error=logical-op-parentheses \ - -Wno-error=null-arithmetic \ - -Wno-error=null-conversion \ - -Wno-error=parentheses-equality \ - -Wno-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/gps/pla/android/loc_pla.h b/gps/pla/android/loc_pla.h index 1b997394..34cb591a 100644 --- a/gps/pla/android/loc_pla.h +++ b/gps/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 @@ -59,6 +59,36 @@ extern "C" { #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/gps/pla/oe/loc_pla.h b/gps/pla/oe/loc_pla.h index 2ab0aaa4..268b6bfa 100644 --- a/gps/pla/oe/loc_pla.h +++ b/gps/pla/oe/loc_pla.h @@ -85,6 +85,10 @@ extern "C" { #include #include #include +#include +#include +#define MAX_COMMAND_STR_LEN (255) +#define BOOT_KPI_FILE "/sys/kernel/debug/bootkpi/kpi_values" #ifndef OFF_TARGET #include #define strlcat g_strlcat @@ -107,6 +111,9 @@ extern "C" { #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 @@ -118,6 +125,49 @@ inline int property_get(const char* key, char* value, const char* default_value) } #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/gps/utils/Android.bp b/gps/utils/Android.bp new file mode 100644 index 00000000..7d43d573 --- /dev/null +++ b/gps/utils/Android.bp @@ -0,0 +1,54 @@ + +cc_library_shared { + + name: "libgps.utils", + vendor: true, + + sanitize: GNSS_SANITIZE, + + //# 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/gps/utils/Android.mk b/gps/utils/Android.mk deleted file mode 100644 index 57d485de..00000000 --- a/gps/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/gps/utils/LocHeap.cpp b/gps/utils/LocHeap.cpp index d667f14f..4d047e4c 100644 --- a/gps/utils/LocHeap.cpp +++ b/gps/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 +namespace loc_util { + class LocHeapNode { friend class LocHeap; @@ -266,6 +268,8 @@ LocRankable* LocHeap::remove(LocRankable& rankable) { return locNode; } +} // namespace loc_util + #ifdef __LOC_UNIT_TEST__ bool LocHeap::checkTree() { return ((NULL == mTree) || mTree->checkNodes()); @@ -274,81 +278,3 @@ uint32_t LocHeap::getTreeSize() { return (NULL == mTree) ? 0 : mTree->getSize(); } #endif - -#ifdef __LOC_DEBUG__ - -#include -#include -#include - -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(&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(*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/gps/utils/LocHeap.h b/gps/utils/LocHeap.h index b491948a..bb62d6b0 100644 --- a/gps/utils/LocHeap.h +++ b/gps/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 #include +namespace loc_util { + // abstract class to be implemented by client to provide a rankable class class LocRankable { public: @@ -93,4 +95,6 @@ public: #endif }; +} // namespace loc_util + #endif //__LOC_HEAP__ diff --git a/gps/utils/LocIpc.cpp b/gps/utils/LocIpc.cpp index 344e4872..746ca87a 100644 --- a/gps/utils/LocIpc.cpp +++ b/gps/utils/LocIpc.cpp @@ -313,7 +313,7 @@ public: 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) { @@ -323,7 +323,7 @@ public: // 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(); @@ -335,8 +335,7 @@ bool LocIpc::startNonBlockingListening(unique_ptr& ipcRecver) { 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(*this, ipcRecver)); } else { LOC_LOGe("ipcRecver is null OR ipcRecver->recvable() is fasle"); return false; @@ -356,10 +355,7 @@ bool LocIpc::startBlockingListening(LocIpcRecver& ipcRecver) { } void LocIpc::stopNonBlockingListening() { - if (mRunnable) { - mRunnable->abort(); - mRunnable = nullptr; - } + mThread.stop(); } void LocIpc::stopBlockingListening(LocIpcRecver& ipcRecver) { @@ -388,15 +384,17 @@ shared_ptr LocIpc::getLocIpcQrtrSender(int service, int instance) return (nullptr == creator) ? nullptr : creator(service, instance); } unique_ptr LocIpc::getLocIpcQrtrRecver(const shared_ptr& listener, - int service, int instance) { - typedef unique_ptr (*creator_t)(const shared_ptr&, int, int); + int service, int instance, + const shared_ptr& watcher) { + typedef unique_ptr (*creator_t)(const shared_ptr&, int, int, + const shared_ptr& 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 LocIpc::getLocIpcInetTcpSender(const char* serverName, int32_t port) { return make_shared(serverName, port); @@ -417,7 +415,13 @@ pair, unique_ptr> typedef pair, unique_ptr> (*creator_t)(const shared_ptr&, 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, unique_ptr>(nullptr, nullptr) : creator(listener, instance); diff --git a/gps/utils/LocIpc.h b/gps/utils/LocIpc.h index e13bd5c9..b2586e61 100644 --- a/gps/utils/LocIpc.h +++ b/gps/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 #include #include +#include +#include #include using namespace std; namespace loc_util { - class LocIpcRecver; class LocIpcSender; -class LocIpcRunnable; class ILocIpcListener { protected: @@ -56,10 +56,39 @@ public: virtual void onReceive(const char* data, uint32_t len, const LocIpcRecver* recver) = 0; }; +class LocIpcQrtrWatcher { + const unordered_set mServicesToWatch; + unordered_set mClientsToWatch; + mutex mMutex; + inline bool isInWatch(const unordered_set& idsToWatch, int id) { + return idsToWatch.find(id) != idsToWatch.end(); + } +protected: + inline virtual ~LocIpcQrtrWatcher() {} + inline LocIpcQrtrWatcher(unordered_set 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 lock(mMutex); + return isInWatch(mClientsToWatch, nodeId); + } + inline void addClientToWatch(int nodeId) { + lock_guard 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& getServicesToWatch() { return mServicesToWatch; } +}; class LocIpc { public: - inline LocIpc() : mRunnable(nullptr) {} + inline LocIpc() = default; inline virtual ~LocIpc() { stopNonBlockingListening(); } @@ -82,9 +111,16 @@ public: static unique_ptr getLocIpcInetTcpRecver(const shared_ptr& listener, const char* serverName, int32_t port); + inline static unique_ptr + getLocIpcQrtrRecver(const shared_ptr& listener, + int service, int instance) { + const shared_ptr qrtrWatcher = nullptr; + return getLocIpcQrtrRecver(listener, service, instance, qrtrWatcher); + } static unique_ptr getLocIpcQrtrRecver(const shared_ptr& listener, - int service, int instance); + int service, int instance, + const shared_ptr& qrtrWatcher); static pair, unique_ptr> getLocIpcQmiLocServiceSenderRecverPair(const shared_ptr& listener, @@ -114,7 +150,6 @@ public: private: LocThread mThread; - LocIpcRunnable *mRunnable; }; /* this is only when client needs to implement Sender / Recver that are not already provided by @@ -127,14 +162,14 @@ protected: 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); } - virtual unique_ptr getRecver(const shared_ptr& /*listener*/) { + virtual unique_ptr getRecver(const shared_ptr& listener) { return nullptr; } + inline virtual void copyDestAddrFrom(const LocIpcSender& otherSender) {} }; class LocIpcRecver { diff --git a/gps/utils/LocLoggerBase.h b/gps/utils/LocLoggerBase.h new file mode 100644 index 00000000..867b6e2d --- /dev/null +++ b/gps/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/gps/utils/LocSharedLock.h b/gps/utils/LocSharedLock.h index a7af35ed..1ef2c574 100644 --- a/gps/utils/LocSharedLock.h +++ b/gps/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 @@ inline int32_t android_atomic_dec(volatile int32_t *addr) volatile std::atomic_int_least32_t* a = (volatile std::atomic_int_least32_t*)addr; return std::atomic_fetch_sub_explicit(a, 1, std::memory_order_release); } - #endif /* FEATURE_EXTERNAL_AP */ - // This is a utility created for use cases such that there are more than + +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 @@ public: inline void unlock() { pthread_mutex_unlock(&mMutex); } }; +} //namespace loc_util + #endif //__LOC_SHARED_LOCK__ diff --git a/gps/utils/LocThread.cpp b/gps/utils/LocThread.cpp index 568a6bb3..3cac1f97 100644 --- a/gps/utils/LocThread.cpp +++ b/gps/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 #include #include -#include +#include +#include #include +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 mRunnable; + thread mThread; + LocThreadDelegate(const string tName, shared_ptr 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 runnable = mRunnable.lock(); + if (nullptr != runnable) { + runnable->interrupt(); + } + } + inline static LocThreadDelegate* create(const char* tName, shared_ptr 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 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 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 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 @@ bool LocThread::start(tCreate creator, const char* threadName, LocRunnable* runn } void LocThread::stop() { - if (mThread) { - mThread->stop(); - mThread = NULL; + if (nullptr != mThread) { + delete mThread; + mThread = nullptr; } } -#ifdef __LOC_DEBUG__ - -#include -#include -#include - -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/gps/utils/LocThread.h b/gps/utils/LocThread.h index 2a65d8fa..c7ece872 100644 --- a/gps/utils/LocThread.h +++ b/gps/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 -#include +#include + +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 @@ public: // 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 @@ class LocThread { 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 @@ public: // 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 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/gps/utils/LocTimer.cpp b/gps/utils/LocTimer.cpp index 93775d06..915cf540 100644 --- a/gps/utils/LocTimer.cpp +++ b/gps/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 @@ public: 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 @@ public: // 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 @@ public: // 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 @@ LocTimerContainer* LocTimerContainer::get(bool wakeOnExpire) { 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 @@ inline 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 @@ LocTimerDelegate* LocTimerContainer::popIfOutRanks(LocTimerDelegate& timer) { 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(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 @@ void LocTimerPollTask::removePoll(LocTimerContainer& timerContainer) { // 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 @@ public: } }; +} // 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 @@ void loc_timer_stop(void*& handle) 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(&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/gps/utils/LocTimer.h b/gps/utils/LocTimer.h index abc7f645..c883de22 100644 --- a/gps/utils/LocTimer.h +++ b/gps/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 #include +namespace loc_util { + // opaque class to provide service implementation. class LocTimerDelegate; class LocSharedLock; @@ -71,4 +73,6 @@ public: virtual void timeOutCallback() = 0; }; +} // namespace loc_util + #endif //__LOC_DELAY_H__ diff --git a/gps/utils/LogBuffer.cpp b/gps/utils/LogBuffer.cpp index 1bb6f0fc..c280c82d 100644 --- a/gps/utils/LogBuffer.cpp +++ b/gps/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 +#ifdef USE_GLIB +#include +#endif +#ifdef LOG_TAG +#undef LOG_TAG +#endif #define LOG_TAG "LocSvc_LogBuffer" namespace loc_util { @@ -131,7 +136,7 @@ void LogBuffer::flush() { 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::registerSignalHandler() { 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/gps/utils/Makefile.am b/gps/utils/Makefile.am index 72c78722..ada504c5 100644 --- a/gps/utils/Makefile.am +++ b/gps/utils/Makefile.am @@ -31,7 +31,8 @@ libgps_utils_la_h_sources = \ 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/gps/utils/MsgTask.cpp b/gps/utils/MsgTask.cpp index 0a978ed0..6ef689a4 100644 --- a/gps/utils/MsgTask.cpp +++ b/gps/utils/MsgTask.cpp @@ -36,41 +36,33 @@ #include #include +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(mQ)); } void MsgTask::sendMsg(const LocMsg* msg) const { @@ -82,12 +74,27 @@ void MsgTask::sendMsg(const LocMsg* msg) const { } } -void MsgTask::prerun() { +void MsgTask::sendMsg(const std::function runnable) const { + struct RunMsg : public LocMsg { + const std::function mRunnable; + public: + inline RunMsg(const std::function runnable) : mRunnable(runnable) {} + ~RunMsg() = default; + inline virtual void proc() const override { mRunnable(); } + }; + sendMsg(new RunMsg(runnable)); +} + +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 MsgTask::run() { +bool MTRunnable::run() { LocMsg* msg; msq_q_err_type result = msg_q_rcv((void*)mQ, (void **)&msg); if (eMSG_Q_SUCCESS != result) { @@ -104,3 +111,10 @@ bool MsgTask::run() { return true; } + +MTRunnable::~MTRunnable() { + msg_q_flush((void*)mQ); + msg_q_destroy((void**)&mQ); +} + +} // namespace loc_util diff --git a/gps/utils/MsgTask.h b/gps/utils/MsgTask.h index 9eb1f567..a8cce9e0 100644 --- a/gps/utils/MsgTask.h +++ b/gps/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 #include +namespace loc_util { + struct LocMsg { inline LocMsg() {} inline virtual ~LocMsg() {} @@ -38,30 +41,16 @@ struct LocMsg { 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 runnable) const; }; +} // + #endif //__MSG_TASK__ diff --git a/gps/utils/gps_extended_c.h b/gps/utils/gps_extended_c.h index fcda385f..8e47ef77 100644 --- a/gps/utils/gps_extended_c.h +++ b/gps/utils/gps_extended_c.h @@ -115,6 +115,9 @@ typedef uint32_t LocPosTechMask; #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 @@ typedef enum { 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 { @@ -403,7 +410,13 @@ typedef uint64_t GpsLocationExtendedFlags; #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 +#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 +#define GPS_LOCATION_EXTENDED_HAS_UPPER_TRIANGLE_FULL_COV_MATRIX 0x800000000000 +#define GPS_LOCATION_EXTENDED_HAS_DR_SOLUTION_STATUS_MASK 0x1000000000000 typedef uint32_t LocNavSolutionMask; /* Bitmask to specify whether SBAS ionospheric correction is used */ @@ -422,6 +435,8 @@ typedef uint32_t LocNavSolutionMask; #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 */ @@ -462,7 +477,7 @@ typedef uint32_t GnssAdditionalSystemInfoMask; #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 @@ -475,6 +490,8 @@ typedef uint32_t GnssAdditionalSystemInfoMask; #define setSvMask(mask, svIdOneBase) \ if (svFitsMask(mask, svIdOneBase)) mask |= (1ULL << ((svIdOneBase) - 1)) +#define isValInRangeInclusive(val, min, max) ((val) >= (min) && (val) <= (max)) + typedef enum { LOC_RELIABILITY_NOT_SET = 0, LOC_RELIABILITY_VERY_LOW = 1, @@ -640,7 +657,6 @@ typedef uint16_t GnssSvPolyStatusMaskValidity; #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*/ @@ -654,7 +670,7 @@ typedef struct { * - For GLONASS: 65 to 96 * - For SBAS: 120 to 158 and 183 to 191 * - For QZSS: 193 to 197 - * - For BDS: 201 to 237 + * - For BDS: 201 to 263 * - For GAL: 301 to 336 * - For NAVIC: 401 to 414 */ uint16_t gnssSvId; @@ -684,7 +700,7 @@ typedef struct { float carrierPhasAmbiguity; } GpsMeasUsageInfo; - +#define COV_MATRIX_SIZE 12 /** Represents gps location extended. */ typedef struct { /** set to sizeof(GpsLocationExtended) */ @@ -819,11 +835,38 @@ typedef struct { /** If DGNSS is used, DGNSS data age in milli-seconds */ uint32_t dgnssDataAgeMsec; - /* When robust location is enabled, this field + /** 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; } GpsLocationExtended; enum loc_sess_status { @@ -969,38 +1012,38 @@ enum loc_api_adapter_event_index { LOC_API_ADAPTER_EVENT_MAX }; -#define LOC_API_ADAPTER_BIT_PARSED_POSITION_REPORT (1< gnssAntennaInformations); + /* Constructs for interaction with loc_net_iface library */ typedef void (*LocAgpsOpenResultCb)(bool isSuccess, AGpsExtType agpsType, const char* apn, AGpsBearerType bearerType, void* userDataPtr); diff --git a/gps/utils/loc_cfg.cpp b/gps/utils/loc_cfg.cpp index db0225be..2a89966b 100644 --- a/gps/utils/loc_cfg.cpp +++ b/gps/utils/loc_cfg.cpp @@ -89,6 +89,9 @@ const char LOC_PATH_SAP_CONF[] = LOC_PATH_SAP_CONF_STR; 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 @@ RETURN VALUE 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 @@ int loc_set_config_entry(const loc_param_s_type* config_entry, loc_param_v_type* 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 @@ SIDE EFFECTS 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; @@ -267,7 +273,7 @@ int loc_fill_conf_item(char* input_buf, 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 @@ int loc_fill_conf_item(char* input_buf, } /*=========================================================================== -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 @@ RETURN VALUE 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 @@ int loc_read_conf_r(FILE *conf_fp, const loc_param_s_type* config_table, uint32_ } } - 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 @@ err: } /*=========================================================================== -FUNCTION loc_udpate_conf +FUNCTION loc_udpate_conf_long DESCRIPTION Parses the passed in buffer for configuration items, and update the table @@ -370,8 +376,9 @@ RETURN VALUE 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 @@ int loc_update_conf(const char* conf_data, int32_t length, 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 @@ int loc_update_conf(const char* conf_data, int32_t length, } /*=========================================================================== -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 @@ RETURN VALUE 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 @@ void loc_read_conf(const char* conf_file_name, const loc_param_s_type* config_ta { 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(); } /*============================================================================= @@ -652,7 +661,8 @@ int loc_read_process_conf(const char* conf_file_name, uint32_t * process_count_p } //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; } @@ -662,9 +672,15 @@ int loc_read_process_conf(const char* conf_file_name, uint32_t * process_count_p } 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) { +#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."\ @@ -965,7 +981,7 @@ int loc_read_process_conf(const char* conf_file_name, uint32_t * process_count_p 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/gps/utils/loc_cfg.h b/gps/utils/loc_cfg.h index 5c77dc64..e87d632b 100644 --- a/gps/utils/loc_cfg.h +++ b/gps/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 @@ extern "C" { *============================================================================*/ 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_SAP_CONF[]; 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/gps/utils/loc_gps.h b/gps/utils/loc_gps.h index eae7383e..90541c44 100644 --- a/gps/utils/loc_gps.h +++ b/gps/utils/loc_gps.h @@ -106,6 +106,8 @@ typedef uint16_t LocGpsLocationFlags; #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 @@ typedef struct { /** 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/gps/utils/loc_log.cpp b/gps/utils/loc_log.cpp index 5bb96b8c..21106837 100644 --- a/gps/utils/loc_log.cpp +++ b/gps/utils/loc_log.cpp @@ -38,8 +38,13 @@ #include "msg_q.h" #include #include "LogBuffer.h" - +#include +#include +#include +#include +#include #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,11 +57,17 @@ const char EXIT_TAG[] = "Exiting"; 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; +/* tag base logging control map*/ +static std::unordered_map tag_level_map; +static bool tag_map_inited = false; + /* returns the least signification bit that is set in the mask Param mask - bit mask. @@ -217,3 +228,55 @@ void log_buffer_insert(char *str, unsigned long buf_size, int level) 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/gps/utils/loc_misc_utils.cpp b/gps/utils/loc_misc_utils.cpp index d674ec51..43856c64 100644 --- a/gps/utils/loc_misc_utils.cpp +++ b/gps/utils/loc_misc_utils.cpp @@ -30,11 +30,19 @@ #define LOG_TAG "LocSvc_misc_utils" #include #include +#include #include +#include #include #include #include +#include +#include +#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 @@ int loc_util_split_string(char *raw_string, char **split_strings_ptr, 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)) { @@ -149,9 +159,193 @@ 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 deltaNED[3]; + + // gps_pos_lla = imu_pos_lla + Cbn*la_b .* [1/geo.Rn; 1/(geo.Re*geo.cL); -1]; + Matrix_MxV(cnb, leverArm, deltaNED); + + // NED to lla conversion + lla[0] = lla[0] + deltaNED[0] / rn; + lla[1] = lla[1] + deltaNED[1] / (re * cl); + lla[2] = lla[2] - deltaNED[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/gps/utils/loc_misc_utils.h b/gps/utils/loc_misc_utils.h index 5e9b11ef..2335e57f 100644 --- a/gps/utils/loc_misc_utils.h +++ b/gps/utils/loc_misc_utils.h @@ -28,6 +28,7 @@ */ #ifndef _LOC_MISC_UTILS_H_ #define _LOC_MISC_UTILS_H_ +#include #include #include #include @@ -142,6 +143,59 @@ SIDE EFFECTS ===========================================================================*/ 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 @@ -204,4 +258,64 @@ static string loc_prim_arr_to_string(T* arr, uint32_t size, bool decIfTrue = tru 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/gps/utils/loc_nmea.cpp b/gps/utils/loc_nmea.cpp index 3f28f04c..237910cb 100644 --- a/gps/utils/loc_nmea.cpp +++ b/gps/utils/loc_nmea.cpp @@ -39,6 +39,7 @@ #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 @@ -140,7 +141,8 @@ typedef struct loc_sv_cache_info_s 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; @@ -462,7 +464,7 @@ static loc_nmea_sv_meta* loc_nmea_sv_meta_init(loc_nmea_sv_meta& sv_meta, sv_meta.talker[0] = 'G'; sv_meta.talker[1] = 'Q'; sv_meta.mask = sv_cache_info.qzss_used_mask; - // QZSS SV ids are from 193-197. So keep svIdOffset 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; switch (signalType) { @@ -486,7 +488,10 @@ static loc_nmea_sv_meta* loc_nmea_sv_meta_init(loc_nmea_sv_meta& sv_meta, sv_meta.systemId = SYSTEM_ID_BDS; switch (signalType) { case GNSS_SIGNAL_BEIDOU_B1I: - sv_meta.svCount = sv_cache_info.bds_b1_count; + 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; @@ -497,7 +502,8 @@ static loc_nmea_sv_meta* loc_nmea_sv_meta_init(loc_nmea_sv_meta& sv_meta, 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; switch (signalType) { case GNSS_SIGNAL_NAVIC_L5: @@ -819,7 +825,7 @@ static void loc_nmea_generate_GSV(const GnssSvNotification &svNotify, if (sv_meta_p->svType == svNotify.gnssSvs[svNumber - 1].type && sv_meta_p->signalId == convert_signalType_to_signalId(signalType)) { - length = snprintf(pMarker, lengthRemaining, ",%02d,%02d,%03d,", + 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 @@ -1077,17 +1083,6 @@ static void loc_nmea_get_fix_quality(const UlpLocation & location, 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; } @@ -1291,10 +1286,12 @@ void loc_nmea_generate_pos(const UlpLocation &location, const LocationSystemInfo &systemInfo, unsigned char generate_nmea, bool custom_gga_fix_quality, - std::vector &nmeaArraystr) + std::vector &nmeaArraystr, + int& indexOfGGA) { ENTRY_LOG(); + indexOfGGA = -1; LocGpsUtcTime utcPosTimestamp = 0; bool inLsTransition = false; @@ -1873,7 +1870,6 @@ void loc_nmea_generate_pos(const UlpLocation &location, length = loc_nmea_put_checksum(sentence_GNS, sizeof(sentence_GNS)); - // ------------------- // ------$--GGA------- // ------------------- @@ -2047,7 +2043,7 @@ void loc_nmea_generate_pos(const UlpLocation &location, } // ------$--GGA------- nmeaArraystr.push_back(sentence_GGA); - + indexOfGGA = static_cast(nmeaArraystr.size() - 1); } //Send blank NMEA reports for non-final fixes else { @@ -2106,17 +2102,9 @@ void loc_nmea_generate_sv(const GnssSvNotification &svNotify, loc_sv_cache_info sv_cache_info = {}; //Count GPS SVs for saparating GPS from GLONASS and throw others - for(uint32_t svOffset = 0; svOffset < svNotify.count; svOffset++) { + for (uint32_t svOffset = 0; svOffset < svNotify.count; svOffset++) { if (GNSS_SV_TYPE_GPS == 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[svOffset].gnssSvOptionsMask & - GNSS_SV_OPTIONS_USED_IN_FIX_BIT)) - { - setSvMask(sv_cache_info.gps_used_mask, svNotify.gnssSvs[svOffset].svId); - } 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) { @@ -2129,14 +2117,6 @@ void loc_nmea_generate_sv(const GnssSvNotification &svNotify, } 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[svOffset].gnssSvOptionsMask & - GNSS_SV_OPTIONS_USED_IN_FIX_BIT)) - { - setSvMask(sv_cache_info.glo_used_mask, svNotify.gnssSvs[svOffset].svId); - } if (GNSS_SIGNAL_GLONASS_G2 == svNotify.gnssSvs[svOffset].gnssSignalTypeMask){ sv_cache_info.glo_g2_count++; } else { @@ -2147,14 +2127,6 @@ void loc_nmea_generate_sv(const GnssSvNotification &svNotify, } 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[svOffset].gnssSvOptionsMask & - GNSS_SV_OPTIONS_USED_IN_FIX_BIT)) - { - setSvMask(sv_cache_info.gal_used_mask, svNotify.gnssSvs[svOffset].svId); - } 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) { @@ -2167,16 +2139,6 @@ void loc_nmea_generate_sv(const GnssSvNotification &svNotify, } 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[svOffset].gnssSvOptionsMask & - GNSS_SV_OPTIONS_USED_IN_FIX_BIT)) - { - // For QZSS we adjusted SV id's in GnssAdapter, we need to re-adjust here - setSvMask(sv_cache_info.qzss_used_mask, - svNotify.gnssSvs[svOffset].svId - (QZSS_SV_PRN_MIN - 1)); - } 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) { @@ -2189,33 +2151,19 @@ void loc_nmea_generate_sv(const GnssSvNotification &svNotify, } 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[svOffset].gnssSvOptionsMask & - GNSS_SV_OPTIONS_USED_IN_FIX_BIT)) - { - setSvMask(sv_cache_info.bds_used_mask, svNotify.gnssSvs[svOffset].svId); - } 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[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[svOffset].gnssSvOptionsMask & - GNSS_SV_OPTIONS_USED_IN_FIX_BIT)) - { - setSvMask(sv_cache_info.navic_used_mask, svNotify.gnssSvs[svOffset].svId); - } // GNSS_SIGNAL_NAVIC_L5 is the only signal type for NAVIC sv_cache_info.navic_l5_count++; } @@ -2307,13 +2255,21 @@ void loc_nmea_generate_sv(const GnssSvNotification &svNotify, 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); + + // ----------------------------- + // ------$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_B1C, false), nmeaArraystr); // ----------------------------- // ------$GBGSV (BEIDOU:B2AI)--- @@ -2321,7 +2277,7 @@ void loc_nmea_generate_sv(const GnssSvNotification &svNotify, 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_B2AI, false), nmeaArraystr); // ----------------------------- // ------$GIGSV (NAVIC:L5)------ diff --git a/gps/utils/loc_nmea.h b/gps/utils/loc_nmea.h index a9cafb76..ef99e0f1 100644 --- a/gps/utils/loc_nmea.h +++ b/gps/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,8 @@ void loc_nmea_generate_pos(const UlpLocation &location, const LocationSystemInfo &systemInfo, unsigned char generate_nmea, bool custom_gga_fix_quality, - std::vector &nmeaArraystr); + std::vector &nmeaArraystr, + int& indexOfGGA); #define DEBUG_NMEA_MINSIZE 6 #define DEBUG_NMEA_MAXSIZE 4096 diff --git a/gps/utils/log_util.h b/gps/utils/log_util.h index 13c08bcf..33aa6e2a 100644 --- a/gps/utils/log_util.h +++ b/gps/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 - +#include #if defined (USE_ANDROID_LOGGING) || defined (ANDROID) // Android and LE targets with logcat support #include @@ -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 #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 EXIT_TAG[]; 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 @@ extern const char EXIT_ERROR_TAG[]; *============================================================================*/ 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 @@ extern void log_buffer_insert(char *str, unsigned long buf_size, int level); 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 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__);} diff --git a/sdm660.mk b/sdm660.mk index 25e4216e..3bf675f9 100644 --- a/sdm660.mk +++ b/sdm660.mk @@ -249,13 +249,13 @@ PRODUCT_PACKAGES += \ # GPS Config PRODUCT_COPY_FILES += \ - $(COMMON_PATH)/gps/etc/apdr.conf:$(TARGET_COPY_OUT_VENDOR)/etc/apdr.conf \ $(COMMON_PATH)/gps/etc/flp.conf:$(TARGET_COPY_OUT_VENDOR)/etc/flp.conf \ $(COMMON_PATH)/gps/etc/gps.conf:$(TARGET_COPY_OUT_VENDOR)/etc/gps.conf \ - $(COMMON_PATH)/gps/etc/izat.conf:$(TARGET_COPY_OUT_VENDOR)/etc/izat.conf \ - $(COMMON_PATH)/gps/etc/lowi.conf:$(TARGET_COPY_OUT_VENDOR)/etc/lowi.conf \ - $(COMMON_PATH)/gps/etc/sap.conf:$(TARGET_COPY_OUT_VENDOR)/etc/sap.conf \ - $(COMMON_PATH)/gps/etc/xtwifi.conf:$(TARGET_COPY_OUT_VENDOR)/etc/xtwifi.conf + $(COMMON_PATH)/gps/etc/gnss_antenna_info.conf:$(TARGET_COPY_OUT_VENDOR)/etc/gnss_antenna_info.conf \ + $(COMMON_PATH)/gps/etc/seccomp_policy/gnss@2.0-base.policy:$(TARGET_COPY_OUT_VENDOR)/etc/seccomp_policy/gnss@2.0-base.policy \ + $(COMMON_PATH)/gps/etc/seccomp_policy/gnss@2.0-xtra-daemon.policy:$(TARGET_COPY_OUT_VENDOR)/etc/seccomp_policy/gnss@2.0-xtra-daemon.policy \ + $(COMMON_PATH)/gps/etc/seccomp_policy/gnss@2.0-xtwifi-client.policy:$(TARGET_COPY_OUT_VENDOR)/etc/seccomp_policy/gnss@2.0-xtwifi-client.policy \ + $(COMMON_PATH)/gps/etc/seccomp_policy/gnss@2.0-xtwifi-inet-agent.policy:$(TARGET_COPY_OUT_VENDOR)/etc/seccomp_policy/gnss@2.0-xtwifi-inet-agent.policy # Healthd PRODUCT_PACKAGES += \