diff options
author | Cyan_Hsieh <cyanhsieh@google.com> | 2020-02-03 14:55:13 +0800 |
---|---|---|
committer | Cyan_Hsieh <cyanhsieh@google.com> | 2020-02-04 21:38:24 +0800 |
commit | 21b02b0b59e62e7712c1239e96d8ea1ab8ce9f0f (patch) | |
tree | 1c7a047a387e9fa1593b5cda05866e4b5707ae12 | |
parent | d1eea9d11b92e53e5c5930fb4da5430174d8d167 (diff) | |
parent | df7f25541d10514585e50372d8c2fea723008683 (diff) | |
download | gps-21b02b0b59e62e7712c1239e96d8ea1ab8ce9f0f.tar.gz |
Merge remote-tracking branch 'goog/qcom/release/LA.UM.8.1.C9.09.00.00.518.406' into qt-qpr1-dev
Conflicts:
android/1.0/Gnss.cpp
android/1.1/Gnss.cpp
android/2.0/Gnss.cpp
gnss/GnssAdapter.cpp
Bug: 148752159
Change-Id: Ifc50f4af34c0980973830793a30c9527461b9d7b
-rw-r--r-- | android/1.0/Gnss.cpp | 2 | ||||
-rw-r--r-- | android/1.1/Gnss.cpp | 2 | ||||
-rw-r--r-- | android/2.0/Gnss.cpp | 2 | ||||
-rw-r--r-- | android/2.0/location_api/LocationUtil.cpp | 38 | ||||
-rw-r--r-- | android/2.0/location_api/LocationUtil.h | 1 | ||||
-rw-r--r-- | android/2.0/location_api/MeasurementAPIClient.cpp | 36 | ||||
-rw-r--r-- | batching/configure.ac | 2 | ||||
-rw-r--r-- | core/ContextBase.cpp | 2 | ||||
-rw-r--r-- | core/SystemStatusOsObserver.cpp | 12 | ||||
-rw-r--r-- | geofence/configure.ac | 2 | ||||
-rw-r--r-- | gnss/GnssAdapter.cpp | 65 | ||||
-rw-r--r-- | gnss/GnssAdapter.h | 4 | ||||
-rw-r--r-- | location/LocationAPI.cpp | 18 | ||||
-rw-r--r-- | location/LocationDataTypes.h | 6 | ||||
-rw-r--r-- | pla/android/loc_pla.h | 3 | ||||
-rw-r--r-- | pla/oe/loc_pla.h | 11 | ||||
-rw-r--r-- | utils/LocIpc.cpp | 16 | ||||
-rw-r--r-- | utils/gps_extended_c.h | 90 | ||||
-rw-r--r-- | utils/loc_nmea.cpp | 208 |
19 files changed, 383 insertions, 137 deletions
diff --git a/android/1.0/Gnss.cpp b/android/1.0/Gnss.cpp index 8fe4d3f..adb5232 100644 --- a/android/1.0/Gnss.cpp +++ b/android/1.0/Gnss.cpp @@ -264,7 +264,7 @@ Return<bool> Gnss::injectLocation(double latitudeDegrees, Return<bool> Gnss::injectTime(int64_t timeMs, int64_t timeReferenceMs, int32_t uncertaintyMs) { - return false; + return true; } Return<void> Gnss::deleteAidingData(V1_0::IGnss::GnssAidingData aidingDataFlags) { diff --git a/android/1.1/Gnss.cpp b/android/1.1/Gnss.cpp index aa761e2..260f999 100644 --- a/android/1.1/Gnss.cpp +++ b/android/1.1/Gnss.cpp @@ -305,7 +305,7 @@ Return<bool> Gnss::injectLocation(double latitudeDegrees, Return<bool> Gnss::injectTime(int64_t timeMs, int64_t timeReferenceMs, int32_t uncertaintyMs) { - return false; + return true; } Return<void> Gnss::deleteAidingData(V1_0::IGnss::GnssAidingData aidingDataFlags) { diff --git a/android/2.0/Gnss.cpp b/android/2.0/Gnss.cpp index 8fa42ff..6f1abf4 100644 --- a/android/2.0/Gnss.cpp +++ b/android/2.0/Gnss.cpp @@ -330,7 +330,7 @@ Return<bool> Gnss::injectLocation(double latitudeDegrees, Return<bool> Gnss::injectTime(int64_t timeMs, int64_t timeReferenceMs, int32_t uncertaintyMs) { - return false; + return true; } Return<void> Gnss::deleteAidingData(V1_0::IGnss::GnssAidingData aidingDataFlags) { diff --git a/android/2.0/location_api/LocationUtil.cpp b/android/2.0/location_api/LocationUtil.cpp index 8a30066..7e6810c 100644 --- a/android/2.0/location_api/LocationUtil.cpp +++ b/android/2.0/location_api/LocationUtil.cpp @@ -81,21 +81,16 @@ void convertGnssLocation(Location& in, V1_0::GnssLocation& out) out.timestamp = static_cast<V1_0::GnssUtcTime>(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; +} + +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 (clockGetTimeSuccess) { + 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/android/2.0/location_api/LocationUtil.h b/android/2.0/location_api/LocationUtil.h index 8426de7..d3dce23 100644 --- a/android/2.0/location_api/LocationUtil.h +++ b/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/android/2.0/location_api/MeasurementAPIClient.cpp b/android/2.0/location_api/MeasurementAPIClient.cpp index dc972ec..b87e508 100644 --- a/android/2.0/location_api/MeasurementAPIClient.cpp +++ b/android/2.0/location_api/MeasurementAPIClient.cpp @@ -32,6 +32,7 @@ #include <log_util.h> #include <loc_cfg.h> +#include <inttypes.h> #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/batching/configure.ac b/batching/configure.ac index 27435c6..e77e497 100644 --- a/batching/configure.ac +++ b/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/core/ContextBase.cpp b/core/ContextBase.cpp index 3b8ffc6..3eb4973 100644 --- a/core/ContextBase.cpp +++ b/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/core/SystemStatusOsObserver.cpp b/core/SystemStatusOsObserver.cpp index 0427380..b51a564 100644 --- a/core/SystemStatusOsObserver.cpp +++ b/core/SystemStatusOsObserver.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -347,11 +347,6 @@ void SystemStatusOsObserver::notify(const list<IDataItemCore*>& dlist) vector<IDataItemCore*> dataItemVec(dlist.size()); for (auto each : dlist) { - IF_LOC_LOGD { - string dv; - each->stringify(dv); - LOC_LOGD("notify: DataItem In Value:%s", dv.c_str()); - } IDataItemCore* di = DataItemsFactoryProxy::createNewDataItem(each->getId()); if (nullptr == di) { @@ -364,6 +359,11 @@ void SystemStatusOsObserver::notify(const list<IDataItemCore*>& 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/geofence/configure.ac b/geofence/configure.ac index 8e3cd81..74eae7a 100644 --- a/geofence/configure.ac +++ b/geofence/configure.ac @@ -1,6 +1,6 @@ AC_PREREQ(2.61) AC_INIT([location-geofence], 1.0.0) -AM_INIT_AUTOMAKE([foreign]) +AM_INIT_AUTOMAKE([foreign subdir-objects]) AC_CONFIG_SRCDIR([Makefile.am]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_MACRO_DIR([m4]) diff --git a/gnss/GnssAdapter.cpp b/gnss/GnssAdapter.cpp index 4dbd182..b2a7633 100644 --- a/gnss/GnssAdapter.cpp +++ b/gnss/GnssAdapter.cpp @@ -784,20 +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; /* Let HAL do nothing to LPPe, just set it by MBN if (gpsConf.LPPE_CP_TECHNOLOGY) { gnssConfigRequested.flags |= GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT; @@ -814,7 +810,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 @@ -892,8 +888,7 @@ GnssAdapter::setConfig() } std::vector<LocationError> 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; @@ -902,13 +897,20 @@ std::vector<LocationError> 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); @@ -1259,7 +1261,7 @@ GnssAdapter::gnssUpdateConfigCommand(GnssConfig config) mApi.sendMsg(new LocApiMsg( [&adapter, gnssConfigRequested, gnssConfigNeedEngineUpdate, - countOfConfigs, configCollectiveResponse, errs] () { + countOfConfigs, configCollectiveResponse, errs] () mutable { std::vector<LocationError> errsList = adapter.gnssUpdateConfig("", gnssConfigRequested, gnssConfigNeedEngineUpdate, countOfConfigs); @@ -2118,6 +2120,7 @@ GnssAdapter::stopClientSessions(LocationAPI* client) } for (auto key : vTimeBasedTrackingClient) { stopTimeBasedTrackingMultiplex(key.client, key.id); + eraseTrackingSession(key.client, key.id); } /* Distance-based Tracking */ @@ -3803,7 +3806,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); @@ -3819,15 +3835,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); } diff --git a/gnss/GnssAdapter.h b/gnss/GnssAdapter.h index ff8131f..136c5c0 100644 --- a/gnss/GnssAdapter.h +++ b/gnss/GnssAdapter.h @@ -319,8 +319,8 @@ public: void deleteAidingData(const GnssAidingData &data, uint32_t sessionId); void gnssUpdateXtraThrottleCommand(const bool enabled); std::vector<LocationError> 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)======================================== */ diff --git a/location/LocationAPI.cpp b/location/LocationAPI.cpp index 7c125b8..d38c023 100644 --- a/location/LocationAPI.cpp +++ b/location/LocationAPI.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -121,7 +121,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 +142,7 @@ void onGeofenceRemoveClientCompleteCb (LocationAPI* client) } LocationAPI* -LocationAPI::createInstance(LocationCallbacks& locationCallbacks) +LocationAPI::createInstance (LocationCallbacks& locationCallbacks) { if (nullptr == locationCallbacks.capabilitiesCb || nullptr == locationCallbacks.responseCb || @@ -234,15 +233,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 +254,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/location/LocationDataTypes.h b/location/LocationDataTypes.h index 65b5e13..fb651c0 100644 --- a/location/LocationDataTypes.h +++ b/location/LocationDataTypes.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -538,7 +538,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 +624,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; diff --git a/pla/android/loc_pla.h b/pla/android/loc_pla.h index 6104bfb..1b99739 100644 --- a/pla/android/loc_pla.h +++ b/pla/android/loc_pla.h @@ -31,7 +31,8 @@ #ifdef __cplusplus #include <utils/SystemClock.h> -#define uptimeMillis android::uptimeMillis +#define uptimeMillis() android::uptimeMillis() +#define elapsedRealtime() android::elapsedRealtime() #endif #ifdef __cplusplus diff --git a/pla/oe/loc_pla.h b/pla/oe/loc_pla.h index e795a23..bbdb0bd 100644 --- a/pla/oe/loc_pla.h +++ b/pla/oe/loc_pla.h @@ -37,16 +37,23 @@ #include <sys/time.h> #include <time.h> -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/utils/LocIpc.cpp b/utils/LocIpc.cpp index e9dbe9d..344e487 100644 --- a/utils/LocIpc.cpp +++ b/utils/LocIpc.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -139,8 +139,20 @@ protected: } public: inline LocIpcLocalSender(const char* name) : LocIpcSender(), - mSock(make_shared<Sock>((nullptr == name) ? -1 : (::socket(AF_UNIX, SOCK_DGRAM, 0)))), + mSock(nullptr), mAddr({.sun_family = AF_UNIX, {}}) { + + int fd = -1; + if (nullptr != name) { + fd = ::socket(AF_UNIX, SOCK_DGRAM, 0); + if (fd >= 0) { + timeval timeout; + timeout.tv_sec = 2; + timeout.tv_usec = 0; + setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)); + } + } + mSock.reset(new Sock(fd)); if (mSock != nullptr && mSock->isValid()) { snprintf(mAddr.sun_path, sizeof(mAddr.sun_path), "%s", name); } diff --git a/utils/gps_extended_c.h b/utils/gps_extended_c.h index f4ad524..677b750 100644 --- a/utils/gps_extended_c.h +++ b/utils/gps_extended_c.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2020 The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -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 */ @@ -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) @@ -761,15 +778,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 { @@ -1249,6 +1285,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; @@ -1388,7 +1443,8 @@ typedef struct float carrierPhaseUnc; - + /** < DGNSS Measurements Report for SVs */ + Gnss_LocDgnssSVMeasurement dgnssSvMeas; } Gnss_SVMeasurementStructType; @@ -1420,6 +1476,9 @@ 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 typedef struct { @@ -1465,6 +1524,22 @@ 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 { @@ -2222,7 +2297,10 @@ enum PowerStateType { #define EAP_LOC_CLIENT_DIR "/data/vendor/location/extap_locclient/" #define LOC_CLIENT_NAME_PREFIX "toclient" -#define LOC_INTAPI_NAME_PREFIX "toIntapiClient" +// Please note that the socket name for all location hal daemon client need +// to start with LOC_CLIENT_NAME_PREFIX so that upon hal daemon restarts, +// every client can get the notification that hal daemon has restarted. +#define LOC_INTAPI_NAME_PREFIX LOC_CLIENT_NAME_PREFIX "_intapi" typedef uint64_t NetworkHandle; #define NETWORK_HANDLE_UNKNOWN ~0 diff --git a/utils/loc_nmea.cpp b/utils/loc_nmea.cpp index 9ee2716..5295f6a 100644 --- a/utils/loc_nmea.cpp +++ b/utils/loc_nmea.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -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)); |