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.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/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/location_api/LocationUtil.cpp b/gps/android/2.0/location_api/LocationUtil.cpp index 8a30066f..7e6810c6 100644 --- a/gps/android/2.0/location_api/LocationUtil.cpp +++ b/gps/android/2.0/location_api/LocationUtil.cpp @@ -81,21 +81,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 +100,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 "" @@ -142,8 +147,7 @@ void convertGnssLocation(Location& in, V2_0::GnssLocation& out) } } } else { - LOC_LOGE("%s]: Failed to calculate elapsedRealtimeNanos timestamp after %u tries", - __FUNCTION__, MAX_GET_TIME_COUNT); + LOC_LOGe("Failed to calculate elapsedRealtimeNanos timestamp"); } } diff --git a/gps/android/2.0/location_api/LocationUtil.h b/gps/android/2.0/location_api/LocationUtil.h index 8426de72..d3dce23c 100644 --- a/gps/android/2.0/location_api/LocationUtil.h +++ b/gps/android/2.0/location_api/LocationUtil.h @@ -49,6 +49,7 @@ void convertGnssConstellationType(GnssSvType& in, V2_0::GnssConstellationType& o 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..b87e5082 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" @@ -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/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/SystemStatusOsObserver.cpp b/gps/core/SystemStatusOsObserver.cpp index 0427380c..b51a564d 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 @@ -347,11 +347,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 +359,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()) { 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..7b9880cc 100644 --- a/gps/gnss/GnssAdapter.cpp +++ b/gps/gnss/GnssAdapter.cpp @@ -784,19 +784,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 +808,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 @@ -889,8 +886,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 +895,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 +1259,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); @@ -2094,6 +2097,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 +2120,7 @@ GnssAdapter::stopClientSessions(LocationAPI* client) } for (auto key : vTimeBasedTrackingClient) { stopTimeBasedTrackingMultiplex(key.client, key.id); + eraseTrackingSession(key.client, key.id); } /* Distance-based Tracking */ @@ -2153,6 +2159,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; @@ -2336,7 +2345,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") @@ -3800,7 +3810,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 +3839,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 +4095,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 diff --git a/gps/gnss/GnssAdapter.h b/gps/gnss/GnssAdapter.h index ff8131ff..32bd84e0 100644 --- a/gps/gnss/GnssAdapter.h +++ b/gps/gnss/GnssAdapter.h @@ -319,8 +319,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)======================================== */ @@ -451,6 +451,10 @@ public: } void updateSystemPowerState(PowerStateType systemPowerState); + void reportSvPolynomial(const GnssSvPolynomial &svPolynomial); + void requestSvPolyForClient(LocationAPI* client, + const LocationCallbacks& callbacks); + /*======== GNSSDEBUG ================================================================*/ bool getDebugReport(GnssDebugReport& report); diff --git a/gps/location/LocationAPI.cpp b/gps/location/LocationAPI.cpp index 7c125b81..d0a560d1 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,8 @@ static bool isGnssClient(LocationCallbacks& locationCallbacks) locationCallbacks.trackingCb != nullptr || locationCallbacks.gnssLocationInfoCb != nullptr || locationCallbacks.engineLocationsInfoCb != nullptr || - locationCallbacks.gnssMeasurementsCb != nullptr); + locationCallbacks.gnssMeasurementsCb != nullptr || + locationCallbacks.gnssSvPolynomialCb != nullptr); } static bool isBatchingClient(LocationCallbacks& locationCallbacks) @@ -121,7 +122,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 +143,7 @@ void onGeofenceRemoveClientCompleteCb (LocationAPI* client) } LocationAPI* -LocationAPI::createInstance(LocationCallbacks& locationCallbacks) +LocationAPI::createInstance (LocationCallbacks& locationCallbacks) { if (nullptr == locationCallbacks.capabilitiesCb || nullptr == locationCallbacks.responseCb || @@ -234,15 +234,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 +255,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) { diff --git a/gps/location/LocationDataTypes.h b/gps/location/LocationDataTypes.h index 65b5e13d..3ff3e4a2 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) @@ -385,6 +385,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 +539,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 +625,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 +883,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; @@ -1061,9 +1059,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 +1120,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; @@ -1158,12 +1192,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 && @@ -1253,7 +1363,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,6 +1608,14 @@ 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 -#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..d6e50a20 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,17 @@ 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 typedef uint32_t LocNavSolutionMask; /* Bitmask to specify whether SBAS ionospheric correction is used */ @@ -442,10 +452,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 +583,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 +619,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 +627,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 +769,34 @@ 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; } GpsLocationExtended; enum loc_sess_status { @@ -978,14 +1005,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 +1195,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 +1277,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 +1303,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 +1429,8 @@ typedef struct float carrierPhaseUnc; - + /** < DGNSS Measurements Report for SVs */ + Gnss_LocDgnssSVMeasurement dgnssSvMeas; } Gnss_SVMeasurementStructType; @@ -1420,6 +1462,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 +1511,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 +1566,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..5295f6a6 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 @@ -1036,12 +1036,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 +1065,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 +1156,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 +1330,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 +1413,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 +1746,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 +1789,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 +1952,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