diff options
author | Cyan_Hsieh <cyanhsieh@google.com> | 2019-12-01 22:19:31 -0800 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2019-12-01 22:19:31 -0800 |
commit | ca0b59b33c9b9db8b9c0174552150a9ac130e4c5 (patch) | |
tree | 96c65fc86d6186be633fb3077d767b998e44a3df | |
parent | 9931645b17edcf6bf2e19cb6ab06156482093e78 (diff) | |
parent | 60680d503e8e62f0476091648d18f62b7ef7c667 (diff) | |
download | gps-ca0b59b33c9b9db8b9c0174552150a9ac130e4c5.tar.gz |
Merge remote-tracking branch 'goog/qcom/release/LA.UM.8.1.C9.09.00.00.518.327' into qt-qpr1-dev am: 771e6abea8
am: 60680d503e
Change-Id: I1326f448701ed30906b91a391aa29f8a2bc758c4
-rw-r--r-- | android/2.0/location_api/LocationUtil.cpp | 41 | ||||
-rw-r--r-- | core/ContextBase.cpp | 18 | ||||
-rw-r--r-- | core/ContextBase.h | 1 | ||||
-rw-r--r-- | core/LocAdapterBase.cpp | 11 | ||||
-rw-r--r-- | core/LocAdapterBase.h | 24 | ||||
-rw-r--r-- | etc/gps.conf | 25 | ||||
-rw-r--r-- | gnss/GnssAdapter.cpp | 14 | ||||
-rw-r--r-- | location/LocationDataTypes.h | 34 | ||||
-rw-r--r-- | utils/gps_extended_c.h | 43 | ||||
-rw-r--r-- | utils/loc_nmea.cpp | 120 | ||||
-rw-r--r-- | utils/loc_nmea.h | 1 | ||||
-rw-r--r-- | utils/log_util.h | 3 |
12 files changed, 237 insertions, 98 deletions
diff --git a/android/2.0/location_api/LocationUtil.cpp b/android/2.0/location_api/LocationUtil.cpp index 38a083a..8a30066 100644 --- a/android/2.0/location_api/LocationUtil.cpp +++ b/android/2.0/location_api/LocationUtil.cpp @@ -88,10 +88,41 @@ void convertGnssLocation(Location& in, V2_0::GnssLocation& out) struct timespec sinceBootTime; struct timespec currentTime; - if (0 == clock_gettime(CLOCK_BOOTTIME,&sinceBootTime) && - 0 == clock_gettime(CLOCK_REALTIME,¤tTime)) { + 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++) { + if (clock_gettime(CLOCK_BOOTTIME, &sinceBootTime) != 0) { + break; + }; + if (clock_gettime(CLOCK_REALTIME, ¤tTime) != 0) { + break; + } + if (clock_gettime(CLOCK_BOOTTIME, &sinceBootTimeTest) != 0) { + break; + }; + sinceBootTimeNanos = sinceBootTime.tv_sec*1000000000 + sinceBootTime.tv_nsec; + int64_t sinceBootTimeTestNanos = + sinceBootTimeTest.tv_sec*1000000000 + sinceBootTimeTest.tv_nsec; + int64_t sinceBootTimeDeltaNanos = sinceBootTimeTestNanos - sinceBootTimeNanos; - int64_t sinceBootTimeNanos = sinceBootTime.tv_sec*1000000000 + sinceBootTime.tv_nsec; + /* sinceBootTime and sinceBootTimeTest should have a close value if there was no + interruption or context switch between clock_gettime for CLOCK_BOOTIME and + clock_gettime for CLOCK_REALTIME */ + if (sinceBootTimeDeltaNanos < MAX_TIME_DELTA_VALUE_NANOS) { + clockGetTimeSuccess = true; + break; + } else { + LOC_LOGD("%s]: Delta:%" PRIi64 "ns time too large, retry number #%u...", + __FUNCTION__, sinceBootTimeDeltaNanos, i+1); + } + } + + if (clockGetTimeSuccess) { int64_t currentTimeNanos = currentTime.tv_sec*1000000000 + currentTime.tv_nsec; int64_t locationTimeNanos = in.timestamp*1000000; LOC_LOGD("%s]: sinceBootTimeNanos:%" PRIi64 " currentTimeNanos:%" PRIi64 "" @@ -110,8 +141,10 @@ void convertGnssLocation(Location& in, V2_0::GnssLocation& out) __FUNCTION__, out.elapsedRealtime.timestampNs); } } + } else { + LOC_LOGE("%s]: Failed to calculate elapsedRealtimeNanos timestamp after %u tries", + __FUNCTION__, MAX_GET_TIME_COUNT); } - } void convertGnssLocation(const V1_0::GnssLocation& in, Location& out) diff --git a/core/ContextBase.cpp b/core/ContextBase.cpp index 22ac849..7434590 100644 --- a/core/ContextBase.cpp +++ b/core/ContextBase.cpp @@ -70,7 +70,8 @@ const loc_param_s_type ContextBase::mGps_conf_table[] = {"XTRA_SERVER_1", &mGps_conf.XTRA_SERVER_1, NULL, 's'}, {"XTRA_SERVER_2", &mGps_conf.XTRA_SERVER_2, NULL, 's'}, {"XTRA_SERVER_3", &mGps_conf.XTRA_SERVER_3, NULL, 's'}, - {"USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL", &mGps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL, NULL, 'n'}, + {"USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL", + &mGps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL, NULL, 'n'}, {"AGPS_CONFIG_INJECT", &mGps_conf.AGPS_CONFIG_INJECT, NULL, 'n'}, {"EXTERNAL_DR_ENABLED", &mGps_conf.EXTERNAL_DR_ENABLED, NULL, 'n'}, {"SUPL_HOST", &mGps_conf.SUPL_HOST, NULL, 's'}, @@ -78,13 +79,19 @@ const loc_param_s_type ContextBase::mGps_conf_table[] = {"MODEM_TYPE", &mGps_conf.MODEM_TYPE, NULL, 'n' }, {"MO_SUPL_HOST", &mGps_conf.MO_SUPL_HOST, NULL, 's' }, {"MO_SUPL_PORT", &mGps_conf.MO_SUPL_PORT, NULL, 'n' }, - {"CONSTRAINED_TIME_UNCERTAINTY_ENABLED", &mGps_conf.CONSTRAINED_TIME_UNCERTAINTY_ENABLED, NULL, 'n'}, - {"CONSTRAINED_TIME_UNCERTAINTY_THRESHOLD", &mGps_conf.CONSTRAINED_TIME_UNCERTAINTY_THRESHOLD, NULL, 'f'}, - {"CONSTRAINED_TIME_UNCERTAINTY_ENERGY_BUDGET", &mGps_conf.CONSTRAINED_TIME_UNCERTAINTY_ENERGY_BUDGET, NULL, 'n'}, - {"POSITION_ASSISTED_CLOCK_ESTIMATOR_ENABLED", &mGps_conf.POSITION_ASSISTED_CLOCK_ESTIMATOR_ENABLED, NULL, 'n'}, + {"CONSTRAINED_TIME_UNCERTAINTY_ENABLED", + &mGps_conf.CONSTRAINED_TIME_UNCERTAINTY_ENABLED, NULL, 'n'}, + {"CONSTRAINED_TIME_UNCERTAINTY_THRESHOLD", + &mGps_conf.CONSTRAINED_TIME_UNCERTAINTY_THRESHOLD, NULL, 'f'}, + {"CONSTRAINED_TIME_UNCERTAINTY_ENERGY_BUDGET", + &mGps_conf.CONSTRAINED_TIME_UNCERTAINTY_ENERGY_BUDGET, NULL, 'n'}, + {"POSITION_ASSISTED_CLOCK_ESTIMATOR_ENABLED", + &mGps_conf.POSITION_ASSISTED_CLOCK_ESTIMATOR_ENABLED, NULL, 'n'}, {"PROXY_APP_PACKAGE_NAME", &mGps_conf.PROXY_APP_PACKAGE_NAME, NULL, 's' }, {"CP_MTLR_ES", &mGps_conf.CP_MTLR_ES, NULL, 'n' }, {"GNSS_DEPLOYMENT", &mGps_conf.GNSS_DEPLOYMENT, NULL, 'n'}, + {"CUSTOM_NMEA_GGA_FIX_QUALITY_ENABLED", + &mGps_conf.CUSTOM_NMEA_GGA_FIX_QUALITY_ENABLED, NULL, 'n'}, }; const loc_param_s_type ContextBase::mSap_conf_table[] = @@ -183,6 +190,7 @@ void ContextBase::readConfig() mGps_conf.POSITION_ASSISTED_CLOCK_ESTIMATOR_ENABLED = 0; /* default configuration QTI GNSS H/W */ mGps_conf.GNSS_DEPLOYMENT = 0; + mGps_conf.CUSTOM_NMEA_GGA_FIX_QUALITY_ENABLED = 0; UTIL_READ_CONF(LOC_PATH_GPS_CONF, mGps_conf_table); UTIL_READ_CONF(LOC_PATH_SAP_CONF, mSap_conf_table); diff --git a/core/ContextBase.h b/core/ContextBase.h index 5da76e2..6701600 100644 --- a/core/ContextBase.h +++ b/core/ContextBase.h @@ -74,6 +74,7 @@ typedef struct loc_gps_cfg_s char PROXY_APP_PACKAGE_NAME[LOC_MAX_PARAM_STRING]; uint32_t CP_MTLR_ES; uint32_t GNSS_DEPLOYMENT; + uint32_t CUSTOM_NMEA_GGA_FIX_QUALITY_ENABLED; } loc_gps_cfg_s_type; /* NOTE: the implementaiton of the parser casts number diff --git a/core/LocAdapterBase.cpp b/core/LocAdapterBase.cpp index 1b844e5..1e91cf8 100644 --- a/core/LocAdapterBase.cpp +++ b/core/LocAdapterBase.cpp @@ -43,13 +43,20 @@ namespace loc_core { // the right locApi should get created. LocAdapterBase::LocAdapterBase(const LOC_API_ADAPTER_EVENT_MASK_T mask, ContextBase* context, bool isMaster, - LocAdapterProxyBase *adapterProxyBase) : + LocAdapterProxyBase *adapterProxyBase, + bool waitForDoneInit) : mIsMaster(isMaster), mEvtMask(mask), mContext(context), mLocApi(context->getLocApi()), mLocAdapterProxyBase(adapterProxyBase), mMsgTask(context->getMsgTask()), mIsEngineCapabilitiesKnown(ContextBase::sIsEngineCapabilitiesKnown) { - mLocApi->addAdapter(this); + LOC_LOGd("waitForDoneInit: %d", waitForDoneInit); + if (!waitForDoneInit) { + mLocApi->addAdapter(this); + mAdapterAdded = true; + } else { + mAdapterAdded = false; + } } uint32_t LocAdapterBase::mSessionIdCounter(1); diff --git a/core/LocAdapterBase.h b/core/LocAdapterBase.h index 909b6fe..7ca3ecd 100644 --- a/core/LocAdapterBase.h +++ b/core/LocAdapterBase.h @@ -70,9 +70,11 @@ protected: LocApiBase* mLocApi; LocAdapterProxyBase* mLocAdapterProxyBase; const MsgTask* mMsgTask; + bool mAdapterAdded; + inline LocAdapterBase(const MsgTask* msgTask) : mIsMaster(false), mEvtMask(0), mContext(NULL), mLocApi(NULL), - mLocAdapterProxyBase(NULL), mMsgTask(msgTask) {} + mLocAdapterProxyBase(NULL), mMsgTask(msgTask), mAdapterAdded(false) {} /* ==== CLIENT ========================================================================= */ typedef std::map<LocationAPI*, LocationCallbacks> ClientDataMap; @@ -89,9 +91,27 @@ protected: public: inline virtual ~LocAdapterBase() { mLocApi->removeAdapter(this); } + // When waitForDoneInit is not specified or specified as false, + // handleEngineUpEvent may be called on the child adapter object from + // a different thread before the constructor of the child + // object finishes. + // + // If the handleEngineUpEvent relies on member variables of the constructor + // of the child adapter to be initialized first, we need to specify the + // waitForDoneInit to *TRUE* to delay handleEngineUpEvent to get called + // until when the child adapter finishes its initialization and notify + // LocAdapterBase via doneInit method. LocAdapterBase(const LOC_API_ADAPTER_EVENT_MASK_T mask, ContextBase* context, bool isMaster = false, - LocAdapterProxyBase *adapterProxyBase = NULL); + LocAdapterProxyBase *adapterProxyBase = NULL, + bool waitForDoneInit = false); + + inline void doneInit() { + if (!mAdapterAdded) { + mLocApi->addAdapter(this); + mAdapterAdded = true; + } + } inline LOC_API_ADAPTER_EVENT_MASK_T checkMask(LOC_API_ADAPTER_EVENT_MASK_T mask) const { diff --git a/etc/gps.conf b/etc/gps.conf index 6354765..47aa8ef 100644 --- a/etc/gps.conf +++ b/etc/gps.conf @@ -99,6 +99,31 @@ DATUM_TYPE = 0 ################################ # NMEA provider (1=Modem Processor, 0=Application Processor) NMEA_PROVIDER=0 + +# Customized NMEA GGA fix quality that can be used to tell +# whether SENSOR contributed to the fix. +# +# When this configuration item is not enabled (set to any value that is not 1), +# GGA fix quality conforms to NMEA standard spec as below: +# PPP/DGNSS/SBAS correction fix w/ or w/o sensor: 2 +# RTK fixed fix w/ or w/o sensor: 4 +# RTK float fix w/ or w/o sensor: 5 +# SPE fix w/ or w/o sensor: 1 +# Sensor dead reckoning fix: 6 +# +# When this configuration is enabled (set to 1), GGA fix quality +# will be output as below: +# PPP fix w/o sensor: 59, w/ sensor: 69 +# DGNSS/SBAS correction fix w/o sensor: 2, w/ sensor: 62 +# RTK fixed fix w/o sensor: 4, w/ sensor: 64 +# RTK float fix w/o sensor: 5, w/ sensor: 65, +# SPE fix w/o sensor: 1, and w/ sensor: 61 +# Sensor dead reckoning fix: 6 +# +# any value that is not 1 - disabled +# 1 - enabled +CUSTOM_NMEA_GGA_FIX_QUALITY_ENABLED = 0 + # Mark if it is a SGLTE target (1=SGLTE, 0=nonSGLTE) SGLTE_TARGET=0 diff --git a/gnss/GnssAdapter.cpp b/gnss/GnssAdapter.cpp index 43fb63b..11f6777 100644 --- a/gnss/GnssAdapter.cpp +++ b/gnss/GnssAdapter.cpp @@ -65,9 +65,10 @@ static void agpsCloseResultCb (bool isSuccess, AGpsExtType agpsType, void* userD GnssAdapter::GnssAdapter() : LocAdapterBase(0, LocContext::getLocContext(NULL, - NULL, - LocContext::mLocationHalName, - false), true, nullptr), + NULL, + LocContext::mLocationHalName, + false), + true, nullptr, true), mEngHubProxy(new EngineHubProxyBase()), mLocPositionMode(), mGnssSvIdUsedInPosition(), @@ -127,6 +128,10 @@ GnssAdapter::GnssAdapter() : readConfigCommand(); initDefaultAgpsCommand(); initEngHubProxyCommand(); + + // at last step, let us inform adapater base that we are done + // with initialization, e.g.: ready to process handleEngineUpEvent + doneInit(); } void @@ -3272,9 +3277,10 @@ GnssAdapter::reportPosition(const UlpLocation& ulpLocation, (0 == ulpLocation.gpsLocation.longitude) && (LOC_RELIABILITY_NOT_SET == locationExtended.horizontal_reliability)); uint8_t generate_nmea = (reportToGnssClient && status != LOC_SESS_FAILURE && !blank_fix); + bool custom_nmea_gga = (1 == ContextBase::mGps_conf.CUSTOM_NMEA_GGA_FIX_QUALITY_ENABLED); std::vector<std::string> nmeaArraystr; loc_nmea_generate_pos(ulpLocation, locationExtended, mLocSystemInfo, - generate_nmea, nmeaArraystr); + generate_nmea, custom_nmea_gga, nmeaArraystr); stringstream ss; for (auto itor = nmeaArraystr.begin(); itor != nmeaArraystr.end(); ++itor) { ss << *itor; diff --git a/location/LocationDataTypes.h b/location/LocationDataTypes.h index 17094ab..956754a 100644 --- a/location/LocationDataTypes.h +++ b/location/LocationDataTypes.h @@ -567,28 +567,32 @@ typedef enum { GNSS_SIGNAL_GALILEO_E5A = (1<<7), /** GALILEO E5B RF Band */ GNSS_SIGNAL_GALILEO_E5B = (1<<8), - /** BEIDOU B1_I RF Band */ - GNSS_SIGNAL_BEIDOU_B1I = (1<<9), - /** BEIDOU B1C RF Band */ - GNSS_SIGNAL_BEIDOU_B1C = (1<<10), - /** BEIDOU B2_I RF Band */ - GNSS_SIGNAL_BEIDOU_B2I = (1<<11), - /** BEIDOU B2A_I RF Band */ - GNSS_SIGNAL_BEIDOU_B2AI = (1<<12), + /** BEIDOU B1 RF Band */ + GNSS_SIGNAL_BEIDOU_B1 = (1<<9), + /** BEIDOU B2 RF Band */ + GNSS_SIGNAL_BEIDOU_B2 = (1<<10), /** QZSS L1CA RF Band */ - GNSS_SIGNAL_QZSS_L1CA = (1<<13), + GNSS_SIGNAL_QZSS_L1CA = (1<<11), /** QZSS L1S RF Band */ - GNSS_SIGNAL_QZSS_L1S = (1<<14), + GNSS_SIGNAL_QZSS_L1S = (1<<12), /** QZSS L2 RF Band */ - GNSS_SIGNAL_QZSS_L2 = (1<<15), + GNSS_SIGNAL_QZSS_L2 = (1<<13), /** QZSS L5 RF Band */ - GNSS_SIGNAL_QZSS_L5 = (1<<16), + GNSS_SIGNAL_QZSS_L5 = (1<<14), /** SBAS L1 RF Band */ - GNSS_SIGNAL_SBAS_L1 = (1<<17), + GNSS_SIGNAL_SBAS_L1 = (1<<15), + /** BEIDOU B1I RF Band */ + GNSS_SIGNAL_BEIDOU_B1I = (1<<16), + /** BEIDOU B1C RF Band */ + GNSS_SIGNAL_BEIDOU_B1C = (1<<17), + /** BEIDOU B2I RF Band */ + GNSS_SIGNAL_BEIDOU_B2I = (1<<18), + /** BEIDOU B2AI RF Band */ + GNSS_SIGNAL_BEIDOU_B2AI = (1<<19), /** NAVIC L5 RF Band */ - GNSS_SIGNAL_NAVIC_L5 = (1<<18), + GNSS_SIGNAL_NAVIC_L5 = (1<<20), /** BEIDOU B2A_Q RF Band */ - GNSS_SIGNAL_BEIDOU_B2AQ = (1<<19) + GNSS_SIGNAL_BEIDOU_B2AQ = (1<<21), } GnssSignalTypeBits; #define GNSS_SIGNAL_TYPE_MASK_ALL\ diff --git a/utils/gps_extended_c.h b/utils/gps_extended_c.h index 69a659e..3ef49e3 100644 --- a/utils/gps_extended_c.h +++ b/utils/gps_extended_c.h @@ -573,49 +573,6 @@ typedef uint8_t CarrierPhaseAmbiguityType; #define CARRIER_PHASE_AMBIGUITY_RESOLUTION_FLOAT ((CarrierPhaseAmbiguityType)1) #define CARRIER_PHASE_AMBIGUITY_RESOLUTION_FIXED ((CarrierPhaseAmbiguityType)2) -/** GNSS Signal Type and RF Band */ -typedef uint32_t GnssSignalTypeMask; -/** GPS L1CA Signal */ -#define GNSS_SIGNAL_GPS_L1CA ((GnssSignalTypeMask)0x00000001ul) -/** GPS L1C Signal */ -#define GNSS_SIGNAL_GPS_L1C ((GnssSignalTypeMask)0x00000002ul) -/** GPS L2 RF Band */ -#define GNSS_SIGNAL_GPS_L2 ((GnssSignalTypeMask)0x00000004ul) -/** GPS L5 RF Band */ -#define GNSS_SIGNAL_GPS_L5 ((GnssSignalTypeMask)0x00000008ul) -/** GLONASS G1 (L1OF) RF Band */ -#define GNSS_SIGNAL_GLONASS_G1 ((GnssSignalTypeMask)0x00000010ul) -/** GLONASS G2 (L2OF) RF Band */ -#define GNSS_SIGNAL_GLONASS_G2 ((GnssSignalTypeMask)0x00000020ul) -/** GALILEO E1 RF Band */ -#define GNSS_SIGNAL_GALILEO_E1 ((GnssSignalTypeMask)0x00000040ul) -/** GALILEO E5A RF Band */ -#define GNSS_SIGNAL_GALILEO_E5A ((GnssSignalTypeMask)0x00000080ul) -/** GALILEO E5B RF Band */ -#define GNSS_SIGNAL_GALILIEO_E5B ((GnssSignalTypeMask)0x00000100ul) -/** BEIDOU B1_I RF Band */ -#define GNSS_SIGNAL_BEIDOU_B1I ((GnssSignalTypeMask)0x00000200ul) -/** BEIDOU B1C RF Band */ -#define GNSS_SIGNAL_BEIDOU_B1C ((GnssSignalTypeMask)0x00000400ul) -/** BEIDOU B2_I RF Band */ -#define GNSS_SIGNAL_BEIDOU_B2I ((GnssSignalTypeMask)0x00000800ul) -/** BEIDOU B2A_I RF Band */ -#define GNSS_SIGNAL_BEIDOU_B2AI ((GnssSignalTypeMask)0x00001000ul) -/** QZSS L1CA RF Band */ -#define GNSS_SIGNAL_QZSS_L1CA ((GnssSignalTypeMask)0x00002000ul) -/** QZSS L1S RF Band */ -#define GNSS_SIGNAL_QZSS_L1S ((GnssSignalTypeMask)0x00004000ul) -/** QZSS L2 RF Band */ -#define GNSS_SIGNAL_QZSS_L2 ((GnssSignalTypeMask)0x00008000ul) -/** QZSS L5 RF Band */ -#define GNSS_SIGNAL_QZSS_L5 ((GnssSignalTypeMask)0x00010000ul) -/** SBAS L1 RF Band */ -#define GNSS_SIGNAL_SBAS_L1 ((GnssSignalTypeMask)0x00020000ul) -/** NAVIC L5 RF Band */ -#define GNSS_SIGNAL_NAVIC_L5 ((GnssSignalTypeMask)0x00040000ul) -/** BEIDOU B2A_Q RF Band */ -#define GNSS_SIGNAL_BEIDOU_B2AQ ((GnssSignalTypeMask)0x00080000ul) - typedef uint16_t GnssMeasUsageStatusBitMask; /** Used in fix */ #define GNSS_MEAS_USED_IN_PVT ((GnssMeasUsageStatusBitMask)0x00000001ul) diff --git a/utils/loc_nmea.cpp b/utils/loc_nmea.cpp index d5e4b57..cf738ba 100644 --- a/utils/loc_nmea.cpp +++ b/utils/loc_nmea.cpp @@ -1033,47 +1033,56 @@ SIDE EFFECTS ===========================================================================*/ static void loc_nmea_get_fix_quality(const UlpLocation & location, const GpsLocationExtended & locationExtended, - char & ggaGpsQuality, + bool custom_gga_fix_quality, + char ggaGpsQuality[3], char & rmcModeIndicator, char & vtgModeIndicator) { - ggaGpsQuality = '0'; - rmcModeIndicator = 'N'; - vtgModeIndicator = 'N'; + ggaGpsQuality[0] = '0'; // 0 means no fix + rmcModeIndicator = 'N'; // N means no fix + vtgModeIndicator = 'N'; // N means no fix do { + // GGA fix quality is defined in NMEA spec as below: + // https://www.trimble.com/OEM_ReceiverHelp/V4.44/en/NMEA-0183messages_GGA.html + // Fix quality: 0 = invalid + // 1 = GPS fix (SPS) + // 2 = DGPS fix + // 3 = PPS fix + // 4 = Real Time Kinematic + // 5 = Float RTK + // 6 = estimated (dead reckoning) (2.3 feature) + // 7 = Manual input mode + // 8 = Simulation mode if (!(location.gpsLocation.flags & LOC_GPS_LOCATION_HAS_LAT_LONG)){ - ggaGpsQuality = '0'; // 0 means no fix - rmcModeIndicator = 'N'; - vtgModeIndicator = 'N'; break; } // NOTE: Order of the check is important if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_NAV_SOLUTION_MASK) { if (LOC_NAV_MASK_PPP_CORRECTION & locationExtended.navSolutionMask) { - ggaGpsQuality = '2'; // 2 means DGPS fix + ggaGpsQuality[0] = '2'; // 2 means DGPS fix rmcModeIndicator = 'P'; // P means precise vtgModeIndicator = 'P'; // P means precise break; } else if (LOC_NAV_MASK_RTK_FIXED_CORRECTION & locationExtended.navSolutionMask){ - ggaGpsQuality = '4'; // 4 means RTK Fixed fix + 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 break; } else if (LOC_NAV_MASK_RTK_CORRECTION & locationExtended.navSolutionMask){ - ggaGpsQuality = '5'; // 5 means RTK float fix + 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 break; } else if (LOC_NAV_MASK_DGNSS_CORRECTION & locationExtended.navSolutionMask){ - ggaGpsQuality = '2'; // 2 means DGPS fix + ggaGpsQuality[0] = '2'; // 2 means DGPS fix rmcModeIndicator = 'D'; // D means differential vtgModeIndicator = 'D'; // D means differential break; } else if (LOC_NAV_MASK_SBAS_CORRECTION_IONO & locationExtended.navSolutionMask){ - ggaGpsQuality = '2'; // 2 means DGPS fix + ggaGpsQuality[0] = '2'; // 2 means DGPS fix rmcModeIndicator = 'D'; // D means differential vtgModeIndicator = 'D'; // D means differential break; @@ -1082,12 +1091,12 @@ static void loc_nmea_get_fix_quality(const UlpLocation & location, // NOTE: Order of the check is important if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_POS_TECH_MASK) { if (LOC_POS_TECH_MASK_SATELLITE & locationExtended.tech_mask){ - ggaGpsQuality = '1'; // 1 means GPS + ggaGpsQuality[0] = '1'; // 1 means GPS rmcModeIndicator = 'A'; // A means autonomous vtgModeIndicator = 'A'; // A means autonomous break; } else if (LOC_POS_TECH_MASK_SENSORS & locationExtended.tech_mask){ - ggaGpsQuality = '6'; // 6 means estimated (dead reckoning) + ggaGpsQuality[0] = '6'; // 6 means estimated (dead reckoning) rmcModeIndicator = 'E'; // E means estimated (dead reckoning) vtgModeIndicator = 'E'; // E means estimated (dead reckoning) break; @@ -1095,7 +1104,54 @@ static void loc_nmea_get_fix_quality(const UlpLocation & location, } } while (0); - LOC_LOGv("gps quality: %c, rmc mode indicator: %c, vtg mode indicator: %c", + do { + // check for customized nmea enabled or not + // with customized GGA quality enabled + // PPP fix w/o sensor: 59, PPP fix w/ sensor: 69 + // DGNSS/SBAS correction fix w/o sensor: 2, w/ sensor: 62 + // RTK fixed fix w/o sensor: 4, w/ sensor: 64 + // RTK float fix w/o sensor: 5, w/ sensor: 65 + // SPE fix w/o sensor: 1, and w/ sensor: 61 + // Sensor dead reckoning fix: 6 + if (true == custom_gga_fix_quality) { + if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_NAV_SOLUTION_MASK) { + // PPP fix w/o sensor: fix quality will now be 59 + // PPP fix w sensor: fix quality will now be 69 + if (LOC_NAV_MASK_PPP_CORRECTION & locationExtended.navSolutionMask) { + if ((locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_POS_TECH_MASK) && + (LOC_POS_TECH_MASK_SENSORS & locationExtended.tech_mask)) { + ggaGpsQuality[0] = '6'; + ggaGpsQuality[1] = '9'; + } else { + ggaGpsQuality[0] = '5'; + ggaGpsQuality[1] = '9'; + } + break; + } + } + + if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_POS_TECH_MASK) { + if (LOC_POS_TECH_MASK_SENSORS & locationExtended.tech_mask){ + char ggaQuality_copy = ggaGpsQuality[0]; + ggaGpsQuality[0] = '6'; // 6 sensor assisted + // RTK fixed fix w/ sensor: fix quality will now be 64 + // RTK float fix w/ sensor: 65 + // DGNSS and/or SBAS correction fix and w/ sensor: 62 + // GPS fix without correction and w/ sensor: 61 + if ((LOC_NAV_MASK_RTK_FIXED_CORRECTION & locationExtended.navSolutionMask)|| + (LOC_NAV_MASK_RTK_CORRECTION & locationExtended.navSolutionMask)|| + (LOC_NAV_MASK_DGNSS_CORRECTION & locationExtended.navSolutionMask)|| + (LOC_NAV_MASK_SBAS_CORRECTION_IONO & locationExtended.navSolutionMask)|| + (LOC_POS_TECH_MASK_SATELLITE & locationExtended.tech_mask)) { + ggaGpsQuality[1] = ggaQuality_copy; + break; + } + } + } + } + } while (0); + + LOC_LOGv("gps quality: %s, rmc mode indicator: %c, vtg mode indicator: %c", ggaGpsQuality, rmcModeIndicator, vtgModeIndicator); } @@ -1127,6 +1183,7 @@ void loc_nmea_generate_pos(const UlpLocation &location, const GpsLocationExtended &locationExtended, const LocationSystemInfo &systemInfo, unsigned char generate_nmea, + bool custom_gga_fix_quality, std::vector<std::string> &nmeaArraystr) { ENTRY_LOG(); @@ -1270,10 +1327,18 @@ void loc_nmea_generate_pos(const UlpLocation &location, talker[1] = sv_meta.talker[1]; } - char ggaGpsQuality = '0'; + // if svUsedCount is 0, it means we do not generate any GSA sentence yet. + // in this case, generate an empty GSA sentence + if (svUsedCount == 0) { + strlcpy(sentence, "$GPGSA,A,1,,,,,,,,,,,,,,,,", sizeof(sentence)); + length = loc_nmea_put_checksum(sentence, sizeof(sentence)); + nmeaArraystr.push_back(sentence); + } + + char ggaGpsQuality[3] = {'0', '\0', '\0'}; char rmcModeIndicator = 'N'; char vtgModeIndicator = 'N'; - loc_nmea_get_fix_quality(location, locationExtended, + loc_nmea_get_fix_quality(location, locationExtended, custom_gga_fix_quality, ggaGpsQuality, rmcModeIndicator, vtgModeIndicator); // ------------------- @@ -1382,8 +1447,19 @@ void loc_nmea_generate_pos(const UlpLocation &location, pMarker = sentence_RMC; lengthRemaining = sizeof(sentence_RMC); - length = snprintf(pMarker, lengthRemaining, "$%sRMC,%02d%02d%02d.%02d,A," , - talker, utcHours, utcMinutes, utcSeconds,utcMSeconds/10); + bool validFix = ((0 != sv_cache_info.gps_used_mask) || + (0 != sv_cache_info.glo_used_mask) || + (0 != sv_cache_info.gal_used_mask) || + (0 != sv_cache_info.qzss_used_mask) || + (0 != sv_cache_info.bds_used_mask)); + + if (validFix) { + length = snprintf(pMarker, lengthRemaining, "$%sRMC,%02d%02d%02d.%02d,A,", + talker, utcHours, utcMinutes, utcSeconds, utcMSeconds/10); + } else { + length = snprintf(pMarker, lengthRemaining, "$%sRMC,%02d%02d%02d.%02d,V,", + talker, utcHours, utcMinutes, utcSeconds, utcMSeconds/10); + } if (length < 0 || length >= lengthRemaining) { @@ -1524,8 +1600,6 @@ void loc_nmea_generate_pos(const UlpLocation &location, // hardcode Navigation Status field to 'V' length = snprintf(pMarker, lengthRemaining, ",%c", 'V'); - pMarker += length; - lengthRemaining -= length; length = loc_nmea_put_checksum(sentence_RMC, sizeof(sentence_RMC)); @@ -1772,12 +1846,12 @@ void loc_nmea_generate_pos(const UlpLocation &location, svUsedCount = MAX_SATELLITES_IN_USE; if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_DOP) { - length = snprintf(pMarker, lengthRemaining, "%c,%02d,%.1f,", + length = snprintf(pMarker, lengthRemaining, "%s,%02d,%.1f,", ggaGpsQuality, svUsedCount, locationExtended.hdop); } else { // no hdop - length = snprintf(pMarker, lengthRemaining, "%c,%02d,,", + length = snprintf(pMarker, lengthRemaining, "%s,%02d,,", ggaGpsQuality, svUsedCount); } diff --git a/utils/loc_nmea.h b/utils/loc_nmea.h index c6c83db..a9cafb7 100644 --- a/utils/loc_nmea.h +++ b/utils/loc_nmea.h @@ -79,6 +79,7 @@ void loc_nmea_generate_pos(const UlpLocation &location, const GpsLocationExtended &locationExtended, const LocationSystemInfo &systemInfo, unsigned char generate_nmea, + bool custom_gga_fix_quality, std::vector<std::string> &nmeaArraystr); #define DEBUG_NMEA_MINSIZE 6 diff --git a/utils/log_util.h b/utils/log_util.h index ed7e19e..192baeb 100644 --- a/utils/log_util.h +++ b/utils/log_util.h @@ -176,6 +176,7 @@ extern char* get_timestamp(char* str, unsigned long buf_size); #define LOG_I(ID, WHAT, SPEC, VAL) LOG_(LOC_LOGI, ID, WHAT, SPEC, VAL) #define LOG_V(ID, WHAT, SPEC, VAL) LOG_(LOC_LOGV, ID, WHAT, SPEC, VAL) #define LOG_E(ID, WHAT, SPEC, VAL) LOG_(LOC_LOGE, ID, WHAT, SPEC, VAL) +#define LOG_D(ID, WHAT, SPEC, VAL) LOG_(LOC_LOGD, ID, WHAT, SPEC, VAL) #define ENTRY_LOG() LOG_V(ENTRY_TAG, __FUNCTION__, %s, "") #define EXIT_LOG(SPEC, VAL) LOG_V(EXIT_TAG, __FUNCTION__, SPEC, VAL) @@ -193,6 +194,8 @@ extern char* get_timestamp(char* str, unsigned long buf_size); #define EXIT_LOG_CALLFLOW(SPEC, VAL) LOG_I(TO_MODEM, __FUNCTION__, SPEC, VAL) // Used for logging callflow from Modem(TO_MODEM, __FUNCTION__, %s, "") #define MODEM_LOG_CALLFLOW(SPEC, VAL) LOG_I(FROM_MODEM, __FUNCTION__, SPEC, VAL) +// Used for logging high frequency callflow from Modem(TO_MODEM, __FUNCTION__, %s, "") +#define MODEM_LOG_CALLFLOW_DEBUG(SPEC, VAL) LOG_D(FROM_MODEM, __FUNCTION__, SPEC, VAL) // Used for logging callflow to Android Framework #define CALLBACK_LOG_CALLFLOW(CB, SPEC, VAL) LOG_I(TO_AFW, CB, SPEC, VAL) |