diff --git a/gps/android/1.0/Gnss.cpp b/gps/android/1.0/Gnss.cpp index 4aac432f..fda58f20 100644 --- a/gps/android/1.0/Gnss.cpp +++ b/gps/android/1.0/Gnss.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. * Not a Contribution */ /* @@ -28,6 +28,7 @@ #include "Gnss.h" #include #include "battery_listener.h" +#include "loc_misc_utils.h" typedef const GnssInterface* (getLocationInterface)(); @@ -102,25 +103,14 @@ GnssAPIClient* Gnss::getApi() { const GnssInterface* Gnss::getGnssInterface() { static bool getGnssInterfaceFailed = false; if (nullptr == mGnssInterface && !getGnssInterfaceFailed) { - LOC_LOGD("%s]: loading libgnss.so::getGnssInterface ...", __func__); - getLocationInterface* getter = NULL; - const char *error = NULL; - dlerror(); - void *handle = dlopen("libgnss.so", RTLD_NOW); - if (NULL == handle || (error = dlerror()) != NULL) { - LOC_LOGW("dlopen for libgnss.so failed, error = %s", error); - } else { - getter = (getLocationInterface*)dlsym(handle, "getGnssInterface"); - if ((error = dlerror()) != NULL) { - LOC_LOGW("dlsym for libgnss.so::getGnssInterface failed, error = %s", error); - getter = NULL; - } - } + void * libHandle = nullptr; + getLocationInterface* getter = (getLocationInterface*) + dlGetSymFromLib(libHandle, "libgnss.so", "getGnssInterface"); - if (NULL == getter) { + if (nullptr == getter) { getGnssInterfaceFailed = true; } else { - mGnssInterface = (const GnssInterface*)(*getter)(); + mGnssInterface = (GnssInterface*)(*getter)(); } } return mGnssInterface; @@ -264,14 +254,7 @@ Return Gnss::injectLocation(double latitudeDegrees, Return Gnss::injectTime(int64_t timeMs, int64_t timeReferenceMs, int32_t uncertaintyMs) { - ENTRY_LOG_CALLFLOW(); - const GnssInterface* gnssInterface = getGnssInterface(); - if (nullptr != gnssInterface) { - gnssInterface->injectTime(timeMs, timeReferenceMs, uncertaintyMs); - return true; - } else { - return false; - } + return true; } Return Gnss::deleteAidingData(V1_0::IGnss::GnssAidingData aidingDataFlags) { diff --git a/gps/android/1.0/location_api/GnssAPIClient.cpp b/gps/android/1.0/location_api/GnssAPIClient.cpp index eb785915..c474d453 100644 --- a/gps/android/1.0/location_api/GnssAPIClient.cpp +++ b/gps/android/1.0/location_api/GnssAPIClient.cpp @@ -540,7 +540,7 @@ static void convertGnssSvStatus(GnssSvNotification& in, IGnssCallback::GnssSvSta } for (size_t i = 0; i < out.numSvs; i++) { IGnssCallback::GnssSvInfo& info = out.gnssSvList[i]; - info.svid = in.gnssSvs[i].svId; + convertGnssSvid(in.gnssSvs[i], info.svid); convertGnssConstellationType(in.gnssSvs[i].type, info.constellation); info.cN0Dbhz = in.gnssSvs[i].cN0Dbhz; info.elevationDegrees = in.gnssSvs[i].elevation; diff --git a/gps/android/1.0/location_api/LocationUtil.cpp b/gps/android/1.0/location_api/LocationUtil.cpp index 102593bc..d14cdac5 100644 --- a/gps/android/1.0/location_api/LocationUtil.cpp +++ b/gps/android/1.0/location_api/LocationUtil.cpp @@ -147,6 +147,64 @@ void convertGnssConstellationType(GnssSvType& in, GnssConstellationType& out) } } +void convertGnssSvid(GnssSv& in, int16_t& out) +{ + switch(in.type){ + case GNSS_SV_TYPE_GPS: + out = in.svId; + break; + case GNSS_SV_TYPE_SBAS: + out = in.svId; + break; + case GNSS_SV_TYPE_GLONASS: + out = in.svId - GLO_SV_PRN_MIN + 1; + break; + case GNSS_SV_TYPE_QZSS: + out = in.svId; + break; + case GNSS_SV_TYPE_BEIDOU: + out = in.svId - BDS_SV_PRN_MIN + 1; + break; + case GNSS_SV_TYPE_GALILEO: + out = in.svId - GAL_SV_PRN_MIN + 1; + break; + default: + out = in.svId; + break; + } +} + +void convertGnssSvid(GnssMeasurementsData& in, int16_t& out) +{ + switch (in.svType) { + case GNSS_SV_TYPE_GPS: + out = in.svId; + break; + case GNSS_SV_TYPE_SBAS: + out = in.svId; + break; + case GNSS_SV_TYPE_GLONASS: + if (in.svId != 255) { // OSN is known + out = in.svId - GLO_SV_PRN_MIN + 1; + } else { // OSN is not known, report FCN + out = in.gloFrequency + 92; + } + break; + case GNSS_SV_TYPE_QZSS: + out = in.svId; + break; + case GNSS_SV_TYPE_BEIDOU: + out = in.svId - BDS_SV_PRN_MIN + 1; + break; + case GNSS_SV_TYPE_GALILEO: + out = in.svId - GAL_SV_PRN_MIN + 1; + break; + default: + out = in.svId; + break; + } +} + void convertGnssEphemerisType(GnssEphemerisType& in, GnssDebug::SatelliteEphemerisType& out) { switch(in) { diff --git a/gps/android/1.0/location_api/LocationUtil.h b/gps/android/1.0/location_api/LocationUtil.h index 9e0cd369..f6760e5f 100644 --- a/gps/android/1.0/location_api/LocationUtil.h +++ b/gps/android/1.0/location_api/LocationUtil.h @@ -43,6 +43,8 @@ namespace implementation { void convertGnssLocation(Location& in, V1_0::GnssLocation& out); void convertGnssLocation(const V1_0::GnssLocation& in, Location& out); void convertGnssConstellationType(GnssSvType& in, V1_0::GnssConstellationType& out); +void convertGnssSvid(GnssSv& in, int16_t& out); +void convertGnssSvid(GnssMeasurementsData& in, int16_t& out); void convertGnssEphemerisType(GnssEphemerisType& in, GnssDebug::SatelliteEphemerisType& out); void convertGnssEphemerisSource(GnssEphemerisSource& in, GnssDebug::SatelliteEphemerisSource& out); void convertGnssEphemerisHealth(GnssEphemerisHealth& in, GnssDebug::SatelliteEphemerisHealth& out); diff --git a/gps/android/1.0/location_api/MeasurementAPIClient.cpp b/gps/android/1.0/location_api/MeasurementAPIClient.cpp index 73709e3a..9b23308b 100644 --- a/gps/android/1.0/location_api/MeasurementAPIClient.cpp +++ b/gps/android/1.0/location_api/MeasurementAPIClient.cpp @@ -163,7 +163,7 @@ static void convertGnssMeasurement(GnssMeasurementsData& in, out.flags |= IGnssMeasurementCallback::GnssMeasurementFlags::HAS_CARRIER_PHASE_UNCERTAINTY; if (in.flags & GNSS_MEASUREMENTS_DATA_AUTOMATIC_GAIN_CONTROL_BIT) out.flags |= IGnssMeasurementCallback::GnssMeasurementFlags::HAS_AUTOMATIC_GAIN_CONTROL; - out.svid = in.svId; + convertGnssSvid(in, out.svid); convertGnssConstellationType(in.svType, out.constellation); out.timeOffsetNs = in.timeOffsetNs; if (in.stateMask & GNSS_MEASUREMENTS_STATE_CODE_LOCK_BIT) diff --git a/gps/android/1.1/Gnss.cpp b/gps/android/1.1/Gnss.cpp index 277dbc16..b6f29650 100644 --- a/gps/android/1.1/Gnss.cpp +++ b/gps/android/1.1/Gnss.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. * Not a Contribution */ /* @@ -29,6 +29,7 @@ #include #include "battery_listener.h" +#include "loc_misc_utils.h" typedef const GnssInterface* (getLocationInterface)(); @@ -143,25 +144,14 @@ GnssAPIClient* Gnss::getApi() { const GnssInterface* Gnss::getGnssInterface() { static bool getGnssInterfaceFailed = false; if (nullptr == mGnssInterface && !getGnssInterfaceFailed) { - LOC_LOGD("%s]: loading libgnss.so::getGnssInterface ...", __func__); - getLocationInterface* getter = NULL; - const char *error = NULL; - dlerror(); - void *handle = dlopen("libgnss.so", RTLD_NOW); - if (NULL == handle || (error = dlerror()) != NULL) { - LOC_LOGW("dlopen for libgnss.so failed, error = %s", error); - } else { - getter = (getLocationInterface*)dlsym(handle, "getGnssInterface"); - if ((error = dlerror()) != NULL) { - LOC_LOGW("dlsym for libgnss.so::getGnssInterface failed, error = %s", error); - getter = NULL; - } - } + void * libHandle = nullptr; + getLocationInterface* getter = (getLocationInterface*) + dlGetSymFromLib(libHandle, "libgnss.so", "getGnssInterface"); - if (NULL == getter) { + if (nullptr == getter) { getGnssInterfaceFailed = true; } else { - mGnssInterface = (const GnssInterface*)(*getter)(); + mGnssInterface = (GnssInterface*)(*getter)(); } } return mGnssInterface; @@ -305,14 +295,7 @@ Return Gnss::injectLocation(double latitudeDegrees, Return Gnss::injectTime(int64_t timeMs, int64_t timeReferenceMs, int32_t uncertaintyMs) { - ENTRY_LOG_CALLFLOW(); - const GnssInterface* gnssInterface = getGnssInterface(); - if (nullptr != gnssInterface) { - gnssInterface->injectTime(timeMs, timeReferenceMs, uncertaintyMs); - return true; - } else { - return false; - } + return true; } Return Gnss::deleteAidingData(V1_0::IGnss::GnssAidingData aidingDataFlags) { diff --git a/gps/android/1.1/location_api/GnssAPIClient.cpp b/gps/android/1.1/location_api/GnssAPIClient.cpp index be4d6596..80710898 100644 --- a/gps/android/1.1/location_api/GnssAPIClient.cpp +++ b/gps/android/1.1/location_api/GnssAPIClient.cpp @@ -540,7 +540,7 @@ static void convertGnssSvStatus(GnssSvNotification& in, IGnssCallback::GnssSvSta } for (size_t i = 0; i < out.numSvs; i++) { IGnssCallback::GnssSvInfo& info = out.gnssSvList[i]; - info.svid = in.gnssSvs[i].svId; + convertGnssSvid(in.gnssSvs[i], info.svid); convertGnssConstellationType(in.gnssSvs[i].type, info.constellation); info.cN0Dbhz = in.gnssSvs[i].cN0Dbhz; info.elevationDegrees = in.gnssSvs[i].elevation; diff --git a/gps/android/1.1/location_api/LocationUtil.cpp b/gps/android/1.1/location_api/LocationUtil.cpp index f1d051c1..459150fd 100644 --- a/gps/android/1.1/location_api/LocationUtil.cpp +++ b/gps/android/1.1/location_api/LocationUtil.cpp @@ -147,6 +147,64 @@ void convertGnssConstellationType(GnssSvType& in, GnssConstellationType& out) } } +void convertGnssSvid(GnssSv& in, int16_t& out) +{ + switch(in.type){ + case GNSS_SV_TYPE_GPS: + out = in.svId; + break; + case GNSS_SV_TYPE_SBAS: + out = in.svId; + break; + case GNSS_SV_TYPE_GLONASS: + out = in.svId - GLO_SV_PRN_MIN + 1; + break; + case GNSS_SV_TYPE_QZSS: + out = in.svId; + break; + case GNSS_SV_TYPE_BEIDOU: + out = in.svId - BDS_SV_PRN_MIN + 1; + break; + case GNSS_SV_TYPE_GALILEO: + out = in.svId - GAL_SV_PRN_MIN + 1; + break; + default: + out = in.svId; + break; + } +} + +void convertGnssSvid(GnssMeasurementsData& in, int16_t& out) +{ + switch (in.svType) { + case GNSS_SV_TYPE_GPS: + out = in.svId; + break; + case GNSS_SV_TYPE_SBAS: + out = in.svId; + break; + case GNSS_SV_TYPE_GLONASS: + if (in.svId != 255) { // OSN is known + out = in.svId - GLO_SV_PRN_MIN + 1; + } else { // OSN is not known, report FCN + out = in.gloFrequency + 92; + } + break; + case GNSS_SV_TYPE_QZSS: + out = in.svId; + break; + case GNSS_SV_TYPE_BEIDOU: + out = in.svId - BDS_SV_PRN_MIN + 1; + break; + case GNSS_SV_TYPE_GALILEO: + out = in.svId - GAL_SV_PRN_MIN + 1; + break; + default: + out = in.svId; + break; + } +} + void convertGnssEphemerisType(GnssEphemerisType& in, GnssDebug::SatelliteEphemerisType& out) { switch(in) { diff --git a/gps/android/1.1/location_api/LocationUtil.h b/gps/android/1.1/location_api/LocationUtil.h index 63f4f6f0..af3c93f3 100644 --- a/gps/android/1.1/location_api/LocationUtil.h +++ b/gps/android/1.1/location_api/LocationUtil.h @@ -43,6 +43,8 @@ namespace implementation { void convertGnssLocation(Location& in, V1_0::GnssLocation& out); void convertGnssLocation(const V1_0::GnssLocation& in, Location& out); void convertGnssConstellationType(GnssSvType& in, V1_0::GnssConstellationType& out); +void convertGnssSvid(GnssSv& in, int16_t& out); +void convertGnssSvid(GnssMeasurementsData& in, int16_t& out); void convertGnssEphemerisType(GnssEphemerisType& in, GnssDebug::SatelliteEphemerisType& out); void convertGnssEphemerisSource(GnssEphemerisSource& in, GnssDebug::SatelliteEphemerisSource& out); void convertGnssEphemerisHealth(GnssEphemerisHealth& in, GnssDebug::SatelliteEphemerisHealth& out); diff --git a/gps/android/1.1/location_api/MeasurementAPIClient.cpp b/gps/android/1.1/location_api/MeasurementAPIClient.cpp index 6f250676..a87ae6d5 100644 --- a/gps/android/1.1/location_api/MeasurementAPIClient.cpp +++ b/gps/android/1.1/location_api/MeasurementAPIClient.cpp @@ -197,7 +197,7 @@ static void convertGnssMeasurement(GnssMeasurementsData& in, out.flags |= IGnssMeasurementCallback::GnssMeasurementFlags::HAS_CARRIER_PHASE_UNCERTAINTY; if (in.flags & GNSS_MEASUREMENTS_DATA_AUTOMATIC_GAIN_CONTROL_BIT) out.flags |= IGnssMeasurementCallback::GnssMeasurementFlags::HAS_AUTOMATIC_GAIN_CONTROL; - out.svid = in.svId; + convertGnssSvid(in, out.svid); convertGnssConstellationType(in.svType, out.constellation); out.timeOffsetNs = in.timeOffsetNs; if (in.stateMask & GNSS_MEASUREMENTS_STATE_CODE_LOCK_BIT) diff --git a/gps/android/2.0/Gnss.cpp b/gps/android/2.0/Gnss.cpp index 2276c148..0e53a34a 100644 --- a/gps/android/2.0/Gnss.cpp +++ b/gps/android/2.0/Gnss.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. * Not a Contribution */ /* @@ -28,6 +28,7 @@ #include "Gnss.h" #include "LocationUtil.h" #include "battery_listener.h" +#include "loc_misc_utils.h" typedef const GnssInterface* (getLocationInterface)(); @@ -145,26 +146,16 @@ GnssAPIClient* Gnss::getApi() { const GnssInterface* Gnss::getGnssInterface() { static bool getGnssInterfaceFailed = false; - if (nullptr == mGnssInterface && !getGnssInterfaceFailed) { - LOC_LOGD("%s]: loading libgnss.so::getGnssInterface ...", __func__); - getLocationInterface* getter = NULL; - const char *error = NULL; - dlerror(); - void *handle = dlopen("libgnss.so", RTLD_NOW); - if (NULL == handle || (error = dlerror()) != NULL) { - LOC_LOGW("dlopen for libgnss.so failed, error = %s", error); - } else { - getter = (getLocationInterface*)dlsym(handle, "getGnssInterface"); - if ((error = dlerror()) != NULL) { - LOC_LOGW("dlsym for libgnss.so::getGnssInterface failed, error = %s", error); - getter = NULL; - } - } - if (NULL == getter) { + if (nullptr == mGnssInterface && !getGnssInterfaceFailed) { + void * libHandle = nullptr; + getLocationInterface* getter = (getLocationInterface*) + dlGetSymFromLib(libHandle, "libgnss.so", "getGnssInterface"); + + if (nullptr == getter) { getGnssInterfaceFailed = true; } else { - mGnssInterface = (const GnssInterface*)(*getter)(); + mGnssInterface = (GnssInterface*)(*getter)(); } } return mGnssInterface; @@ -330,14 +321,7 @@ Return Gnss::injectLocation(double latitudeDegrees, Return Gnss::injectTime(int64_t timeMs, int64_t timeReferenceMs, int32_t uncertaintyMs) { - ENTRY_LOG_CALLFLOW(); - const GnssInterface* gnssInterface = getGnssInterface(); - if (nullptr != gnssInterface) { - gnssInterface->injectTime(timeMs, timeReferenceMs, uncertaintyMs); - return true; - } else { - return false; - } + return true; } Return Gnss::deleteAidingData(V1_0::IGnss::GnssAidingData aidingDataFlags) { @@ -385,31 +369,41 @@ Return> Gnss::getExtensionGnssMeasurement() { Return> Gnss::getExtensionGnssConfiguration() { ENTRY_LOG_CALLFLOW(); - mGnssConfig = new GnssConfiguration(this); + if (mGnssConfig == nullptr) { + mGnssConfig = new GnssConfiguration(this); + } return mGnssConfig; } Return> Gnss::getExtensionGnssGeofencing() { ENTRY_LOG_CALLFLOW(); - mGnssGeofencingIface = new GnssGeofencing(); + if (mGnssGeofencingIface == nullptr) { + mGnssGeofencingIface = new GnssGeofencing(); + } return mGnssGeofencingIface; } Return> Gnss::getExtensionGnssBatching() { ENTRY_LOG_CALLFLOW(); - mGnssBatching = new GnssBatching(); + if (mGnssBatching == nullptr) { + mGnssBatching = new GnssBatching(); + } return mGnssBatching; } Return> Gnss::getExtensionGnssDebug() { ENTRY_LOG_CALLFLOW(); - mGnssDebug = new GnssDebug(this); + if (mGnssDebug == nullptr) { + mGnssDebug = new GnssDebug(this); + } return mGnssDebug; } Return> Gnss::getExtensionAGnssRil() { ENTRY_LOG_CALLFLOW(); - mGnssRil = new AGnssRil(this); + if (mGnssRil == nullptr) { + mGnssRil = new AGnssRil(this); + } return mGnssRil; } @@ -596,17 +590,23 @@ Return Gnss::setCallback_2_0(const sp& callback) { Return> Gnss::getExtensionAGnss_2_0() { ENTRY_LOG_CALLFLOW(); - mAGnssIface_2_0 = new AGnss(this); + if (mAGnssIface_2_0 == nullptr) { + mAGnssIface_2_0 = new AGnss(this); + } return mAGnssIface_2_0; } Return> Gnss::getExtensionAGnssRil_2_0() { - mGnssRil = new AGnssRil(this); + if (mGnssRil == nullptr) { + mGnssRil = new AGnssRil(this); + } return mGnssRil; } Return> Gnss::getExtensionGnssConfiguration_2_0() { ENTRY_LOG_CALLFLOW(); - mGnssConfig = new GnssConfiguration(this); + if (mGnssConfig == nullptr) { + mGnssConfig = new GnssConfiguration(this); + } return mGnssConfig; } Return> Gnss::getExtensionGnssMeasurement_2_0() { @@ -646,13 +646,17 @@ Return Gnss::injectBestLocation_2_0(const V2_0::GnssLocation& gnssLocation Return> Gnss::getExtensionGnssDebug_2_0() { ENTRY_LOG_CALLFLOW(); - mGnssDebug = new GnssDebug(this); + if (mGnssDebug == nullptr) { + mGnssDebug = new GnssDebug(this); + } return mGnssDebug; } Return> Gnss::getExtensionGnssBatching_2_0() { ENTRY_LOG_CALLFLOW(); - mGnssBatching = new GnssBatching(); + if (mGnssBatching == nullptr) { + mGnssBatching = new GnssBatching(); + } return mGnssBatching; } diff --git a/gps/android/2.0/android.hardware.gnss@2.0-service-qti.xml b/gps/android/2.0/android.hardware.gnss@2.0-service-qti.xml index ff9fb2c9..de82c60e 100644 --- a/gps/android/2.0/android.hardware.gnss@2.0-service-qti.xml +++ b/gps/android/2.0/android.hardware.gnss@2.0-service-qti.xml @@ -29,6 +29,7 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. android.hardware.gnss hwbinder + @1.0::IGnss/gnss_vendor @1.1::IGnss/default @2.0::IGnss/default diff --git a/gps/android/2.0/location_api/GnssAPIClient.cpp b/gps/android/2.0/location_api/GnssAPIClient.cpp index d505241c..1fcf5300 100644 --- a/gps/android/2.0/location_api/GnssAPIClient.cpp +++ b/gps/android/2.0/location_api/GnssAPIClient.cpp @@ -678,7 +678,7 @@ static void convertGnssSvStatus(GnssSvNotification& in, V1_0::IGnssCallback::Gns out.numSvs = static_cast(V1_0::GnssMax::SVS_COUNT); } for (size_t i = 0; i < out.numSvs; i++) { - out.gnssSvList[i].svid = in.gnssSvs[i].svId; + convertGnssSvid(in.gnssSvs[i], out.gnssSvList[i].svid); convertGnssConstellationType(in.gnssSvs[i].type, out.gnssSvList[i].constellation); out.gnssSvList[i].cN0Dbhz = in.gnssSvs[i].cN0Dbhz; out.gnssSvList[i].elevationDegrees = in.gnssSvs[i].elevation; @@ -701,7 +701,7 @@ static void convertGnssSvStatus(GnssSvNotification& in, { out.resize(in.count); for (size_t i = 0; i < in.count; i++) { - out[i].v1_0.svid = in.gnssSvs[i].svId; + convertGnssSvid(in.gnssSvs[i], out[i].v1_0.svid); out[i].v1_0.cN0Dbhz = in.gnssSvs[i].cN0Dbhz; out[i].v1_0.elevationDegrees = in.gnssSvs[i].elevation; out[i].v1_0.azimuthDegrees = in.gnssSvs[i].azimuth; diff --git a/gps/android/2.0/location_api/LocationUtil.cpp b/gps/android/2.0/location_api/LocationUtil.cpp old mode 100644 new mode 100755 index 8a30066f..c2a75576 --- a/gps/android/2.0/location_api/LocationUtil.cpp +++ b/gps/android/2.0/location_api/LocationUtil.cpp @@ -30,6 +30,7 @@ #include #include #include +#include namespace android { namespace hardware { @@ -81,21 +82,16 @@ void convertGnssLocation(Location& in, V1_0::GnssLocation& out) out.timestamp = static_cast(in.timestamp); } -void convertGnssLocation(Location& in, V2_0::GnssLocation& out) +bool getCurrentTime(struct timespec& currentTime, int64_t& sinceBootTimeNanos) { - memset(&out, 0, sizeof(V2_0::GnssLocation)); - convertGnssLocation(in, out.v1_0); - struct timespec sinceBootTime; - struct timespec currentTime; struct timespec sinceBootTimeTest; - int64_t sinceBootTimeNanos = 0; 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++) { + 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; }; @@ -105,24 +101,34 @@ void convertGnssLocation(Location& in, V2_0::GnssLocation& out) if (clock_gettime(CLOCK_BOOTTIME, &sinceBootTimeTest) != 0) { break; }; - sinceBootTimeNanos = sinceBootTime.tv_sec*1000000000 + sinceBootTime.tv_nsec; + sinceBootTimeNanos = sinceBootTime.tv_sec * 1000000000 + sinceBootTime.tv_nsec; int64_t sinceBootTimeTestNanos = - sinceBootTimeTest.tv_sec*1000000000 + sinceBootTimeTest.tv_nsec; + 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 */ + 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("%s]: Delta:%" PRIi64 "ns time too large, retry number #%u...", - __FUNCTION__, sinceBootTimeDeltaNanos, i+1); + LOC_LOGd("Delta:%" PRIi64 "ns time too large, retry number #%u...", + sinceBootTimeDeltaNanos, i + 1); } } + return clockGetTimeSuccess; +} - if (clockGetTimeSuccess) { +void convertGnssLocation(Location& in, V2_0::GnssLocation& out) +{ + memset(&out, 0, sizeof(V2_0::GnssLocation)); + convertGnssLocation(in, out.v1_0); + + struct timespec currentTime; + int64_t sinceBootTimeNanos; + + if (getCurrentTime(currentTime, sinceBootTimeNanos)) { int64_t currentTimeNanos = currentTime.tv_sec*1000000000 + currentTime.tv_nsec; int64_t locationTimeNanos = in.timestamp*1000000; LOC_LOGD("%s]: sinceBootTimeNanos:%" PRIi64 " currentTimeNanos:%" PRIi64 "" @@ -131,19 +137,23 @@ void convertGnssLocation(Location& in, V2_0::GnssLocation& out) if (currentTimeNanos >= locationTimeNanos) { int64_t ageTimeNanos = currentTimeNanos - locationTimeNanos; LOC_LOGD("%s]: ageTimeNanos:%" PRIi64 ")", __FUNCTION__, ageTimeNanos); - if (ageTimeNanos >= 0 && ageTimeNanos <= sinceBootTimeNanos) { + // the max trusted propagation time 30s for ageTimeNanos to avoid user setting + //wrong time, it will affect elapsedRealtimeNanos + if (ageTimeNanos >= 0 && ageTimeNanos <= 30000000000) { out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIMESTAMP_NS; out.elapsedRealtime.timestampNs = sinceBootTimeNanos - ageTimeNanos; out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS; - // time uncertainty is 1 ms since it is calculated from utc time that is in ms - out.elapsedRealtime.timeUncertaintyNs = 1000000; + // 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((int64_t)abs(currentTimeNanos - locationTimeNanos), + (int64_t)100000000); LOC_LOGD("%s]: timestampNs:%" PRIi64 ")", __FUNCTION__, out.elapsedRealtime.timestampNs); } } } else { - LOC_LOGE("%s]: Failed to calculate elapsedRealtimeNanos timestamp after %u tries", - __FUNCTION__, MAX_GET_TIME_COUNT); + LOC_LOGe("Failed to calculate elapsedRealtimeNanos timestamp"); } } @@ -252,6 +262,64 @@ void convertGnssConstellationType(GnssSvType& in, V2_0::GnssConstellationType& o } } +void convertGnssSvid(GnssSv& in, int16_t& out) +{ + switch (in.type) { + case GNSS_SV_TYPE_GPS: + out = in.svId; + break; + case GNSS_SV_TYPE_SBAS: + out = in.svId; + break; + case GNSS_SV_TYPE_GLONASS: + out = in.svId - GLO_SV_PRN_MIN + 1; + break; + case GNSS_SV_TYPE_QZSS: + out = in.svId; + break; + case GNSS_SV_TYPE_BEIDOU: + out = in.svId - BDS_SV_PRN_MIN + 1; + break; + case GNSS_SV_TYPE_GALILEO: + out = in.svId - GAL_SV_PRN_MIN + 1; + break; + default: + out = in.svId; + break; + } +} + +void convertGnssSvid(GnssMeasurementsData& in, int16_t& out) +{ + switch (in.svType) { + case GNSS_SV_TYPE_GPS: + out = in.svId; + break; + case GNSS_SV_TYPE_SBAS: + out = in.svId; + break; + case GNSS_SV_TYPE_GLONASS: + if (in.svId != 255) { // OSN is known + out = in.svId - GLO_SV_PRN_MIN + 1; + } else { // OSN is not known, report FCN + out = in.gloFrequency + 92; + } + break; + case GNSS_SV_TYPE_QZSS: + out = in.svId; + break; + case GNSS_SV_TYPE_BEIDOU: + out = in.svId - BDS_SV_PRN_MIN + 1; + break; + case GNSS_SV_TYPE_GALILEO: + out = in.svId - GAL_SV_PRN_MIN + 1; + break; + default: + out = in.svId; + break; + } +} + void convertGnssEphemerisType(GnssEphemerisType& in, GnssDebug::SatelliteEphemerisType& out) { switch(in) { diff --git a/gps/android/2.0/location_api/LocationUtil.h b/gps/android/2.0/location_api/LocationUtil.h index 8426de72..3c345149 100644 --- a/gps/android/2.0/location_api/LocationUtil.h +++ b/gps/android/2.0/location_api/LocationUtil.h @@ -46,9 +46,12 @@ void convertGnssLocation(const V1_0::GnssLocation& in, Location& out); void convertGnssLocation(const V2_0::GnssLocation& in, Location& out); void convertGnssConstellationType(GnssSvType& in, V1_0::GnssConstellationType& out); void convertGnssConstellationType(GnssSvType& in, V2_0::GnssConstellationType& out); +void convertGnssSvid(GnssSv& in, int16_t& out); +void convertGnssSvid(GnssMeasurementsData& in, int16_t& out); void convertGnssEphemerisType(GnssEphemerisType& in, GnssDebug::SatelliteEphemerisType& out); void convertGnssEphemerisSource(GnssEphemerisSource& in, GnssDebug::SatelliteEphemerisSource& out); void convertGnssEphemerisHealth(GnssEphemerisHealth& in, GnssDebug::SatelliteEphemerisHealth& out); +bool getCurrentTime(struct timespec& currentTime, int64_t& sinceBootTimeNanos); } // 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 dc972ec3..5894e46e 100644 --- a/gps/android/2.0/location_api/MeasurementAPIClient.cpp +++ b/gps/android/2.0/location_api/MeasurementAPIClient.cpp @@ -32,6 +32,7 @@ #include #include +#include #include "LocationUtil.h" #include "MeasurementAPIClient.h" @@ -230,7 +231,7 @@ static void convertGnssMeasurement(GnssMeasurementsData& in, out.flags |= IGnssMeasurementCallback::GnssMeasurementFlags::HAS_CARRIER_PHASE_UNCERTAINTY; if (in.flags & GNSS_MEASUREMENTS_DATA_AUTOMATIC_GAIN_CONTROL_BIT) out.flags |= IGnssMeasurementCallback::GnssMeasurementFlags::HAS_AUTOMATIC_GAIN_CONTROL; - out.svid = in.svId; + convertGnssSvid(in, out.svid); convertGnssConstellationType(in.svType, out.constellation); out.timeOffsetNs = in.timeOffsetNs; if (in.stateMask & GNSS_MEASUREMENTS_STATE_CODE_LOCK_BIT) @@ -414,6 +415,41 @@ static void convertGnssData_2_0(GnssMeasurementsNotification& in, out.measurements[i].state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_2ND_CODE_LOCK; } convertGnssClock(in.clock, out.clock); + + const uint32_t UTC_TO_GPS_SECONDS = 315964800; + struct timespec currentTime; + int64_t sinceBootTimeNanos; + + if (getCurrentTime(currentTime, sinceBootTimeNanos) && + in.clock.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_LEAP_SECOND_BIT && + in.clock.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_FULL_BIAS_BIT && + in.clock.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_BIAS_BIT && + in.clock.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_BIAS_UNCERTAINTY_BIT) { + int64_t currentTimeNanos = currentTime.tv_sec * 1000000000 + currentTime.tv_nsec; + int64_t measTimeNanos = (int64_t)in.clock.timeNs - (int64_t)in.clock.fullBiasNs + - (int64_t)in.clock.biasNs - (int64_t)in.clock.leapSecond * 1000000000 + + (int64_t)UTC_TO_GPS_SECONDS * 1000000000; + + LOC_LOGd("sinceBootTimeNanos:%" PRIi64 " currentTimeNanos:%" PRIi64 "" + " measTimeNanos:%" PRIi64 "", + sinceBootTimeNanos, currentTimeNanos, measTimeNanos); + if (currentTimeNanos >= measTimeNanos) { + int64_t ageTimeNanos = currentTimeNanos - measTimeNanos; + LOC_LOGD("%s]: ageTimeNanos:%" PRIi64 ")", __FUNCTION__, ageTimeNanos); + if (ageTimeNanos >= 0 && ageTimeNanos <= sinceBootTimeNanos) { + out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIMESTAMP_NS; + out.elapsedRealtime.timestampNs = sinceBootTimeNanos - ageTimeNanos; + out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS; + // time uncertainty is 1 ms since it is calculated from utc time that is in ms + out.elapsedRealtime.timeUncertaintyNs = 1000000; + LOC_LOGd("timestampNs:%" PRIi64 ") timeUncertaintyNs:%" PRIi64 ")", + out.elapsedRealtime.timestampNs, + out.elapsedRealtime.timeUncertaintyNs); + } + } + } else { + LOC_LOGe("Failed to calculate elapsedRealtimeNanos timestamp"); + } } static void convertGnssMeasurementsCodeType(GnssMeasurementsCodeType& in, diff --git a/gps/android/2.0/service.cpp b/gps/android/2.0/service.cpp index 664c661f..e484a16d 100644 --- a/gps/android/2.0/service.cpp +++ b/gps/android/2.0/service.cpp @@ -73,6 +73,11 @@ int main() { #else ALOGE("LOC_HIDL_VERSION not defined."); #endif + } else { + status = registerPassthroughServiceImplementation("gnss_vendor"); + if (status != OK) { + ALOGE("Error while registering gnss_vendor service: %d", status); + } } joinRpcThreadpool(); diff --git a/gps/batching/configure.ac b/gps/batching/configure.ac index 27435c66..e77e4972 100644 --- a/gps/batching/configure.ac +++ b/gps/batching/configure.ac @@ -7,7 +7,7 @@ AC_PREREQ(2.61) # Initialize the gps location-batching package version 1.0.0 AC_INIT([location-batching],1.0.0) # Does not strictly follow GNU Coding standards -AM_INIT_AUTOMAKE([foreign]) +AM_INIT_AUTOMAKE([foreign subdir-objects]) # Disables auto rebuilding of configure, Makefile.ins AM_MAINTAINER_MODE # Verifies the --srcdir is correct by checking for the path diff --git a/gps/core/ContextBase.cpp b/gps/core/ContextBase.cpp index 3b8ffc6e..3eb49739 100644 --- a/gps/core/ContextBase.cpp +++ b/gps/core/ContextBase.cpp @@ -193,7 +193,7 @@ void ContextBase::readConfig() mGps_conf.GNSS_DEPLOYMENT = 0; mGps_conf.CUSTOM_NMEA_GGA_FIX_QUALITY_ENABLED = 0; /* default configuration for NI_SUPL_DENY_ON_NFW_LOCKED */ - mGps_conf.NI_SUPL_DENY_ON_NFW_LOCKED = 0; + mGps_conf.NI_SUPL_DENY_ON_NFW_LOCKED = 1; UTIL_READ_CONF(LOC_PATH_GPS_CONF, mGps_conf_table); UTIL_READ_CONF(LOC_PATH_SAP_CONF, mSap_conf_table); diff --git a/gps/core/LocAdapterBase.cpp b/gps/core/LocAdapterBase.cpp index 1e91cf83..8df7198a 100644 --- a/gps/core/LocAdapterBase.cpp +++ b/gps/core/LocAdapterBase.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2014, 2016-2019 The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2014, 2016-2020 The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -185,6 +185,10 @@ DEFAULT_IMPL() void LocAdapterBase::reportGnssSvTypeConfigEvent(const GnssSvTypeConfig& /*config*/) DEFAULT_IMPL() +void LocAdapterBase::reportGnssConfigEvent(uint32_t, /* session id*/ + const GnssConfig& /*gnssConfig*/) +DEFAULT_IMPL() + bool LocAdapterBase:: requestOdcpiEvent(OdcpiRequestInfo& /*request*/) DEFAULT_IMPL(false) diff --git a/gps/core/LocAdapterBase.h b/gps/core/LocAdapterBase.h index 7ca3ecda..4a5d1abc 100644 --- a/gps/core/LocAdapterBase.h +++ b/gps/core/LocAdapterBase.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2014, 2016-2019 The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2014, 2016-2020 The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -206,6 +206,7 @@ public: GpsLocationExtended &location_extended, LocPosTechMask tech_mask); virtual void reportGnssSvIdConfigEvent(const GnssSvIdConfig& config); virtual void reportGnssSvTypeConfigEvent(const GnssSvTypeConfig& config); + virtual void reportGnssConfigEvent(uint32_t sessionId, const GnssConfig& gnssConfig); virtual bool requestOdcpiEvent(OdcpiRequestInfo& request); virtual bool reportGnssEngEnergyConsumedEvent(uint64_t energyConsumedSinceFirstBoot); virtual bool reportDeleteAidingDataEvent(GnssAidingData &aidingData); diff --git a/gps/core/LocApiBase.cpp b/gps/core/LocApiBase.cpp index 71abdf9f..60bfdd21 100644 --- a/gps/core/LocApiBase.cpp +++ b/gps/core/LocApiBase.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2014, 2016-2019 The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2014, 2016-2020 The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -415,19 +415,17 @@ void LocApiBase::reportSv(GnssSvNotification& svNotify) svNotify.gnssSvs[i].type = GNSS_SV_TYPE_UNKNOWN; } // Display what we report to clients - uint16_t displaySvId = GNSS_SV_TYPE_QZSS == svNotify.gnssSvs[i].type ? - svNotify.gnssSvs[i].svId + QZSS_SV_PRN_MIN - 1 : - svNotify.gnssSvs[i].svId; - LOC_LOGV(" %03zu: %*s %02d %f %f %f %f 0x%02X", + LOC_LOGV(" %03zu: %*s %02d %f %f %f %f 0x%02X 0x%2X", i, 13, constellationString[svNotify.gnssSvs[i].type], - displaySvId, + svNotify.gnssSvs[i].svId, svNotify.gnssSvs[i].cN0Dbhz, svNotify.gnssSvs[i].elevation, svNotify.gnssSvs[i].azimuth, svNotify.gnssSvs[i].carrierFrequencyHz, - svNotify.gnssSvs[i].gnssSvOptionsMask); + svNotify.gnssSvs[i].gnssSvOptionsMask, + svNotify.gnssSvs[i].gnssSignalTypeMask); } // loop through adapters, and deliver to all adapters. TO_ALL_LOCADAPTERS( @@ -593,6 +591,11 @@ void LocApiBase::handleBatchStatusEvent(BatchingStatus batchStatus) TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportBatchStatusChangeEvent(batchStatus)); } +void LocApiBase::reportGnssConfig(uint32_t sessionId, const GnssConfig& gnssConfig) +{ + // loop through adapters, and deliver to the first handling adapter. + TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportGnssConfigEvent(sessionId, gnssConfig)); +} enum loc_api_adapter_err LocApiBase:: open(LOC_API_ADAPTER_EVENT_MASK_T /*mask*/) @@ -879,4 +882,14 @@ DEFAULT_IMPL() void LocApiBase::updateSystemPowerState(PowerStateType /*powerState*/) DEFAULT_IMPL() +void LocApiBase:: + configRobustLocation(bool /*enabled*/, + bool /*enableForE911*/, + LocApiResponse* /*adapterResponse*/) +DEFAULT_IMPL() + +void LocApiBase:: + getRobustLocationConfig(uint32_t sessionId, LocApiResponse* /*adapterResponse*/) +DEFAULT_IMPL() + } // namespace loc_core diff --git a/gps/core/LocApiBase.h b/gps/core/LocApiBase.h index 9c76bab2..1e8337c5 100644 --- a/gps/core/LocApiBase.h +++ b/gps/core/LocApiBase.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2014, 2016-2019 The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2014, 2016-2020 The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -195,6 +195,7 @@ public: void reportDeleteAidingDataEvent(GnssAidingData& aidingData); void reportKlobucharIonoModel(GnssKlobucharIonoModel& ionoModel); void reportGnssAdditionalSystemInfo(GnssAdditionalSystemInfo& additionalSystemInfo); + void reportGnssConfig(uint32_t sessionId, const GnssConfig& gnssConfig); void sendNfwNotification(GnssNfwNotification& notification); void geofenceBreach(size_t count, uint32_t* hwIds, Location& location, @@ -318,6 +319,9 @@ public: void updateNmeaMask(uint32_t mask); virtual void updateSystemPowerState(PowerStateType systemPowerState); + virtual void configRobustLocation(bool enable, bool enableForE911, + LocApiResponse* adapterResponse=nullptr); + virtual void getRobustLocationConfig(uint32_t sessionId, LocApiResponse* adapterResponse); }; typedef LocApiBase* (getLocApi_t)(LOC_API_ADAPTER_EVENT_MASK_T exMask, diff --git a/gps/core/SystemStatusOsObserver.cpp b/gps/core/SystemStatusOsObserver.cpp index 0427380c..af33f2df 100644 --- a/gps/core/SystemStatusOsObserver.cpp +++ b/gps/core/SystemStatusOsObserver.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -67,6 +67,7 @@ void SystemStatusOsObserver::setSubscriptionObj(IDataItemSubscription* subscript inline SetSubsObj(ObserverContext& context, IDataItemSubscription* subscriptionObj) : mContext(context), mSubsObj(subscriptionObj) {} void proc() const { + LOC_LOGi("SetSubsObj::enter"); mContext.mSubscriptionObj = mSubsObj; if (!mContext.mSSObserver->mDataItemToClients.empty()) { @@ -76,6 +77,7 @@ void SystemStatusOsObserver::setSubscriptionObj(IDataItemSubscription* subscript mContext.mSubscriptionObj->subscribe(dis, mContext.mSSObserver); mContext.mSubscriptionObj->requestData(dis, mContext.mSSObserver); } + LOC_LOGi("SetSubsObj::exit"); } }; @@ -347,11 +349,6 @@ void SystemStatusOsObserver::notify(const list& dlist) vector dataItemVec(dlist.size()); for (auto each : dlist) { - IF_LOC_LOGD { - string dv; - each->stringify(dv); - LOC_LOGD("notify: DataItem In Value:%s", dv.c_str()); - } IDataItemCore* di = DataItemsFactoryProxy::createNewDataItem(each->getId()); if (nullptr == di) { @@ -364,6 +361,11 @@ void SystemStatusOsObserver::notify(const list& dlist) // add this dataitem if updated from last one dataItemVec.push_back(di); + IF_LOC_LOGD { + string dv; + di->stringify(dv); + LOC_LOGd("notify: DataItem In Value:%s", dv.c_str()); + } } if (!dataItemVec.empty()) { @@ -459,8 +461,9 @@ bool SystemStatusOsObserver::connectBackhaul() mFwkActionReqObj(fwkActReq) {} virtual ~HandleConnectBackhaul() {} void proc() const { - LOC_LOGD("HandleConnectBackhaul"); + LOC_LOGi("HandleConnectBackhaul::enter"); mFwkActionReqObj->connectBackhaul(); + LOC_LOGi("HandleConnectBackhaul::exit"); } IFrameworkActionReq* mFwkActionReqObj; }; @@ -488,8 +491,9 @@ bool SystemStatusOsObserver::disconnectBackhaul() mFwkActionReqObj(fwkActReq) {} virtual ~HandleDisconnectBackhaul() {} void proc() const { - LOC_LOGD("HandleDisconnectBackhaul"); + LOC_LOGi("HandleDisconnectBackhaul::enter"); mFwkActionReqObj->disconnectBackhaul(); + LOC_LOGi("HandleDisconnectBackhaul::exit"); } IFrameworkActionReq* mFwkActionReqObj; }; diff --git a/gps/core/data-items/DataItemsFactoryProxy.cpp b/gps/core/data-items/DataItemsFactoryProxy.cpp index f8a5e039..10f73f4d 100644 --- a/gps/core/data-items/DataItemsFactoryProxy.cpp +++ b/gps/core/data-items/DataItemsFactoryProxy.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -34,6 +34,7 @@ #include #include #include +#include "loc_misc_utils.h" namespace loc_core { @@ -48,40 +49,21 @@ IDataItemCore* DataItemsFactoryProxy::createNewDataItem(DataItemId id) mydi = (*getConcreteDIFunc)(id); } else { - // first call to this function, symbol not yet loaded - if (NULL == dataItemLibHandle) { - LOC_LOGD("Loaded library %s",DATA_ITEMS_LIB_NAME); - dataItemLibHandle = dlopen(DATA_ITEMS_LIB_NAME, RTLD_NOW); - if (NULL == dataItemLibHandle) { - // dlopen failed. - const char * err = dlerror(); - if (NULL == err) - { - err = "Unknown"; - } - LOC_LOGE("%s:%d]: failed to load library %s; error=%s", - __func__, __LINE__, DATA_ITEMS_LIB_NAME, err); - } - } + getConcreteDIFunc = (get_concrete_data_item_fn * ) + dlGetSymFromLib(dataItemLibHandle, DATA_ITEMS_LIB_NAME, DATA_ITEMS_GET_CONCRETE_DI); - // load sym - if dlopen handle is obtained and symbol is not yet obtained - if (NULL != dataItemLibHandle) { - getConcreteDIFunc = (get_concrete_data_item_fn * ) - dlsym(dataItemLibHandle, DATA_ITEMS_GET_CONCRETE_DI); - if (NULL != getConcreteDIFunc) { - LOC_LOGD("Loaded function %s : %p",DATA_ITEMS_GET_CONCRETE_DI,getConcreteDIFunc); - mydi = (*getConcreteDIFunc)(id); - } - else { - // dlysm failed. - const char * err = dlerror(); - if (NULL == err) - { - err = "Unknown"; - } - LOC_LOGE("%s:%d]: failed to find symbol %s; error=%s", - __func__, __LINE__, DATA_ITEMS_GET_CONCRETE_DI, err); + if (NULL != getConcreteDIFunc) { + LOC_LOGd("Loaded function %s : %p", DATA_ITEMS_GET_CONCRETE_DI, getConcreteDIFunc); + mydi = (*getConcreteDIFunc)(id); + } + else { + // dlysm failed. + const char * err = dlerror(); + if (NULL == err) + { + err = "Unknown"; } + LOC_LOGe("failed to find symbol %s; error=%s", DATA_ITEMS_GET_CONCRETE_DI, err); } } return mydi; diff --git a/gps/etc/gps.conf b/gps/etc/gps.conf index 159bfe67..df658cc9 100644 --- a/gps/etc/gps.conf +++ b/gps/etc/gps.conf @@ -322,3 +322,24 @@ CP_MTLR_ES=0 # and QCSR SS5 hardware receiver. # By default QTI GNSS receiver is enabled. # GNSS_DEPLOYMENT = 0 + +################################################## +## LOG BUFFER CONFIGURATION +################################################## +#LOG_BUFFER_ENABLED, 1=enable, 0=disable +#*_LEVEL_TIME_DEPTH, maximum time depth of level * +#in log buffer, unit is second +#*_LEVEL_MAX_CAPACITY, maximum numbers of level * +#log print sentences in log buffer +LOG_BUFFER_ENABLED = 0 +E_LEVEL_TIME_DEPTH = 600 +E_LEVEL_MAX_CAPACITY = 50 +W_LEVEL_TIME_DEPTH = 500 +W_LEVEL_MAX_CAPACITY = 100 +I_LEVEL_TIME_DEPTH = 400 +I_LEVEL_MAX_CAPACITY = 200 +D_LEVEL_TIME_DEPTH = 30 +D_LEVEL_MAX_CAPACITY = 300 +V_LEVEL_TIME_DEPTH = 200 +V_LEVEL_MAX_CAPACITY = 400 + diff --git a/gps/geofence/configure.ac b/gps/geofence/configure.ac index 8e3cd819..74eae7af 100644 --- a/gps/geofence/configure.ac +++ b/gps/geofence/configure.ac @@ -1,6 +1,6 @@ AC_PREREQ(2.61) AC_INIT([location-geofence], 1.0.0) -AM_INIT_AUTOMAKE([foreign]) +AM_INIT_AUTOMAKE([foreign subdir-objects]) AC_CONFIG_SRCDIR([Makefile.am]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_MACRO_DIR([m4]) diff --git a/gps/gnss/GnssAdapter.cpp b/gps/gnss/GnssAdapter.cpp index 5ce7b18a..b0566a4f 100644 --- a/gps/gnss/GnssAdapter.cpp +++ b/gps/gnss/GnssAdapter.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -526,6 +526,11 @@ GnssAdapter::convertLocationInfo(GnssLocationInfoNotification& out, out.flags |= GNSS_LOCATION_INFO_OUTPUT_ENG_MASK_BIT; out.locOutputEngMask = locationExtended.locOutputEngMask; } + + if (GPS_LOCATION_EXTENDED_HAS_CONFORMITY_INDEX & locationExtended.flags) { + out.flags |= GNSS_LOCATION_INFO_CONFORMITY_INDEX_BIT; + out.conformityIndex = locationExtended.conformityIndex; + } } @@ -784,19 +789,16 @@ GnssAdapter::setConfig() } else { gnssConfigRequested.gpsLock = GNSS_CONFIG_GPS_LOCK_NONE; } - - if (gpsConf.AGPS_CONFIG_INJECT) { - gnssConfigRequested.flags |= GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT | - GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT | - GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT | - GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT; - gnssConfigRequested.suplVersion = - mLocApi->convertSuplVersion(gpsConf.SUPL_VER); - gnssConfigRequested.lppProfile = - mLocApi->convertLppProfile(gpsConf.LPP_PROFILE); - gnssConfigRequested.aGlonassPositionProtocolMask = - gpsConf.A_GLONASS_POS_PROTOCOL_SELECT; - } + gnssConfigRequested.flags |= GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT | + GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT | + GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT | + GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT; + gnssConfigRequested.suplVersion = + mLocApi->convertSuplVersion(gpsConf.SUPL_VER); + gnssConfigRequested.lppProfile = + mLocApi->convertLppProfile(gpsConf.LPP_PROFILE); + gnssConfigRequested.aGlonassPositionProtocolMask = + gpsConf.A_GLONASS_POS_PROTOCOL_SELECT; if (gpsConf.LPPE_CP_TECHNOLOGY) { gnssConfigRequested.flags |= GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT; gnssConfigRequested.lppeControlPlaneMask = @@ -811,7 +813,7 @@ GnssAdapter::setConfig() gnssConfigRequested.blacklistedSvIds.assign(mBlacklistedSvIds.begin(), mBlacklistedSvIds.end()); mLocApi->sendMsg(new LocApiMsg( - [this, gpsConf, sapConf, oldMoServerUrl, gnssConfigRequested] () { + [this, gpsConf, sapConf, oldMoServerUrl, gnssConfigRequested] () mutable { gnssUpdateConfig(oldMoServerUrl, gnssConfigRequested, gnssConfigRequested); // set nmea mask type @@ -856,6 +858,13 @@ GnssAdapter::setConfig() mLocApi->setPositionAssistedClockEstimatorMode( mLocConfigInfo.paceConfigInfo.enable); + // we do not support control robust location from gps.conf + if (mLocConfigInfo.robustLocationConfigInfo.isValid == true) { + mLocApi->configRobustLocation( + mLocConfigInfo.robustLocationConfigInfo.enable, + mLocConfigInfo.robustLocationConfigInfo.enableFor911); + } + if (sapConf.GYRO_BIAS_RANDOM_WALK_VALID || sapConf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY_VALID || sapConf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY_VALID || @@ -889,8 +898,7 @@ GnssAdapter::setConfig() } std::vector GnssAdapter::gnssUpdateConfig(const std::string& oldMoServerUrl, - const GnssConfig& gnssConfigRequested, - const GnssConfig& gnssConfigNeedEngineUpdate, size_t count) { + GnssConfig& gnssConfigRequested, GnssConfig& gnssConfigNeedEngineUpdate, size_t count) { loc_gps_cfg_s gpsConf = ContextBase::mGps_conf; size_t index = 0; LocationError err = LOCATION_ERROR_SUCCESS; @@ -899,13 +907,20 @@ std::vector GnssAdapter::gnssUpdateConfig(const std::string& oldM errsList.insert(errsList.begin(), count, LOCATION_ERROR_SUCCESS); } - std::string serverUrl = getServerUrl(); std::string moServerUrl = getMoServerUrl(); int serverUrlLen = serverUrl.length(); int moServerUrlLen = moServerUrl.length(); + if (!ContextBase::mGps_conf.AGPS_CONFIG_INJECT) { + LOC_LOGd("AGPS_CONFIG_INJECT is 0. Not setting flags for AGPS configurations"); + gnssConfigRequested.flags &= ~(GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT | + GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT | + GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT | + GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT); + } + if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT) { if (gnssConfigNeedEngineUpdate.flags & GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT) { err = mLocApi->setGpsLockSync(gnssConfigRequested.gpsLock); @@ -1256,7 +1271,7 @@ GnssAdapter::gnssUpdateConfigCommand(GnssConfig config) mApi.sendMsg(new LocApiMsg( [&adapter, gnssConfigRequested, gnssConfigNeedEngineUpdate, - countOfConfigs, configCollectiveResponse, errs] () { + countOfConfigs, configCollectiveResponse, errs] () mutable { std::vector errsList = adapter.gnssUpdateConfig("", gnssConfigRequested, gnssConfigNeedEngineUpdate, countOfConfigs); @@ -1295,9 +1310,10 @@ void GnssAdapter::gnssSvIdConfigUpdate() { LOC_LOGd("blacklist bds 0x%" PRIx64 ", glo 0x%" PRIx64 - ", qzss 0x%" PRIx64 ", gal 0x%" PRIx64, + ", qzss 0x%" PRIx64 ", gal 0x%" PRIx64 ", sbas 0x%" PRIx64, mGnssSvIdConfig.bdsBlacklistSvMask, mGnssSvIdConfig.gloBlacklistSvMask, - mGnssSvIdConfig.qzssBlacklistSvMask, mGnssSvIdConfig.galBlacklistSvMask); + mGnssSvIdConfig.qzssBlacklistSvMask, mGnssSvIdConfig.galBlacklistSvMask, + mGnssSvIdConfig.sbasBlacklistSvMask); // Now set required blacklisted SVs mLocApi->setBlacklistSv(mGnssSvIdConfig); @@ -1320,9 +1336,10 @@ LocationError GnssAdapter::gnssSvIdConfigUpdateSync() { LOC_LOGd("blacklist bds 0x%" PRIx64 ", glo 0x%" PRIx64 - ", qzss 0x%" PRIx64 ", gal 0x%" PRIx64, + ", qzss 0x%" PRIx64 ", gal 0x%" PRIx64 ", sbas 0x%" PRIx64, mGnssSvIdConfig.bdsBlacklistSvMask, mGnssSvIdConfig.gloBlacklistSvMask, - mGnssSvIdConfig.qzssBlacklistSvMask, mGnssSvIdConfig.galBlacklistSvMask); + mGnssSvIdConfig.qzssBlacklistSvMask, mGnssSvIdConfig.galBlacklistSvMask, + mGnssSvIdConfig.sbasBlacklistSvMask); // Now set required blacklisted SVs return mLocApi->setBlacklistSvSync(mGnssSvIdConfig); @@ -1476,6 +1493,19 @@ GnssAdapter::gnssGetConfigCommand(GnssConfigFlagsMask configMask) { errs[index++] = LOCATION_ERROR_NOT_SUPPORTED; } } + if (mConfigMask & GNSS_CONFIG_FLAGS_ROBUST_LOCATION_BIT) { + uint32_t sessionId = *(mIds+index); + LocApiResponse* locApiResponse = + new LocApiResponse(*mAdapter.getContext(), + [this, sessionId] (LocationError err) { + mAdapter.reportResponse(err, sessionId);}); + if (!locApiResponse) { + LOC_LOGe("memory alloc failed"); + mAdapter.reportResponse(LOCATION_ERROR_GENERAL_FAILURE, sessionId); + } else { + mApi.getRobustLocationConfig(sessionId, locApiResponse); + } + } mAdapter.reportResponse(index, errs, mIds); delete[] errs; @@ -1505,12 +1535,14 @@ GnssAdapter::convertToGnssSvIdConfig( config.bdsBlacklistSvMask = 0; config.qzssBlacklistSvMask = 0; config.galBlacklistSvMask = 0; + config.sbasBlacklistSvMask = 0; retVal = true; } else { // Parse the vector and convert SV IDs to mask values for (GnssSvIdSource source : blacklistedSvIds) { uint64_t* svMaskPtr = NULL; GnssSvId initialSvId = 0; + uint16_t svIndexOffset = 0; switch(source.constellation) { case GNSS_SV_TYPE_GLONASS: svMaskPtr = &config.gloBlacklistSvMask; @@ -1528,6 +1560,28 @@ GnssAdapter::convertToGnssSvIdConfig( svMaskPtr = &config.galBlacklistSvMask; initialSvId = GNSS_SV_CONFIG_GAL_INITIAL_SV_ID; break; + case GNSS_SV_TYPE_SBAS: + // SBAS does not support enable/disable whole constellation + // so do not set up svTypeMask for SBAS + svMaskPtr = &config.sbasBlacklistSvMask; + // SBAS currently has two ranges + // range of SV id: 120 to 158 and 183 to 191 + if (0 == source.svId) { + LOC_LOGd("blacklist all SBAS SV"); + } else if (source.svId >= GNSS_SV_CONFIG_SBAS_INITIAL2_SV_ID) { + // handle SV id in range of 183 to 191 + initialSvId = GNSS_SV_CONFIG_SBAS_INITIAL2_SV_ID; + svIndexOffset = GNSS_SV_CONFIG_SBAS_INITIAL_SV_LENGTH; + } else if ((source.svId >= GNSS_SV_CONFIG_SBAS_INITIAL_SV_ID) && + (source.svId < (GNSS_SV_CONFIG_SBAS_INITIAL_SV_ID + + GNSS_SV_CONFIG_SBAS_INITIAL_SV_LENGTH))){ + // handle SV id in range of 120 to 158 + initialSvId = GNSS_SV_CONFIG_SBAS_INITIAL_SV_ID; + } else { + LOC_LOGe("invalid SBAS sv id %d", source.svId); + svMaskPtr = nullptr; + } + break; default: break; } @@ -1542,7 +1596,8 @@ GnssAdapter::convertToGnssSvIdConfig( LOC_LOGe("Invalid sv id %d for sv type %d", source.svId, source.constellation); } else { - *svMaskPtr |= (1ULL << (source.svId - initialSvId)); + uint32_t shiftCnt = source.svId + svIndexOffset - initialSvId; + *svMaskPtr |= (1ULL << shiftCnt); } } } @@ -1551,41 +1606,49 @@ GnssAdapter::convertToGnssSvIdConfig( if (0 != config.gloBlacklistSvMask || 0 != config.bdsBlacklistSvMask || 0 != config.galBlacklistSvMask || - 0 != config.qzssBlacklistSvMask) { + 0 != config.qzssBlacklistSvMask || + 0 != config.sbasBlacklistSvMask) { retVal = true; } } + LOC_LOGd("blacklist bds 0x%" PRIx64 ", glo 0x%" PRIx64 + ", qzss 0x%" PRIx64 ", gal 0x%" PRIx64 ", sbas 0x%" PRIx64, + config.bdsBlacklistSvMask, config.gloBlacklistSvMask, + config.qzssBlacklistSvMask, config.galBlacklistSvMask, + config.sbasBlacklistSvMask); + return retVal; } void GnssAdapter::convertFromGnssSvIdConfig( - const GnssSvIdConfig& svConfig, GnssConfig& config) + const GnssSvIdConfig& svConfig, std::vector& blacklistedSvIds) { // Convert blacklisted SV mask values to vectors if (svConfig.bdsBlacklistSvMask) { convertGnssSvIdMaskToList( - svConfig.bdsBlacklistSvMask, config.blacklistedSvIds, + svConfig.bdsBlacklistSvMask, blacklistedSvIds, GNSS_SV_CONFIG_BDS_INITIAL_SV_ID, GNSS_SV_TYPE_BEIDOU); - config.flags |= GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT; } if (svConfig.galBlacklistSvMask) { convertGnssSvIdMaskToList( - svConfig.galBlacklistSvMask, config.blacklistedSvIds, + svConfig.galBlacklistSvMask, blacklistedSvIds, GNSS_SV_CONFIG_GAL_INITIAL_SV_ID, GNSS_SV_TYPE_GALILEO); - config.flags |= GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT; } if (svConfig.gloBlacklistSvMask) { convertGnssSvIdMaskToList( - svConfig.gloBlacklistSvMask, config.blacklistedSvIds, + svConfig.gloBlacklistSvMask, blacklistedSvIds, GNSS_SV_CONFIG_GLO_INITIAL_SV_ID, GNSS_SV_TYPE_GLONASS); - config.flags |= GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT; } if (svConfig.qzssBlacklistSvMask) { convertGnssSvIdMaskToList( - svConfig.qzssBlacklistSvMask, config.blacklistedSvIds, + svConfig.qzssBlacklistSvMask, blacklistedSvIds, GNSS_SV_CONFIG_QZSS_INITIAL_SV_ID, GNSS_SV_TYPE_QZSS); - config.flags |= GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT; + } + if (svConfig.sbasBlacklistSvMask) { + convertGnssSvIdMaskToList( + svConfig.sbasBlacklistSvMask, blacklistedSvIds, + GNSS_SV_CONFIG_SBAS_INITIAL_SV_ID, GNSS_SV_TYPE_SBAS); } } @@ -1599,6 +1662,7 @@ void GnssAdapter::convertGnssSvIdMaskToList( // SV ID 0 => All SV IDs in mask if (GNSS_SV_CONFIG_ALL_BITS_ENABLED_MASK == svIdMask) { + LOC_LOGd("blacklist all SVs in constellation %d", source.constellation); source.svId = 0; svIds.push_back(source); return; @@ -1609,6 +1673,18 @@ void GnssAdapter::convertGnssSvIdMaskToList( while (svIdMask > 0) { if (svIdMask & 0x1) { source.svId = bitNumber + initialSvId; + // SBAS has two ranges: + // SBAS - SV 120 to 158, maps to 0 to 38 + // SV 183 to 191, maps to 39 to 47 + // #define GNSS_SV_CONFIG_SBAS_INITIAL_SV_ID 120 + // #define GNSS_SV_CONFIG_SBAS_INITIAL_SV_LENGTH 39 + // #define GNSS_SV_CONFIG_SBAS_INITIAL2_SV_ID 183 + if (svType == GNSS_SV_TYPE_SBAS) { + if (bitNumber >= GNSS_SV_CONFIG_SBAS_INITIAL_SV_LENGTH) { + source.svId = bitNumber - GNSS_SV_CONFIG_SBAS_INITIAL_SV_LENGTH + + GNSS_SV_CONFIG_SBAS_INITIAL2_SV_ID; + } + } svIds.push_back(source); } bitNumber++; @@ -1642,12 +1718,18 @@ void GnssAdapter::reportGnssSvIdConfig(const GnssSvIdConfig& svIdConfig) // Invoke control clients config callback if (nullptr != mControlCallbacks.gnssConfigCb && svIdConfig.size == sizeof(GnssSvIdConfig)) { - convertFromGnssSvIdConfig(svIdConfig, config); - LOC_LOGd("blacklist bds 0x%" PRIx64 ", glo 0x%" PRIx64 - ", qzss 0x%" PRIx64 ", gal 0x%" PRIx64, - svIdConfig.bdsBlacklistSvMask, svIdConfig.gloBlacklistSvMask, - svIdConfig.qzssBlacklistSvMask, svIdConfig.galBlacklistSvMask); - mControlCallbacks.gnssConfigCb(config); + + convertFromGnssSvIdConfig(svIdConfig, config.blacklistedSvIds); + if (config.blacklistedSvIds.size() > 0) { + config.flags |= GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT; + } + LOC_LOGd("blacklist bds 0x%" PRIx64 ", glo 0x%" PRIx64 ", " + "qzss 0x%" PRIx64 ", gal 0x%" PRIx64 ", sbas 0x%" PRIx64, + svIdConfig.bdsBlacklistSvMask, svIdConfig.gloBlacklistSvMask, + svIdConfig.qzssBlacklistSvMask, svIdConfig.galBlacklistSvMask, + svIdConfig.sbasBlacklistSvMask); + // use 0 session id to indicate that receiver does not yet care about session id + mControlCallbacks.gnssConfigCb(0, config); } else { LOC_LOGe("Failed to report, size %d", (uint32_t)config.size); } @@ -1708,6 +1790,12 @@ GnssAdapter::gnssSvTypeConfigUpdate(bool sendReset) mGnssSvTypeConfig.size, mGnssSvTypeConfig.blacklistedSvTypesMask, mGnssSvTypeConfig.enabledSvTypesMask, sendReset); + LOC_LOGd("blacklist bds 0x%" PRIx64 ", glo 0x%" PRIx64 + ", qzss 0x%" PRIx64 ", gal 0x%" PRIx64 ", sbas 0x%" PRIx64, + mGnssSvIdConfig.bdsBlacklistSvMask, mGnssSvIdConfig.gloBlacklistSvMask, + mGnssSvIdConfig.qzssBlacklistSvMask, mGnssSvIdConfig.galBlacklistSvMask, + mGnssSvIdConfig.sbasBlacklistSvMask); + if (mGnssSvTypeConfig.size == sizeof(mGnssSvTypeConfig)) { if (sendReset) { @@ -2094,6 +2182,8 @@ GnssAdapter::addClientCommand(LocationAPI* client, const LocationCallbacks& call inline virtual void proc() const { // check whether we need to notify client of cached location system info mAdapter.notifyClientOfCachedLocationSystemInfo(mClient, mCallbacks); + // check whether we need to request sv poly for the registered client + mAdapter.requestSvPolyForClient(mClient, mCallbacks); mAdapter.saveClient(mClient, mCallbacks); } }; @@ -2115,6 +2205,7 @@ GnssAdapter::stopClientSessions(LocationAPI* client) } for (auto key : vTimeBasedTrackingClient) { stopTimeBasedTrackingMultiplex(key.client, key.id); + eraseTrackingSession(key.client, key.id); } /* Distance-based Tracking */ @@ -2153,6 +2244,9 @@ GnssAdapter::updateClientsEventMask() if (it->second.gnssMeasurementsCb != nullptr) { mask |= LOC_API_ADAPTER_BIT_GNSS_MEASUREMENT; } + if (it->second.gnssSvPolynomialCb != nullptr) { + mask |= LOC_API_ADAPTER_BIT_GNSS_SV_POLYNOMIAL_REPORT; + } if (it->second.gnssDataCb != nullptr) { mask |= LOC_API_ADAPTER_BIT_PARSED_POSITION_REPORT; mask |= LOC_API_ADAPTER_BIT_NMEA_1HZ_REPORT; @@ -2219,7 +2313,8 @@ GnssAdapter::handleEngineUpEvent() mAdapter.gnssSvIdConfigUpdate(); mAdapter.gnssSvTypeConfigUpdate(); mAdapter.updateSystemPowerState(mAdapter.getSystemPowerState()); - mAdapter.restartSessions(); + // restart sessions + mAdapter.restartSessions(true); for (auto msg: mAdapter.mPendingMsgs) { mAdapter.sendMsg(msg); } @@ -2232,12 +2327,14 @@ GnssAdapter::handleEngineUpEvent() } void -GnssAdapter::restartSessions() +GnssAdapter::restartSessions(bool modemSSR) { - LOC_LOGD("%s]: ", __func__); + LOC_LOGi(":enter"); - // odcpi session is no longer active after restart - mOdcpiRequestActive = false; + if (modemSSR) { + // odcpi session is no longer active after restart + mOdcpiRequestActive = false; + } // SPE will be restarted now, so set this variable to false. mSPEAlreadyRunningAtHighestInterval = false; @@ -2252,6 +2349,20 @@ GnssAdapter::restartSessions() } } +// suspend all on-going sessions +void +GnssAdapter::suspendSessions() +{ + LOC_LOGi(":enter"); + + if (!mTimeBasedTrackingSessions.empty()) { + // inform engine hub that GNSS session has stopped + mEngHubProxy->gnssStopFix(); + mLocApi->stopFix(nullptr); + mSPEAlreadyRunningAtHighestInterval = false; + } +} + void GnssAdapter::checkAndRestartTimeBasedSession() { LOC_LOGD("%s]: ", __func__); @@ -2336,7 +2447,8 @@ GnssAdapter::hasCallbacksToStartTracking(LocationAPI* client) auto it = mClientData.find(client); if (it != mClientData.end()) { if (it->second.trackingCb || it->second.gnssLocationInfoCb || - it->second.engineLocationsInfoCb || it->second.gnssMeasurementsCb) { + it->second.engineLocationsInfoCb || it->second.gnssMeasurementsCb || + it->second.gnssSvPolynomialCb) { allowed = true; } else { LOC_LOGi("missing right callback to start tracking") @@ -3394,12 +3506,18 @@ GnssAdapter::reportPosition(const UlpLocation& ulpLocation, } } - // if PACE is enabled and engine hub is running and the fix is from sensor, - // e.g.: DRE, inject DRE fix to modem - if ((true == mLocConfigInfo.paceConfigInfo.isValid && - true == mLocConfigInfo.paceConfigInfo.enable) && - (true == initEngHubProxy()) && (LOC_POS_TECH_MASK_SENSORS & techMask)) { - mLocApi->injectPosition(locationInfo, false); + // if PACE is enabled + if ((true == mLocConfigInfo.paceConfigInfo.isValid) && + (true == mLocConfigInfo.paceConfigInfo.enable)) { + // If fix has sensor contribution, and it is fused fix with DRE engine + // contributing to the fix, inject to modem + if ((LOC_POS_TECH_MASK_SENSORS & techMask) && + (locationInfo.flags & GNSS_LOCATION_INFO_OUTPUT_ENG_TYPE_BIT) && + (locationInfo.locOutputEngType == LOC_OUTPUT_ENGINE_FUSED) && + (locationInfo.flags & GNSS_LOCATION_INFO_OUTPUT_ENG_MASK_BIT) && + (locationInfo.locOutputEngMask & DEAD_RECKONING_ENGINE)) { + mLocApi->injectPosition(locationInfo, false); + } } } } @@ -3608,10 +3726,6 @@ GnssAdapter::reportSv(GnssSvNotification& svNotify) svUsedIdMask = mGnssSvIdUsedInPosition.qzss_sv_used_ids_mask; } } - // QZSS SV id's need to reported as it is to framework, since - // framework expects it as it is. See GnssStatus.java. - // SV id passed to here by LocApi is 1-based. - svNotify.gnssSvs[i].svId += (QZSS_SV_PRN_MIN - 1); break; case GNSS_SV_TYPE_NAVIC: if (mGnssSvIdUsedInPosAvail) { @@ -3800,7 +3914,20 @@ GnssAdapter::requestNiNotifyEvent(const GnssNiNotification ¬ify, const void* mAdapter.getE911State()) || // older modems (LOC_IN_EMERGENCY_SET == mEmergencyState); // newer modems - if (GNSS_NI_TYPE_EMERGENCY_SUPL == mNotify.type) { + if ((mAdapter.mSupportNfwControl || 0 == mAdapter.getAfwControlId()) && + (GNSS_NI_TYPE_SUPL == mNotify.type || GNSS_NI_TYPE_EMERGENCY_SUPL == mNotify.type) + && !bIsInEmergency && + !(GNSS_NI_OPTIONS_PRIVACY_OVERRIDE_BIT & mNotify.options) && + (GNSS_CONFIG_GPS_LOCK_NI & ContextBase::mGps_conf.GPS_LOCK) && + 1 == ContextBase::mGps_conf.NI_SUPL_DENY_ON_NFW_LOCKED) { + /* If all these conditions are TRUE, then deny the NI Request: + -'Q' Lock behavior OR 'P' Lock behavior and GNSS is Locked + -NI SUPL Request type or NI SUPL Emergency Request type + -NOT in an Emergency Call Session + -NOT Privacy Override option + -NFW is locked and config item NI_SUPL_DENY_ON_NFW_LOCKED = 1 */ + mApi.informNiResponse(GNSS_NI_RESPONSE_DENY, mData); + } else if (GNSS_NI_TYPE_EMERGENCY_SUPL == mNotify.type) { bInformNiAccept = bIsInEmergency || (GNSS_CONFIG_SUPL_EMERGENCY_SERVICES_NO == ContextBase::mGps_conf.SUPL_ES); @@ -3816,15 +3943,6 @@ GnssAdapter::requestNiNotifyEvent(const GnssNiNotification ¬ify, const void* else { mAdapter.requestNiNotify(mNotify, mData, false); } - } else if ((mAdapter.mSupportNfwControl || 0 == mAdapter.getAfwControlId()) && - GNSS_NI_TYPE_SUPL == mNotify.type && !bIsInEmergency && - !(GNSS_NI_OPTIONS_PRIVACY_OVERRIDE_BIT & mNotify.options) && - (GNSS_CONFIG_GPS_LOCK_NI & ContextBase::mGps_conf.GPS_LOCK) && - 1 == ContextBase::mGps_conf.NI_SUPL_DENY_ON_NFW_LOCKED) { - // If 'Q' Lock behavior OR 'P' Lock behavior and GNSS is Locked - // If an NI SUPL Request that does not have Privacy Override option comes when - // NFW is locked and config item NI_SUPL_DENY_ON_NFW_LOCKED = 1, then deny it - mApi.informNiResponse(GNSS_NI_RESPONSE_DENY, mData); } else { mAdapter.requestNiNotify(mNotify, mData, false); } @@ -4081,11 +4199,53 @@ GnssAdapter::reportGnssMeasurementData(const GnssMeasurementsNotification& measu } } +void +GnssAdapter::requestSvPolyForClient(LocationAPI* client, const LocationCallbacks& callbacks) { + if (callbacks.gnssSvPolynomialCb) { + LocationCallbacks oldCallbacks = getClientCallbacks(client); + if (!oldCallbacks.gnssSvPolynomialCb) { + LOC_LOGd("request sv poly"); + GnssAidingDataSvMask svDataMask = GNSS_AIDING_DATA_SV_POLY_BIT; + mLocApi->requestForAidingData(svDataMask); + } + } +} + +void +GnssAdapter::reportSvPolynomial(const GnssSvPolynomial &svPolynomial) +{ + for (auto it=mClientData.begin(); it != mClientData.end(); ++it) { + if (nullptr != it->second.gnssSvPolynomialCb) { + it->second.gnssSvPolynomialCb(svPolynomial); + } + } +} + void GnssAdapter::reportSvPolynomialEvent(GnssSvPolynomial &svPolynomial) { LOC_LOGD("%s]: ", __func__); + + // report SV poly to engine hub to dispatch to engine plugins mEngHubProxy->gnssReportSvPolynomial(svPolynomial); + + // report SV poly to registered client + struct MsgReportGnssSvPolynomial : public LocMsg { + GnssAdapter& mAdapter; + GnssSvPolynomial mGnssSvPolynomialNotify; + inline MsgReportGnssSvPolynomial(GnssAdapter& adapter, + const GnssSvPolynomial& svPoly) : + LocMsg(), + mAdapter(adapter), + mGnssSvPolynomialNotify(svPoly) { + } + + inline virtual void proc() const { + mAdapter.reportSvPolynomial(mGnssSvPolynomialNotify); + } + }; + + sendMsg(new MsgReportGnssSvPolynomial(*this, svPolynomial)); } void @@ -5207,6 +5367,8 @@ GnssAdapter::updateSvConfig(uint32_t sessionId, mGnssSvTypeConfig = svTypeConfig; mGnssSvIdConfig = svIdConfig; + mBlacklistedSvIds.clear(); + convertFromGnssSvIdConfig(svIdConfig, mBlacklistedSvIds); // Send blacklist info mLocApi->setBlacklistSv(mGnssSvIdConfig); @@ -5261,6 +5423,17 @@ uint32_t GnssAdapter::gnssUpdateSvConfigCommand( void GnssAdapter::resetSvConfig(uint32_t sessionId) { + // Clear blacklisting + memset(&mGnssSvIdConfig, 0, sizeof(GnssSvIdConfig)); + mGnssSvIdConfig.size = sizeof(mGnssSvIdConfig); + mBlacklistedSvIds.clear(); + gnssSvIdConfigUpdate(); + + // Reset constellation config, including mGnssSvTypeConfig + // when size is set to 0, upon subsequent modem restart, sv type + // config will not be sent down to modem + gnssSetSvTypeConfig({sizeof(GnssSvTypeConfig), 0, 0}); + LocApiResponse* locApiResponse = nullptr; if (sessionId != 0) { locApiResponse = @@ -5337,6 +5510,91 @@ GnssAdapter::configLeverArmCommand(const LeverArmConfigInfo& configInfo) { return sessionId; } + +void +GnssAdapter::configRobustLocation(uint32_t sessionId, + bool enable, bool enableForE911) { + + mLocConfigInfo.robustLocationConfigInfo.isValid = true; + mLocConfigInfo.robustLocationConfigInfo.enable = enable; + mLocConfigInfo.robustLocationConfigInfo.enableFor911 = enableForE911; + + // suspend all tracking sessions so modem can take the E911 configure + suspendSessions(); + + LocApiResponse* locApiResponse = nullptr; + if (sessionId != 0) { + locApiResponse = + new LocApiResponse(*getContext(), + [this, sessionId] (LocationError err) { + reportResponse(err, sessionId);}); + if (!locApiResponse) { + LOC_LOGe("memory alloc failed"); + } + } + mLocApi->configRobustLocation(enable, enableForE911, locApiResponse); + + // resume all tracking sessions after the E911 configure + restartSessions(false); +} + +uint32_t GnssAdapter::configRobustLocationCommand( + bool enable, bool enableForE911) { + + // generated session id will be none-zero + uint32_t sessionId = generateSessionId(); + LOC_LOGd("session id %u", sessionId); + + struct MsgConfigRobustLocation : public LocMsg { + GnssAdapter& mAdapter; + uint32_t mSessionId; + bool mEnable; + bool mEnableForE911; + + inline MsgConfigRobustLocation(GnssAdapter& adapter, + uint32_t sessionId, + bool enable, + bool enableForE911) : + LocMsg(), + mAdapter(adapter), + mSessionId(sessionId), + mEnable(enable), + mEnableForE911(enableForE911) {} + inline virtual void proc() const { + mAdapter.configRobustLocation(mSessionId, mEnable, mEnableForE911); + } + }; + + sendMsg(new MsgConfigRobustLocation(*this, sessionId, enable, enableForE911)); + return sessionId; +} + +void GnssAdapter::reportGnssConfigEvent(uint32_t sessionId, const GnssConfig& gnssConfig) +{ + struct MsgReportGnssConfig : public LocMsg { + GnssAdapter& mAdapter; + uint32_t mSessionId; + mutable GnssConfig mGnssConfig; + inline MsgReportGnssConfig(GnssAdapter& adapter, + uint32_t sessionId, + const GnssConfig& gnssConfig) : + LocMsg(), + mAdapter(adapter), + mSessionId(sessionId), + mGnssConfig(gnssConfig) {} + inline virtual void proc() const { + // Invoke control clients config callback + if (nullptr != mAdapter.mControlCallbacks.gnssConfigCb) { + mAdapter.mControlCallbacks.gnssConfigCb(mSessionId, mGnssConfig); + } else { + LOC_LOGe("Failed to report, callback not registered"); + } + } + }; + + sendMsg(new MsgReportGnssConfig(*this, sessionId, gnssConfig)); +} + /* ==== Eng Hub Proxy ================================================================= */ /* ======== UTILITIES ================================================================= */ void diff --git a/gps/gnss/GnssAdapter.h b/gps/gnss/GnssAdapter.h index ff8131ff..d28a59ed 100644 --- a/gps/gnss/GnssAdapter.h +++ b/gps/gnss/GnssAdapter.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -134,9 +134,16 @@ typedef struct { bool enable; } PaceConfigInfo; +typedef struct { + bool isValid; + bool enable; + bool enableFor911; +} RobustLocationConfigInfo; + typedef struct { TuncConfigInfo tuncConfigInfo; PaceConfigInfo paceConfigInfo; + RobustLocationConfigInfo robustLocationConfigInfo; } LocIntegrationConfigInfo; using namespace loc_core; @@ -248,8 +255,9 @@ public: /* ======== EVENTS ====(Called from QMI Thread)========================================= */ virtual void handleEngineUpEvent(); /* ======== UTILITIES ================================================================== */ - void restartSessions(); + void restartSessions(bool modemSSR = false); void checkAndRestartTimeBasedSession(); + void suspendSessions(); /* ==== CLIENT ========================================================================= */ /* ======== COMMANDS ====(Called from Client Thread)==================================== */ @@ -295,6 +303,7 @@ public: const GnssSvIdConfig& svIdConfig); void resetSvConfig(uint32_t sessionId); void configLeverArm(uint32_t sessionId, const LeverArmConfigInfo& configInfo); + void configRobustLocation(uint32_t sessionId, bool enable, bool enableForE911); /* ==== NI ============================================================================= */ /* ======== COMMANDS ====(Called from Client Thread)==================================== */ @@ -319,8 +328,8 @@ public: void deleteAidingData(const GnssAidingData &data, uint32_t sessionId); void gnssUpdateXtraThrottleCommand(const bool enabled); std::vector gnssUpdateConfig(const std::string& oldMoServerUrl, - const GnssConfig& gnssConfigRequested, - const GnssConfig& gnssConfigNeedEngineUpdate, size_t count = 0); + GnssConfig& gnssConfigRequested, + GnssConfig& gnssConfigNeedEngineUpdate, size_t count = 0); /* ==== GNSS SV TYPE CONFIG ============================================================ */ /* ==== COMMANDS ====(Called from Client Thread)======================================== */ @@ -362,6 +371,7 @@ public: const GnssSvIdConfig& svIdConfig); uint32_t gnssResetSvConfigCommand(); uint32_t configLeverArmCommand(const LeverArmConfigInfo& configInfo); + uint32_t configRobustLocationCommand(bool enable, bool enableForE911); /* ========= ODCPI ===================================================================== */ /* ======== COMMANDS ====(Called from Client Thread)==================================== */ @@ -404,6 +414,7 @@ public: virtual void reportSvEphemerisEvent(GnssSvEphemerisReport & svEphemeris); virtual void reportGnssSvIdConfigEvent(const GnssSvIdConfig& config); virtual void reportGnssSvTypeConfigEvent(const GnssSvTypeConfig& config); + virtual void reportGnssConfigEvent(uint32_t sessionId, const GnssConfig& gnssConfig); virtual bool reportGnssEngEnergyConsumedEvent(uint64_t energyConsumedSinceFirstBoot); virtual void reportLocationSystemInfoEvent(const LocationSystemInfo& locationSystemInfo); @@ -451,6 +462,10 @@ public: } void updateSystemPowerState(PowerStateType systemPowerState); + void reportSvPolynomial(const GnssSvPolynomial &svPolynomial); + void requestSvPolyForClient(LocationAPI* client, + const LocationCallbacks& callbacks); + /*======== GNSSDEBUG ================================================================*/ bool getDebugReport(GnssDebugReport& report); @@ -479,7 +494,7 @@ public: static bool convertToGnssSvIdConfig( const std::vector& blacklistedSvIds, GnssSvIdConfig& config); static void convertFromGnssSvIdConfig( - const GnssSvIdConfig& svConfig, GnssConfig& config); + const GnssSvIdConfig& svConfig, std::vector& blacklistedSvIds); static void convertGnssSvIdMaskToList( uint64_t svIdMask, std::vector& svIds, GnssSvId initialSvId, GnssSvType svType); diff --git a/gps/gnss/location_gnss.cpp b/gps/gnss/location_gnss.cpp index 97e99e42..dc41f25f 100644 --- a/gps/gnss/location_gnss.cpp +++ b/gps/gnss/location_gnss.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -87,6 +87,7 @@ static uint32_t gnssUpdateSvConfig(const GnssSvTypeConfig& svTypeConfig, const GnssSvIdConfig& svIdConfig); static uint32_t gnssResetSvConfig(); static uint32_t configLeverArm(const LeverArmConfigInfo& configInfo); +static uint32_t configRobustLocation(bool enable, bool enableForE911); static const GnssInterface gGnssInterface = { sizeof(GnssInterface), @@ -132,6 +133,7 @@ static const GnssInterface gGnssInterface = { gnssUpdateSvConfig, gnssResetSvConfig, configLeverArm, + configRobustLocation, }; #ifndef DEBUG_X86 @@ -453,3 +455,11 @@ static uint32_t configLeverArm(const LeverArmConfigInfo& configInfo){ return 0; } } + +static uint32_t configRobustLocation(bool enable, bool enableForE911){ + if (NULL != gGnssAdapter) { + return gGnssAdapter->configRobustLocationCommand(enable, enableForE911); + } else { + return 0; + } +} diff --git a/gps/location/ILocationAPI.h b/gps/location/ILocationAPI.h index 87aa99bd..b53e41ea 100644 --- a/gps/location/ILocationAPI.h +++ b/gps/location/ILocationAPI.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2018 The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -302,6 +302,27 @@ public: LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid */ virtual uint32_t configLeverArm(const LeverArmConfigInfo& configInfo) = 0; + + /** @brief + Configure the robust location setting. + + @param + enable: true to enable robust location and false to disable + robust location. + + @param + enableForE911: true to enable robust location when device is on + E911 session and false to disable on E911 session. + This parameter is only valid if robust location is enabled. + + @return + A session id that will be returned in responseCallback to + match command with response. This effect is global for all + clients of LocationAPI responseCallback returns: + LOCATION_ERROR_SUCCESS if successful + LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid + */ + virtual uint32_t configRobustLocation(bool enable, bool enableForE911) = 0; }; #endif /* ILOCATIONAPI_H */ diff --git a/gps/location/LocationAPI.cpp b/gps/location/LocationAPI.cpp index 7c125b81..6045a231 100644 --- a/gps/location/LocationAPI.cpp +++ b/gps/location/LocationAPI.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -86,7 +86,9 @@ static bool isGnssClient(LocationCallbacks& locationCallbacks) locationCallbacks.trackingCb != nullptr || locationCallbacks.gnssLocationInfoCb != nullptr || locationCallbacks.engineLocationsInfoCb != nullptr || - locationCallbacks.gnssMeasurementsCb != nullptr); + locationCallbacks.gnssMeasurementsCb != nullptr || + locationCallbacks.gnssSvPolynomialCb != nullptr || + locationCallbacks.locationSystemInfoCb != nullptr); } static bool isBatchingClient(LocationCallbacks& locationCallbacks) @@ -121,7 +123,6 @@ void LocationAPI::onRemoveClientCompleteCb (LocationAdapterTypeMask adapterType) if ((true == invokeCallback) && (nullptr != destroyCompleteCb)) { LOC_LOGd("invoke client destroy cb"); (destroyCompleteCb) (); - LOC_LOGd("finish invoke client destroy cb"); delete this; } @@ -143,7 +144,7 @@ void onGeofenceRemoveClientCompleteCb (LocationAPI* client) } LocationAPI* -LocationAPI::createInstance(LocationCallbacks& locationCallbacks) +LocationAPI::createInstance (LocationCallbacks& locationCallbacks) { if (nullptr == locationCallbacks.capabilitiesCb || nullptr == locationCallbacks.responseCb || @@ -234,15 +235,12 @@ LocationAPI::destroy(locationApiDestroyCompleteCallback destroyCompleteCb) pthread_mutex_lock(&gDataMutex); auto it = gData.clientData.find(this); if (it != gData.clientData.end()) { - bool removeFromGnssInf = - (isGnssClient(it->second) && NULL != gData.gnssInterface); - bool removeFromBatchingInf = - (isBatchingClient(it->second) && NULL != gData.batchingInterface); - bool removeFromGeofenceInf = - (isGeofenceClient(it->second) && NULL != gData.geofenceInterface); + bool removeFromGnssInf = (NULL != gData.gnssInterface); + bool removeFromBatchingInf = (NULL != gData.batchingInterface); + bool removeFromGeofenceInf = (NULL != gData.geofenceInterface); bool needToWait = (removeFromGnssInf || removeFromBatchingInf || removeFromGeofenceInf); LOC_LOGe("removeFromGnssInf: %d, removeFromBatchingInf: %d, removeFromGeofenceInf: %d," - "need %d", removeFromGnssInf, removeFromBatchingInf, removeFromGeofenceInf, + "needToWait: %d", removeFromGnssInf, removeFromBatchingInf, removeFromGeofenceInf, needToWait); if ((NULL != destroyCompleteCb) && (true == needToWait)) { @@ -258,7 +256,7 @@ LocationAPI::destroy(locationApiDestroyCompleteCallback destroyCompleteCb) destroyCbData.waitAdapterMask |= (removeFromGeofenceInf ? LOCATION_ADAPTER_GEOFENCE_TYPE_BIT : 0); gData.destroyClientData[this] = destroyCbData; - LOC_LOGe("destroy data stored in the map: 0x%x", destroyCbData.waitAdapterMask); + LOC_LOGi("destroy data stored in the map: 0x%x", destroyCbData.waitAdapterMask); } if (removeFromGnssInf) { @@ -799,3 +797,17 @@ uint32_t LocationControlAPI::configLeverArm(const LeverArmConfigInfo& configInfo pthread_mutex_unlock(&gDataMutex); return id; } + +uint32_t LocationControlAPI::configRobustLocation(bool enable, bool enableForE911) { + uint32_t id = 0; + pthread_mutex_lock(&gDataMutex); + + if (gData.gnssInterface != NULL) { + id = gData.gnssInterface->configRobustLocation(enable, enableForE911); + } else { + LOC_LOGe("No gnss interface available for Location Control API"); + } + + pthread_mutex_unlock(&gDataMutex); + return id; +} diff --git a/gps/location/LocationAPI.h b/gps/location/LocationAPI.h index f70fc2f8..c949fcc7 100644 --- a/gps/location/LocationAPI.h +++ b/gps/location/LocationAPI.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -374,6 +374,27 @@ public: LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid */ virtual uint32_t configLeverArm(const LeverArmConfigInfo& configInfo) override; + + /** @brief + Configure the robust location setting. + + @param + enable: true to enable robust location and false to disable + robust location. + + @param + enableForE911: true to enable robust location when device is + on E911 session and false to disable on E911 session. + This parameter is only valid if robust location is enabled. + + @return + A session id that will be returned in responseCallback to + match command with response. This effect is global for all + clients of LocationAPI responseCallback returns: + LOCATION_ERROR_SUCCESS if successful + LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid + */ + virtual uint32_t configRobustLocation(bool enable, bool enableForE911) override; }; #endif /* LOCATIONAPI_H */ diff --git a/gps/location/LocationDataTypes.h b/gps/location/LocationDataTypes.h index 65b5e13d..d69a3e19 100644 --- a/gps/location/LocationDataTypes.h +++ b/gps/location/LocationDataTypes.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -37,7 +37,7 @@ #define GNSS_NI_REQUESTOR_MAX (256) #define GNSS_NI_MESSAGE_ID_MAX (2048) -#define GNSS_SV_MAX (176) +#define GNSS_SV_MAX (128) #define GNSS_MEASUREMENTS_MAX (128) #define GNSS_UTC_TIME_OFFSET (3657) @@ -177,6 +177,7 @@ typedef enum { GNSS_LOCATION_INFO_CALIBRATION_STATUS_BIT = (1<<26), // valid sensor cal status GNSS_LOCATION_INFO_OUTPUT_ENG_TYPE_BIT = (1<<27), // valid output engine type GNSS_LOCATION_INFO_OUTPUT_ENG_MASK_BIT = (1<<28), // valid output engine mask + GNSS_LOCATION_INFO_CONFORMITY_INDEX_BIT = (1<<29), // valid conformity index } GnssLocationInfoFlagBits; typedef enum { @@ -318,6 +319,7 @@ typedef enum { GNSS_CONFIG_FLAGS_SUPL_MODE_BIT = (1<<9), GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT = (1<<10), GNSS_CONFIG_FLAGS_EMERGENCY_EXTENSION_SECONDS_BIT = (1<<11), + GNSS_CONFIG_FLAGS_ROBUST_LOCATION_BIT = (1<<12), } GnssConfigFlagsBits; typedef enum { @@ -385,6 +387,7 @@ typedef enum { GNSS_SV_OPTIONS_HAS_ALMANAC_BIT = (1<<1), GNSS_SV_OPTIONS_USED_IN_FIX_BIT = (1<<2), GNSS_SV_OPTIONS_HAS_CARRIER_FREQUENCY_BIT = (1<<3), + GNSS_SV_OPTIONS_HAS_GNSS_SIGNAL_TYPE_BIT = (1<<4) } GnssSvOptionsBits; typedef enum { @@ -538,7 +541,7 @@ typedef enum { GNSS_CONSTELLATION_TYPE_BEIDOU_BIT = (1<<3), GNSS_CONSTELLATION_TYPE_GALILEO_BIT = (1<<4), GNSS_CONSTELLATION_TYPE_SBAS_BIT = (1<<5), - GNSS_CONSTELLATION_TYPE_NAVIC_BIT = (1<<6) + GNSS_CONSTELLATION_TYPE_NAVIC_BIT = (1<<6), } GnssConstellationTypeBits; #define GNSS_CONSTELLATION_TYPE_MASK_ALL\ @@ -624,7 +627,7 @@ typedef enum GNSS_LOC_SV_SYSTEM_QZSS = 6, /**< QZSS satellite. */ GNSS_LOC_SV_SYSTEM_NAVIC = 7, - /**< QZSS satellite. */ + /**< NAVIC satellite. */ GNSS_LOC_SV_SYSTEM_MAX = 7, /**< Max enum of valid SV system. */ } Gnss_LocSvSystemEnumType; @@ -882,14 +885,11 @@ typedef struct { GnssSignalTypeMask gnssSignalType; /** Specifies GNSS Constellation Type */ Gnss_LocSvSystemEnumType gnssConstellation; - /** GNSS SV ID. - For GPS: 1 to 32 - For GLONASS: 65 to 96. When slot-number to SV ID mapping is unknown, set as 255. - For SBAS: 120 to 151 - For QZSS-L1CA:193 to 197 - For BDS: 201 to 237 - For GAL: 301 to 336 - For NAVIC: 401 to 414 */ + /** Unique SV Identifier. + * For SV Range of supported constellation, please refer to + * the comment section of svId in GnssSv. + * For GLONASS: When slot-number to SV ID mapping is unknown, set as 255. + */ uint16_t gnssSvId; } GnssMeasUsageInfo; @@ -1046,6 +1046,11 @@ typedef struct { // when loc output eng type is set to fused, this field // indicates the set of engines contribute to the fix. PositioningEngineMask locOutputEngMask; + /* When robust location is enabled, this field + * will how well the various input data considered for + * navigation solution conform to expectations. + * Range: 0 (least conforming) to 1 (most conforming) */ + float conformityIndex; } GnssLocationInfoNotification; typedef struct { @@ -1061,9 +1066,40 @@ typedef struct { char extras[GNSS_NI_MESSAGE_ID_MAX]; } GnssNiNotification; +// carrier frequency of the signal tracked +#define GPS_L1CA_CARRIER_FREQUENCY (1575420000.0) +#define GPS_L1C_CARRIER_FREQUENCY (1575420000.0) +#define GPS_L2C_L_CARRIER_FREQUENCY (1227600000.0) +#define GPS_L5_Q_CARRIER_FREQUENCY (1176450000.0) +#define GLONASS_G1_CARRIER_FREQUENCY (1602000000.0) +#define GLONASS_G2_CARRIER_FREQUENCY (1246000000.0) +#define GALILEO_E1_C_CARRIER_FREQUENCY (1575420000.0) +#define GALILEO_E5A_Q_CARRIER_FREQUENCY (1176450000.0) +#define GALILEO_E5B_Q_CARRIER_FREQUENCY (1207140000.0) +#define BEIDOU_B1_I_CARRIER_FREQUENCY (1561098000.0) +#define BEIDOU_B1C_CARRIER_FREQUENCY (1575420000.0) +#define BEIDOU_B2_I_CARRIER_FREQUENCY (1207140000.0) +#define BEIDOU_B2A_I_CARRIER_FREQUENCY (1176450000.0) +#define BEIDOU_B2A_Q_CARRIER_FREQUENCY (1176450000.0) +#define QZSS_L1CA_CARRIER_FREQUENCY (1575420000.0) +#define QZSS_L1S_CARRIER_FREQUENCY (1575420000.0) +#define QZSS_L2C_L_CARRIER_FREQUENCY (1227600000.0) +#define QZSS_L5_Q_CARRIER_FREQUENCY (1176450000.0) +#define SBAS_L1_CA_CARRIER_FREQUENCY (1575420000.0) +#define NAVIC_L5_CARRIER_FREQUENCY (1176450000.0) + typedef struct { uint32_t size; // set to sizeof(GnssSv) - uint16_t svId; // Unique Identifier + // Unique SV Identifier. + // SV Range for supported constellation is specified as below: + // - For GPS: 1 to 32 + // - For GLONASS: 65 to 96 + // - For SBAS: 120 to 158 and 183 to 191 + // - For QZSS: 193 to 197 + // - For BDS: 201 to 237 + // - For GAL: 301 to 336 + // - For NAVIC: 401 to 41 + uint16_t svId; GnssSvType type; // type of SV (GPS, SBAS, GLONASS, QZSS, BEIDOU, GALILEO) float cN0Dbhz; // signal strength float elevation; // elevation of SV (in degrees) @@ -1091,8 +1127,13 @@ struct GnssConfigSetAssistanceServer { }; typedef struct { - uint32_t size; // set to sizeof(GnssMeasurementsData) - GnssMeasurementsDataFlagsMask flags; // bitwise OR of GnssMeasurementsDataFlagsBits + // set to sizeof(GnssMeasurementsData) + uint32_t size; + // bitwise OR of GnssMeasurementsDataFlagsBits + GnssMeasurementsDataFlagsMask flags; + // Unique SV Identifier + // For SV Range of supported constellation, + // please refer to the comment section of svId in GnssSv. int16_t svId; GnssSvType svType; double timeOffsetNs; @@ -1114,6 +1155,7 @@ typedef struct { double agcLevelDb; GnssMeasurementsCodeType codeType; char otherCodeTypeName[GNSS_MAX_NAME_LENGTH]; + int16_t gloFrequency; } GnssMeasurementsData; typedef struct { @@ -1158,12 +1200,88 @@ typedef struct { GnssMeasurementsClock clock; // clock } GnssMeasurementsNotification; +#define GNSS_SV_POLY_VELOCITY_COEF_MAX_SIZE 12 +#define GNSS_SV_POLY_XYZ_0_TH_ORDER_COEFF_MAX_SIZE 3 +#define GNSS_SV_POLY_XYZ_N_TH_ORDER_COEFF_MAX_SIZE 9 +#define GNSS_SV_POLY_SV_CLKBIAS_COEFF_MAX_SIZE 4 + +typedef uint16_t GnssSvPolyStatusMask; +#define GNSS_SV_POLY_SRC_ALM_CORR_V02 ((GnssSvPolyStatusMask)0x01) +#define GNSS_SV_POLY_GLO_STR4_V02 ((GnssSvPolyStatusMask)0x02) +#define GNSS_SV_POLY_DELETE_V02 ((GnssSvPolyStatusMask)0x04) +#define GNSS_SV_POLY_SRC_GAL_FNAV_OR_INAV_V02 ((GnssSvPolyStatusMask)0x08) +typedef uint16_t GnssSvPolyStatusMaskValidity; +#define GNSS_SV_POLY_SRC_ALM_CORR_VALID_V02 ((GnssSvPolyStatusMaskValidity)0x01) +#define GNSS_SV_POLY_GLO_STR4_VALID_V02 ((GnssSvPolyStatusMaskValidity)0x02) +#define GNSS_SV_POLY_DELETE_VALID_V02 ((GnssSvPolyStatusMaskValidity)0x04) +#define GNSS_SV_POLY_SRC_GAL_FNAV_OR_INAV_VALID_V02 ((GnssSvPolyStatusMaskValidity)0x08) + +typedef struct { + uint32_t size; + uint16_t gnssSvId; + /* GPS: 1-32, GLO: 65-96, 0: Invalid, + SBAS: 120-151, BDS:201-237,GAL:301 to 336 + All others are reserved + */ + int8_t freqNum; + /* Freq index, only valid if u_SysInd is GLO */ + + GnssSvPolyStatusMaskValidity svPolyStatusMaskValidity; + GnssSvPolyStatusMask svPolyStatusMask; + + uint32_t is_valid; + + uint16_t iode; + /* Ephemeris reference time + GPS:Issue of Data Ephemeris used [unitless]. + GLO: Tb 7-bit, refer to ICD02 + */ + double T0; + /* Reference time for polynominal calculations + GPS: Secs in week. + GLO: Full secs since Jan/01/96 + */ + double polyCoeffXYZ0[GNSS_SV_POLY_XYZ_0_TH_ORDER_COEFF_MAX_SIZE]; + /* C0X, C0Y, C0Z */ + double polyCoefXYZN[GNSS_SV_POLY_XYZ_N_TH_ORDER_COEFF_MAX_SIZE]; + /* C1X, C2X ... C2Z, C3Z */ + float polyCoefOther[GNSS_SV_POLY_SV_CLKBIAS_COEFF_MAX_SIZE]; + /* C0T, C1T, C2T, C3T */ + float svPosUnc; /* SV position uncertainty [m]. */ + float ionoDelay; /* Ionospheric delay at d_T0 [m]. */ + float ionoDot; /* Iono delay rate [m/s]. */ + float sbasIonoDelay;/* SBAS Ionospheric delay at d_T0 [m]. */ + float sbasIonoDot; /* SBAS Iono delay rate [m/s]. */ + float tropoDelay; /* Tropospheric delay [m]. */ + float elevation; /* Elevation [rad] at d_T0 */ + float elevationDot; /* Elevation rate [rad/s] */ + float elevationUnc; /* SV elevation [rad] uncertainty */ + double velCoef[GNSS_SV_POLY_VELOCITY_COEF_MAX_SIZE]; + /* Coefficients of velocity poly */ + uint32_t enhancedIOD; /* Enhanced Reference Time */ + float gpsIscL1ca; + float gpsIscL2c; + float gpsIscL5I5; + float gpsIscL5Q5; + float gpsTgd; + float gloTgdG1G2; + float bdsTgdB1; + float bdsTgdB2; + float bdsTgdB2a; + float bdsIscB2a; + float galBgdE1E5a; + float galBgdE1E5b; + float navicTgdL5; +} GnssSvPolynomial; + typedef uint32_t GnssSvId; struct GnssSvIdSource{ uint32_t size; // set to sizeof(GnssSvIdSource) GnssSvType constellation; // constellation for the sv to blacklist - GnssSvId svId; // sv id to blacklist + GnssSvId svId; // Unique SV Identifier, + // For SV Range of supported constellation, + // please refer to the comment section of svId in GnssSv. }; inline bool operator ==(GnssSvIdSource const& left, GnssSvIdSource const& right) { return left.size == right.size && @@ -1198,6 +1316,32 @@ typedef struct { uint64_t sbasBlacklistSvMask; } GnssSvIdConfig; +// Specify the valid mask for robust location configure that +// will be returned via LocConfigGetMinGpsWeekCb when invoking +// getRobustLocationConfig. */ +enum GnssConfigRobustLocationValidMask { + // GnssConfigRobustLocation has valid enabled field. + GNSS_CONFIG_ROBUST_LOCATION_ENABLED_VALID_BIT = (1<<0), + // GnssConfigRobustLocation has valid enabledForE911 field. + GNSS_CONFIG_ROBUST_LOCATION_ENABLED_FOR_E911_VALID_BIT = (1<<1), +}; + +// specify the robust location configuration used by modem GNSS engine +struct GnssConfigRobustLocation { + GnssConfigRobustLocationValidMask validMask; + bool enabled; + bool enabledForE911; + + inline bool equals(const GnssConfigRobustLocation& config) const { + if (config.validMask == validMask && + config.enabled == enabled && + config.enabledForE911 == enabledForE911) { + return true; + } + return false; + } +}; + struct GnssConfig{ uint32_t size; // set to sizeof(GnssConfig) GnssConfigFlagsMask flags; // bitwise OR of GnssConfigFlagsBits to mark which params are valid @@ -1213,6 +1357,7 @@ struct GnssConfig{ GnssConfigSuplModeMask suplModeMask; //bitwise OR of GnssConfigSuplModeBits std::vector blacklistedSvIds; uint32_t emergencyExtensionSeconds; + GnssConfigRobustLocation robustLocationConfig; inline bool equals(const GnssConfig& config) { if (flags == config.flags && @@ -1227,7 +1372,8 @@ struct GnssConfig{ suplEmergencyServices == config.suplEmergencyServices && suplModeMask == config.suplModeMask && blacklistedSvIds == config.blacklistedSvIds && - emergencyExtensionSeconds == config.emergencyExtensionSeconds) { + emergencyExtensionSeconds == config.emergencyExtensionSeconds && + robustLocationConfig.equals(config.robustLocationConfig)) { return true; } return false; @@ -1253,7 +1399,11 @@ typedef struct { } GnssDebugTime; typedef struct { - uint32_t size; // set to sizeof + // set to sizeof + uint32_t size; + // Unique SV Identifier + // For SV Range of supported constellation, + // please refer to the comment section of svId in GnssSv. uint32_t svid; GnssSvType constellation; GnssEphemerisType mEphemerisType; @@ -1494,9 +1644,18 @@ typedef std::function gnssMeasurementsCallback; +/* Gives GNSS SV poly information, optional can be NULL + gnssSvPolyCallback is called only during a tracking session + broadcasted to all clients that registers for the poly */ +typedef std::function gnssSvPolynomialCallback; + + /* Provides the current GNSS configuration to the client */ typedef std::function gnssConfigCallback; /* LocationSystemInfoCb is for receiving rare occuring location @@ -1534,6 +1693,7 @@ typedef struct { batchingStatusCallback batchingStatusCb; // optional locationSystemInfoCallback locationSystemInfoCb; // optional engineLocationsInfoCallback engineLocationsInfoCb; // optional + gnssSvPolynomialCallback gnssSvPolynomialCb; // optional } LocationCallbacks; #endif /* LOCATIONDATATYPES_H */ diff --git a/gps/location/location_interface.h b/gps/location/location_interface.h index 6edb9116..1f1cfb9a 100644 --- a/gps/location/location_interface.h +++ b/gps/location/location_interface.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -95,6 +95,7 @@ struct GnssInterface { const GnssSvIdConfig& svIdConfig); uint32_t (*gnssResetSvConfig)(); uint32_t (*configLeverArm)(const LeverArmConfigInfo& configInfo); + uint32_t (*configRobustLocation)(bool enable, bool enableForE911); }; struct BatchingInterface { diff --git a/gps/pla/android/loc_pla.h b/gps/pla/android/loc_pla.h index 6104bfb2..1b997394 100644 --- a/gps/pla/android/loc_pla.h +++ b/gps/pla/android/loc_pla.h @@ -31,7 +31,8 @@ #ifdef __cplusplus #include -#define uptimeMillis android::uptimeMillis +#define uptimeMillis() android::uptimeMillis() +#define elapsedRealtime() android::elapsedRealtime() #endif #ifdef __cplusplus diff --git a/gps/pla/oe/loc_pla.h b/gps/pla/oe/loc_pla.h index e795a23e..bbdb0bd3 100644 --- a/gps/pla/oe/loc_pla.h +++ b/gps/pla/oe/loc_pla.h @@ -37,16 +37,23 @@ #include #include -inline int64_t uptimeMillis() +inline int64_t sysTimeMillis(int clock) { struct timespec ts; int64_t time_ms = 0; - clock_gettime(CLOCK_BOOTTIME, &ts); + clock_gettime(clock, &ts); time_ms += (ts.tv_sec * 1000000000LL); time_ms += ts.tv_nsec + 500000LL; return time_ms / 1000000LL; } +inline int64_t uptimeMillis() { + return sysTimeMillis(CLOCK_MONOTONIC); +} +inline int64_t elapsedRealtime() { + return sysTimeMillis(CLOCK_BOOTTIME); +} + extern "C" { #endif diff --git a/gps/utils/Android.mk b/gps/utils/Android.mk index 88ad487b..57d485de 100644 --- a/gps/utils/Android.mk +++ b/gps/utils/Android.mk @@ -27,7 +27,8 @@ LOCAL_SRC_FILES += \ MsgTask.cpp \ loc_misc_utils.cpp \ loc_nmea.cpp \ - LocIpc.cpp + LocIpc.cpp \ + LogBuffer.cpp # Flag -std=c++11 is not accepted by compiler when LOCAL_CLANG is set to true LOCAL_CFLAGS += \ diff --git a/gps/utils/LocIpc.cpp b/gps/utils/LocIpc.cpp index e9dbe9da..344e4872 100644 --- a/gps/utils/LocIpc.cpp +++ b/gps/utils/LocIpc.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -139,8 +139,20 @@ protected: } public: inline LocIpcLocalSender(const char* name) : LocIpcSender(), - mSock(make_shared((nullptr == name) ? -1 : (::socket(AF_UNIX, SOCK_DGRAM, 0)))), + mSock(nullptr), mAddr({.sun_family = AF_UNIX, {}}) { + + int fd = -1; + if (nullptr != name) { + fd = ::socket(AF_UNIX, SOCK_DGRAM, 0); + if (fd >= 0) { + timeval timeout; + timeout.tv_sec = 2; + timeout.tv_usec = 0; + setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)); + } + } + mSock.reset(new Sock(fd)); if (mSock != nullptr && mSock->isValid()) { snprintf(mAddr.sun_path, sizeof(mAddr.sun_path), "%s", name); } diff --git a/gps/utils/LogBuffer.cpp b/gps/utils/LogBuffer.cpp new file mode 100644 index 00000000..1bb6f0fc --- /dev/null +++ b/gps/utils/LogBuffer.cpp @@ -0,0 +1,167 @@ +/* Copyright (c) 2019 The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation, nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "LogBuffer.h" +#include + +#define LOG_TAG "LocSvc_LogBuffer" + +namespace loc_util { + +LogBuffer* LogBuffer::mInstance; +struct sigaction LogBuffer::mOriSigAction[NSIG]; +struct sigaction LogBuffer::mNewSigAction; +mutex LogBuffer::sLock; + +LogBuffer* LogBuffer::getInstance() { + if (mInstance == nullptr) { + lock_guard guard(sLock); + if (mInstance == nullptr) { + mInstance = new LogBuffer(); + } + } + return mInstance; +} + +LogBuffer::LogBuffer(): mLogList(TOTAL_LOG_LEVELS), + mConfigVec(TOTAL_LOG_LEVELS, ConfigsInLevel(TIME_DEPTH_THRESHOLD_MINIMAL_IN_SEC, + MAXIMUM_NUM_IN_LIST, 0)) { + loc_param_s_type log_buff_config_table[] = + { + {"E_LEVEL_TIME_DEPTH", &mConfigVec[0].mTimeDepthThres, NULL, 'n'}, + {"E_LEVEL_MAX_CAPACITY", &mConfigVec[0].mMaxNumThres, NULL, 'n'}, + {"W_LEVEL_TIME_DEPTH", &mConfigVec[1].mTimeDepthThres, NULL, 'n'}, + {"W_LEVEL_MAX_CAPACITY", &mConfigVec[1].mMaxNumThres, NULL, 'n'}, + {"I_LEVEL_TIME_DEPTH", &mConfigVec[2].mTimeDepthThres, NULL, 'n'}, + {"I_LEVEL_MAX_CAPACITY", &mConfigVec[2].mMaxNumThres, NULL, 'n'}, + {"D_LEVEL_TIME_DEPTH", &mConfigVec[3].mTimeDepthThres, NULL, 'n'}, + {"D_LEVEL_MAX_CAPACITY", &mConfigVec[3].mMaxNumThres, NULL, 'n'}, + {"V_LEVEL_TIME_DEPTH", &mConfigVec[4].mTimeDepthThres, NULL, 'n'}, + {"V_LEVEL_MAX_CAPACITY", &mConfigVec[4].mMaxNumThres, NULL, 'n'}, + }; + loc_read_conf(LOC_PATH_GPS_CONF_STR, log_buff_config_table, + sizeof(log_buff_config_table)/sizeof(log_buff_config_table[0])); + registerSignalHandler(); +} + +void LogBuffer::append(string& data, int level, uint64_t timestamp) { + lock_guard guard(mLock); + pair item(timestamp, data); + mLogList.append(item, level); + mConfigVec[level].mCurrentSize++; + + while ((timestamp - mLogList.front(level).first) > mConfigVec[level].mTimeDepthThres || + mConfigVec[level].mCurrentSize > mConfigVec[level].mMaxNumThres) { + mLogList.pop(level); + mConfigVec[level].mCurrentSize--; + } +} + +//Dump the log buffer of specific level, level = -1 to dump all the levels in log buffer. +void LogBuffer::dump(std::function log, int level) { + lock_guard guard(mLock); + list, int>> li; + if (-1 == level) { + li = mLogList.dump(); + } else { + li = mLogList.dump(level); + } + ALOGE("Begining of dump, buffer size: %d", (int)li.size()); + stringstream ln; + ln << "dump log buffer, level[" << level << "]" << ", buffer size: " << li.size() << endl; + log(ln); + for_each (li.begin(), li.end(), [&, this](const pair, int> &item){ + stringstream line; + line << "["<dumpToAdbLogcat(); + + //Dump the log buffer to file + time_t now = time(NULL); + struct tm *curr_time = localtime(&now); + char path[50]; + snprintf(path, 50, LOG_BUFFER_FILE_PATH "gpslog_%d%d%d-%d%d%d.log", + (1900 + curr_time->tm_year), ( 1 + curr_time->tm_mon), curr_time->tm_mday, + curr_time->tm_hour, curr_time->tm_min, curr_time->tm_sec); + + mInstance->dumpToLogFile(path); + + //Process won't be terminated if SIGUSR1 is recieved + if (code != SIGUSR1) { + mOriSigAction[code].sa_sigaction(code, si, sc); + } +} + +} diff --git a/gps/utils/LogBuffer.h b/gps/utils/LogBuffer.h new file mode 100644 index 00000000..8d904396 --- /dev/null +++ b/gps/utils/LogBuffer.h @@ -0,0 +1,95 @@ +/* Copyright (c) 2019 The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation, nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef LOG_BUFFER_H +#define LOG_BUFFER_H + +#include "SkipList.h" +#include "log_util.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//default error level time depth threshold, +#define TIME_DEPTH_THRESHOLD_MINIMAL_IN_SEC 60 +//default maximum log buffer size +#define MAXIMUM_NUM_IN_LIST 50 +//file path of dumped log buffer +#define LOG_BUFFER_FILE_PATH "/data/vendor/location/" + +namespace loc_util { + +class ConfigsInLevel{ +public: + uint32_t mTimeDepthThres; + uint32_t mMaxNumThres; + int mCurrentSize; + + ConfigsInLevel(uint32_t time, int num, int size): + mTimeDepthThres(time), mMaxNumThres(num), mCurrentSize(size) {} +}; + +class LogBuffer { +private: + static LogBuffer* mInstance; + static struct sigaction mOriSigAction[NSIG]; + static struct sigaction mNewSigAction; + static mutex sLock; + + SkipList> mLogList; + vector mConfigVec; + mutex mLock; + + const vector mLevelMap {"E", "W", "I", "D", "V"}; + +public: + static LogBuffer* getInstance(); + void append(string& data, int level, uint64_t timestamp); + void dump(std::function log, int level = -1); + void dumpToAdbLogcat(); + void dumpToLogFile(string filePath); + void flush(); +private: + LogBuffer(); + void registerSignalHandler(); + static void signalHandler(const int code, siginfo_t *const si, void *const sc); + +}; + +} + +#endif diff --git a/gps/utils/Makefile.am b/gps/utils/Makefile.am index 9a9c67e9..72c78722 100644 --- a/gps/utils/Makefile.am +++ b/gps/utils/Makefile.am @@ -23,6 +23,7 @@ libgps_utils_la_h_sources = \ LocThread.h \ LocTimer.h \ LocIpc.h \ + SkipList.h\ loc_misc_utils.h \ loc_nmea.h \ gps_extended_c.h \ @@ -42,6 +43,7 @@ libgps_utils_la_c_sources = \ LocTimer.cpp \ LocThread.cpp \ LocIpc.cpp \ + LogBuffer.cpp \ MsgTask.cpp \ loc_misc_utils.cpp \ loc_nmea.cpp diff --git a/gps/utils/SkipList.h b/gps/utils/SkipList.h new file mode 100644 index 00000000..afaa1a62 --- /dev/null +++ b/gps/utils/SkipList.h @@ -0,0 +1,158 @@ +/* Copyright (c) 2019 The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation, nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef LOC_SKIP_LIST_H +#define LOC_SKIP_LIST_H + +#include +#include +#include +#include +#include + +using namespace std; + +namespace loc_util { + +template > class container = list> +class SkipNode { +public: + typedef typename container>::iterator NodeIterator; + + int mLevel; + T mData; + NodeIterator mNextInLevel; + + SkipNode(int level, T& data): mLevel(level), mData(data) {} +}; + +template +class SkipList { + using NodeIterator = typename SkipNode::NodeIterator; +private: + list> mMainList; + vector mHeadVec; + vector mTailVec; +public: + SkipList(int totalLevels); + void append(T& data, int level); + void pop(int level); + void pop(); + T front(int level); + int size(); + void flush(); + list> dump(); + list> dump(int level); +}; + +template +SkipList::SkipList(int totalLevels): mHeadVec(totalLevels, mMainList.end()), + mTailVec(totalLevels, mMainList.end()) {} + +template +void SkipList::append(T& data, int level) { + if ( level < 0 || level >= mHeadVec.size()) { + return; + } + + SkipNode node(level, data); + node.mNextInLevel = mMainList.end(); + mMainList.push_back(node); + auto iter = --mMainList.end(); + if (mHeadVec[level] == mMainList.end()) { + mHeadVec[level] = iter; + } else { + (*mTailVec[level]).mNextInLevel = iter; + } + mTailVec[level] = iter; +} + +template +void SkipList::pop(int level) { + if (mHeadVec[level] == mMainList.end()) { + return; + } + + if ((*mHeadVec[level]).mNextInLevel == mMainList.end()) { + mTailVec[level] = mMainList.end(); + } + + auto tmp_iter = (*mHeadVec[level]).mNextInLevel; + mMainList.erase(mHeadVec[level]); + mHeadVec[level] = tmp_iter; +} + +template +void SkipList::pop() { + pop(mMainList.front().mLevel); +} + +template +T SkipList::front(int level) { + return (*mHeadVec[level]).mData; +} + +template +int SkipList::size() { + return mMainList.size(); +} + +template +void SkipList::flush() { + mMainList.clear(); + for (int i = 0; i < mHeadVec.size(); i++) { + mHeadVec[i] = mMainList.end(); + mTailVec[i] = mMainList.end(); + } +} + +template +list> SkipList::dump() { + list> li; + for_each(mMainList.begin(), mMainList.end(), [&](SkipNode &item) { + li.push_back(make_pair(item.mData, item.mLevel)); + }); + return li; +} + +template +list> SkipList::dump(int level) { + list> li; + auto head = mHeadVec[level]; + while (head != mMainList.end()) { + li.push_back(make_pair((*head).mData, (*head).mLevel)); + head = (*head).mNextInLevel; + } + return li; +} + +} + +#endif diff --git a/gps/utils/gps_extended_c.h b/gps/utils/gps_extended_c.h index f4ad5241..6acb8c8b 100644 --- a/gps/utils/gps_extended_c.h +++ b/gps/utils/gps_extended_c.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2020 The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -390,7 +390,20 @@ typedef uint64_t GpsLocationExtendedFlags; #define GPS_LOCATION_EXTENDED_HAS_OUTPUT_ENG_TYPE 0x2000000000 /** GpsLocationExtended has the engine mask that indicates the * set of engines contribute to the fix. */ -#define GPS_LOCATION_EXTENDED_HAS_OUTPUT_ENG_MASK 0x4000000000 +#define GPS_LOCATION_EXTENDED_HAS_OUTPUT_ENG_MASK 0x4000000000 +/** GpsLocationExtended has dgnss correction source */ +#define GPS_LOCATION_EXTENDED_HAS_DGNSS_CORRECTION_SOURCE_TYPE 0x8000000000 +/** GpsLocationExtended has dgnss correction source ID */ +#define GPS_LOCATION_EXTENDED_HAS_DGNSS_CORRECTION_SOURCE_ID 0x10000000000 +/** GpsLocationExtended has dgnss constellation usage */ +#define GPS_LOCATION_EXTENDED_HAS_DGNSS_CONSTELLATION_USAGE 0x20000000000 +/** GpsLocationExtended has dgnss ref station Id */ +#define GPS_LOCATION_EXTENDED_HAS_DGNSS_REF_STATION_ID 0x40000000000 +/** GpsLocationExtended has dgnss data age */ +#define GPS_LOCATION_EXTENDED_HAS_DGNSS_DATA_AGE 0x80000000000 + /** GpsLocationExtended has the conformityIndex computed from + * robust location feature. */ +#define GPS_LOCATION_EXTENDED_HAS_CONFORMITY_INDEX 0x100000000000 typedef uint32_t LocNavSolutionMask; /* Bitmask to specify whether SBAS ionospheric correction is used */ @@ -442,10 +455,10 @@ typedef uint32_t GnssAdditionalSystemInfoMask; /** GPS PRN Range */ #define GPS_SV_PRN_MIN 1 #define GPS_SV_PRN_MAX 32 -#define SBAS_SV_PRN_MIN 33 -#define SBAS_SV_PRN_MAX 64 #define GLO_SV_PRN_MIN 65 #define GLO_SV_PRN_MAX 96 +#define SBAS_SV_PRN_MIN 120 +#define SBAS_SV_PRN_MAX 191 #define QZSS_SV_PRN_MIN 193 #define QZSS_SV_PRN_MAX 197 #define BDS_SV_PRN_MIN 201 @@ -573,6 +586,13 @@ typedef uint8_t CarrierPhaseAmbiguityType; #define CARRIER_PHASE_AMBIGUITY_RESOLUTION_FLOAT ((CarrierPhaseAmbiguityType)1) #define CARRIER_PHASE_AMBIGUITY_RESOLUTION_FIXED ((CarrierPhaseAmbiguityType)2) + +typedef enum { + LOC_DGNSS_CORR_SOURCE_TYPE_INVALID = 0, /**< Invalid DGNSS correction source type \n */ + LOC_DGNSS_CORR_SOURCE_TYPE_RTCM = 1, /**< DGNSS correction source type RTCM \n */ + LOC_DGNSS_CORR_SOURCE_TYPE_3GPP = 2, /**< DGNSS correction source type 3GPP \n */ +}LocDgnssCorrectionSourceType; + typedef uint16_t GnssMeasUsageStatusBitMask; /** Used in fix */ #define GNSS_MEAS_USED_IN_PVT ((GnssMeasUsageStatusBitMask)0x00000001ul) @@ -602,17 +622,6 @@ typedef uint16_t GnssMeasUsageInfoValidityMask; #define GNSS_CARRIER_PHASE_RESIDUAL_VALID ((GnssMeasUsageInfoValidityMask)0x00000004ul) #define GNSS_CARRIER_PHASE_AMBIGUITY_TYPE_VALID ((GnssMeasUsageInfoValidityMask)0x00000008ul) -typedef uint16_t GnssSvPolyStatusMask; -#define GNSS_SV_POLY_SRC_ALM_CORR_V02 ((GnssSvPolyStatusMask)0x01) -#define GNSS_SV_POLY_GLO_STR4_V02 ((GnssSvPolyStatusMask)0x02) -#define GNSS_SV_POLY_DELETE_V02 ((GnssSvPolyStatusMask)0x04) -#define GNSS_SV_POLY_SRC_GAL_FNAV_OR_INAV_V02 ((GnssSvPolyStatusMask)0x08) -typedef uint16_t GnssSvPolyStatusMaskValidity; -#define GNSS_SV_POLY_SRC_ALM_CORR_VALID_V02 ((GnssSvPolyStatusMaskValidity)0x01) -#define GNSS_SV_POLY_GLO_STR4_VALID_V02 ((GnssSvPolyStatusMaskValidity)0x02) -#define GNSS_SV_POLY_DELETE_VALID_V02 ((GnssSvPolyStatusMaskValidity)0x04) -#define GNSS_SV_POLY_SRC_GAL_FNAV_OR_INAV_VALID_V02 ((GnssSvPolyStatusMaskValidity)0x08) - typedef struct { /** Specifies GNSS signal type @@ -621,13 +630,15 @@ typedef struct { /** Specifies GNSS Constellation Type Mandatory Field*/ Gnss_LocSvSystemEnumType gnssConstellation; - /** GNSS SV ID. - For GPS: 1 to 32 - For GLONASS: 65 to 96. When slot-number to SV ID mapping is unknown, set as 255. - For SBAS: 120 to 151 - For QZSS-L1CA:193 to 197 - For BDS: 201 to 237 - For GAL: 301 to 336 */ + /** Unique SV Identifier. + * SV Range for supported constellation is specified as below: + * - For GPS: 1 to 32 + * - For GLONASS: 65 to 96 + * - For SBAS: 120 to 158 and 183 to 191 + * - For QZSS: 193 to 197 + * - For BDS: 201 to 237 + * - For GAL: 301 to 336 + * - For NAVIC: 401 to 414 */ uint16_t gnssSvId; /** GLONASS frequency number + 7. Valid only for a GLONASS system and @@ -761,15 +772,40 @@ typedef struct { /** Sensor calibration confidence percent. Range: 0 - 100 */ uint8_t calibrationConfidence; DrCalibrationStatusMask calibrationStatus; - /* location engine type. When the fix. when the type is set to + /** location engine type. When the fix. when the type is set to LOC_ENGINE_SRC_FUSED, the fix is the propagated/aggregated reports from all engines running on the system (e.g.: DR/SPE/PPE). To check which location engine contributes to the fused output, check for locOutputEngMask. */ LocOutputEngineType locOutputEngType; - /* when loc output eng type is set to fused, this field + /** when loc output eng type is set to fused, this field indicates the set of engines contribute to the fix. */ PositioningEngineMask locOutputEngMask; + + /** DGNSS Correction Source for position report: RTCM, 3GPP + * etc. */ + LocDgnssCorrectionSourceType dgnssCorrectionSourceType; + + /** If DGNSS is used, the SourceID is a 32bit number identifying + * the DGNSS source ID */ + uint32_t dgnssCorrectionSourceID; + + /** If DGNSS is used, which constellation was DGNSS used for to + * produce the pos report. */ + GnssConstellationTypeMask dgnssConstellationUsage; + + /** If DGNSS is used, DGNSS Reference station ID used for + * position report */ + uint16_t dgnssRefStationId; + + /** If DGNSS is used, DGNSS data age in milli-seconds */ + uint32_t dgnssDataAgeMsec; + + /* When robust location is enabled, this field + * will how well the various input data considered for + * navigation solution conform to expectations. + * Range: 0 (least conforming) to 1 (most conforming) */ + float conformityIndex; } GpsLocationExtended; enum loc_sess_status { @@ -978,14 +1014,9 @@ typedef uint32_t LOC_GPS_LOCK_MASK; #define isGpsLockAll(lock) (((lock) & ((LOC_GPS_LOCK_MASK)3)) == 3) /*++ *********************************************** -** Satellite Measurement and Satellite Polynomial -** Structure definitions +** Satellite Measurement Structure definitions ** *********************************************** --*/ -#define GNSS_SV_POLY_VELOCITY_COEF_MAX_SIZE 12 -#define GNSS_SV_POLY_XYZ_0_TH_ORDER_COEFF_MAX_SIZE 3 -#define GNSS_SV_POLY_XYZ_N_TH_ORDER_COEFF_MAX_SIZE 9 -#define GNSS_SV_POLY_SV_CLKBIAS_COEFF_MAX_SIZE 4 /** Max number of GNSS SV measurement */ #define GNSS_LOC_SV_MEAS_LIST_MAX_SIZE 128 @@ -1173,20 +1204,26 @@ typedef enum /**< Satellite Doppler measured */ GNSS_LOC_MEAS_STATUS_VELOCITY_FINE = 0x00000020, /**< TRUE: Fine Doppler measured, FALSE: Coarse Doppler measured */ + GNSS_LOC_MEAS_STATUS_LP_VALID = 0x00000040, + /**< TRUE/FALSE -- Lock Point is valid/invalid */ + GNSS_LOC_MEAS_STATUS_LP_POS_VALID = 0x00000080, + /**< TRUE/FALSE -- Lock Point is positive/negative */ GNSS_LOC_MEAS_STATUS_FROM_RNG_DIFF = 0x00000200, /**< Range update from Satellite differences */ GNSS_LOC_MEAS_STATUS_FROM_VE_DIFF = 0x00000400, /**< Doppler update from Satellite differences */ GNSS_LOC_MEAS_STATUS_DONT_USE_X = 0x00000800, /**< Don't use measurement if bit is set */ - GNSS_LOC_MEAS_STATUS_DONT_USE_M = 0x000001000, + GNSS_LOC_MEAS_STATUS_DONT_USE_M = 0x00001000, /**< Don't use measurement if bit is set */ - GNSS_LOC_MEAS_STATUS_DONT_USE_D = 0x000002000, + GNSS_LOC_MEAS_STATUS_DONT_USE_D = 0x00002000, /**< Don't use measurement if bit is set */ - GNSS_LOC_MEAS_STATUS_DONT_USE_S = 0x000004000, + GNSS_LOC_MEAS_STATUS_DONT_USE_S = 0x00004000, /**< Don't use measurement if bit is set */ - GNSS_LOC_MEAS_STATUS_DONT_USE_P = 0x000008000 + GNSS_LOC_MEAS_STATUS_DONT_USE_P = 0x00008000, /**< Don't use measurement if bit is set */ + GNSS_LOC_MEAS_STATUS_GNSS_FRESH_MEAS = 0x08000000 + /**< TRUE -- Fresh GNSS measurement observed in last second */ }Gnss_LocSvMeasStatusMaskType; typedef struct @@ -1249,6 +1286,25 @@ typedef enum /**< SV is being tracked */ }Gnss_LocSvSearchStatusEnumT; +typedef uint32_t LocSvDgnssMeasStatusMask; +#define LOC_MASK_DGNSS_EPOCH_TIME_VALID 0x1 /**< DGNSS Epoch time is valid */ +#define LOC_MASK_DGNSS_MEAS_STATUS_PR_VALID 0x2 /**< Pseudo Range correction is valid */ +#define LOC_MASK_DGNSS_MEAS_STATUS_PRR_VALID 0x4 /**< Pseudo Range rate correction is valid */ + +typedef struct { + LocSvDgnssMeasStatusMask dgnssMeasStatus; + /**< Bitmask indicating the DGNSS SV measurement status. */ + + uint32_t diffDataEpochTimeMsec; + /**< Age of differential data in Milli Seconds with respect to the Measurement time. */ + + float prCorrMeters; + /**< Pseudo Range correction in meters. */ + + float prrCorrMetersPerSec; + /**< Pseudo Range rate correction in meters per second. */ +} Gnss_LocDgnssSVMeasurement; + typedef struct { uint32_t size; @@ -1256,15 +1312,9 @@ typedef struct // 0 signal type mask indicates invalid value GnssSignalTypeMask gnssSignalTypeMask; uint16_t gnssSvId; - /**< GNSS SV ID. - \begin{itemize1} - \item Range: \begin{itemize1} - \item For GPS: 1 to 32 - \item For GLONASS: 1 to 32 - \item For SBAS: 120 to 151 - \item For BDS: 201 to 237 - \end{itemize1} \end{itemize1} - The GPS and GLONASS SVs can be disambiguated using the system field. + /** Unique SV Identifier. + * For SV Range of supported constellation, please refer to the + * comment section of gnssSvId in GpsMeasUsageInfo. */ uint8_t gloFrequency; /**< GLONASS frequency number + 7 \n @@ -1388,7 +1438,8 @@ typedef struct float carrierPhaseUnc; - + /** < DGNSS Measurements Report for SVs */ + Gnss_LocDgnssSVMeasurement dgnssSvMeas; } Gnss_SVMeasurementStructType; @@ -1420,6 +1471,10 @@ typedef uint64_t GpsSvMeasHeaderFlags; #define GNSS_SV_MEAS_HEADER_HAS_BDS_NAVIC_INTER_SYSTEM_BIAS 0x01000000 #define GNSS_SV_MEAS_HEADER_HAS_NAVIC_SYSTEM_TIME 0x02000000 #define GNSS_SV_MEAS_HEADER_HAS_NAVIC_SYSTEM_TIME_EXT 0x04000000 +#define GNSS_SV_MEAS_HEADER_HAS_DGNSS_CORRECTION_SOURCE_TYPE 0x08000000 +#define GNSS_SV_MEAS_HEADER_HAS_DGNSS_CORRECTION_SOURCE_ID 0x010000000 +#define GNSS_SV_MEAS_HEADER_HAS_DGNSS_REF_STATION_ID 0x020000000 +#define GNSS_SV_MEAS_HEADER_HAS_REF_COUNT_TICKS 0x040000000 typedef struct { @@ -1465,6 +1520,21 @@ typedef struct Gnss_LocGnssTimeExtStructType gloSystemTimeExt; /** NAVIC system RTC time information. */ Gnss_LocGnssTimeExtStructType navicSystemTimeExt; + + /** Receiver tick at frame count */ + uint64_t refCountTicks; + + /** DGNSS corrections source type RTCM, 3GPP etc, if DGNSS was + * used for these measurements. */ + LocDgnssCorrectionSourceType dgnssCorrectionSourceType; + + /** DGNSS SourceID: 32bit number identifying the DGNSS source + * ID, if DGNSS was used for these measurements. */ + uint32_t dgnssCorrectionSourceID; + + /** DGNSS Ref station ID: 32bit number identifying the DGNSS + * ref station ID, if DGNSS was used for these measurements. */ + uint16_t dgnssRefStationId; } GnssSvMeasurementHeader; typedef struct { @@ -1505,66 +1575,6 @@ typedef enum /**< GLONASS String 4 has been received */ }Gnss_SvPolyStatusMaskType; - -typedef struct -{ - uint32_t size; - uint16_t gnssSvId; - /* GPS: 1-32, GLO: 65-96, 0: Invalid, - SBAS: 120-151, BDS:201-237,GAL:301 to 336 - All others are reserved - */ - int8_t freqNum; - /* Freq index, only valid if u_SysInd is GLO */ - - GnssSvPolyStatusMaskValidity svPolyStatusMaskValidity; - GnssSvPolyStatusMask svPolyStatusMask; - - uint32_t is_valid; - - uint16_t iode; - /* Ephemeris reference time - GPS:Issue of Data Ephemeris used [unitless]. - GLO: Tb 7-bit, refer to ICD02 - */ - double T0; - /* Reference time for polynominal calculations - GPS: Secs in week. - GLO: Full secs since Jan/01/96 - */ - double polyCoeffXYZ0[GNSS_SV_POLY_XYZ_0_TH_ORDER_COEFF_MAX_SIZE]; - /* C0X, C0Y, C0Z */ - double polyCoefXYZN[GNSS_SV_POLY_XYZ_N_TH_ORDER_COEFF_MAX_SIZE]; - /* C1X, C2X ... C2Z, C3Z */ - float polyCoefOther[GNSS_SV_POLY_SV_CLKBIAS_COEFF_MAX_SIZE]; - /* C0T, C1T, C2T, C3T */ - float svPosUnc; /* SV position uncertainty [m]. */ - float ionoDelay; /* Ionospheric delay at d_T0 [m]. */ - float ionoDot; /* Iono delay rate [m/s]. */ - float sbasIonoDelay;/* SBAS Ionospheric delay at d_T0 [m]. */ - float sbasIonoDot; /* SBAS Iono delay rate [m/s]. */ - float tropoDelay; /* Tropospheric delay [m]. */ - float elevation; /* Elevation [rad] at d_T0 */ - float elevationDot; /* Elevation rate [rad/s] */ - float elevationUnc; /* SV elevation [rad] uncertainty */ - double velCoef[GNSS_SV_POLY_VELOCITY_COEF_MAX_SIZE]; - /* Coefficients of velocity poly */ - uint32_t enhancedIOD; /* Enhanced Reference Time */ - float gpsIscL1ca; - float gpsIscL2c; - float gpsIscL5I5; - float gpsIscL5Q5; - float gpsTgd; - float gloTgdG1G2; - float bdsTgdB1; - float bdsTgdB2; - float bdsTgdB2a; - float bdsIscB2a; - float galBgdE1E5a; - float galBgdE1E5b; - float navicTgdL5; -} GnssSvPolynomial; - typedef enum { GNSS_EPH_ACTION_UPDATE_SRC_UNKNOWN_V02 = 0, /** #include +#include #include #include "log_util.h" #include "loc_log.h" #include "msg_q.h" #include +#include "LogBuffer.h" #define BUFFER_SIZE 120 @@ -179,35 +181,6 @@ char *loc_get_time(char *time_string, size_t buf_size) return time_string; } - -/*=========================================================================== -FUNCTION loc_logger_init - -DESCRIPTION - Initializes the state of DEBUG_LEVEL and TIMESTAMP - -DEPENDENCIES - N/A - -RETURN VALUE - None - -SIDE EFFECTS - N/A -===========================================================================*/ -void loc_logger_init(unsigned long debug, unsigned long timestamp) -{ - loc_logger.DEBUG_LEVEL = debug; -#ifdef TARGET_BUILD_VARIANT_USER - // force user builds to 2 or less - if (loc_logger.DEBUG_LEVEL > 2) { - loc_logger.DEBUG_LEVEL = 2; - } -#endif - loc_logger.TIMESTAMP = timestamp; -} - - /*=========================================================================== FUNCTION get_timestamp @@ -236,3 +209,22 @@ char * get_timestamp(char *str, unsigned long buf_size) return str; } +/*=========================================================================== + +FUNCTION log_buffer_insert + +DESCRIPTION + Insert a log sentence with specific level to the log buffer. + +RETURN VALUE + N/A + +===========================================================================*/ +void log_buffer_insert(char *str, unsigned long buf_size, int level) +{ + timespec tv; + clock_gettime(CLOCK_BOOTTIME, &tv); + uint64_t elapsedTime = (uint64_t)tv.tv_sec + (uint64_t)tv.tv_nsec/1000000000; + string ss = str; + loc_util::LogBuffer::getInstance()->append(ss, level, elapsedTime); +} diff --git a/gps/utils/loc_misc_utils.cpp b/gps/utils/loc_misc_utils.cpp index 70fdbc3a..d674ec51 100644 --- a/gps/utils/loc_misc_utils.cpp +++ b/gps/utils/loc_misc_utils.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014, 2020 The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -143,3 +143,15 @@ void* dlGetSymFromLib(void*& libHandle, const char* libName, const char* symName return sym; } + +uint64_t getQTimerTickCount() +{ + uint64_t qTimerCount = 0; +#if __aarch64__ + asm volatile("mrs %0, cntvct_el0" : "=r" (qTimerCount)); +#else + asm volatile("mrrc p15, 1, %Q0, %R0, c14" : "=r" (qTimerCount)); +#endif + + return qTimerCount; +} diff --git a/gps/utils/loc_misc_utils.h b/gps/utils/loc_misc_utils.h index fad1b6db..046cb7cd 100644 --- a/gps/utils/loc_misc_utils.h +++ b/gps/utils/loc_misc_utils.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014, 2020 The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -32,7 +32,8 @@ #ifdef __cplusplus extern "C" { #endif - +#include +#include /*=========================================================================== FUNCTION loc_split_string @@ -120,6 +121,27 @@ SIDE EFFECTS ===========================================================================*/ void* dlGetSymFromLib(void*& libHandle, const char* libName, const char* symName); +/*=========================================================================== +FUNCTION getQTimerTickCount + +DESCRIPTION + This function is used to read the QTimer ticks count. This value is globally maintained and + must be the same across all processors on a target. + +DEPENDENCIES + N/A + +RETURN VALUE + uint64_t QTimer tick count + +SIDE EFFECTS + N/A +===========================================================================*/ + + +uint64_t getQTimerTickCount(); + + #ifdef __cplusplus } #endif diff --git a/gps/utils/loc_nmea.cpp b/gps/utils/loc_nmea.cpp index 9ee27164..cc850a87 100644 --- a/gps/utils/loc_nmea.cpp +++ b/gps/utils/loc_nmea.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -36,7 +36,9 @@ #include #define GLONASS_SV_ID_OFFSET 64 -#define QZSS_SV_ID_OFFSET (-192) +#define QZSS_SV_ID_OFFSET (192) +#define BDS_SV_ID_OFFSET (200) +#define GALILEO_SV_ID_OFFSET (300) #define MAX_SV_COUNT_SUPPORTED_IN_ONE_CONSTELLATION 64 #define MAX_SATELLITES_IN_USE 12 #define MSEC_IN_ONE_WEEK 604800000ULL @@ -429,6 +431,8 @@ static loc_nmea_sv_meta* loc_nmea_sv_meta_init(loc_nmea_sv_meta& sv_meta, sv_meta.talker[0] = 'G'; sv_meta.talker[1] = 'A'; sv_meta.mask = sv_cache_info.gal_used_mask; + // GALILEO SV ids are from 301-336, So keep svIdOffset 300 + sv_meta.svIdOffset = GALILEO_SV_ID_OFFSET; sv_meta.systemId = SYSTEM_ID_GALILEO; if (GNSS_SIGNAL_GALILEO_E1 == signalType) { sv_meta.svCount = sv_cache_info.gal_e1_count; @@ -440,7 +444,7 @@ static loc_nmea_sv_meta* loc_nmea_sv_meta_init(loc_nmea_sv_meta& sv_meta, sv_meta.talker[0] = 'G'; sv_meta.talker[1] = 'Q'; sv_meta.mask = sv_cache_info.qzss_used_mask; - // QZSS SV ids are from 193-199. So keep svIdOffset -192 + // QZSS SV ids are from 193-197. So keep svIdOffset 192 sv_meta.svIdOffset = QZSS_SV_ID_OFFSET; sv_meta.systemId = SYSTEM_ID_QZSS; if (GNSS_SIGNAL_QZSS_L1CA == signalType) { @@ -453,7 +457,8 @@ static loc_nmea_sv_meta* loc_nmea_sv_meta_init(loc_nmea_sv_meta& sv_meta, sv_meta.talker[0] = 'G'; sv_meta.talker[1] = 'B'; sv_meta.mask = sv_cache_info.bds_used_mask; - // BDS SV ids are from 201-235. So keep svIdOffset 0 + // BDS SV ids are from 201-237. So keep svIdOffset 200 + sv_meta.svIdOffset = BDS_SV_ID_OFFSET; sv_meta.systemId = SYSTEM_ID_BDS; if (GNSS_SIGNAL_BEIDOU_B1I == signalType) { sv_meta.svCount = sv_cache_info.bds_b1_count; @@ -724,6 +729,9 @@ static void loc_nmea_generate_GSV(const GnssSvNotification &svNotify, return; } + if (GNSS_SV_TYPE_GLONASS == sv_meta_p->svType) { + svIdOffset = 0; + } svNumber = 1; sentenceNumber = 1; sentenceCount = svCount / 4 + (svCount % 4 != 0); @@ -782,13 +790,8 @@ static void loc_nmea_generate_GSV(const GnssSvNotification &svNotify, if (sv_meta_p->svType == svNotify.gnssSvs[svNumber - 1].type && sv_meta_p->signalId == convert_signalType_to_signalId(signalType)) { - uint16_t svId = svNotify.gnssSvs[svNumber - 1].svId; - // For QZSS we adjusted SV id's in GnssAdapter, we need to re-adjust here - if (GNSS_SV_TYPE_QZSS == svNotify.gnssSvs[svNumber - 1].type) { - svId = svId - (QZSS_SV_PRN_MIN - 1); - } - length = snprintf(pMarker, lengthRemaining,",%02d,%02d,%03d,", - svId + svIdOffset, + 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 @@ -1036,12 +1039,14 @@ static void loc_nmea_get_fix_quality(const UlpLocation & location, bool custom_gga_fix_quality, char ggaGpsQuality[3], char & rmcModeIndicator, - char & vtgModeIndicator) { + char & vtgModeIndicator, + char gnsModeIndicator[7]) { ggaGpsQuality[0] = '0'; // 0 means no fix rmcModeIndicator = 'N'; // N means no fix vtgModeIndicator = 'N'; // N means no fix - + memset(gnsModeIndicator, 'N', 6); // N means no fix + gnsModeIndicator[6] = '\0'; do { // GGA fix quality is defined in NMEA spec as below: // https://www.trimble.com/OEM_ReceiverHelp/V4.44/en/NMEA-0183messages_GGA.html @@ -1063,28 +1068,88 @@ static void loc_nmea_get_fix_quality(const UlpLocation & location, ggaGpsQuality[0] = '2'; // 2 means DGPS fix rmcModeIndicator = 'P'; // P means precise vtgModeIndicator = 'P'; // P means precise + if (locationExtended.gnss_sv_used_ids.gps_sv_used_ids_mask ? 1 : 0) + gnsModeIndicator[0] = 'P'; // P means precise + if (locationExtended.gnss_sv_used_ids.glo_sv_used_ids_mask ? 1 : 0) + gnsModeIndicator[1] = 'P'; // P means precise + if (locationExtended.gnss_sv_used_ids.gal_sv_used_ids_mask ? 1 : 0) + gnsModeIndicator[2] = 'P'; // P means precise + if (locationExtended.gnss_sv_used_ids.bds_sv_used_ids_mask ? 1 : 0) + gnsModeIndicator[3] = 'P'; // P means precise + if (locationExtended.gnss_sv_used_ids.qzss_sv_used_ids_mask ? 1 : 0) + gnsModeIndicator[4] = 'P'; // P means precise + if (locationExtended.gnss_sv_used_ids.navic_sv_used_ids_mask ? 1 : 0) + gnsModeIndicator[5] = 'P'; // P means precise break; } else if (LOC_NAV_MASK_RTK_FIXED_CORRECTION & locationExtended.navSolutionMask){ ggaGpsQuality[0] = '4'; // 4 means RTK Fixed fix rmcModeIndicator = 'R'; // use R (RTK fixed) vtgModeIndicator = 'D'; // use D (differential) as // no RTK fixed defined for VTG in NMEA 183 spec + if (locationExtended.gnss_sv_used_ids.gps_sv_used_ids_mask ? 1 : 0) + gnsModeIndicator[0] = 'R'; // R means RTK fixed + if (locationExtended.gnss_sv_used_ids.glo_sv_used_ids_mask ? 1 : 0) + gnsModeIndicator[1] = 'R'; // R means RTK fixed + if (locationExtended.gnss_sv_used_ids.gal_sv_used_ids_mask ? 1 : 0) + gnsModeIndicator[2] = 'R'; // R means RTK fixed + if (locationExtended.gnss_sv_used_ids.bds_sv_used_ids_mask ? 1 : 0) + gnsModeIndicator[3] = 'R'; // R means RTK fixed + if (locationExtended.gnss_sv_used_ids.qzss_sv_used_ids_mask ? 1 : 0) + gnsModeIndicator[4] = 'R'; // R means RTK fixed + if (locationExtended.gnss_sv_used_ids.navic_sv_used_ids_mask ? 1 : 0) + gnsModeIndicator[5] = 'R'; // R means RTK fixed break; } else if (LOC_NAV_MASK_RTK_CORRECTION & locationExtended.navSolutionMask){ ggaGpsQuality[0] = '5'; // 5 means RTK float fix rmcModeIndicator = 'F'; // F means RTK float fix vtgModeIndicator = 'D'; // use D (differential) as // no RTK float defined for VTG in NMEA 183 spec + if (locationExtended.gnss_sv_used_ids.gps_sv_used_ids_mask ? 1 : 0) + gnsModeIndicator[0] = 'F'; // F means RTK float fix + if (locationExtended.gnss_sv_used_ids.glo_sv_used_ids_mask ? 1 : 0) + gnsModeIndicator[1] = 'F'; // F means RTK float fix + if (locationExtended.gnss_sv_used_ids.gal_sv_used_ids_mask ? 1 : 0) + gnsModeIndicator[2] = 'F'; // F means RTK float fix + if (locationExtended.gnss_sv_used_ids.bds_sv_used_ids_mask ? 1 : 0) + gnsModeIndicator[3] = 'F'; // F means RTK float fix + if (locationExtended.gnss_sv_used_ids.qzss_sv_used_ids_mask ? 1 : 0) + gnsModeIndicator[4] = 'F'; // F means RTK float fix + if (locationExtended.gnss_sv_used_ids.navic_sv_used_ids_mask ? 1 : 0) + gnsModeIndicator[5] = 'F'; // F means RTK float fix break; } else if (LOC_NAV_MASK_DGNSS_CORRECTION & locationExtended.navSolutionMask){ ggaGpsQuality[0] = '2'; // 2 means DGPS fix rmcModeIndicator = 'D'; // D means differential vtgModeIndicator = 'D'; // D means differential + if (locationExtended.gnss_sv_used_ids.gps_sv_used_ids_mask ? 1 : 0) + gnsModeIndicator[0] = 'D'; // D means differential + if (locationExtended.gnss_sv_used_ids.glo_sv_used_ids_mask ? 1 : 0) + gnsModeIndicator[1] = 'D'; // D means differential + if (locationExtended.gnss_sv_used_ids.gal_sv_used_ids_mask ? 1 : 0) + gnsModeIndicator[2] = 'D'; // D means differential + if (locationExtended.gnss_sv_used_ids.bds_sv_used_ids_mask ? 1 : 0) + gnsModeIndicator[3] = 'D'; // D means differential + if (locationExtended.gnss_sv_used_ids.qzss_sv_used_ids_mask ? 1 : 0) + gnsModeIndicator[4] = 'D'; // D means differential + if (locationExtended.gnss_sv_used_ids.navic_sv_used_ids_mask ? 1 : 0) + gnsModeIndicator[5] = 'D'; // D means differential break; } else if (LOC_NAV_MASK_SBAS_CORRECTION_IONO & locationExtended.navSolutionMask){ ggaGpsQuality[0] = '2'; // 2 means DGPS fix rmcModeIndicator = 'D'; // D means differential vtgModeIndicator = 'D'; // D means differential + if (locationExtended.gnss_sv_used_ids.gps_sv_used_ids_mask ? 1 : 0) + gnsModeIndicator[0] = 'D'; // D means differential + if (locationExtended.gnss_sv_used_ids.glo_sv_used_ids_mask ? 1 : 0) + gnsModeIndicator[1] = 'D'; // D means differential + if (locationExtended.gnss_sv_used_ids.gal_sv_used_ids_mask ? 1 : 0) + gnsModeIndicator[2] = 'D'; // D means differential + if (locationExtended.gnss_sv_used_ids.bds_sv_used_ids_mask ? 1 : 0) + gnsModeIndicator[3] = 'D'; // D means differential + if (locationExtended.gnss_sv_used_ids.qzss_sv_used_ids_mask ? 1 : 0) + gnsModeIndicator[4] = 'D'; // D means differential + if (locationExtended.gnss_sv_used_ids.navic_sv_used_ids_mask ? 1 : 0) + gnsModeIndicator[5] = 'D'; // D means differential break; } } @@ -1094,11 +1159,24 @@ static void loc_nmea_get_fix_quality(const UlpLocation & location, ggaGpsQuality[0] = '1'; // 1 means GPS rmcModeIndicator = 'A'; // A means autonomous vtgModeIndicator = 'A'; // A means autonomous + if (locationExtended.gnss_sv_used_ids.gps_sv_used_ids_mask ? 1 : 0) + gnsModeIndicator[0] = 'A'; // A means autonomous + if (locationExtended.gnss_sv_used_ids.glo_sv_used_ids_mask ? 1 : 0) + gnsModeIndicator[1] = 'A'; // A means autonomous + if (locationExtended.gnss_sv_used_ids.gal_sv_used_ids_mask ? 1 : 0) + gnsModeIndicator[2] = 'A'; // A means autonomous + if (locationExtended.gnss_sv_used_ids.bds_sv_used_ids_mask ? 1 : 0) + gnsModeIndicator[3] = 'A'; // A means autonomous + if (locationExtended.gnss_sv_used_ids.qzss_sv_used_ids_mask ? 1 : 0) + gnsModeIndicator[4] = 'A'; // A means autonomous + if (locationExtended.gnss_sv_used_ids.navic_sv_used_ids_mask ? 1 : 0) + gnsModeIndicator[5] = 'A'; // A means autonomous break; } else if (LOC_POS_TECH_MASK_SENSORS & locationExtended.tech_mask){ ggaGpsQuality[0] = '6'; // 6 means estimated (dead reckoning) rmcModeIndicator = 'E'; // E means estimated (dead reckoning) vtgModeIndicator = 'E'; // E means estimated (dead reckoning) + memset(gnsModeIndicator, 'E', 6); // E means estimated (dead reckoning) break; } } @@ -1255,7 +1333,6 @@ void loc_nmea_generate_pos(const UlpLocation &location, if (generate_nmea) { char talker[3] = {'G', 'P', '\0'}; - char modeIndicator[7] = {0}; uint32_t svUsedCount = 0; uint32_t count = 0; loc_nmea_sv_meta sv_meta; @@ -1339,8 +1416,9 @@ void loc_nmea_generate_pos(const UlpLocation &location, char ggaGpsQuality[3] = {'0', '\0', '\0'}; char rmcModeIndicator = 'N'; char vtgModeIndicator = 'N'; + char gnsModeIndicator[7] = {'N', 'N', 'N', 'N', 'N', 'N', '\0'}; loc_nmea_get_fix_quality(location, locationExtended, custom_gga_fix_quality, - ggaGpsQuality, rmcModeIndicator, vtgModeIndicator); + ggaGpsQuality, rmcModeIndicator, vtgModeIndicator, gnsModeIndicator); // ------------------- // ------$--VTG------- @@ -1671,49 +1749,7 @@ void loc_nmea_generate_pos(const UlpLocation &location, pMarker += length; lengthRemaining -= length; - if(!(sv_cache_info.gps_used_mask ? 1 : 0)) - modeIndicator[0] = 'N'; - else if (LOC_NAV_MASK_SBAS_CORRECTION_IONO & locationExtended.navSolutionMask) - modeIndicator[0] = 'D'; - else if (LOC_POS_TECH_MASK_SENSORS == locationExtended.tech_mask) - modeIndicator[0] = 'E'; - else - modeIndicator[0] = 'A'; - if(!(sv_cache_info.glo_used_mask ? 1 : 0)) - modeIndicator[1] = 'N'; - else if (LOC_POS_TECH_MASK_SENSORS == locationExtended.tech_mask) - modeIndicator[1] = 'E'; - else - modeIndicator[1] = 'A'; - if(!(sv_cache_info.gal_used_mask ? 1 : 0)) - modeIndicator[2] = 'N'; - else if (LOC_POS_TECH_MASK_SENSORS == locationExtended.tech_mask) - modeIndicator[2] = 'E'; - else - modeIndicator[2] = 'A'; - if(!(sv_cache_info.bds_used_mask ? 1 : 0)) - modeIndicator[3] = 'N'; - else if (LOC_POS_TECH_MASK_SENSORS == locationExtended.tech_mask) - modeIndicator[3] = 'E'; - else - modeIndicator[3] = 'A'; - if(!(sv_cache_info.qzss_used_mask ? 1 : 0)) - modeIndicator[4] = 'N'; - else if (LOC_POS_TECH_MASK_SENSORS == locationExtended.tech_mask) - modeIndicator[4] = 'E'; - else - modeIndicator[4] = 'A'; - if(!(sv_cache_info.navic_used_mask ? 1 : 0)) - modeIndicator[5] = 'N'; - else if (LOC_POS_TECH_MASK_SENSORS == locationExtended.tech_mask) - modeIndicator[5] = 'E'; - else - modeIndicator[5] = 'A'; - modeIndicator[6] = '\0'; - for(int index = 5; index > 0 && 'N' == modeIndicator[index]; index--) { - modeIndicator[index] = '\0'; - } - length = snprintf(pMarker, lengthRemaining,"%s,", modeIndicator); + length = snprintf(pMarker, lengthRemaining, "%s,", gnsModeIndicator); pMarker += length; lengthRemaining -= length; @@ -1756,17 +1792,51 @@ void loc_nmea_generate_pos(const UlpLocation &location, if ((location.gpsLocation.flags & LOC_GPS_LOCATION_HAS_ALTITUDE) && (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_ALTITUDE_MEAN_SEA_LEVEL)) { - length = snprintf(pMarker, lengthRemaining, "%.1lf,,", + length = snprintf(pMarker, lengthRemaining, "%.1lf,", ref_lla.alt - locationExtended.altitudeMeanSeaLevel); } else { - length = snprintf(pMarker, lengthRemaining,",,"); + length = snprintf(pMarker, lengthRemaining, ","); + } + if (length < 0 || length >= lengthRemaining) + { + LOC_LOGE("NMEA Error in string formatting"); + return; } - pMarker += length; lengthRemaining -= length; + if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_DGNSS_DATA_AGE) + { + length = snprintf(pMarker, lengthRemaining, "%.1f,", + (float)locationExtended.dgnssDataAgeMsec / 1000); + } + else + { + length = snprintf(pMarker, lengthRemaining, ","); + } + if (length < 0 || length >= lengthRemaining) + { + LOC_LOGE("NMEA Error in string formatting"); + return; + } + pMarker += length; + lengthRemaining -= length; + + if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_DGNSS_REF_STATION_ID) + { + length = snprintf(pMarker, lengthRemaining, "%04d", + locationExtended.dgnssRefStationId); + if (length < 0 || length >= lengthRemaining) + { + LOC_LOGE("NMEA Error in string formatting"); + return; + } + pMarker += length; + lengthRemaining -= length; + } + // hardcode Navigation Status field to 'V' length = snprintf(pMarker, lengthRemaining, ",%c", 'V'); pMarker += length; @@ -1885,12 +1955,49 @@ void loc_nmea_generate_pos(const UlpLocation &location, if ((location.gpsLocation.flags & LOC_GPS_LOCATION_HAS_ALTITUDE) && (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_ALTITUDE_MEAN_SEA_LEVEL)) { - length = snprintf(pMarker, lengthRemaining, "%.1lf,M,,", + length = snprintf(pMarker, lengthRemaining, "%.1lf,M,", ref_lla.alt - locationExtended.altitudeMeanSeaLevel); } else { - length = snprintf(pMarker, lengthRemaining,",,,"); + length = snprintf(pMarker, lengthRemaining, ",,"); + } + if (length < 0 || length >= lengthRemaining) + { + LOC_LOGE("NMEA Error in string formatting"); + return; + } + pMarker += length; + lengthRemaining -= length; + + if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_DGNSS_DATA_AGE) + { + length = snprintf(pMarker, lengthRemaining, "%.1f,", + (float)locationExtended.dgnssDataAgeMsec / 1000); + } + else + { + length = snprintf(pMarker, lengthRemaining, ","); + } + if (length < 0 || length >= lengthRemaining) + { + LOC_LOGE("NMEA Error in string formatting"); + return; + } + pMarker += length; + lengthRemaining -= length; + + if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_DGNSS_REF_STATION_ID) + { + length = snprintf(pMarker, lengthRemaining, "%04d", + locationExtended.dgnssRefStationId); + if (length < 0 || length >= lengthRemaining) + { + LOC_LOGE("NMEA Error in string formatting"); + return; + } + pMarker += length; + lengthRemaining -= length; } length = loc_nmea_put_checksum(sentence_GGA, sizeof(sentence_GGA)); diff --git a/gps/utils/log_util.h b/gps/utils/log_util.h index 192baebb..13c08bcf 100644 --- a/gps/utils/log_util.h +++ b/gps/utils/log_util.h @@ -30,9 +30,13 @@ #ifndef __LOG_UTIL_H__ #define __LOG_UTIL_H__ +#include + #if defined (USE_ANDROID_LOGGING) || defined (ANDROID) // Android and LE targets with logcat support #include +#include +#include #elif defined (USE_GLIB) // LE targets with no logcat support @@ -41,6 +45,7 @@ #include #include #include +#include #ifndef LOG_TAG #define LOG_TAG "GPS_UTILS" @@ -90,18 +95,20 @@ typedef struct loc_logger_s { unsigned long DEBUG_LEVEL; unsigned long TIMESTAMP; + bool LOG_BUFFER_ENABLE; } loc_logger_s_type; + /*============================================================================= * * EXTERNAL DATA * *============================================================================*/ -extern loc_logger_s_type loc_logger; // Logging Improvements extern const char *loc_logger_boolStr[]; +extern loc_logger_s_type loc_logger; extern const char *boolStr[]; extern const char VOID_RET[]; extern const char FROM_AFW[]; @@ -117,8 +124,49 @@ extern const char EXIT_ERROR_TAG[]; * MODULE EXPORTED FUNCTIONS * *============================================================================*/ -extern void loc_logger_init(unsigned long debug, unsigned long timestamp); +inline void loc_logger_init(unsigned long debug, unsigned long timestamp) +{ + loc_logger.DEBUG_LEVEL = debug; +#ifdef TARGET_BUILD_VARIANT_USER + // force user builds to 2 or less + if (loc_logger.DEBUG_LEVEL > 2) { + loc_logger.DEBUG_LEVEL = 2; + } +#endif + loc_logger.TIMESTAMP = timestamp; +} + +inline void log_buffer_init(bool enabled) { + loc_logger.LOG_BUFFER_ENABLE = enabled; +} + extern char* get_timestamp(char* str, unsigned long buf_size); +extern void log_buffer_insert(char *str, unsigned long buf_size, int level); + +/*============================================================================= + * + * LOGGING BUFFER MACROS + * + *============================================================================*/ +#ifndef LOG_NDEBUG +#define LOG_NDEBUG 0 +#endif +#define TOTAL_LOG_LEVELS 5 +#define LOGGING_BUFFER_MAX_LEN 1024 +#define IF_LOG_BUFFER_ENABLE if (loc_logger.LOG_BUFFER_ENABLE) +#define INSERT_BUFFER(flag, level, format, x...) \ +{ \ + IF_LOG_BUFFER_ENABLE { \ + if (flag == 0) { \ + char timestr[32]; \ + get_timestamp(timestr, sizeof(timestr)); \ + char log_str[LOGGING_BUFFER_MAX_LEN]; \ + snprintf(log_str, LOGGING_BUFFER_MAX_LEN, "%s %d %ld %s :" format "\n", \ + timestr, getpid(), syscall(SYS_gettid), LOG_TAG==NULL ? "": LOG_TAG, ##x);\ + log_buffer_insert(log_str, sizeof(log_str), level); \ + } \ + } \ +} #ifndef DEBUG_DMN_LOC_API @@ -133,11 +181,11 @@ extern char* get_timestamp(char* str, unsigned long buf_size); #define IF_LOC_LOGD if((loc_logger.DEBUG_LEVEL >= 4) && (loc_logger.DEBUG_LEVEL <= 5)) #define IF_LOC_LOGV if((loc_logger.DEBUG_LEVEL >= 5) && (loc_logger.DEBUG_LEVEL <= 5)) -#define LOC_LOGE(...) IF_LOC_LOGE { ALOGE(__VA_ARGS__); } -#define LOC_LOGW(...) IF_LOC_LOGW { ALOGW(__VA_ARGS__); } -#define LOC_LOGI(...) IF_LOC_LOGI { ALOGI(__VA_ARGS__); } -#define LOC_LOGD(...) IF_LOC_LOGD { ALOGD(__VA_ARGS__); } -#define LOC_LOGV(...) IF_LOC_LOGV { ALOGV(__VA_ARGS__); } +#define LOC_LOGE(...) IF_LOC_LOGE { ALOGE(__VA_ARGS__); INSERT_BUFFER(LOG_NDEBUG, 0, __VA_ARGS__);} +#define LOC_LOGW(...) IF_LOC_LOGW { ALOGW(__VA_ARGS__); INSERT_BUFFER(LOG_NDEBUG, 1, __VA_ARGS__);} +#define LOC_LOGI(...) IF_LOC_LOGI { ALOGI(__VA_ARGS__); INSERT_BUFFER(LOG_NDEBUG, 2, __VA_ARGS__);} +#define LOC_LOGD(...) IF_LOC_LOGD { ALOGD(__VA_ARGS__); INSERT_BUFFER(LOG_NDEBUG, 3, __VA_ARGS__);} +#define LOC_LOGV(...) IF_LOC_LOGV { ALOGV(__VA_ARGS__); INSERT_BUFFER(LOG_NDEBUG, 4, __VA_ARGS__);} #else /* DEBUG_DMN_LOC_API */ diff --git a/gps/utils/msg_q.c b/gps/utils/msg_q.c index 2d49b4a3..3383960a 100644 --- a/gps/utils/msg_q.c +++ b/gps/utils/msg_q.c @@ -26,6 +26,8 @@ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +// Uncomment to log verbose logs +#define LOG_NDEBUG 1 #define LOG_TAG "LocSvc_utils_q" #include #include