From 504dfee87f41b3477fa6c55ebca8a45d3d695af4 Mon Sep 17 00:00:00 2001 From: clarencelol Date: Sat, 10 Apr 2021 05:45:42 +0200 Subject: [PATCH] sdm660-common: gps: Update gps hal from LA.UM.9.1.r1-10200-SMxxx0.0 Signed-off-by: clarencelol Signed-off-by: pix106 --- gps/android/1.0/AGnssRil.cpp | 3 +- .../1.0/location_api/BatchingAPIClient.cpp | 3 +- .../1.0/location_api/GnssAPIClient.cpp | 3 +- gps/android/1.0/location_api/LocationUtil.cpp | 12 +- gps/android/1.1/AGnssRil.cpp | 3 +- .../1.1/location_api/BatchingAPIClient.cpp | 3 +- .../1.1/location_api/GnssAPIClient.cpp | 3 +- gps/android/1.1/location_api/LocationUtil.cpp | 12 +- gps/android/2.0/AGnssRil.cpp | 8 +- .../2.0/location_api/BatchingAPIClient.cpp | 3 +- .../2.0/location_api/GnssAPIClient.cpp | 3 +- gps/android/2.0/location_api/LocationUtil.cpp | 119 +------ gps/android/2.0/location_api/LocationUtil.h | 1 - .../2.0/location_api/MeasurementAPIClient.cpp | 80 +---- gps/android/2.1/AGnssRil.cpp | 8 +- .../2.1/location_api/BatchingAPIClient.cpp | 3 +- .../2.1/location_api/GnssAPIClient.cpp | 3 +- gps/android/2.1/location_api/LocationUtil.cpp | 119 +------ gps/android/2.1/location_api/LocationUtil.h | 1 - .../2.1/location_api/MeasurementAPIClient.cpp | 82 +---- gps/core/ContextBase.cpp | 1 + gps/core/ContextBase.h | 118 ++++++ gps/core/EngineHubProxyBase.h | 18 +- gps/core/LocAdapterBase.cpp | 8 + gps/core/LocAdapterBase.h | 5 +- gps/core/LocApiBase.cpp | 155 +++++++- gps/core/LocApiBase.h | 33 ++ gps/core/SystemStatus.cpp | 7 +- gps/core/SystemStatus.h | 28 +- .../data-items/DataItemConcreteTypesBase.h | 7 +- gps/gnss/Android.bp | 1 + gps/gnss/GnssAdapter.cpp | 335 +++++++++++++++--- gps/gnss/GnssAdapter.h | 39 +- gps/gnss/Makefile.am | 3 +- gps/gnss/NativeAgpsHandler.cpp | 127 +++++++ gps/gnss/NativeAgpsHandler.h | 64 ++++ gps/gnss/location_gnss.cpp | 21 +- gps/location/ILocationAPI.h | 38 ++ gps/location/LocationAPI.cpp | 117 ++++++ gps/location/LocationAPI.h | 65 ++++ gps/location/LocationDataTypes.h | 133 ++++++- gps/location/location_interface.h | 4 +- gps/utils/gps_extended_c.h | 28 +- gps/utils/loc_misc_utils.cpp | 10 +- gps/utils/loc_nmea.cpp | 42 ++- 45 files changed, 1398 insertions(+), 481 deletions(-) create mode 100644 gps/gnss/NativeAgpsHandler.cpp create mode 100644 gps/gnss/NativeAgpsHandler.h diff --git a/gps/android/1.0/AGnssRil.cpp b/gps/android/1.0/AGnssRil.cpp index 0437cf15..d7f30eb0 100644 --- a/gps/android/1.0/AGnssRil.cpp +++ b/gps/android/1.0/AGnssRil.cpp @@ -54,6 +54,7 @@ Return AGnssRil::updateNetworkState(bool connected, NetworkType type, bool const int NetworkType_BLUETOOTH = 7; const int NetworkType_ETHERNET = 9; const int NetworkType_PROXY = 16; + std::string apn(""); // for XTRA if (nullptr != mGnss && ( nullptr != mGnss->getGnssInterface() )) { @@ -102,7 +103,7 @@ Return AGnssRil::updateNetworkState(bool connected, NetworkType type, bool } break; } - mGnss->getGnssInterface()->updateConnectionStatus(connected, false, typeout, 0); + mGnss->getGnssInterface()->updateConnectionStatus(connected, typeout, false, 0, apn); } return true; } diff --git a/gps/android/1.0/location_api/BatchingAPIClient.cpp b/gps/android/1.0/location_api/BatchingAPIClient.cpp index 264ab83b..94a234df 100644 --- a/gps/android/1.0/location_api/BatchingAPIClient.cpp +++ b/gps/android/1.0/location_api/BatchingAPIClient.cpp @@ -30,6 +30,7 @@ #define LOG_NDEBUG 0 #define LOG_TAG "LocSvc_BatchingAPIClient" +#include #include #include @@ -153,7 +154,7 @@ void BatchingAPIClient::flushBatchedLocations() void BatchingAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask) { - LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask); + LOC_LOGD("%s]: (%" PRIu64 ")", __FUNCTION__, capabilitiesMask); mLocationCapabilitiesMask = capabilitiesMask; } diff --git a/gps/android/1.0/location_api/GnssAPIClient.cpp b/gps/android/1.0/location_api/GnssAPIClient.cpp index 235e6336..42472589 100644 --- a/gps/android/1.0/location_api/GnssAPIClient.cpp +++ b/gps/android/1.0/location_api/GnssAPIClient.cpp @@ -31,6 +31,7 @@ #define LOG_TAG "LocSvc_GnssAPIClient" #define SINGLE_SHOT_MIN_TRACKING_INTERVAL_MSEC (590 * 60 * 60 * 1000) // 590 hours +#include #include #include @@ -299,7 +300,7 @@ void GnssAPIClient::requestCapabilities() { // callbacks void GnssAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask) { - LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask); + LOC_LOGD("%s]: (%" PRIu64 ")", __FUNCTION__, capabilitiesMask); mLocationCapabilitiesMask = capabilitiesMask; mLocationCapabilitiesCached = true; diff --git a/gps/android/1.0/location_api/LocationUtil.cpp b/gps/android/1.0/location_api/LocationUtil.cpp index 7bbc0648..870a8aa1 100644 --- a/gps/android/1.0/location_api/LocationUtil.cpp +++ b/gps/android/1.0/location_api/LocationUtil.cpp @@ -157,7 +157,11 @@ void convertGnssSvid(GnssSv& in, int16_t& out) out = in.svId; break; case GNSS_SV_TYPE_GLONASS: - out = in.svId - GLO_SV_PRN_MIN + 1; + if (!isGloSlotUnknown(in.svId)) { // OSN is known + out = in.svId - GLO_SV_PRN_MIN + 1; + } else { // OSN is not known, report FCN + out = in.gloFrequency + 92; + } break; case GNSS_SV_TYPE_QZSS: out = in.svId; @@ -169,8 +173,6 @@ void convertGnssSvid(GnssSv& in, int16_t& out) 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: @@ -189,7 +191,7 @@ void convertGnssSvid(GnssMeasurementsData& in, int16_t& out) out = in.svId; break; case GNSS_SV_TYPE_GLONASS: - if (in.svId != 255) { // OSN is known + if (!isGloSlotUnknown(in.svId)) { // OSN is known out = in.svId - GLO_SV_PRN_MIN + 1; } else { // OSN is not known, report FCN out = in.gloFrequency + 92; @@ -205,8 +207,6 @@ void convertGnssSvid(GnssMeasurementsData& in, int16_t& out) 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: diff --git a/gps/android/1.1/AGnssRil.cpp b/gps/android/1.1/AGnssRil.cpp index 1e774f1a..95c8d63c 100644 --- a/gps/android/1.1/AGnssRil.cpp +++ b/gps/android/1.1/AGnssRil.cpp @@ -54,6 +54,7 @@ Return AGnssRil::updateNetworkState(bool connected, NetworkType type, bool const int NetworkType_BLUETOOTH = 7; const int NetworkType_ETHERNET = 9; const int NetworkType_PROXY = 16; + std::string apn(""); // for XTRA if (nullptr != mGnss && ( nullptr != mGnss->getGnssInterface() )) { @@ -102,7 +103,7 @@ Return AGnssRil::updateNetworkState(bool connected, NetworkType type, bool } break; } - mGnss->getGnssInterface()->updateConnectionStatus(connected, false, typeout, 0); + mGnss->getGnssInterface()->updateConnectionStatus(connected, typeout, false, 0, apn); } return true; } diff --git a/gps/android/1.1/location_api/BatchingAPIClient.cpp b/gps/android/1.1/location_api/BatchingAPIClient.cpp index 82a803f8..6ec27a92 100644 --- a/gps/android/1.1/location_api/BatchingAPIClient.cpp +++ b/gps/android/1.1/location_api/BatchingAPIClient.cpp @@ -30,6 +30,7 @@ #define LOG_NDEBUG 0 #define LOG_TAG "LocSvc_BatchingAPIClient" +#include #include #include @@ -153,7 +154,7 @@ void BatchingAPIClient::flushBatchedLocations() void BatchingAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask) { - LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask); + LOC_LOGD("%s]: (%" PRIu64 ")", __FUNCTION__, capabilitiesMask); mLocationCapabilitiesMask = capabilitiesMask; } diff --git a/gps/android/1.1/location_api/GnssAPIClient.cpp b/gps/android/1.1/location_api/GnssAPIClient.cpp index 42c05ccc..a2c4eecf 100644 --- a/gps/android/1.1/location_api/GnssAPIClient.cpp +++ b/gps/android/1.1/location_api/GnssAPIClient.cpp @@ -31,6 +31,7 @@ #define LOG_TAG "LocSvc_GnssAPIClient" #define SINGLE_SHOT_MIN_TRACKING_INTERVAL_MSEC (590 * 60 * 60 * 1000) // 590 hours +#include #include #include @@ -299,7 +300,7 @@ void GnssAPIClient::requestCapabilities() { // callbacks void GnssAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask) { - LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask); + LOC_LOGD("%s]: (%" PRIu64 ")", __FUNCTION__, capabilitiesMask); mLocationCapabilitiesMask = capabilitiesMask; mLocationCapabilitiesCached = true; diff --git a/gps/android/1.1/location_api/LocationUtil.cpp b/gps/android/1.1/location_api/LocationUtil.cpp index e0c1849a..26fd9205 100644 --- a/gps/android/1.1/location_api/LocationUtil.cpp +++ b/gps/android/1.1/location_api/LocationUtil.cpp @@ -157,7 +157,11 @@ void convertGnssSvid(GnssSv& in, int16_t& out) out = in.svId; break; case GNSS_SV_TYPE_GLONASS: - out = in.svId - GLO_SV_PRN_MIN + 1; + if (!isGloSlotUnknown(in.svId)) { // OSN is known + out = in.svId - GLO_SV_PRN_MIN + 1; + } else { //OSN is not known, report FCN + out = in.gloFrequency + 92; + } break; case GNSS_SV_TYPE_QZSS: out = in.svId; @@ -169,8 +173,6 @@ void convertGnssSvid(GnssSv& in, int16_t& out) 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: @@ -189,7 +191,7 @@ void convertGnssSvid(GnssMeasurementsData& in, int16_t& out) out = in.svId; break; case GNSS_SV_TYPE_GLONASS: - if (in.svId != 255) { // OSN is known + if (!isGloSlotUnknown(in.svId)) { // OSN is known out = in.svId - GLO_SV_PRN_MIN + 1; } else { // OSN is not known, report FCN out = in.gloFrequency + 92; @@ -205,8 +207,6 @@ void convertGnssSvid(GnssMeasurementsData& in, int16_t& out) 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: diff --git a/gps/android/2.0/AGnssRil.cpp b/gps/android/2.0/AGnssRil.cpp index a477fc2f..d8005e4d 100644 --- a/gps/android/2.0/AGnssRil.cpp +++ b/gps/android/2.0/AGnssRil.cpp @@ -54,6 +54,7 @@ Return AGnssRil::updateNetworkState(bool connected, NetworkType type, bool const int NetworkType_BLUETOOTH = 7; const int NetworkType_ETHERNET = 9; const int NetworkType_PROXY = 16; + std::string apn(""); // for XTRA if (nullptr != mGnss && ( nullptr != mGnss->getGnssInterface() )) { @@ -102,13 +103,13 @@ Return AGnssRil::updateNetworkState(bool connected, NetworkType type, bool } break; } - mGnss->getGnssInterface()->updateConnectionStatus(connected, false, typeout, 0); + mGnss->getGnssInterface()->updateConnectionStatus(connected, typeout, false, 0, apn); } return true; } Return AGnssRil::updateNetworkState_2_0(const V2_0::IAGnssRil::NetworkAttributes& attributes) { ENTRY_LOG_CALLFLOW(); - + std::string apn = attributes.apn; if (nullptr != mGnss && (nullptr != mGnss->getGnssInterface())) { int8_t typeout = loc_core::TYPE_UNKNOWN; bool roaming = false; @@ -120,8 +121,9 @@ Return AGnssRil::updateNetworkState_2_0(const V2_0::IAGnssRil::NetworkAttr if (attributes.capabilities & IAGnssRil::NetworkCapability::NOT_ROAMING) { roaming = false; } + LOC_LOGd("apn string received is: %s", apn.c_str()); mGnss->getGnssInterface()->updateConnectionStatus(attributes.isConnected, - typeout, roaming, (NetworkHandle) attributes.networkHandle); + typeout, roaming, (NetworkHandle) attributes.networkHandle, apn); } return true; } diff --git a/gps/android/2.0/location_api/BatchingAPIClient.cpp b/gps/android/2.0/location_api/BatchingAPIClient.cpp index 49cd18a7..766c37a6 100644 --- a/gps/android/2.0/location_api/BatchingAPIClient.cpp +++ b/gps/android/2.0/location_api/BatchingAPIClient.cpp @@ -30,6 +30,7 @@ #define LOG_NDEBUG 0 #define LOG_TAG "LocSvc_BatchingAPIClient" +#include #include #include @@ -191,7 +192,7 @@ void BatchingAPIClient::flushBatchedLocations() void BatchingAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask) { - LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask); + LOC_LOGD("%s]: (%" PRIu64 ")", __FUNCTION__, capabilitiesMask); mLocationCapabilitiesMask = capabilitiesMask; } diff --git a/gps/android/2.0/location_api/GnssAPIClient.cpp b/gps/android/2.0/location_api/GnssAPIClient.cpp index c588978b..44007d90 100644 --- a/gps/android/2.0/location_api/GnssAPIClient.cpp +++ b/gps/android/2.0/location_api/GnssAPIClient.cpp @@ -31,6 +31,7 @@ #define LOG_TAG "LocSvc_GnssAPIClient" #define SINGLE_SHOT_MIN_TRACKING_INTERVAL_MSEC (590 * 60 * 60 * 1000) // 590 hours +#include #include #include @@ -349,7 +350,7 @@ void GnssAPIClient::requestCapabilities() { // callbacks void GnssAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask) { - LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask); + LOC_LOGD("%s]: (%" PRIu64 ")", __FUNCTION__, capabilitiesMask); mLocationCapabilitiesMask = capabilitiesMask; mLocationCapabilitiesCached = true; diff --git a/gps/android/2.0/location_api/LocationUtil.cpp b/gps/android/2.0/location_api/LocationUtil.cpp index fe8d22cd..961b7b1c 100644 --- a/gps/android/2.0/location_api/LocationUtil.cpp +++ b/gps/android/2.0/location_api/LocationUtil.cpp @@ -84,109 +84,22 @@ void convertGnssLocation(Location& in, V1_0::GnssLocation& out) 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_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 - 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_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); - } - } - } + if (in.flags & LOCATION_HAS_ELAPSED_REAL_TIME) { + out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIMESTAMP_NS; + out.elapsedRealtime.timestampNs = in.elapsedRealTime; + out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS; + out.elapsedRealtime.timeUncertaintyNs = in.elapsedRealTimeUnc; + LOC_LOGd("out.elapsedRealtime.timestampNs=%" PRIi64 "" + " out.elapsedRealtime.timeUncertaintyNs=%" PRIi64 "" + " out.elapsedRealtime.flags=0x%X", + out.elapsedRealtime.timestampNs, + out.elapsedRealtime.timeUncertaintyNs, out.elapsedRealtime.flags); } - 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) @@ -304,7 +217,11 @@ void convertGnssSvid(GnssSv& in, int16_t& out) out = in.svId; break; case GNSS_SV_TYPE_GLONASS: - out = in.svId - GLO_SV_PRN_MIN + 1; + if (!isGloSlotUnknown(in.svId)) { // OSN is known + out = in.svId - GLO_SV_PRN_MIN + 1; + } else { // OSN is not known, report FCN + out = in.gloFrequency + 92; + } break; case GNSS_SV_TYPE_QZSS: out = in.svId; @@ -316,8 +233,6 @@ void convertGnssSvid(GnssSv& in, int16_t& out) 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: @@ -336,7 +251,7 @@ void convertGnssSvid(GnssMeasurementsData& in, int16_t& out) out = in.svId; break; case GNSS_SV_TYPE_GLONASS: - if (in.svId != 255) { // OSN is known + if (!isGloSlotUnknown(in.svId)) { // OSN is known out = in.svId - GLO_SV_PRN_MIN + 1; } else { // OSN is not known, report FCN out = in.gloFrequency + 92; @@ -352,8 +267,6 @@ void convertGnssSvid(GnssMeasurementsData& in, int16_t& out) 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: diff --git a/gps/android/2.0/location_api/LocationUtil.h b/gps/android/2.0/location_api/LocationUtil.h index 3c345149..70729e4a 100644 --- a/gps/android/2.0/location_api/LocationUtil.h +++ b/gps/android/2.0/location_api/LocationUtil.h @@ -51,7 +51,6 @@ void convertGnssSvid(GnssMeasurementsData& in, int16_t& out); void convertGnssEphemerisType(GnssEphemerisType& in, GnssDebug::SatelliteEphemerisType& out); void convertGnssEphemerisSource(GnssEphemerisSource& in, GnssDebug::SatelliteEphemerisSource& out); void convertGnssEphemerisHealth(GnssEphemerisHealth& in, GnssDebug::SatelliteEphemerisHealth& out); -bool getCurrentTime(struct timespec& currentTime, int64_t& sinceBootTimeNanos); } // namespace implementation } // namespace V2_0 diff --git a/gps/android/2.0/location_api/MeasurementAPIClient.cpp b/gps/android/2.0/location_api/MeasurementAPIClient.cpp index a32b1cd9..425415f2 100644 --- a/gps/android/2.0/location_api/MeasurementAPIClient.cpp +++ b/gps/android/2.0/location_api/MeasurementAPIClient.cpp @@ -437,78 +437,16 @@ static void convertGnssData_2_0(GnssMeasurementsNotification& in, 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 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"); - } - } + if (in.clock.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_ELAPSED_REAL_TIME_BIT) { + elapsedRealtime.flags |= V2_0::ElapsedRealtimeFlags::HAS_TIMESTAMP_NS; + elapsedRealtime.timestampNs = in.clock.elapsedRealTime; + elapsedRealtime.flags |= V2_0::ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS; + elapsedRealtime.timeUncertaintyNs = in.clock.elapsedRealTimeUnc; + LOC_LOGd("elapsedRealtime.timestampNs=%" PRIi64 "" + " elapsedRealtime.timeUncertaintyNs=%" PRIi64 " elapsedRealtime.flags=0x%X", + elapsedRealtime.timestampNs, + elapsedRealtime.timeUncertaintyNs, elapsedRealtime.flags); } - 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.1/AGnssRil.cpp b/gps/android/2.1/AGnssRil.cpp index 65fb3005..f413e930 100644 --- a/gps/android/2.1/AGnssRil.cpp +++ b/gps/android/2.1/AGnssRil.cpp @@ -54,6 +54,7 @@ Return AGnssRil::updateNetworkState(bool connected, NetworkType type, bool const int NetworkType_BLUETOOTH = 7; const int NetworkType_ETHERNET = 9; const int NetworkType_PROXY = 16; + std::string apn(""); // for XTRA if (nullptr != mGnss && ( nullptr != mGnss->getGnssInterface() )) { @@ -102,13 +103,13 @@ Return AGnssRil::updateNetworkState(bool connected, NetworkType type, bool } break; } - mGnss->getGnssInterface()->updateConnectionStatus(connected, false, typeout, 0); + mGnss->getGnssInterface()->updateConnectionStatus(connected, typeout, false, 0, apn); } return true; } Return AGnssRil::updateNetworkState_2_0(const V2_0::IAGnssRil::NetworkAttributes& attributes) { ENTRY_LOG_CALLFLOW(); - + std::string apn = attributes.apn; if (nullptr != mGnss && (nullptr != mGnss->getGnssInterface())) { int8_t typeout = loc_core::TYPE_UNKNOWN; bool roaming = false; @@ -120,8 +121,9 @@ Return AGnssRil::updateNetworkState_2_0(const V2_0::IAGnssRil::NetworkAttr if (attributes.capabilities & IAGnssRil::NetworkCapability::NOT_ROAMING) { roaming = false; } + LOC_LOGd("apn string received is: %s", apn.c_str()); mGnss->getGnssInterface()->updateConnectionStatus(attributes.isConnected, - typeout, roaming, (NetworkHandle) attributes.networkHandle); + typeout, roaming, (NetworkHandle) attributes.networkHandle, apn); } return true; } diff --git a/gps/android/2.1/location_api/BatchingAPIClient.cpp b/gps/android/2.1/location_api/BatchingAPIClient.cpp index f1f1fe43..00d2ed90 100644 --- a/gps/android/2.1/location_api/BatchingAPIClient.cpp +++ b/gps/android/2.1/location_api/BatchingAPIClient.cpp @@ -30,6 +30,7 @@ #define LOG_NDEBUG 0 #define LOG_TAG "LocSvc_BatchingAPIClient" +#include #include #include @@ -191,7 +192,7 @@ void BatchingAPIClient::flushBatchedLocations() void BatchingAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask) { - LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask); + LOC_LOGD("%s]: (%" PRIu64 ")", __FUNCTION__, capabilitiesMask); mLocationCapabilitiesMask = capabilitiesMask; } diff --git a/gps/android/2.1/location_api/GnssAPIClient.cpp b/gps/android/2.1/location_api/GnssAPIClient.cpp index 09c83dfb..07f617d0 100644 --- a/gps/android/2.1/location_api/GnssAPIClient.cpp +++ b/gps/android/2.1/location_api/GnssAPIClient.cpp @@ -31,6 +31,7 @@ #define LOG_TAG "LocSvc_GnssAPIClient" #define SINGLE_SHOT_MIN_TRACKING_INTERVAL_MSEC (590 * 60 * 60 * 1000) // 590 hours +#include #include #include @@ -380,7 +381,7 @@ void GnssAPIClient::requestCapabilities() { // callbacks void GnssAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask) { - LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask); + LOC_LOGD("%s]: (%" PRIu64 ")", __FUNCTION__, capabilitiesMask); mLocationCapabilitiesMask = capabilitiesMask; mLocationCapabilitiesCached = true; diff --git a/gps/android/2.1/location_api/LocationUtil.cpp b/gps/android/2.1/location_api/LocationUtil.cpp index 43711199..5154e708 100644 --- a/gps/android/2.1/location_api/LocationUtil.cpp +++ b/gps/android/2.1/location_api/LocationUtil.cpp @@ -85,109 +85,22 @@ void convertGnssLocation(Location& in, V1_0::GnssLocation& out) 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); - } - } - } + if (in.flags & LOCATION_HAS_ELAPSED_REAL_TIME) { + out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIMESTAMP_NS; + out.elapsedRealtime.timestampNs = in.elapsedRealTime; + out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS; + out.elapsedRealtime.timeUncertaintyNs = in.elapsedRealTimeUnc; + LOC_LOGd("out.elapsedRealtime.timestampNs=%" PRIi64 "" + " out.elapsedRealtime.timeUncertaintyNs=%" PRIi64 "" + " out.elapsedRealtime.flags=0x%X", + out.elapsedRealtime.timestampNs, + out.elapsedRealtime.timeUncertaintyNs, out.elapsedRealtime.flags); } - 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) @@ -305,7 +218,11 @@ void convertGnssSvid(GnssSv& in, int16_t& out) out = in.svId; break; case GNSS_SV_TYPE_GLONASS: - out = in.svId - GLO_SV_PRN_MIN + 1; + if (!isGloSlotUnknown(in.svId)) { // OSN is known + out = in.svId - GLO_SV_PRN_MIN + 1; + } else { // OSN is not known, report FCN + out = in.gloFrequency + 92; + } break; case GNSS_SV_TYPE_QZSS: out = in.svId; @@ -317,8 +234,6 @@ void convertGnssSvid(GnssSv& in, int16_t& out) 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: @@ -337,7 +252,7 @@ void convertGnssSvid(GnssMeasurementsData& in, int16_t& out) out = in.svId; break; case GNSS_SV_TYPE_GLONASS: - if (in.svId != 255) { // OSN is known + if (!isGloSlotUnknown(in.svId)) { // OSN is known out = in.svId - GLO_SV_PRN_MIN + 1; } else { // OSN is not known, report FCN out = in.gloFrequency + 92; @@ -353,8 +268,6 @@ void convertGnssSvid(GnssMeasurementsData& in, int16_t& out) 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: diff --git a/gps/android/2.1/location_api/LocationUtil.h b/gps/android/2.1/location_api/LocationUtil.h index fde15950..2d95a2db 100644 --- a/gps/android/2.1/location_api/LocationUtil.h +++ b/gps/android/2.1/location_api/LocationUtil.h @@ -56,7 +56,6 @@ 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); diff --git a/gps/android/2.1/location_api/MeasurementAPIClient.cpp b/gps/android/2.1/location_api/MeasurementAPIClient.cpp index 58697744..00280742 100644 --- a/gps/android/2.1/location_api/MeasurementAPIClient.cpp +++ b/gps/android/2.1/location_api/MeasurementAPIClient.cpp @@ -623,80 +623,16 @@ static void convertGnssData_2_1(GnssMeasurementsNotification& in, 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"); - } - } + if (in.clock.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_ELAPSED_REAL_TIME_BIT) { + elapsedRealtime.flags |= V2_0::ElapsedRealtimeFlags::HAS_TIMESTAMP_NS; + elapsedRealtime.timestampNs = in.clock.elapsedRealTime; + elapsedRealtime.flags |= V2_0::ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS; + elapsedRealtime.timeUncertaintyNs = in.clock.elapsedRealTimeUnc; + LOC_LOGd("elapsedRealtime.timestampNs=%" PRIi64 "" + " elapsedRealtime.timeUncertaintyNs=%" PRIi64 " elapsedRealtime.flags=0x%X", + elapsedRealtime.timestampNs, + elapsedRealtime.timeUncertaintyNs, elapsedRealtime.flags); } - LOC_LOGv("elapsedRealtime.timestampNs=%" PRIi64 "" - " elapsedRealtime.timeUncertaintyNs=%" PRIi64 " elapsedRealtime.flags=0x%X", - elapsedRealtime.timestampNs, - elapsedRealtime.timeUncertaintyNs, elapsedRealtime.flags); } } // namespace implementation diff --git a/gps/core/ContextBase.cpp b/gps/core/ContextBase.cpp index 411c9900..d5ce6c1a 100644 --- a/gps/core/ContextBase.cpp +++ b/gps/core/ContextBase.cpp @@ -50,6 +50,7 @@ uint64_t ContextBase::sSupportedMsgMask = 0; bool ContextBase::sGnssMeasurementSupported = false; uint8_t ContextBase::sFeaturesSupported[MAX_FEATURE_LENGTH]; GnssNMEARptRate ContextBase::sNmeaReportRate = GNSS_NMEA_REPORT_RATE_NHZ; +LocationCapabilitiesMask ContextBase::sQwesFeatureMask = 0; const loc_param_s_type ContextBase::mGps_conf_table[] = { diff --git a/gps/core/ContextBase.h b/gps/core/ContextBase.h index 026ab49d..9ae3141c 100644 --- a/gps/core/ContextBase.h +++ b/gps/core/ContextBase.h @@ -35,6 +35,11 @@ #include #include #include +#ifdef NO_UNORDERED_SET_OR_MAP + #include +#else + #include +#endif /* GPS.conf support */ /* NOTE: the implementaiton of the parser casts number @@ -160,6 +165,7 @@ public: static uint8_t sFeaturesSupported[MAX_FEATURE_LENGTH]; static bool sGnssMeasurementSupported; static GnssNMEARptRate sNmeaReportRate; + static LocationCapabilitiesMask sQwesFeatureMask; void readConfig(); static uint32_t getCarrierCapabilities(); @@ -192,6 +198,118 @@ public: */ static bool gnssConstellationConfig(); + /* + set QWES feature status info + */ + static inline void setQwesFeatureStatus( + const std::unordered_map &featureMap) { + std::unordered_map::const_iterator itr; + static LocationQwesFeatureType locQwesFeatType[LOCATION_QWES_FEATURE_TYPE_MAX]; + for (itr = featureMap.begin(); itr != featureMap.end(); ++itr) { + LOC_LOGi("Feature : %d isValid: %d", itr->first, itr->second); + locQwesFeatType[itr->first] = itr->second; + switch (itr->first) { + case LOCATION_QWES_FEATURE_TYPE_CARRIER_PHASE: + if (itr->second) { + sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_CARRIER_PHASE_BIT; + } else { + sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_CARRIER_PHASE_BIT; + } + break; + case LOCATION_QWES_FEATURE_TYPE_SV_POLYNOMIAL: + if (itr->second) { + sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_SV_POLYNOMIAL_BIT; + } else { + sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_SV_POLYNOMIAL_BIT; + } + break; + case LOCATION_QWES_FEATURE_TYPE_GNSS_SINGLE_FREQUENCY: + if (itr->second) { + sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_GNSS_SINGLE_FREQUENCY; + } else { + sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_GNSS_SINGLE_FREQUENCY; + } + break; + case LOCATION_QWES_FEATURE_TYPE_SV_EPH: + if (itr->second) { + sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_SV_EPHEMERIS_BIT; + } else { + sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_SV_EPHEMERIS_BIT; + } + break; + case LOCATION_QWES_FEATURE_TYPE_GNSS_MULTI_FREQUENCY: + if (itr->second) { + sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_GNSS_MULTI_FREQUENCY; + } else { + sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_GNSS_MULTI_FREQUENCY; + } + break; + case LOCATION_QWES_FEATURE_TYPE_PPE: + if (itr->second) { + sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_PPE; + } else { + sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_PPE; + } + break; + case LOCATION_QWES_FEATURE_TYPE_QDR2: + if (itr->second) { + sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_QDR2; + } else { + sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_QDR2; + } + break; + case LOCATION_QWES_FEATURE_TYPE_QDR3: + if (itr->second) { + sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_QDR3; + } else { + sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_QDR3; + } + break; + case LOCATION_QWES_FEATURE_TYPE_VPE: + if (itr->second) { + sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_VPE; + } else { + sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_VPE; + } + break; + } + } + + // Set CV2X basic when time freq and tunc is set + // CV2X_BASIC = LOCATION_QWES_FEATURE_TYPE_TIME_FREQUENCY & + // LOCATION_QWES_FEATURE_TYPE_TIME_UNCERTAINTY + + // Set CV2X premium when time freq and tunc is set + // CV2X_PREMIUM = CV2X_BASIC & LOCATION_QWES_FEATURE_TYPE_QDR3 & + // LOCATION_QWES_FEATURE_TYPE_CLOCK_ESTIMATE + + bool cv2xBasicEnabled = (1 == locQwesFeatType[LOCATION_QWES_FEATURE_TYPE_TIME_FREQUENCY]) && + (1 == locQwesFeatType[LOCATION_QWES_FEATURE_TYPE_TIME_UNCERTAINTY]); + bool cv2xPremiumEnabled = cv2xBasicEnabled && + (1 == locQwesFeatType[LOCATION_QWES_FEATURE_TYPE_QDR3]) && + (1 == locQwesFeatType[LOCATION_QWES_FEATURE_TYPE_CLOCK_ESTIMATE]); + + LOC_LOGd("CV2X_BASIC:%d, CV2X_PREMIUM:%d", cv2xBasicEnabled, cv2xPremiumEnabled); + if (cv2xBasicEnabled) { + sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_CV2X_LOCATION_BASIC; + } else { + sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_CV2X_LOCATION_BASIC; + } + if (cv2xPremiumEnabled) { + sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_CV2X_LOCATION_PREMIUM; + } else { + sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_CV2X_LOCATION_PREMIUM; + } + } + + /* + get QWES feature status info + */ + static inline LocationCapabilitiesMask getQwesFeatureStatus() { + return (ContextBase::sQwesFeatureMask); + } + + }; struct LocApiResponse: LocMsg { diff --git a/gps/core/EngineHubProxyBase.h b/gps/core/EngineHubProxyBase.h index 13a1cd75..468a8f05 100644 --- a/gps/core/EngineHubProxyBase.h +++ b/gps/core/EngineHubProxyBase.h @@ -28,6 +28,11 @@ */ #ifndef ENGINE_HUB_PROXY_BASE_H #define ENGINE_HUB_PROXY_BASE_H +#ifdef NO_UNORDERED_SET_OR_MAP + #include +#else + #include +#endif namespace loc_core { @@ -114,6 +119,13 @@ public: (void) dreConfig; return false; } + + inline virtual bool configEngineRunState( + PositioningEngineMask engType, LocEngineRunState engState) { + (void) engType; + (void) engState; + return false; + } }; typedef std::function @@ -129,6 +141,9 @@ typedef std::function typedef std::function GnssAdapterUpdateNHzRequirementCb; +typedef std::function &featureMap)> + GnssAdapterUpdateQwesFeatureStatusCb; + // potential parameters: message queue: MsgTask * msgTask; // callback function to report back dr and ppe position and sv report typedef EngineHubProxyBase* (getEngHubProxyFn)( @@ -137,7 +152,8 @@ typedef EngineHubProxyBase* (getEngHubProxyFn)( GnssAdapterReportEnginePositionsEventCb positionEventCb, GnssAdapterReportSvEventCb svEventCb, GnssAdapterReqAidingDataCb reqAidingDataCb, - GnssAdapterUpdateNHzRequirementCb updateNHzRequirementCb); + GnssAdapterUpdateNHzRequirementCb updateNHzRequirementCb, + GnssAdapterUpdateQwesFeatureStatusCb updateQwesFeatureStatusCb); } // namespace loc_core diff --git a/gps/core/LocAdapterBase.cpp b/gps/core/LocAdapterBase.cpp index 5ada84b7..95f27288 100644 --- a/gps/core/LocAdapterBase.cpp +++ b/gps/core/LocAdapterBase.cpp @@ -428,4 +428,12 @@ LocAdapterBase::requestCapabilitiesCommand(LocationAPI* client) sendMsg(new MsgRequestCapabilities(*this, client)); } +void +LocAdapterBase::reportLatencyInfoEvent(const GnssLatencyInfo& /*gnssLatencyInfo*/) +DEFAULT_IMPL() + +bool LocAdapterBase:: + reportQwesCapabilities(const std::unordered_map &featureMap) +DEFAULT_IMPL(false) + } // namespace loc_core diff --git a/gps/core/LocAdapterBase.h b/gps/core/LocAdapterBase.h index 4a5d1abc..51b23060 100644 --- a/gps/core/LocAdapterBase.h +++ b/gps/core/LocAdapterBase.h @@ -156,7 +156,7 @@ public: return ContextBase::isFeatureSupported(featureVal); } - uint32_t generateSessionId(); + static uint32_t generateSessionId(); inline bool isAdapterMaster() { return mIsMaster; @@ -236,6 +236,9 @@ public: removeClientCompleteCallback rmClientCb); void requestCapabilitiesCommand(LocationAPI* client); + virtual void reportLatencyInfoEvent(const GnssLatencyInfo& gnssLatencyInfo); + virtual bool reportQwesCapabilities( + const std::unordered_map &featureMap); }; } // namespace loc_core diff --git a/gps/core/LocApiBase.cpp b/gps/core/LocApiBase.cpp index 0044d07d..6a0ff84b 100644 --- a/gps/core/LocApiBase.cpp +++ b/gps/core/LocApiBase.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2014, 2016-2020 The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2014, 2016-2021 The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -36,6 +36,7 @@ #include #include #include +#include namespace loc_core { @@ -483,6 +484,14 @@ void LocApiBase::reportLocationSystemInfo(const LocationSystemInfo& locationSyst TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportLocationSystemInfoEvent(locationSystemInfo)); } +void LocApiBase::reportQwesCapabilities +( + const std::unordered_map &featureMap +) +{ + // loop through adapters, and deliver to all adapters. + TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportQwesCapabilities(featureMap)); +} void LocApiBase::requestXtraData() { // loop through adapters, and deliver to the first handling adapter. @@ -600,6 +609,12 @@ void LocApiBase::reportGnssConfig(uint32_t sessionId, const GnssConfig& gnssConf TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportGnssConfigEvent(sessionId, gnssConfig)); } +void LocApiBase::reportLatencyInfo(GnssLatencyInfo& gnssLatencyInfo) +{ + // loop through adapters, and deliver to the first handling adapter. + TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportLatencyInfoEvent(gnssLatencyInfo)); +} + enum loc_api_adapter_err LocApiBase:: open(LOC_API_ADAPTER_EVENT_MASK_T /*mask*/) DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS) @@ -913,4 +928,142 @@ DEFAULT_IMPL() void LocApiBase:: getConstellationMultiBandConfig(uint32_t sessionId, LocApiResponse* /*adapterResponse*/) DEFAULT_IMPL() + +int64_t ElapsedRealtimeEstimator::getElapsedRealtimeEstimateNanos(int64_t curDataTimeNanos, + bool isCurDataTimeTrustable, int64_t tbf) { + //The algorithm works follow below steps: + //When isCurDataTimeTrustable is meet (means Modem timestamp is already stable), + //1, Wait for mFixTimeStablizationThreshold fixes; While waiting for modem time + // stable, we set the traveltime to a default value; + //2, When the mFixTimeStablizationThreshold fix comes, we think now the mode time + // is already stable, calculate the initial AP-Modem clock diff(mCurrentClockDiff) + // using formula: + // mCurrentClockDiff = currentTimeNanos - locationTimeNanos - currentTravelTimeNanos + //3, since then, when the nth fix comes, + // 3.1 First update mCurrentClockDiff using below formula: + // mCurrentClockDiff = mCurrentClockDiff + (currentTimeNanos - sinceBootTimeNanos) + // - (mPrevUtcTimeNanos - mPrevBootTimeNanos) + // 3.2 Calculate currentTravelTimeNanos: + // currentTravelTimeNanos = currentTimeNanos - locationTimeNanos - mCurrentClockDiff + //4, It is possible that locationTimeNanos will jump, + // reset mFixTimeStablizationThreshold to default value, jump to step 2 to continue. + + int64_t currentTravelTimeNanos = mInitialTravelTime; + struct timespec currentTime; + int64_t sinceBootTimeNanos; + if (getCurrentTime(currentTime, sinceBootTimeNanos)) { + if (isCurDataTimeTrustable) { + if (tbf > 0 && tbf != curDataTimeNanos - mPrevDataTimeNanos) { + mFixTimeStablizationThreshold = 5; + } + int64_t currentTimeNanos = (int64_t)currentTime.tv_sec*1000000000 + currentTime.tv_nsec; + LOC_LOGd("sinceBootTimeNanos:%" PRIi64 " currentTimeNanos:%" PRIi64 "" + " locationTimeNanos:%" PRIi64 "", + sinceBootTimeNanos, currentTimeNanos, curDataTimeNanos); + if (mFixTimeStablizationThreshold == 0) { + currentTravelTimeNanos = mInitialTravelTime; + mCurrentClockDiff = currentTimeNanos - curDataTimeNanos - currentTravelTimeNanos; + } else if (mFixTimeStablizationThreshold < 0) { + mCurrentClockDiff = mCurrentClockDiff + (currentTimeNanos - sinceBootTimeNanos) + - (mPrevUtcTimeNanos - mPrevBootTimeNanos); + currentTravelTimeNanos = currentTimeNanos - curDataTimeNanos - mCurrentClockDiff; + } + + mPrevUtcTimeNanos = currentTimeNanos; + mPrevBootTimeNanos = sinceBootTimeNanos; + mPrevDataTimeNanos = curDataTimeNanos; + mFixTimeStablizationThreshold--; + } + } else { + return -1; + } + LOC_LOGd("Estimated travel time: %" PRIi64 "", currentTravelTimeNanos); + return (sinceBootTimeNanos - currentTravelTimeNanos); +} + +void ElapsedRealtimeEstimator::reset() { + mCurrentClockDiff = 0; + mPrevDataTimeNanos = 0; + mPrevUtcTimeNanos = 0; + mPrevBootTimeNanos = 0; + mFixTimeStablizationThreshold = 5; +} + +int64_t ElapsedRealtimeEstimator::getElapsedRealtimeQtimer(int64_t qtimerTicksAtOrigin) { + struct timespec currentTime; + int64_t sinceBootTimeNanos; + int64_t elapsedRealTimeNanos; + + if (getCurrentTime(currentTime, sinceBootTimeNanos)) { + uint64_t qtimerDiff = 0; + uint64_t qTimerTickCount = getQTimerTickCount(); + if (qTimerTickCount >= qtimerTicksAtOrigin) { + qtimerDiff = qTimerTickCount - qtimerTicksAtOrigin; + } + LOC_LOGd("sinceBootTimeNanos:%" PRIi64 " qtimerTicksAtOrigin=%" PRIi64 "" + " qTimerTickCount=%" PRIi64 " qtimerDiff=%" PRIi64 "", + sinceBootTimeNanos, qtimerTicksAtOrigin, qTimerTickCount, qtimerDiff); + uint64_t qTimerDiffNanos = qTimerTicksToNanos(double(qtimerDiff)); + + /* If the time difference between Qtimer on modem side and Qtimer on AP side + is greater than one second we assume this is a dual-SoC device such as + Kona and will try to get Qtimer on modem side and on AP side and + will adjust our difference accordingly */ + if (qTimerDiffNanos > 1000000000) { + uint64_t qtimerDelta = getQTimerDeltaNanos(); + if (qTimerDiffNanos >= qtimerDelta) { + qTimerDiffNanos -= qtimerDelta; + } + } + + LOC_LOGd("Qtimer travel time: %" PRIi64 "", qTimerDiffNanos); + if (sinceBootTimeNanos >= qTimerDiffNanos) { + elapsedRealTimeNanos = sinceBootTimeNanos - qTimerDiffNanos; + } else { + elapsedRealTimeNanos = -1; + } + } else { + elapsedRealTimeNanos = -1; + } + return elapsedRealTimeNanos; +} + +bool ElapsedRealtimeEstimator::getCurrentTime( + struct timespec& currentTime, int64_t& sinceBootTimeNanos) +{ + struct timespec sinceBootTime; + struct timespec sinceBootTimeTest; + bool clockGetTimeSuccess = false; + const uint32_t MAX_TIME_DELTA_VALUE_NANOS = 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 = (int64_t)sinceBootTime.tv_sec * 1000000000 + sinceBootTime.tv_nsec; + int64_t sinceBootTimeTestNanos = + (int64_t)sinceBootTimeTest.tv_sec * 1000000000 + sinceBootTimeTest.tv_nsec; + int64_t sinceBootTimeDeltaNanos = sinceBootTimeTestNanos - sinceBootTimeNanos; + + /* sinceBootTime and sinceBootTimeTest should have a close value if there was no + interruption or context switch between clock_gettime for CLOCK_BOOTIME and + clock_gettime for CLOCK_REALTIME */ + if (sinceBootTimeDeltaNanos < MAX_TIME_DELTA_VALUE_NANOS) { + clockGetTimeSuccess = true; + break; + } else { + LOC_LOGd("Delta:%" PRIi64 "ns time too large, retry number #%u...", + sinceBootTimeDeltaNanos, i + 1); + } + } + return clockGetTimeSuccess; +} } // namespace loc_core diff --git a/gps/core/LocApiBase.h b/gps/core/LocApiBase.h index fd0f1d21..121f795c 100644 --- a/gps/core/LocApiBase.h +++ b/gps/core/LocApiBase.h @@ -36,6 +36,13 @@ #include #include #include +#ifdef NO_UNORDERED_SET_OR_MAP + #include +#else + #include +#endif +#include +#include using namespace loc_util; @@ -194,6 +201,11 @@ public: void reportGnssAdditionalSystemInfo(GnssAdditionalSystemInfo& additionalSystemInfo); void sendNfwNotification(GnssNfwNotification& notification); void reportGnssConfig(uint32_t sessionId, const GnssConfig& gnssConfig); + void reportLatencyInfo(GnssLatencyInfo& gnssLatencyInfo); + void reportQwesCapabilities + ( + const std::unordered_map &featureMap + ); void geofenceBreach(size_t count, uint32_t* hwIds, Location& location, GeofenceBreachType breachType, uint64_t timestamp); @@ -334,6 +346,27 @@ public: LocApiResponse* adapterResponse=nullptr); }; +class ElapsedRealtimeEstimator { +private: + int64_t mCurrentClockDiff; + int64_t mPrevUtcTimeNanos; + int64_t mPrevBootTimeNanos; + int64_t mFixTimeStablizationThreshold; + int64_t mInitialTravelTime; + int64_t mPrevDataTimeNanos; +public: + + ElapsedRealtimeEstimator(int64_t travelTimeNanosEstimate): + mInitialTravelTime(travelTimeNanosEstimate) {reset();} + int64_t getElapsedRealtimeEstimateNanos(int64_t curDataTimeNanos, + bool isCurDataTimeTrustable, int64_t tbf); + inline int64_t getElapsedRealtimeUncNanos() { return 5000000;} + void reset(); + + static int64_t getElapsedRealtimeQtimer(int64_t qtimerTicksAtOrigin); + static bool getCurrentTime(struct timespec& currentTime, int64_t& sinceBootTimeNanos); +}; + typedef LocApiBase* (getLocApi_t)(LOC_API_ADAPTER_EVENT_MASK_T exMask, ContextBase *context); diff --git a/gps/core/SystemStatus.cpp b/gps/core/SystemStatus.cpp index 891a8e65..d792577a 100644 --- a/gps/core/SystemStatus.cpp +++ b/gps/core/SystemStatus.cpp @@ -1291,7 +1291,7 @@ void SystemStatus::resetNetworkInfo() { for (int i=0; i(curInfo)).mAllTypes; + string& apn = (static_cast(curInfo)).mApn; // Replace current with cached table for now and then update memcpy(mAllNetworkHandles, (static_cast(curInfo)).getNetworkHandle(), sizeof(mAllNetworkHandles)); + // Update the apn for non-mobile type connections. + if (TYPE_MOBILE != mType && apn.compare("") != 0) { + mApn = apn; + } if (mConnected) { mAllTypes |= allTypes; for (uint8_t i = 0; i < MAX_NETWORK_HANDLES; ++i) { @@ -577,8 +583,8 @@ public: return *this; } inline void dump(void) override { - LOC_LOGD("NetworkInfo: mAllTypes=%" PRIx64 " connected=%u mType=%x", - mAllTypes, mConnected, mType); + LOC_LOGD("NetworkInfo: mAllTypes=%" PRIx64 " connected=%u mType=%x mApn=%s", + mAllTypes, mConnected, mType, mApn.c_str()); } }; @@ -907,7 +913,7 @@ public: bool getReport(SystemStatusReports& reports, bool isLatestonly = false) const; bool setDefaultGnssEngineStates(void); bool eventConnectionStatus(bool connected, int8_t type, - bool roaming, NetworkHandle networkHandle); + bool roaming, NetworkHandle networkHandle, string& apn); bool updatePowerConnectState(bool charging); void resetNetworkInfo(); }; diff --git a/gps/core/data-items/DataItemConcreteTypesBase.h b/gps/core/data-items/DataItemConcreteTypesBase.h index c32d65d7..11a3cce1 100644 --- a/gps/core/data-items/DataItemConcreteTypesBase.h +++ b/gps/core/data-items/DataItemConcreteTypesBase.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2017, 2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2017, 2020, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -284,7 +284,7 @@ class NetworkInfoDataItemBase : public IDataItemCore { public: NetworkInfoDataItemBase( NetworkType initialType, int32_t type, string typeName, string subTypeName, - bool available, bool connected, bool roaming, uint64_t networkHandle ): + bool available, bool connected, bool roaming, uint64_t networkHandle, string apn): mAllTypes(typeToAllTypes(initialType)), mType(type), mTypeName(typeName), @@ -293,7 +293,7 @@ public: mConnected(connected), mRoaming(roaming), mNetworkHandle(networkHandle), - mId(NETWORKINFO_DATA_ITEM_ID) { + mId(NETWORKINFO_DATA_ITEM_ID), mApn(apn) { mAllNetworkHandles[0].networkHandle = networkHandle; mAllNetworkHandles[0].networkType = initialType; } @@ -318,6 +318,7 @@ public: bool mRoaming; NetworkInfoType mAllNetworkHandles[MAX_NETWORK_HANDLES]; uint64_t mNetworkHandle; + string mApn; protected: DataItemId mId; inline uint64_t typeToAllTypes(NetworkType type) { diff --git a/gps/gnss/Android.bp b/gps/gnss/Android.bp index af0a208b..a3e8de97 100644 --- a/gps/gnss/Android.bp +++ b/gps/gnss/Android.bp @@ -21,6 +21,7 @@ cc_library_shared { "GnssAdapter.cpp", "Agps.cpp", "XtraSystemStatusObserver.cpp", + "NativeAgpsHandler.cpp", ], cflags: ["-fno-short-enums"] + GNSS_CFLAGS, diff --git a/gps/gnss/GnssAdapter.cpp b/gps/gnss/GnssAdapter.cpp index 2c2e155b..0b198439 100644 --- a/gps/gnss/GnssAdapter.cpp +++ b/gps/gnss/GnssAdapter.cpp @@ -77,6 +77,15 @@ static void agpsCloseResultCb (bool isSuccess, AGpsExtType agpsType, void* userD typedef const CdfwInterface* (*getCdfwInterface)(); +inline bool GnssReportLoggerUtil::isLogEnabled() { + return (mLogLatency != nullptr); +} + +inline void GnssReportLoggerUtil::log(const GnssLatencyInfo& gnssLatencyMeasInfo) { + if (mLogLatency != nullptr) { + mLogLatency(gnssLatencyMeasInfo); + } +} GnssAdapter::GnssAdapter() : LocAdapterBase(0, @@ -110,8 +119,9 @@ GnssAdapter::GnssAdapter() : mSystemStatus(SystemStatus::getInstance(mMsgTask)), mServerUrl(":"), mXtraObserver(mSystemStatus->getOsObserver(), mMsgTask), - mLocSystemInfo{}, mBlockCPIInfo{}, + mDreIntEnabled(false), + mLocSystemInfo{}, mNfwCb(NULL), mPowerOn(false), mAllowFlpNetworkFixes(0), @@ -127,7 +137,8 @@ GnssAdapter::GnssAdapter() : mLastDeleteAidingDataTime(0), mDgnssState(0), mSendNmeaConsent(false), - mDgnssLastNmeaBootTimeMilli(0) + mDgnssLastNmeaBootTimeMilli(0), + mNativeAgpsHandler(mSystemStatus->getOsObserver(), *this) { LOC_LOGD("%s]: Constructor %p", __func__, this); mLocPositionMode.mode = LOC_POSITION_MODE_INVALID; @@ -346,7 +357,8 @@ uint16_t GnssAdapter::getNumSvUsed(uint64_t svUsedIdsMask, void GnssAdapter::convertLocationInfo(GnssLocationInfoNotification& out, - const GpsLocationExtended& locationExtended) + const GpsLocationExtended& locationExtended, + enum loc_sess_status status) { out.size = sizeof(GnssLocationInfoNotification); if (GPS_LOCATION_EXTENDED_HAS_ALTITUDE_MEAN_SEA_LEVEL & locationExtended.flags) { @@ -650,6 +662,14 @@ GnssAdapter::convertLocationInfo(GnssLocationInfoNotification& out, out.flags |= GNSS_LOCATION_INFO_DR_SOLUTION_STATUS_MASK_BIT; out.drSolutionStatusMask = locationExtended.drSolutionStatusMask; } + + if (GPS_LOCATION_EXTENDED_HAS_ALTITUDE_ASSUMED & locationExtended.flags) { + out.flags |= GNSS_LOCATION_INFO_ALTITUDE_ASSUMED_BIT; + out.altitudeAssumed = locationExtended.altitudeAssumed; + } + + out.flags |= GNSS_LOCATION_INFO_SESSION_STATUS_BIT; + out.sessionStatus = status; } inline uint32_t @@ -1536,8 +1556,8 @@ GnssAdapter::gnssGetConfigCommand(GnssConfigFlagsMask configMask) { mAdapter(adapter), mApi(api), mConfigMask(configMask), - mIds(nullptr), - mCount(count) { + mCount(count), + mIds(nullptr) { if (mCount > 0) { mIds = new uint32_t[count]; if (mIds) { @@ -2458,7 +2478,10 @@ GnssAdapter::stopClientSessions(LocationAPI* client) void GnssAdapter::updateClientsEventMask() { - LOC_API_ADAPTER_EVENT_MASK_T mask = 0; + // need to register for leap second info + // for proper nmea generation + LOC_API_ADAPTER_EVENT_MASK_T mask = LOC_API_ADAPTER_BIT_LOC_SYSTEM_INFO | + LOC_API_ADAPTER_BIT_EVENT_REPORT_INFO; for (auto it=mClientData.begin(); it != mClientData.end(); ++it) { if (it->second.trackingCb != nullptr || it->second.gnssLocationInfoCb != nullptr || @@ -2493,8 +2516,6 @@ GnssAdapter::updateClientsEventMask() mask |= LOC_API_ADAPTER_BIT_GNSS_SV_POLYNOMIAL_REPORT; mask |= LOC_API_ADAPTER_BIT_PARSED_UNPROPAGATED_POSITION_REPORT; mask |= LOC_API_ADAPTER_BIT_GNSS_SV_EPHEMERIS_REPORT; - mask |= LOC_API_ADAPTER_BIT_LOC_SYSTEM_INFO; - mask |= LOC_API_ADAPTER_BIT_EVENT_REPORT_INFO; // Nhz measurement bit is set based on callback from loc eng hub // for Nhz engines. @@ -2519,6 +2540,13 @@ GnssAdapter::updateClientsEventMask() // always register for NI NOTIFY VERIFY to handle internally in HAL mask |= LOC_API_ADAPTER_BIT_NI_NOTIFY_VERIFY_REQUEST; + // Enable the latency report + if (mask & LOC_API_ADAPTER_BIT_GNSS_MEASUREMENT) { + if (mLogger.isLogEnabled()) { + mask |= LOC_API_ADAPTER_BIT_LATENCY_INFORMATION; + } + } + updateEvtMask(mask, LOC_REGISTRATION_MASK_SET); } @@ -2573,6 +2601,7 @@ GnssAdapter::restartSessions(bool modemSSR) // inform engine hub that GNSS session is about to start mEngHubProxy->gnssSetFixMode(mLocPositionMode); mEngHubProxy->gnssStartFix(); + checkUpdateDgnssNtrip(false); } checkAndRestartSPESession(); @@ -2605,6 +2634,10 @@ GnssAdapter::suspendSessions() // inform engine hub that GNSS session has stopped mEngHubProxy->gnssStopFix(); mLocApi->stopFix(nullptr); + if (isDgnssNmeaRequired()) { + mDgnssState &= ~DGNSS_STATE_NO_NMEA_PENDING; + } + stopDgnssNtrip(); mSPEAlreadyRunningAtHighestInterval = false; } } @@ -2643,6 +2676,48 @@ void GnssAdapter::checkAndRestartTimeBasedSession() } } +LocationCapabilitiesMask +GnssAdapter::getCapabilities() +{ + LocationCapabilitiesMask mask = 0; + uint32_t carrierCapabilities = ContextBase::getCarrierCapabilities(); + // time based tracking always supported + mask |= LOCATION_CAPABILITIES_TIME_BASED_TRACKING_BIT; + // geofence always supported + mask |= LOCATION_CAPABILITIES_GEOFENCE_BIT; + if (carrierCapabilities & LOC_GPS_CAPABILITY_MSB) { + mask |= LOCATION_CAPABILITIES_GNSS_MSB_BIT; + } + if (LOC_GPS_CAPABILITY_MSA & carrierCapabilities) { + mask |= LOCATION_CAPABILITIES_GNSS_MSA_BIT; + } + if (ContextBase::isMessageSupported(LOC_API_ADAPTER_MESSAGE_DISTANCE_BASE_LOCATION_BATCHING)) { + mask |= LOCATION_CAPABILITIES_TIME_BASED_BATCHING_BIT | + LOCATION_CAPABILITIES_DISTANCE_BASED_BATCHING_BIT; + } + if (ContextBase::isMessageSupported(LOC_API_ADAPTER_MESSAGE_DISTANCE_BASE_TRACKING)) { + mask |= LOCATION_CAPABILITIES_DISTANCE_BASED_TRACKING_BIT; + } + if (ContextBase::isMessageSupported(LOC_API_ADAPTER_MESSAGE_OUTDOOR_TRIP_BATCHING)) { + mask |= LOCATION_CAPABILITIES_OUTDOOR_TRIP_BATCHING_BIT; + } + if (ContextBase::gnssConstellationConfig()) { + mask |= LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT; + } + if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_DEBUG_NMEA_V02)) { + mask |= LOCATION_CAPABILITIES_DEBUG_NMEA_BIT; + } + if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_CONSTELLATION_ENABLEMENT_V02)) { + mask |= LOCATION_CAPABILITIES_CONSTELLATION_ENABLEMENT_BIT; + } + if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_AGPM_V02)) { + mask |= LOCATION_CAPABILITIES_AGPM_BIT; + } + //Get QWES feature status mask + mask |= ContextBase::getQwesFeatureStatus(); + return mask; +} + void GnssAdapter::notifyClientOfCachedLocationSystemInfo( LocationAPI* client, const LocationCallbacks& callbacks) { @@ -2759,7 +2834,6 @@ GnssAdapter::saveTrackingSession(LocationAPI* client, uint32_t sessionId, mTimeBasedTrackingSessions[key] = options; } reportPowerStateIfChanged(); - checkUpdateDgnssNtrip(false); } void @@ -2776,16 +2850,8 @@ 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(); } - bool GnssAdapter::setLocPositionMode(const LocPosMode& mode) { if (!mLocPositionMode.equals(mode)) { mLocPositionMode = mode; @@ -3003,6 +3069,8 @@ GnssAdapter::startTimeBasedTracking(LocationAPI* client, uint32_t sessionId, [this, client, sessionId] (LocationError err) { if (LOCATION_ERROR_SUCCESS != err) { eraseTrackingSession(client, sessionId); + } else { + checkUpdateDgnssNtrip(false); } reportResponse(client, err, sessionId); @@ -3344,6 +3412,11 @@ GnssAdapter::stopTracking(LocationAPI* client, uint32_t id) reportResponse(client, err, id); })); + if (isDgnssNmeaRequired()) { + mDgnssState &= ~DGNSS_STATE_NO_NMEA_PENDING; + } + stopDgnssNtrip(); + mSPEAlreadyRunningAtHighestInterval = false; } @@ -3814,6 +3887,62 @@ bool GnssAdapter::needToGenerateNmeaReport(const uint32_t &gpsTimeOfWeekMs, return retVal; } +void +GnssAdapter::logLatencyInfo() +{ + if (0 == mGnssLatencyInfoQueue.size()) { + LOC_LOGv("mGnssLatencyInfoQueue.size is 0"); + return; + } + mGnssLatencyInfoQueue.front().hlosQtimer5 = getQTimerTickCount(); + if (0 == mGnssLatencyInfoQueue.front().hlosQtimer3) { + /* if SPE from engine hub is not reported then hlosQtimer3 = 0, set it + equal to hlosQtimer2 to make sense */ + LOC_LOGv("hlosQtimer3 is 0, setting it to hlosQtimer2"); + mGnssLatencyInfoQueue.front().hlosQtimer3 = mGnssLatencyInfoQueue.front().hlosQtimer2; + } + if (0 == mGnssLatencyInfoQueue.front().hlosQtimer4) { + /* if PPE from engine hub is not reported then hlosQtimer4 = 0, set it + equal to hlosQtimer3 to make sense */ + LOC_LOGv("hlosQtimer4 is 0, setting it to hlosQtimer3"); + mGnssLatencyInfoQueue.front().hlosQtimer4 = mGnssLatencyInfoQueue.front().hlosQtimer3; + } + if (mGnssLatencyInfoQueue.front().hlosQtimer4 < mGnssLatencyInfoQueue.front().hlosQtimer3) { + /* hlosQtimer3 is timestamped when SPE from engine hub is reported, + and hlosQtimer4 is timestamped when PPE from engine hub is reported. + The order is random though, hence making sure the timestamps are sorted */ + LOC_LOGv("hlosQtimer4 is < hlosQtimer3, swapping them"); + std::swap(mGnssLatencyInfoQueue.front().hlosQtimer3, + mGnssLatencyInfoQueue.front().hlosQtimer4); + } + LOC_LOGv("meQtimer1=%" PRIi64 " " + "meQtimer2=%" PRIi64 " " + "meQtimer3=%" PRIi64 " " + "peQtimer1=%" PRIi64 " " + "peQtimer2=%" PRIi64 " " + "peQtimer3=%" PRIi64 " " + "smQtimer1=%" PRIi64 " " + "smQtimer2=%" PRIi64 " " + "smQtimer3=%" PRIi64 " " + "locMwQtimer=%" PRIi64 " " + "hlosQtimer1=%" PRIi64 " " + "hlosQtimer2=%" PRIi64 " " + "hlosQtimer3=%" PRIi64 " " + "hlosQtimer4=%" PRIi64 " " + "hlosQtimer5=%" PRIi64 " ", + mGnssLatencyInfoQueue.front().meQtimer1, mGnssLatencyInfoQueue.front().meQtimer2, + mGnssLatencyInfoQueue.front().meQtimer3, mGnssLatencyInfoQueue.front().peQtimer1, + mGnssLatencyInfoQueue.front().peQtimer2, mGnssLatencyInfoQueue.front().peQtimer3, + mGnssLatencyInfoQueue.front().smQtimer1, mGnssLatencyInfoQueue.front().smQtimer2, + mGnssLatencyInfoQueue.front().smQtimer3, mGnssLatencyInfoQueue.front().locMwQtimer, + mGnssLatencyInfoQueue.front().hlosQtimer1, mGnssLatencyInfoQueue.front().hlosQtimer2, + mGnssLatencyInfoQueue.front().hlosQtimer3, mGnssLatencyInfoQueue.front().hlosQtimer4, + mGnssLatencyInfoQueue.front().hlosQtimer5); + mLogger.log(mGnssLatencyInfoQueue.front()); + mGnssLatencyInfoQueue.pop(); + LOC_LOGv("mGnssLatencyInfoQueue.size after pop=%zu", mGnssLatencyInfoQueue.size()); +} + // only fused report (when engine hub is enabled) or // SPE report (when engine hub is disabled) will reach this function void @@ -3827,16 +3956,16 @@ GnssAdapter::reportPosition(const UlpLocation& ulpLocation, if (reportToGnssClient || reportToFlpClient) { GnssLocationInfoNotification locationInfo = {}; - convertLocationInfo(locationInfo, locationExtended); + convertLocationInfo(locationInfo, locationExtended, status); convertLocation(locationInfo.location, ulpLocation, locationExtended); - + logLatencyInfo(); for (auto it=mClientData.begin(); it != mClientData.end(); ++it) { if ((reportToFlpClient && isFlpClient(it->second)) || (reportToGnssClient && !isFlpClient(it->second))) { if (nullptr != it->second.gnssLocationInfoCb) { it->second.gnssLocationInfoCb(locationInfo); } else if ((nullptr != it->second.engineLocationsInfoCb) && - (false == initEngHubProxy())) { + (false == initEngHubProxy())) { // if engine hub is disabled, this is SPE fix from modem // we need to mark one copy marked as fused and one copy marked as PPE // and dispatch it to the engineLocationsInfoCb @@ -3911,6 +4040,25 @@ GnssAdapter::reportPosition(const UlpLocation& ulpLocation, } } +void +GnssAdapter::reportLatencyInfoEvent(const GnssLatencyInfo& gnssLatencyInfo) +{ + struct MsgReportLatencyInfo : public LocMsg { + GnssAdapter& mAdapter; + GnssLatencyInfo mGnssLatencyInfo; + inline MsgReportLatencyInfo(GnssAdapter& adapter, + const GnssLatencyInfo& gnssLatencyInfo) : + mGnssLatencyInfo(gnssLatencyInfo), + mAdapter(adapter) {} + inline virtual void proc() const { + mAdapter.mGnssLatencyInfoQueue.push(mGnssLatencyInfo); + LOC_LOGv("mGnssLatencyInfoQueue.size after push=%zu", + mAdapter.mGnssLatencyInfoQueue.size()); + } + }; + sendMsg(new MsgReportLatencyInfo(*this, gnssLatencyInfo)); +} + void GnssAdapter::reportEnginePositions(unsigned int count, const EngineLocationInfo* locationArr) @@ -3936,13 +4084,30 @@ GnssAdapter::reportEnginePositions(unsigned int count, } if (needReportEnginePositions) { - convertLocationInfo(locationInfo[i], engLocation->locationExtended); + convertLocationInfo(locationInfo[i], engLocation->locationExtended, + engLocation->sessionStatus); convertLocation(locationInfo[i].location, engLocation->location, engLocation->locationExtended); } } + const EngineLocationInfo* engLocation = locationArr; + LOC_LOGv("engLocation->locationExtended.locOutputEngType=%d", + engLocation->locationExtended.locOutputEngType); + + if (0 != mGnssLatencyInfoQueue.size()) { + if ((GPS_LOCATION_EXTENDED_HAS_OUTPUT_ENG_TYPE & engLocation->locationExtended.flags) && + (LOC_OUTPUT_ENGINE_SPE == engLocation->locationExtended.locOutputEngType)) { + mGnssLatencyInfoQueue.front().hlosQtimer3 = getQTimerTickCount(); + LOC_LOGv("SPE hlosQtimer3=%" PRIi64 " ", mGnssLatencyInfoQueue.front().hlosQtimer3); + } + if ((GPS_LOCATION_EXTENDED_HAS_OUTPUT_ENG_TYPE & engLocation->locationExtended.flags) && + (LOC_OUTPUT_ENGINE_PPE == engLocation->locationExtended.locOutputEngType)) { + mGnssLatencyInfoQueue.front().hlosQtimer4 = getQTimerTickCount(); + LOC_LOGv("PPE hlosQtimer4=%" PRIi64 " ", mGnssLatencyInfoQueue.front().hlosQtimer4); + } + } if (needReportEnginePositions) { for (auto it=mClientData.begin(); it != mClientData.end(); ++it) { if (nullptr != it->second.engineLocationsInfoCb) { @@ -4709,8 +4874,33 @@ bool GnssAdapter::reportGnssAdditionalSystemInfoEvent( return true; } +bool GnssAdapter::reportQwesCapabilities( + const std::unordered_map &featureMap) +{ + struct MsgReportQwesFeatureStatus : public LocMsg { + GnssAdapter& mAdapter; + const std::unordered_map mFeatureMap; + inline MsgReportQwesFeatureStatus(GnssAdapter& adapter, + const std::unordered_map &featureMap) : + LocMsg(), + mAdapter(adapter), + mFeatureMap(std::move(featureMap)) {} + inline virtual void proc() const { + LOC_LOGi("ReportQwesFeatureStatus before caps %" PRIx64 " ", + mAdapter.getCapabilities()); + ContextBase::setQwesFeatureStatus(mFeatureMap); + LOC_LOGi("ReportQwesFeatureStatus After caps %" PRIx64 " ", + mAdapter.getCapabilities()); + mAdapter.broadcastCapabilities(mAdapter.getCapabilities()); + } + }; + + sendMsg(new MsgReportQwesFeatureStatus(*this, featureMap)); + return true; +} + void GnssAdapter::initOdcpiCommand(const OdcpiRequestCallback& callback, - OdcpiPrioritytype priority) + OdcpiPrioritytype priority) { struct MsgInitOdcpi : public LocMsg { GnssAdapter& mAdapter; @@ -4838,23 +5028,20 @@ GnssAdapter::reportGnssEngEnergyConsumedEvent(uint64_t energyConsumedSinceFirstB void GnssAdapter::initDefaultAgps() { LOC_LOGD("%s]: ", __func__); - void *handle = nullptr; - if ((handle = dlopen("libloc_net_iface.so", RTLD_NOW)) == nullptr) { - LOC_LOGD("%s]: libloc_net_iface.so not found !", __func__); - return; - } - LocAgpsGetAgpsCbInfo getAgpsCbInfo = (LocAgpsGetAgpsCbInfo) - dlsym(handle, "LocNetIfaceAgps_getAgpsCbInfo"); - if (getAgpsCbInfo == nullptr) { - LOC_LOGE("%s]: Failed to get method LocNetIfaceAgps_getStatusCb", __func__); - dlclose(handle); - return; + LocAgpsGetAgpsCbInfo getAgpsCbInfo = + (LocAgpsGetAgpsCbInfo)dlGetSymFromLib(handle, "libloc_net_iface.so", + "LocNetIfaceAgps_getAgpsCbInfo"); + // Below step is to make sure we init nativeAgpsHandler + // for Android platforms only + AgpsCbInfo cbInfo = {}; + if (nullptr != getAgpsCbInfo) { + cbInfo = getAgpsCbInfo(agpsOpenResultCb, agpsCloseResultCb, this); + } else { + cbInfo = mNativeAgpsHandler.getAgpsCbInfo(); } - AgpsCbInfo& cbInfo = getAgpsCbInfo(agpsOpenResultCb, agpsCloseResultCb, this); - if (cbInfo.statusV4Cb == nullptr) { LOC_LOGE("%s]: statusV4Cb is nullptr!", __func__); dlclose(handle); @@ -5926,7 +6113,7 @@ 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 + // save the lever ARM config info for translating position from GNSS antenna based // to VRP based if (mConfigInfo.leverArmValidMask & LEVER_ARM_TYPE_GNSS_TO_VRP_BIT) { mAdapter.mLocConfigInfo.leverArmConfigInfo.leverArmValidMask |= @@ -6181,6 +6368,47 @@ uint32_t GnssAdapter::configDeadReckoningEngineParamsCommand( return sessionId; } +uint32_t GnssAdapter::configEngineRunStateCommand( + PositioningEngineMask engType, LocEngineRunState engState) { + + // generated session id will be none-zero + uint32_t sessionId = generateSessionId(); + LOC_LOGe("session id %u, eng type 0x%x, eng state %d, dre enabled %d", + sessionId, engType, engState, mDreIntEnabled); + + struct MsgConfigEngineRunState : public LocMsg { + GnssAdapter& mAdapter; + uint32_t mSessionId; + PositioningEngineMask mEngType; + LocEngineRunState mEngState; + + inline MsgConfigEngineRunState(GnssAdapter& adapter, + uint32_t sessionId, + PositioningEngineMask engType, + LocEngineRunState engState) : + LocMsg(), + mAdapter(adapter), + mSessionId(sessionId), + mEngType(engType), + mEngState(engState) {} + inline virtual void proc() const { + LocationError err = LOCATION_ERROR_NOT_SUPPORTED; + // Currently, only DR engine supports pause/resume request + if ((mEngType == DEAD_RECKONING_ENGINE) && + (mAdapter.mDreIntEnabled == true)) { + if (true == mAdapter.mEngHubProxy->configEngineRunState(mEngType, mEngState)) { + err = LOCATION_ERROR_SUCCESS; + } + } + mAdapter.reportResponse(err, mSessionId); + } + }; + + sendMsg(new MsgConfigEngineRunState(*this, sessionId, engType, engState)); + + return sessionId; +} + void GnssAdapter::reportGnssConfigEvent(uint32_t sessionId, const GnssConfig& gnssConfig) { struct MsgReportGnssConfig : public LocMsg { @@ -6255,7 +6483,12 @@ GnssAdapter::initEngHubProxy() { strlen(PROCESS_NAME_ENGINE_SERVICE)) == 0) && (processInfoList[i].proc_status == ENABLED)) { pluginDaemonEnabled = true; - break; + // check if this is DRE-INT engine + if ((processInfoList[i].args[1]!= nullptr) && + (strncmp(processInfoList[i].args[1], "DRE-INT", sizeof("DRE-INT")) == 0)) { + mDreIntEnabled = true; + break; + } } } @@ -6315,14 +6548,20 @@ GnssAdapter::initEngHubProxy() { mNHzNeeded = nHzNeeded; checkAndRestartSPESession(); } - }; + }; + + GnssAdapterUpdateQwesFeatureStatusCb updateQwesFeatureStatusCb = + [this] (const std::unordered_map &featureMap) { + reportQwesCapabilities(featureMap); + }; getEngHubProxyFn* getter = (getEngHubProxyFn*) dlsym(handle, "getEngHubProxy"); if(getter != nullptr) { EngineHubProxyBase* hubProxy = (*getter) (mMsgTask, mSystemStatus->getOsObserver(), - reportPositionEventCb, - reportSvEventCb, reqAidingDataCb, - updateNHzRequirementCb); + reportPositionEventCb, + reportSvEventCb, reqAidingDataCb, + updateNHzRequirementCb, + updateQwesFeatureStatusCb); if (hubProxy != nullptr) { mEngHubProxy = hubProxy; engHubLoadSuccessful = true; @@ -6539,9 +6778,6 @@ void GnssAdapter::enablePPENtripStreamCommand(const GnssNtripConnectionParams& p } 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(), @@ -6555,7 +6791,8 @@ void GnssAdapter::handleEnablePPENtrip(const GnssNtripConnectionParams& params) 0 == pNtripParams->mountPoint.compare(params.mountPoint) && 0 == pNtripParams->username.compare(params.username) && 0 == pNtripParams->password.compare(params.password) && - params.requiresNmeaLocation == params.requiresNmeaLocation) { + pNtripParams->requiresNmeaLocation == params.requiresNmeaLocation && + mDgnssState & DGNSS_STATE_ENABLE_NTRIP_COMMAND) { LOC_LOGd("received same Ntrip param"); return; } @@ -6590,13 +6827,14 @@ void GnssAdapter::disablePPENtripStreamCommand() { } void GnssAdapter::handleDisablePPENtrip() { - mStartDgnssNtripParams.clear(); mDgnssState &= ~DGNSS_STATE_ENABLE_NTRIP_COMMAND; mDgnssState |= DGNSS_STATE_NO_NMEA_PENDING; stopDgnssNtrip(); } void GnssAdapter::checkUpdateDgnssNtrip(bool isLocationValid) { + LOC_LOGd("isInSession %d mDgnssState 0x%x isLocationValid %d", + isInSession(), mDgnssState, isLocationValid); if (isInSession()) { uint64_t curBootTime = getBootTimeMilliSec(); if (mDgnssState == (DGNSS_STATE_ENABLE_NTRIP_COMMAND | DGNSS_STATE_NO_NMEA_PENDING)) { @@ -6615,12 +6853,11 @@ void GnssAdapter::checkUpdateDgnssNtrip(bool isLocationValid) { } void GnssAdapter::stopDgnssNtrip() { + LOC_LOGd("isInSession %d mDgnssState 0x%x", isInSession(), mDgnssState); + mStartDgnssNtripParams.nmea.clear(); if (mDgnssState & DGNSS_STATE_NTRIP_SESSION_STARTED) { mDgnssState &= ~DGNSS_STATE_NTRIP_SESSION_STARTED; mXtraObserver.stopDgnssSource(); - } else { - LOC_LOGd("isInSession %d mDgnssState 0x%x", - isInSession(), mDgnssState); } } diff --git a/gps/gnss/GnssAdapter.h b/gps/gnss/GnssAdapter.h index 20064e60..6b8d024b 100644 --- a/gps/gnss/GnssAdapter.h +++ b/gps/gnss/GnssAdapter.h @@ -39,6 +39,9 @@ #include #include #include +#include +#include +#include #define MAX_URL_LEN 256 #define NMEA_SENTENCE_MAX_LENGTH 200 @@ -177,6 +180,23 @@ typedef uint16_t DGnssStateBitMask; #define DGNSS_STATE_NO_NMEA_PENDING 0X02 #define DGNSS_STATE_NTRIP_SESSION_STARTED 0X04 +class GnssReportLoggerUtil { +public: + typedef void (*LogGnssLatency)(const GnssLatencyInfo& gnssLatencyMeasInfo); + + GnssReportLoggerUtil() : mLogLatency(nullptr) { + const char* libname = "liblocdiagiface.so"; + void* libHandle = nullptr; + mLogLatency = (LogGnssLatency)dlGetSymFromLib(libHandle, libname, "LogGnssLatency"); + } + + bool isLogEnabled(); + void log(const GnssLatencyInfo& gnssLatencyMeasInfo); + +private: + LogGnssLatency mLogLatency; +}; + class GnssAdapter : public LocAdapterBase { /* ==== Engine Hub ===================================================================== */ @@ -258,6 +278,12 @@ class GnssAdapter : public LocAdapterBase { BlockCPIInfo mBlockCPIInfo; bool mPowerOn; uint32_t mAllowFlpNetworkFixes; + std::queue mGnssLatencyInfoQueue; + GnssReportLoggerUtil mLogger; + bool mDreIntEnabled; + + /* === NativeAgpsHandler ======================================================== */ + NativeAgpsHandler mNativeAgpsHandler; /* === Misc callback from QMI LOC API ============================================== */ GnssEnergyConsumedCallback mGnssEnergyConsumedCb; @@ -268,7 +294,8 @@ class GnssAdapter : public LocAdapterBase { static void convertLocation(Location& out, const UlpLocation& ulpLocation, const GpsLocationExtended& locationExtended); static void convertLocationInfo(GnssLocationInfoNotification& out, - const GpsLocationExtended& locationExtended); + const GpsLocationExtended& locationExtended, + loc_sess_status status); static uint16_t getNumSvUsed(uint64_t svUsedIdsMask, int totalSvCntInThisConstellation); @@ -290,6 +317,8 @@ protected: /* ==== CLIENT ========================================================================= */ virtual void updateClientsEventMask(); virtual void stopClientSessions(LocationAPI* client); + inline void setNmeaReportRateConfig(); + void logLatencyInfo(); public: @@ -434,6 +463,8 @@ public: inline void antennaInfoCloseCommand() { mIsAntennaInfoInterfaceOpened = false; } uint32_t configMinGpsWeekCommand(uint16_t minGpsWeek); uint32_t configDeadReckoningEngineParamsCommand(const DeadReckoningEngineConfig& dreConfig); + uint32_t configEngineRunStateCommand(PositioningEngineMask engType, + LocEngineRunState engState); /* ========= ODCPI ===================================================================== */ /* ======== COMMANDS ====(Called from Client Thread)==================================== */ @@ -489,6 +520,11 @@ public: virtual bool reportGnssAdditionalSystemInfoEvent( GnssAdditionalSystemInfo& additionalSystemInfo); virtual void reportNfwNotificationEvent(GnssNfwNotification& notification); + virtual void reportLatencyInfoEvent(const GnssLatencyInfo& gnssLatencyInfo); + virtual bool reportQwesCapabilities + ( + const std::unordered_map &featureMap + ); /* ======== UTILITIES ================================================================= */ bool needReportForGnssClient(const UlpLocation& ulpLocation, @@ -589,6 +625,7 @@ public: void setSuplHostServer(const char* server, int port, LocServerType type); void notifyClientOfCachedLocationSystemInfo(LocationAPI* client, const LocationCallbacks& callbacks); + LocationCapabilitiesMask getCapabilities(); void updateSystemPowerStateCommand(PowerStateType systemPowerState); /*==== DGnss Usable Report Flag ====================================================*/ diff --git a/gps/gnss/Makefile.am b/gps/gnss/Makefile.am index db20c15a..dd313a1a 100644 --- a/gps/gnss/Makefile.am +++ b/gps/gnss/Makefile.am @@ -13,7 +13,8 @@ libgnss_la_SOURCES = \ location_gnss.cpp \ GnssAdapter.cpp \ XtraSystemStatusObserver.cpp \ - Agps.cpp + Agps.cpp \ + NativeAgpsHandler.cpp if USE_GLIB libgnss_la_CFLAGS = -DUSE_GLIB $(AM_CFLAGS) @GLIB_CFLAGS@ diff --git a/gps/gnss/NativeAgpsHandler.cpp b/gps/gnss/NativeAgpsHandler.cpp new file mode 100644 index 00000000..ce4c03a6 --- /dev/null +++ b/gps/gnss/NativeAgpsHandler.cpp @@ -0,0 +1,127 @@ +/* Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation, nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +#define LOG_TAG "LocSvc_NativeAgpsHandler" + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace loc_core; + +// IDataItemObserver overrides +void NativeAgpsHandler::getName(string& name) { + name = "NativeAgpsHandler"; +} + +void NativeAgpsHandler::notify(const list& dlist) { + for (auto each : dlist) { + switch (each->getId()) { + case NETWORKINFO_DATA_ITEM_ID: { + NetworkInfoDataItemBase* networkInfo = + static_cast(each); + uint64_t mobileBit = (uint64_t )1 << loc_core::TYPE_MOBILE; + uint64_t allTypes = networkInfo->mAllTypes; + mConnected = ((networkInfo->mAllTypes & mobileBit) == mobileBit); + /** + * mApn Telephony preferred Access Point Name to use for + * carrier data connection when connected to a cellular network. + * Empty string, otherwise. + */ + mApn = networkInfo->mApn; + LOC_LOGd("updated mConnected:%d, mApn: %s", mConnected, mApn.c_str()); + break; + } + default: + break; + } + } +} + +NativeAgpsHandler* NativeAgpsHandler::sLocalHandle = nullptr; +NativeAgpsHandler::NativeAgpsHandler(IOsObserver* sysStatObs, GnssAdapter& adapter) : + mSystemStatusObsrvr(sysStatObs), mConnected(false), mAdapter(adapter) { + sLocalHandle = this; + list subItemIdList = {NETWORKINFO_DATA_ITEM_ID}; + mSystemStatusObsrvr->subscribe(subItemIdList, this); +} + +NativeAgpsHandler::~NativeAgpsHandler() { + if (nullptr != mSystemStatusObsrvr) { + LOC_LOGd("Unsubscribe for network info."); + list subItemIdList = {NETWORKINFO_DATA_ITEM_ID}; + mSystemStatusObsrvr->unsubscribe(subItemIdList, this); + } + sLocalHandle = nullptr; + mSystemStatusObsrvr = nullptr; +} + + +AgpsCbInfo NativeAgpsHandler::getAgpsCbInfo() { + AgpsCbInfo nativeCbInfo = {}; + nativeCbInfo.statusV4Cb = (void*)agnssStatusIpV4Cb; + nativeCbInfo.atlType = AGPS_ATL_TYPE_WWAN; + return nativeCbInfo; +} + +void NativeAgpsHandler::agnssStatusIpV4Cb(AGnssExtStatusIpV4 statusInfo) { + if (nullptr != sLocalHandle) { + sLocalHandle->processATLRequestRelease(statusInfo); + } else { + LOC_LOGe("sLocalHandle is null"); + } +} + +void NativeAgpsHandler::processATLRequestRelease(AGnssExtStatusIpV4 statusInfo) { + if (LOC_AGPS_TYPE_WWAN_ANY == statusInfo.type) { + LOC_LOGd("status.type = %d status.apnTypeMask = 0x%X", statusInfo.type, + statusInfo.apnTypeMask); + switch (statusInfo.status) { + case LOC_GPS_REQUEST_AGPS_DATA_CONN: + if (mConnected) { + mAdapter.dataConnOpenCommand(LOC_AGPS_TYPE_WWAN_ANY, mApn.c_str(), mApn.size(), + AGPS_APN_BEARER_IPV4); + } else { + mAdapter.dataConnFailedCommand(LOC_AGPS_TYPE_WWAN_ANY); + } + break; + case LOC_GPS_RELEASE_AGPS_DATA_CONN: + mAdapter.dataConnClosedCommand(LOC_AGPS_TYPE_WWAN_ANY); + break; + default: + LOC_LOGe("Invalid Request: %d", statusInfo.status); + } + } else { + LOC_LOGe("mAgpsManger is null or invalid request type!"); + } +} diff --git a/gps/gnss/NativeAgpsHandler.h b/gps/gnss/NativeAgpsHandler.h new file mode 100644 index 00000000..fb0b46cc --- /dev/null +++ b/gps/gnss/NativeAgpsHandler.h @@ -0,0 +1,64 @@ +/* Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation, nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +#ifndef NATIVEAGPSHANDLER_H +#define NATIVEAGPSHANDLER_H + +#include +#include +#include +#include +#include +#include + +using namespace std; +using loc_core::IOsObserver; +using loc_core::IDataItemObserver; +using loc_core::IDataItemCore; + +class GnssAdapter; + +class NativeAgpsHandler : public IDataItemObserver { +public: + NativeAgpsHandler(IOsObserver* sysStatObs, GnssAdapter& adapter); + ~NativeAgpsHandler(); + AgpsCbInfo getAgpsCbInfo(); + // IDataItemObserver overrides + virtual void notify(const list& dlist); + inline virtual void getName(string& name); +private: + static NativeAgpsHandler* sLocalHandle; + static void agnssStatusIpV4Cb(AGnssExtStatusIpV4 statusInfo); + void processATLRequestRelease(AGnssExtStatusIpV4 statusInfo); + IOsObserver* mSystemStatusObsrvr; + bool mConnected; + string mApn; + GnssAdapter& mAdapter; +}; + +#endif // NATIVEAGPSHANDLER_H diff --git a/gps/gnss/location_gnss.cpp b/gps/gnss/location_gnss.cpp index d0978f44..0454a132 100644 --- a/gps/gnss/location_gnss.cpp +++ b/gps/gnss/location_gnss.cpp @@ -66,8 +66,8 @@ static void agpsDataConnOpen(AGpsExtType agpsType, const char* apnName, int apnL static void agpsDataConnClosed(AGpsExtType agpsType); static void agpsDataConnFailed(AGpsExtType agpsType); static void getDebugReport(GnssDebugReport& report); -static void updateConnectionStatus(bool connected, int8_t type, bool roaming = false, - NetworkHandle networkHandle = NETWORK_HANDLE_UNKNOWN); +static void updateConnectionStatus(bool connected, int8_t type, bool roaming, + NetworkHandle networkHandle, string& apn); static void getGnssEnergyConsumed(GnssEnergyConsumedCallback energyConsumedCb); static void enableNfwLocationAccess(bool enable); static void nfwInit(const NfwCbInfo& cbInfo); @@ -103,6 +103,7 @@ static bool measCorrSetCorrections(const GnssMeasurementCorrections gnssMeasCorr static void measCorrClose(); static uint32_t antennaInfoInit(const antennaInfoCb antennaInfoCallback); static void antennaInfoClose(); +static uint32_t configEngineRunState(PositioningEngineMask engType, LocEngineRunState engState); static const GnssInterface gGnssInterface = { sizeof(GnssInterface), @@ -160,7 +161,8 @@ static const GnssInterface gGnssInterface = { disablePPENtripStream, gnssUpdateSecondaryBandConfig, gnssGetSecondaryBandConfig, - resetNetworkInfo + resetNetworkInfo, + configEngineRunState }; #ifndef DEBUG_X86 @@ -369,10 +371,11 @@ static void getDebugReport(GnssDebugReport& report) { } static void updateConnectionStatus(bool connected, int8_t type, - bool roaming, NetworkHandle networkHandle) { + bool roaming, NetworkHandle networkHandle, + string& apn) { if (NULL != gGnssAdapter) { gGnssAdapter->getSystemStatus()->eventConnectionStatus( - connected, type, roaming, networkHandle); + connected, type, roaming, networkHandle, apn); } } @@ -580,3 +583,11 @@ static void disablePPENtripStream(){ gGnssAdapter->disablePPENtripStreamCommand(); } } + +static uint32_t configEngineRunState(PositioningEngineMask engType, LocEngineRunState engState) { + if (NULL != gGnssAdapter) { + return gGnssAdapter->configEngineRunStateCommand(engType, engState); + } else { + return 0; + } +} diff --git a/gps/location/ILocationAPI.h b/gps/location/ILocationAPI.h index 96076e9e..29846ac4 100644 --- a/gps/location/ILocationAPI.h +++ b/gps/location/ILocationAPI.h @@ -363,6 +363,44 @@ public: LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid */ virtual uint32_t configDeadReckoningEngineParams(const DeadReckoningEngineConfig& dreConfig)=0; + + /** @brief + This API is used to instruct the specified engine to be in + the pause/resume state.
+ + When the engine is placed in paused state, the engine will + stop. If there is an on-going session, engine will no longer + produce fixes. In the paused state, calling API to delete + aiding data from the paused engine may not have effect. + Request to delete Aiding data shall be issued after + engine resume.
+ + Currently, only DRE engine will support pause/resume + request. responseCb() will return not supported when request + is made to pause/resume none-DRE engine.
+ + Request to pause/resume DRE engine can be made with or + without an on-going session. With QDR engine, on resume, + GNSS position & heading re-acquisition is needed for DR + engine to engage. If DR engine is already in the requested + state, the request will be no-op.
+ + @param + engType: the engine that is instructed to change its run + state.
+ + engState: the new engine run state that the engine is + instructed to be in.
+ + @return + A session id that will be returned in responseCallback to + match command with response. This effect is global for all + clients of LocationAPI responseCallback returns: + LOCATION_ERROR_SUCCESS if successful + LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid + */ + virtual uint32_t configEngineRunState(PositioningEngineMask engType, + LocEngineRunState engState) = 0; }; #endif /* ILOCATIONAPI_H */ diff --git a/gps/location/LocationAPI.cpp b/gps/location/LocationAPI.cpp index 06c1e46c..3a50c46b 100644 --- a/gps/location/LocationAPI.cpp +++ b/gps/location/LocationAPI.cpp @@ -39,6 +39,15 @@ typedef const GnssInterface* (getGnssInterface)(); typedef const GeofenceInterface* (getGeofenceInterface)(); typedef const BatchingInterface* (getBatchingInterface)(); +typedef void (createOSFramework)(); +typedef void (destroyOSFramework)(); + +// GTP services +typedef uint32_t (setOptInStatusGetter)(bool userConsent, responseCallback* callback); +typedef void (enableProviderGetter)(); +typedef void (disableProviderGetter)(); +typedef void (getSingleNetworkLocationGetter)(trackingCallback* callback); +typedef void (stopNetworkLocationGetter)(trackingCallback* callback); typedef struct { // bit mask of the adpaters that we need to wait for the removeClientCompleteCallback @@ -68,6 +77,7 @@ static pthread_mutex_t gDataMutex = PTHREAD_MUTEX_INITIALIZER; static bool gGnssLoadFailed = false; static bool gBatchingLoadFailed = false; static bool gGeofenceLoadFailed = false; +static uint32_t gOSFrameworkRefCount = 0; template static const T1* loadLocationInterface(const char* library, const char* name) { @@ -80,6 +90,28 @@ static const T1* loadLocationInterface(const char* library, const char* name) { } } +static void createOSFrameworkInstance() { + void* libHandle = nullptr; + createOSFramework* getter = (createOSFramework*)dlGetSymFromLib(libHandle, + "liblocationservice_glue.so", "createOSFramework"); + if (getter != nullptr) { + (*getter)(); + } else { + LOC_LOGe("dlGetSymFromLib failed for liblocationservice_glue.so"); + } +} + +static void destroyOSFrameworkInstance() { + void* libHandle = nullptr; + destroyOSFramework* getter = (destroyOSFramework*)dlGetSymFromLib(libHandle, + "liblocationservice_glue.so", "destroyOSFramework"); + if (getter != nullptr) { + (*getter)(); + } else { + LOC_LOGe("dlGetSymFromLib failed for liblocationservice_glue.so"); + } +} + static bool needsGnssTrackingInfo(LocationCallbacks& locationCallbacks) { return (locationCallbacks.gnssLocationInfoCb != nullptr || @@ -163,6 +195,7 @@ LocationAPI::createInstance (LocationCallbacks& locationCallbacks) if (nullptr == locationCallbacks.capabilitiesCb || nullptr == locationCallbacks.responseCb || nullptr == locationCallbacks.collectiveResponseCb) { + LOC_LOGe("missing mandatory callback, return null"); return NULL; } @@ -171,6 +204,11 @@ LocationAPI::createInstance (LocationCallbacks& locationCallbacks) pthread_mutex_lock(&gDataMutex); + gOSFrameworkRefCount++; + if (1 == gOSFrameworkRefCount) { + createOSFrameworkInstance(); + } + if (isGnssClient(locationCallbacks)) { if (NULL == gData.gnssInterface && !gGnssLoadFailed) { gData.gnssInterface = @@ -296,6 +334,11 @@ LocationAPI::destroy(locationApiDestroyCompleteCallback destroyCompleteCb) __func__, __LINE__, this); } + if (1 == gOSFrameworkRefCount) { + destroyOSFrameworkInstance(); + } + gOSFrameworkRefCount--; + pthread_mutex_unlock(&gDataMutex); if (invokeDestroyCb) { if (!destroyCompleteCb) { @@ -606,6 +649,52 @@ LocationAPI::gnssNiResponse(uint32_t id, GnssNiResponse response) pthread_mutex_unlock(&gDataMutex); } +void LocationAPI::enableNetworkProvider() { + void* libHandle = nullptr; + enableProviderGetter* setter = (enableProviderGetter*)dlGetSymFromLib(libHandle, + "liblocationservice_glue.so", "enableNetworkProvider"); + if (setter != nullptr) { + (*setter)(); + } else { + LOC_LOGe("dlGetSymFromLib failed for liblocationservice_glue.so"); + } +} + +void LocationAPI::disableNetworkProvider() { + void* libHandle = nullptr; + disableProviderGetter* setter = (disableProviderGetter*)dlGetSymFromLib(libHandle, + "liblocationservice_glue.so", "disableNetworkProvider"); + if (setter != nullptr) { + (*setter)(); + } else { + LOC_LOGe("dlGetSymFromLib failed for liblocationservice_glue.so"); + } +} + +void LocationAPI::startNetworkLocation(trackingCallback* callback) { + void* libHandle = nullptr; + getSingleNetworkLocationGetter* setter = + (getSingleNetworkLocationGetter*)dlGetSymFromLib(libHandle, + "liblocationservice_glue.so", "startNetworkLocation"); + if (setter != nullptr) { + (*setter)(callback); + } else { + LOC_LOGe("dlGetSymFromLib failed for liblocationservice_glue.so"); + } +} + +void LocationAPI::stopNetworkLocation(trackingCallback* callback) { + void* libHandle = nullptr; + stopNetworkLocationGetter* setter = (stopNetworkLocationGetter*)dlGetSymFromLib(libHandle, + "liblocationservice_glue.so", "stopNetworkLocation"); + if (setter != nullptr) { + LOC_LOGe("called"); + (*setter)(callback); + } else { + LOC_LOGe("dlGetSymFromLib failed for liblocationservice_glue.so"); + } +} + LocationControlAPI* LocationControlAPI::createInstance(LocationControlCallbacks& locationControlCallbacks) { @@ -857,3 +946,31 @@ uint32_t LocationControlAPI::configDeadReckoningEngineParams( pthread_mutex_unlock(&gDataMutex); return id; } + +uint32_t LocationControlAPI::configEngineRunState( + PositioningEngineMask engType, LocEngineRunState engState) { + uint32_t id = 0; + pthread_mutex_lock(&gDataMutex); + + if (gData.gnssInterface != NULL) { + id = gData.gnssInterface->configEngineRunState(engType, engState); + } else { + LOC_LOGe("No gnss interface available for Location Control API"); + } + + pthread_mutex_unlock(&gDataMutex); + return id; +} + +uint32_t LocationControlAPI::setOptInStatus(bool userConsent) { + void* libHandle = nullptr; + uint32_t sessionId = 0; + setOptInStatusGetter* setter = (setOptInStatusGetter*)dlGetSymFromLib(libHandle, + "liblocationservice_glue.so", "setOptInStatus"); + if (setter != nullptr) { + sessionId = (*setter)(userConsent, &gData.controlCallbacks.responseCb); + } else { + LOC_LOGe("dlGetSymFromLib failed for liblocationservice_glue.so"); + } + return sessionId; +} diff --git a/gps/location/LocationAPI.h b/gps/location/LocationAPI.h index 21a3a1fa..7c705064 100644 --- a/gps/location/LocationAPI.h +++ b/gps/location/LocationAPI.h @@ -178,6 +178,20 @@ public: LOCATION_ERROR_INVALID_PARAMETER if any parameters in GnssNiResponse are invalid LOCATION_ERROR_ID_UNKNOWN if id does not match a gnssNiCallback */ virtual void gnssNiResponse(uint32_t id, GnssNiResponse response) override; + + /* ================================== NETWORK PROVIDER =========================== */ + + /* enableNetworkProvider enables Network Provider */ + virtual void enableNetworkProvider(); + + /* disableNetworkProvider disables Network Provider */ + virtual void disableNetworkProvider(); + + /* startNetworkLocation start a single shot network location request */ + virtual void startNetworkLocation(trackingCallback* callback); + + /* stopNetworkLocation stop any ongoing network location request */ + virtual void stopNetworkLocation(trackingCallback* callback); }; typedef struct { @@ -442,6 +456,57 @@ public: */ virtual uint32_t configDeadReckoningEngineParams( const DeadReckoningEngineConfig& dreConfig) override; + + /** @brief + This API is used to instruct the specified engine to be in + the pause/resume state.
+ + When the engine is placed in paused state, the engine will + stop. If there is an on-going session, engine will no longer + produce fixes. In the paused state, calling API to delete + aiding data from the paused engine may not have effect. + Request to delete Aiding data shall be issued after + engine resume.
+ + Currently, only DRE engine will support pause/resume + request. responseCb() will return not supported when request + is made to pause/resume none-DRE engine.
+ + Request to pause/resume DRE engine can be made with or + without an on-going session. With QDR engine, on resume, GNSS + position & heading re-acquisition is needed for DR engine to + engage. If DR engine is already in the requested state, the + request will be no-op.
+ + @param + engType: the engine that is instructed to change its run + state.
+ + engState: the new engine run state that the engine is + instructed to be in.
+ + @return + A session id that will be returned in responseCallback to + match command with response. This effect is global for all + clients of LocationAPI responseCallback returns: + LOCATION_ERROR_SUCCESS if successful + LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid + */ + virtual uint32_t configEngineRunState(PositioningEngineMask engType, + LocEngineRunState engState) override; + + /** @brief + Set the EULA opt-in status from system user. This is used as consent to + use network-based positioning. + + @param + userConsnt: user agrees to use GTP service or not. + + @return + A session id that will be returned in responseCallback to + match command with response. + */ + virtual uint32_t setOptInStatus(bool userConsent); }; #endif /* LOCATIONAPI_H */ diff --git a/gps/location/LocationDataTypes.h b/gps/location/LocationDataTypes.h index 9fc40aff..b85464a4 100644 --- a/gps/location/LocationDataTypes.h +++ b/gps/location/LocationDataTypes.h @@ -61,7 +61,8 @@ typedef enum { LOCATION_ERROR_ID_UNKNOWN, LOCATION_ERROR_ALREADY_STARTED, LOCATION_ERROR_GEOFENCES_AT_MAX, - LOCATION_ERROR_NOT_SUPPORTED + LOCATION_ERROR_NOT_SUPPORTED, + LOCATION_ERROR_TIMEOUT, } LocationError; // Flags to indicate which values are valid in a Location @@ -209,7 +210,9 @@ typedef enum { 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 + GNSS_LOCATION_INFO_DR_SOLUTION_STATUS_MASK_BIT = (1ULL<<31), // Valid DR solution status + GNSS_LOCATION_INFO_ALTITUDE_ASSUMED_BIT = (1ULL<<32), // Valid altitude assumed + GNSS_LOCATION_INFO_SESSION_STATUS_BIT = (1ULL<<33), // session status } GnssLocationInfoFlagBits; typedef enum { @@ -233,7 +236,8 @@ typedef enum { GEOFENCE_STATUS_AVAILABILE_YES, } GeofenceStatusAvailable; -typedef uint32_t LocationCapabilitiesMask; +// Set of masks for Modem and QWES capabilities. +typedef uint64_t LocationCapabilitiesMask; typedef enum { // supports startTracking API with minInterval param LOCATION_CAPABILITIES_TIME_BASED_TRACKING_BIT = (1<<0), @@ -267,8 +271,86 @@ typedef enum { LOCATION_CAPABILITIES_CONFORMITY_INDEX_BIT = (1<<14), // support precise location edgnss LOCATION_CAPABILITIES_EDGNSS_BIT = (1<<15), + // Modem supports Carrier Phase for Precise Positioning + // Measurement Engine (PPME). + LOCATION_CAPABILITIES_QWES_CARRIER_PHASE_BIT = (1<<16), + // Modem supports SV Polynomial for tightly coupled external + // DR support. This is a Standalone Feature. + LOCATION_CAPABILITIES_QWES_SV_POLYNOMIAL_BIT = (1<<17), + // Modem supports SV Ephemeris for tightly coupled external + // PPE engines. This is a Standalone Feature. + LOCATION_CAPABILITIES_QWES_SV_EPHEMERIS_BIT = (1<<18), + // Modem supports GNSS Single Frequency feature. This is a + // Standalone Feature. + LOCATION_CAPABILITIES_QWES_GNSS_SINGLE_FREQUENCY = (1<<19), + // Modem supports GNSS Multi Frequency feature. Multi Frequency + // enables Single frequency also. + LOCATION_CAPABILITIES_QWES_GNSS_MULTI_FREQUENCY = (1<<20), + // This mask indicates VPe license bundle is enabled. VEPP + // bundle include Carrier Phase and SV Polynomial features. + LOCATION_CAPABILITIES_QWES_VPE = (1<<21), + // This mask indicates support for CV2X Location basic features. + // This bundle includes features for GTS Time & Freq, C-TUNC + // (Constrained Time uncertainity. + LOCATION_CAPABILITIES_QWES_CV2X_LOCATION_BASIC = (1<<22), + // This mask indicates support for CV2X Location premium features. + // This bundle includes features for CV2X Location Basic features, + // QDR3 feature, and PACE. (Position Assisted Clock Estimator. + LOCATION_CAPABILITIES_QWES_CV2X_LOCATION_PREMIUM = (1<<23), + // This mask indicates that PPE (Precise Positioning Engine) + // library is enabled or Precise Positioning Framework (PPF) + // is available. This bundle includes features for Carrier + // Phase and SV Ephermeris. + LOCATION_CAPABILITIES_QWES_PPE = (1<<24), + // This mask indicates QDR2_C license bundle is enabled. This + // bundle includes features for SV Polynomial. + LOCATION_CAPABILITIES_QWES_QDR2 = (1<<25), + // This mask indicates QDR3_C license bundle is enabled. This + // bundle includes features for SV Polynomial. + LOCATION_CAPABILITIES_QWES_QDR3 = (1<<26), } LocationCapabilitiesBits; +typedef uint8_t LocationQwesFeatureType; +typedef enum { + // Modem supports Carrier Phase for Precise Positioning + // Measurement Engine (PPME). + LOCATION_QWES_FEATURE_TYPE_CARRIER_PHASE = 1, + // Modem supports SV Polynomial for tightly coupled external + // DR support. This is a Standalone Feature. + LOCATION_QWES_FEATURE_TYPE_SV_POLYNOMIAL, + // Modem supports SV Ephemeris for tightly coupled external + // PPE support. This is a Standalone Feature. + LOCATION_QWES_FEATURE_TYPE_SV_EPH, + // Modem supports GNSS Single Frequency feature. This is a + // Standalone Feature. + LOCATION_QWES_FEATURE_TYPE_GNSS_SINGLE_FREQUENCY, + // Modem supports GNSS Multi Frequency feature. Multi Frequency + // enables Single frequency also. + LOCATION_QWES_FEATURE_TYPE_GNSS_MULTI_FREQUENCY, + // This indicates Time and Frequency status. + LOCATION_QWES_FEATURE_TYPE_TIME_FREQUENCY, + // This indicates Time Uncertainty status. + LOCATION_QWES_FEATURE_TYPE_TIME_UNCERTAINTY, + // This indicates Clock Estimate status. + LOCATION_QWES_FEATURE_TYPE_CLOCK_ESTIMATE, + // This mask indicates that PPE (Precise Positioning Engine) + // library is enabled or Precise Positioning Framework (PPF) + // is available. This bundle includes features for Carrier + // Phase and SV Ephermeris. + LOCATION_QWES_FEATURE_TYPE_PPE, + // This indicates QDR2_C license bundle is enabled. This + // bundle includes features for SV Polynomial. + LOCATION_QWES_FEATURE_TYPE_QDR2, + // This indicates QDR3_C license bundle is enabled. This + // bundle includes features for SV Polynomial. + LOCATION_QWES_FEATURE_TYPE_QDR3, + // This indicates VEPP license bundle is enabled. VEPP + // bundle include Carrier Phase and SV Polynomial features. + LOCATION_QWES_FEATURE_TYPE_VPE, + // Max value + LOCATION_QWES_FEATURE_TYPE_MAX +} LocationQwesFeatureTypes; + typedef enum { LOCATION_TECHNOLOGY_TYPE_GNSS = 0, } LocationTechnologyType; @@ -727,6 +809,16 @@ typedef enum { (STANDARD_POSITIONING_ENGINE|DEAD_RECKONING_ENGINE| \ PRECISE_POSITIONING_ENGINE|VP_POSITIONING_ENGINE) +/** Specify the position engine running state.
*/ +enum LocEngineRunState { + /** Request the position engine to be put into resume state. + *
*/ + LOC_ENGINE_RUN_STATE_PAUSE = 1, + /** Request the position engine to be put into resume state. + *
*/ + LOC_ENGINE_RUN_STATE_RESUME = 2, +}; + typedef uint64_t GnssDataMask; typedef enum { // Jammer Indicator is available @@ -1094,6 +1186,12 @@ typedef struct { float altitude; // altitude wrt to ellipsoid } LLAInfo; +enum loc_sess_status { + LOC_SESS_SUCCESS, + LOC_SESS_INTERMEDIATE, + LOC_SESS_FAILURE +}; + typedef struct { uint32_t size; // set to sizeof(GnssLocationInfo) Location location; // basic locaiton info, latitude, longitude, and etc @@ -1151,6 +1249,10 @@ typedef struct { // VRR-based east, north, and up velocity float enuVelocityVRPBased[3]; DrSolutionStatusMask drSolutionStatusMask; + // true: altitude is assumed, false: altitude is calculated + bool altitudeAssumed; + // location session status + loc_sess_status sessionStatus; } GnssLocationInfoNotification; typedef struct { @@ -1208,6 +1310,7 @@ typedef struct { float carrierFrequencyHz; // carrier frequency of the signal tracked GnssSignalTypeMask gnssSignalTypeMask; // Specifies GNSS signal type double basebandCarrierToNoiseDbHz; // baseband signal strength + uint16_t gloFrequency; // GLONASS Frequency channel number } GnssSv; struct GnssConfigSetAssistanceServer { @@ -1619,6 +1722,11 @@ struct LocationSystemInfo { LeapSecondSystemInfo leapSecondSysInfo; }; +// Specify the set of terrestrial technologies +enum TerrestrialTechMask { + TERRESTRIAL_TECH_GTP_WWAN = 1 << 0, +}; + // Specify parameters related to lever arm struct LeverArmParams { // Offset along the vehicle forward axis @@ -1940,4 +2048,23 @@ typedef struct { uint32_t port; bool useSSL; } GnssNtripConnectionParams; + +typedef struct { + uint64_t meQtimer1; + uint64_t meQtimer2; + uint64_t meQtimer3; + uint64_t peQtimer1; + uint64_t peQtimer2; + uint64_t peQtimer3; + uint64_t smQtimer1; + uint64_t smQtimer2; + uint64_t smQtimer3; + uint64_t locMwQtimer; + uint64_t hlosQtimer1; + uint64_t hlosQtimer2; + uint64_t hlosQtimer3; + uint64_t hlosQtimer4; + uint64_t hlosQtimer5; +} GnssLatencyInfo; + #endif /* LOCATIONDATATYPES_H */ diff --git a/gps/location/location_interface.h b/gps/location/location_interface.h index 53b71415..69d4f0ce 100644 --- a/gps/location/location_interface.h +++ b/gps/location/location_interface.h @@ -78,7 +78,7 @@ struct GnssInterface { void (*agpsDataConnFailed)(AGpsExtType agpsType); void (*getDebugReport)(GnssDebugReport& report); void (*updateConnectionStatus)(bool connected, int8_t type, bool roaming, - NetworkHandle networkHandle); + NetworkHandle networkHandle, std::string& apn); void (*odcpiInit)(const OdcpiRequestCallback& callback, OdcpiPrioritytype priority); void (*odcpiInject)(const Location& location); void (*blockCPI)(double latitude, double longitude, float accuracy, @@ -109,6 +109,8 @@ struct GnssInterface { uint32_t (*gnssUpdateSecondaryBandConfig)(const GnssSvTypeConfig& secondaryBandConfig); uint32_t (*gnssGetSecondaryBandConfig)(); void (*resetNetworkInfo)(); + uint32_t (*configEngineRunState)(PositioningEngineMask engType, + LocEngineRunState engState); }; struct BatchingInterface { diff --git a/gps/utils/gps_extended_c.h b/gps/utils/gps_extended_c.h index 8e47ef77..7d2aa080 100644 --- a/gps/utils/gps_extended_c.h +++ b/gps/utils/gps_extended_c.h @@ -415,8 +415,12 @@ typedef uint64_t GpsLocationExtendedFlags; #define GPS_LOCATION_EXTENDED_HAS_LLA_VRP_BASED 0x200000000000 /** GpsLocationExtended has the velocityVRPased. */ #define GPS_LOCATION_EXTENDED_HAS_ENU_VELOCITY_LLA_VRP_BASED 0x400000000000 +/** GpsLocationExtended has upperTriangleFullCovMatrix. */ #define GPS_LOCATION_EXTENDED_HAS_UPPER_TRIANGLE_FULL_COV_MATRIX 0x800000000000 +/** GpsLocationExtended has drSolutionStatusMask. */ #define GPS_LOCATION_EXTENDED_HAS_DR_SOLUTION_STATUS_MASK 0x1000000000000 +/** GpsLocationExtended has altitudeAssumed. */ +#define GPS_LOCATION_EXTENDED_HAS_ALTITUDE_ASSUMED 0x2000000000000 typedef uint32_t LocNavSolutionMask; /* Bitmask to specify whether SBAS ionospheric correction is used */ @@ -482,6 +486,7 @@ typedef uint32_t GnssAdditionalSystemInfoMask; #define GAL_SV_PRN_MAX 336 #define NAVIC_SV_PRN_MIN 401 #define NAVIC_SV_PRN_MAX 414 +#define GLO_SV_PRN_SLOT_UNKNOWN 255 /* Checking svIdOneBase can be set to the corresponding bit in mask */ #define svFitsMask(mask, svIdOneBase) \ @@ -491,6 +496,7 @@ typedef uint32_t GnssAdditionalSystemInfoMask; if (svFitsMask(mask, svIdOneBase)) mask |= (1ULL << ((svIdOneBase) - 1)) #define isValInRangeInclusive(val, min, max) ((val) >= (min) && (val) <= (max)) +#define isGloSlotUnknown(val) ((val) == GLO_SV_PRN_SLOT_UNKNOWN) typedef enum { LOC_RELIABILITY_NOT_SET = 0, @@ -867,14 +873,14 @@ typedef struct { */ float upperTriangleFullCovMatrix[COV_MATRIX_SIZE]; DrSolutionStatusMask drSolutionStatusMask; + /** When this field is valid, it will indicates whether altitude + * is assumed or calculated. + * false: Altitude is calculated. + * true: Altitude is assumed; there may not be enough + * satellites to determine the precise altitude. */ + bool altitudeAssumed; } GpsLocationExtended; -enum loc_sess_status { - LOC_SESS_SUCCESS, - LOC_SESS_INTERMEDIATE, - LOC_SESS_FAILURE -}; - // struct that contains complete position info from engine typedef struct { UlpLocation location; @@ -1009,6 +1015,7 @@ enum loc_api_adapter_event_index { LOC_API_ADAPTER_LOC_SYSTEM_INFO, // Location system info event LOC_API_ADAPTER_GNSS_NHZ_MEASUREMENT_REPORT, // GNSS SV nHz measurement report LOC_API_ADAPTER_EVENT_REPORT_INFO, // Event report info + LOC_API_ADAPTER_LATENCY_INFORMATION_REPORT, // Latency information report LOC_API_ADAPTER_EVENT_MAX }; @@ -1051,6 +1058,7 @@ enum loc_api_adapter_event_index { #define LOC_API_ADAPTER_BIT_LOC_SYSTEM_INFO (1ULL< #define GLONASS_SV_ID_OFFSET 64 +#define SBAS_SV_ID_OFFSET (87) #define QZSS_SV_ID_OFFSET (192) #define BDS_SV_ID_OFFSET (200) #define GALILEO_SV_ID_OFFSET (300) @@ -113,7 +114,7 @@ typedef struct loc_nmea_sv_meta_s { char talker[3]; - LocGnssConstellationType svType; + uint32_t svTypeMask; uint64_t mask; uint32_t svCount; uint32_t totalSvUsedCount; @@ -292,6 +293,7 @@ static uint32_t convert_signalType_to_signalId(GnssSignalTypeMask signalType) switch (signalType) { case GNSS_SIGNAL_GPS_L1CA: + case GNSS_SIGNAL_SBAS_L1: signalId = SIGNAL_ID_GPS_L1CA; break; case GNSS_SIGNAL_GPS_L2: @@ -404,7 +406,7 @@ static loc_nmea_sv_meta* loc_nmea_sv_meta_init(loc_nmea_sv_meta& sv_meta, bool needCombine) { memset(&sv_meta, 0, sizeof(sv_meta)); - sv_meta.svType = svType; + sv_meta.svTypeMask = (1 << svType); switch (svType) { @@ -413,6 +415,7 @@ static loc_nmea_sv_meta* loc_nmea_sv_meta_init(loc_nmea_sv_meta& sv_meta, sv_meta.talker[1] = 'P'; sv_meta.mask = sv_cache_info.gps_used_mask; sv_meta.systemId = SYSTEM_ID_GPS; + sv_meta.svTypeMask |= (1 << GNSS_SV_TYPE_SBAS); switch (signalType) { case GNSS_SIGNAL_GPS_L1CA: sv_meta.svCount = sv_cache_info.gps_l1_count; @@ -631,7 +634,7 @@ static uint32_t loc_nmea_generate_GSA(const GpsLocationExtended &locationExtende uint32_t svIdOffset = sv_meta_p->svIdOffset; uint64_t mask = sv_meta_p->mask; - if(sv_meta_p->svType != GNSS_SV_TYPE_GLONASS) { + if (!(sv_meta_p->svTypeMask & (1 << GNSS_SV_TYPE_GLONASS))) { svIdOffset = 0; } @@ -764,7 +767,7 @@ static void loc_nmea_generate_GSV(const GnssSvNotification &svNotify, return; } - if (GNSS_SV_TYPE_GLONASS == sv_meta_p->svType) { + if ((1 << GNSS_SV_TYPE_GLONASS) & sv_meta_p->svTypeMask) { svIdOffset = 0; } svNumber = 1; @@ -822,14 +825,23 @@ static void loc_nmea_generate_GSV(const GnssSvNotification &svNotify, } } - if (sv_meta_p->svType == svNotify.gnssSvs[svNumber - 1].type && + if ((sv_meta_p->svTypeMask & (1 << svNotify.gnssSvs[svNumber - 1].type)) && sv_meta_p->signalId == convert_signalType_to_signalId(signalType)) { - length = snprintf(pMarker, lengthRemaining,",%02d,%02d,%03d,", + if (GNSS_SV_TYPE_SBAS == svNotify.gnssSvs[svNumber - 1].type) { + svIdOffset = SBAS_SV_ID_OFFSET; + } + if (GNSS_SV_TYPE_GLONASS == svNotify.gnssSvs[svNumber - 1].type && + GLO_SV_PRN_SLOT_UNKNOWN == svNotify.gnssSvs[svNumber - 1].svId) { + length = snprintf(pMarker, lengthRemaining, ",,%02d,%03d,", + (int)(0.5 + svNotify.gnssSvs[svNumber - 1].elevation), //float to int + (int)(0.5 + svNotify.gnssSvs[svNumber - 1].azimuth)); //float to int + } else { + length = snprintf(pMarker, lengthRemaining, ",%02d,%02d,%03d,", svNotify.gnssSvs[svNumber - 1].svId - svIdOffset, (int)(0.5 + svNotify.gnssSvs[svNumber - 1].elevation), //float to int (int)(0.5 + svNotify.gnssSvs[svNumber - 1].azimuth)); //float to int - + } if (length < 0 || length >= lengthRemaining) { LOC_LOGE("NMEA Error in string formatting"); @@ -1458,7 +1470,7 @@ void loc_nmea_generate_pos(const UlpLocation &location, float magTrack = location.gpsLocation.bearing; if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_MAG_DEV) { - float magTrack = location.gpsLocation.bearing - locationExtended.magneticDeviation; + magTrack = location.gpsLocation.bearing - locationExtended.magneticDeviation; if (magTrack < 0.0) magTrack += 360.0; else if (magTrack > 360.0) @@ -2103,14 +2115,15 @@ void loc_nmea_generate_sv(const GnssSvNotification &svNotify, //Count GPS SVs for saparating GPS from GLONASS and throw others for (uint32_t svOffset = 0; svOffset < svNotify.count; svOffset++) { - if (GNSS_SV_TYPE_GPS == svNotify.gnssSvs[svOffset].type) + if ((GNSS_SV_TYPE_GPS == svNotify.gnssSvs[svOffset].type) || + (GNSS_SV_TYPE_SBAS == svNotify.gnssSvs[svOffset].type)) { if (GNSS_SIGNAL_GPS_L5 == svNotify.gnssSvs[svOffset].gnssSignalTypeMask) { sv_cache_info.gps_l5_count++; } else if (GNSS_SIGNAL_GPS_L2 == svNotify.gnssSvs[svOffset].gnssSignalTypeMask) { sv_cache_info.gps_l2_count++; } else { - // GNSS_SIGNAL_GPS_L1CA or default + // GNSS_SIGNAL_GPS_L1CA, GNSS_SIGNAL_SBAS_L1 or default // If no signal type in report, it means default L1 sv_cache_info.gps_l1_count++; } @@ -2151,6 +2164,14 @@ 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++; @@ -2267,6 +2288,7 @@ void loc_nmea_generate_sv(const GnssSvNotification &svNotify, // ----------------------------- // ------$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);