Merge "force undefined symbols to treat as errors"
diff --git a/android/Android.mk b/android/Android.mk
index b493f5e..000cd59 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -12,6 +12,7 @@
GnssMeasurement.cpp \
GnssNi.cpp \
GnssConfiguration.cpp \
+ GnssDebug.cpp \
LOCAL_SRC_FILES += \
location_api/LocationUtil.cpp \
diff --git a/android/Gnss.cpp b/android/Gnss.cpp
index 1412883..d17077c 100644
--- a/android/Gnss.cpp
+++ b/android/Gnss.cpp
@@ -121,6 +121,7 @@
if (api != nullptr) {
api->gnssUpdateCallbacks(mGnssCbIface, mGnssNiCbIface);
api->locAPIEnable(LOCATION_TECHNOLOGY_TYPE_GNSS);
+ api->requestCapabilities();
}
return true;
}
@@ -309,6 +310,12 @@
return mGnssBatching;
}
+Return<sp<IGnssDebug>> Gnss::getExtensionGnssDebug() {
+ ENTRY_LOG_CALLFLOW();
+ mGnssDebug = new GnssDebug(this);
+ return mGnssDebug;
+}
+
IGnss* HIDL_FETCH_IGnss(const char* hal) {
ENTRY_LOG_CALLFLOW();
IGnss* iface = nullptr;
diff --git a/android/Gnss.h b/android/Gnss.h
index b338b08..99c5e40 100644
--- a/android/Gnss.h
+++ b/android/Gnss.h
@@ -27,6 +27,7 @@
#include <GnssGeofencing.h>
#include <GnssMeasurement.h>
#include <GnssNi.h>
+#include <GnssDebug.h>
#include <android/hardware/gnss/1.0/IGnss.h>
#include <hidl/Status.h>
@@ -102,9 +103,7 @@
return nullptr;
}
- inline Return<sp<IGnssDebug>> getExtensionGnssDebug() override {
- return nullptr;
- }
+ Return<sp<IGnssDebug>> getExtensionGnssDebug() override;
// These methods are not part of the IGnss base class.
GnssAPIClient* getApi();
@@ -130,6 +129,7 @@
sp<GnssConfiguration> mGnssConfig = nullptr;
sp<GnssGeofencing> mGnssGeofencingIface = nullptr;
sp<GnssBatching> mGnssBatching = nullptr;
+ sp<IGnssDebug> mGnssDebug = nullptr;
GnssAPIClient* mApi = nullptr;
sp<IGnssCallback> mGnssCbIface = nullptr;
diff --git a/android/GnssDebug.cpp b/android/GnssDebug.cpp
new file mode 100644
index 0000000..3ab94d3
--- /dev/null
+++ b/android/GnssDebug.cpp
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "LocSvc_GnssDebugInterface"
+
+#include <log/log.h>
+#include <log_util.h>
+#include "Gnss.h"
+#include "GnssDebug.h"
+#include "LocationUtil.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::hidl_vec;
+
+GnssDebug::GnssDebug(Gnss* gnss) : mGnss(gnss)
+{
+}
+
+/*
+ * This methods requests position, time and satellite ephemeris debug information
+ * from the HAL.
+ *
+ * @return void
+*/
+Return<void> GnssDebug::getDebugData(getDebugData_cb _hidl_cb)
+{
+ LOC_LOGI("GnssDebug - 0317a");
+
+ DebugData data = { };
+
+ if((nullptr == mGnss) || (nullptr == mGnss->getGnssInterface())){
+ LOC_LOGE("GnssDebug - Null GNSS interface");
+ _hidl_cb(data);
+ return Void();
+ }
+
+ // get debug report snapshot via hal interface
+ GnssDebugReport reports = { };
+ mGnss->getGnssInterface()->getDebugReport(reports);
+
+ // location block
+ data.position.valid = true;
+ data.position.latitudeDegrees = reports.mLocation.mLocation.latitude;
+ data.position.longitudeDegrees = reports.mLocation.mLocation.longitude;
+ data.position.altitudeMeters = reports.mLocation.mLocation.altitude;
+ data.position.speedMetersPerSec = (double)(reports.mLocation.mLocation.speed);
+ data.position.bearingDegrees = (double)(reports.mLocation.mLocation.bearing);
+ data.position.horizontalAccuracyMeters = (double)(reports.mLocation.mLocation.accuracy);
+ data.position.verticalAccuracyMeters = reports.mLocation.verticalAccuracyMeters;
+ data.position.speedAccuracyMetersPerSecond = reports.mLocation.speedAccuracyMetersPerSecond;
+ data.position.bearingAccuracyDegrees = reports.mLocation.bearingAccuracyDegrees;
+
+ LOC_LOGV("GnssDebug - lat=%f lon=%f", data.position.latitudeDegrees, data.position.longitudeDegrees);
+
+ timeval tv_now, tv_report;
+ tv_report.tv_sec = reports.mLocation.mLocation.timestamp / 1000ULL;
+ tv_report.tv_usec = (reports.mLocation.mLocation.timestamp % 1000ULL) * 1000ULL;
+ gettimeofday(&tv_now, NULL);
+ data.position.ageSeconds =
+ (tv_now.tv_sec - tv_report.tv_sec) + (float)((tv_now.tv_usec - tv_report.tv_usec)) / 1000000;
+
+ LOC_LOGV("GnssDebug - time now=%lld:%lld", tv_now.tv_sec, tv_now.tv_usec);
+ LOC_LOGV("GnssDebug - time rep=%lld:%lld", tv_report.tv_sec, tv_report.tv_usec);
+ LOC_LOGV("GnssDebug - age=%f", data.position.ageSeconds);
+
+ // time block
+ data.time.valid = true;
+ data.time.timeEstimate = reports.mTime.timeEstimate;
+ data.time.timeUncertaintyNs = reports.mTime.timeUncertaintyNs;
+
+ LOC_LOGV("GnssDebug - timeestimate=%lld", data.time.timeEstimate);
+
+ // satellite data block
+ SatelliteData s = { };
+ std::vector<SatelliteData> s_array = { };
+
+ for (uint32_t i=0; i<reports.mSatelliteInfo.size(); i++) {
+ memset(&s, 0, sizeof(s));
+ s.svid = reports.mSatelliteInfo[i].svid;
+ convertGnssConstellationType(reports.mSatelliteInfo[i].constellation, s.constellation);
+ s.ephemerisType = SatelliteEphemerisType::UNKNOWN;
+ s.ephemerisAgeSeconds = reports.mSatelliteInfo[i].ephemerisAgeSeconds;
+ s_array.push_back(s);
+ }
+ data.satelliteDataArray = s_array;
+ LOC_LOGV("GnssDebug - satellite=%d", data.satelliteDataArray.size());
+
+ // callback HIDL with collected debug data
+ _hidl_cb(data);
+
+ LOC_LOGV("GnssDebug - done");
+ return Void();
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/android/GnssDebug.h b/android/GnssDebug.h
new file mode 100644
index 0000000..7d29131
--- /dev/null
+++ b/android/GnssDebug.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GNSS_V1_1_GNSSDEBUG_H
+#define ANDROID_HARDWARE_GNSS_V1_1_GNSSDEBUG_H
+
+
+#include <android/hardware/gnss/1.0/IGnssDebug.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IGnssDebug;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+/* Interface for GNSS Debug support. */
+struct Gnss;
+struct GnssDebug : public IGnssDebug {
+ GnssDebug(Gnss* gnss);
+ ~GnssDebug() {};
+
+ /*
+ * Methods from ::android::hardware::gnss::V1_0::IGnssDebug follow.
+ * These declarations were generated from IGnssDebug.hal.
+ */
+ Return<void> getDebugData(getDebugData_cb _hidl_cb) override;
+
+private:
+ Gnss* mGnss = nullptr;
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V1_1_GNSSDEBUG_H
diff --git a/android/location_api/GeofenceAPIClient.cpp b/android/location_api/GeofenceAPIClient.cpp
index 5be1cff..ee4bfc3 100644
--- a/android/location_api/GeofenceAPIClient.cpp
+++ b/android/location_api/GeofenceAPIClient.cpp
@@ -100,7 +100,10 @@
data.longitude = longitude;
data.radius = radius_meters;
- locAPIAddGeofences(1, &geofence_id, &options, &data);
+ LocationError err = (LocationError)locAPIAddGeofences(1, &geofence_id, &options, &data);
+ if (LOCATION_ERROR_SUCCESS != err) {
+ onAddGeofencesCb(1, &err, &geofence_id);
+ }
}
void GeofenceAPIClient::geofencePause(uint32_t geofence_id)
diff --git a/android/location_api/GnssAPIClient.cpp b/android/location_api/GnssAPIClient.cpp
index b4f0406..4cb3f7d 100644
--- a/android/location_api/GnssAPIClient.cpp
+++ b/android/location_api/GnssAPIClient.cpp
@@ -49,7 +49,8 @@
LocationAPIClientBase(),
mGnssCbIface(nullptr),
mGnssNiCbIface(nullptr),
- mLocationCapabilitiesMask(0)
+ mLocationCapabilitiesMask(0),
+ mLocationCapabilitiesCached(false)
{
LOC_LOGD("%s]: (%p %p)", __FUNCTION__, &gpsCb, &niCb);
@@ -218,11 +219,20 @@
locAPIGnssUpdateConfig(gnssConfig);
}
+void GnssAPIClient::requestCapabilities() {
+ // only send capablities if it's already cached, otherwise the first time LocationAPI
+ // is initialized, capabilities will be sent by LocationAPI
+ if (mLocationCapabilitiesCached) {
+ onCapabilitiesCb(mLocationCapabilitiesMask);
+ }
+}
+
// callbacks
void GnssAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)
{
LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask);
mLocationCapabilitiesMask = capabilitiesMask;
+ mLocationCapabilitiesCached = true;
if (mGnssCbIface != nullptr) {
uint32_t data = 0;
if ((capabilitiesMask & LOCATION_CAPABILITIES_TIME_BASED_TRACKING_BIT) ||
diff --git a/android/location_api/GnssAPIClient.h b/android/location_api/GnssAPIClient.h
index 1809c09..d447157 100644
--- a/android/location_api/GnssAPIClient.h
+++ b/android/location_api/GnssAPIClient.h
@@ -74,6 +74,7 @@
inline LocationCapabilitiesMask gnssGetCapabilities() const {
return mLocationCapabilitiesMask;
}
+ void requestCapabilities();
// callbacks we are interested in
void onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask) final;
@@ -90,6 +91,7 @@
sp<IGnssNiCallback> mGnssNiCbIface;
LocationCapabilitiesMask mLocationCapabilitiesMask;
+ bool mLocationCapabilitiesCached;
LocationOptions mLocationOptions;
};
diff --git a/android/location_api/LocationUtil.cpp b/android/location_api/LocationUtil.cpp
index dbafe5d..d782375 100644
--- a/android/location_api/LocationUtil.cpp
+++ b/android/location_api/LocationUtil.cpp
@@ -46,21 +46,23 @@
out.gnssLocationFlags |= GnssLocationFlags::HAS_SPEED;
if (in.flags & LOCATION_HAS_BEARING_BIT)
out.gnssLocationFlags |= GnssLocationFlags::HAS_BEARING;
- if (in.flags & LOCATION_HAS_ACCURACY_BIT) {
+ if (in.flags & LOCATION_HAS_ACCURACY_BIT)
out.gnssLocationFlags |= GnssLocationFlags::HAS_HORIZONTAL_ACCURACY;
- //out.gnssLocationFlags |= GnssLocationFlags::HAS_VERTICAL_ACCURACY;
- //out.gnssLocationFlags |= GnssLocationFlags::HAS_SPEED_ACCURACY;
- //out.gnssLocationFlags |= GnssLocationFlags::HAS_BEARING_ACCURACY;
- }
+ if (in.flags & LOCATION_HAS_VERTICAL_ACCURACY_BIT)
+ out.gnssLocationFlags |= GnssLocationFlags::HAS_VERTICAL_ACCURACY;
+ if (in.flags & LOCATION_HAS_SPEED_ACCURACY_BIT)
+ out.gnssLocationFlags |= GnssLocationFlags::HAS_SPEED_ACCURACY;
+ if (in.flags & LOCATION_HAS_BEARING_ACCURACY_BIT)
+ out.gnssLocationFlags |= GnssLocationFlags::HAS_BEARING_ACCURACY;
out.latitudeDegrees = in.latitude;
out.longitudeDegrees = in.longitude;
out.altitudeMeters = in.altitude;
out.speedMetersPerSec = in.speed;
out.bearingDegrees = in.bearing;
out.horizontalAccuracyMeters = in.accuracy;
- //out.verticalAccuracyMeters = in.accuracy;
- //out.speedAccuracyMetersPerSecond = in.accuracy;
- //out.bearingAccuracyDegrees = in.accuracy;
+ out.verticalAccuracyMeters = in.verticalAccuracy;
+ out.speedAccuracyMetersPerSecond = in.speedAccuracy;
+ out.bearingAccuracyDegrees = in.bearingAccuracy;
out.timestamp = static_cast<GnssUtcTime>(in.timestamp);
}
diff --git a/core/Android.mk b/core/Android.mk
index b260b1d..b8e25a9 100644
--- a/core/Android.mk
+++ b/core/Android.mk
@@ -30,7 +30,8 @@
LocAdapterBase.cpp \
ContextBase.cpp \
LocDualContext.cpp \
- loc_core_log.cpp
+ loc_core_log.cpp \
+ SystemStatus.cpp
LOCAL_CFLAGS += \
-fno-short-enums \
@@ -53,7 +54,8 @@
gps_extended_c.h \
gps_extended.h \
loc_core_log.h \
- LocAdapterProxyBase.h
+ LocAdapterProxyBase.h \
+ SystemStatus.h
include $(BUILD_SHARED_LIBRARY)
diff --git a/core/ContextBase.cpp b/core/ContextBase.cpp
index a9858e2..849a7d3 100644
--- a/core/ContextBase.cpp
+++ b/core/ContextBase.cpp
@@ -96,7 +96,7 @@
mGps_conf.NMEA_PROVIDER = 0;
mGps_conf.GPS_LOCK = 0;
mGps_conf.SUPL_VER = 0x10000;
- mGps_conf.SUPL_MODE = 0x3;
+ mGps_conf.SUPL_MODE = 0x1;
mGps_conf.SUPL_ES = 0;
mGps_conf.CAPABILITIES = 0x7;
/* LTE Positioning Profile configuration is disable by default*/
@@ -145,10 +145,8 @@
/* inject supl config to modem with config values from config.xml or gps.conf, default 1 */
mGps_conf.AGPS_CONFIG_INJECT = 1;
- const char* GPS_CONF_FILE = "/etc/gps.conf";
- const char* SAP_CONF_FILE = "/etc/sap.conf";
- UTIL_READ_CONF(GPS_CONF_FILE, mGps_conf_table);
- UTIL_READ_CONF(SAP_CONF_FILE, mSap_conf_table);
+ UTIL_READ_CONF(LOC_PATH_GPS_CONF, mGps_conf_table);
+ UTIL_READ_CONF(LOC_PATH_SAP_CONF, mSap_conf_table);
}
uint32_t ContextBase::getCarrierCapabilities() {
diff --git a/core/LocApiBase.cpp b/core/LocApiBase.cpp
index 3bbbf8f..0036d88 100644
--- a/core/LocApiBase.cpp
+++ b/core/LocApiBase.cpp
@@ -26,7 +26,7 @@
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
-#define LOG_NDDEBUG 0
+#define LOG_NDEBUG 0 //Define to enable LOGV
#define LOG_TAG "LocSvc_LocApiBase"
#include <dlfcn.h>
diff --git a/core/LocDualContext.cpp b/core/LocDualContext.cpp
index fd465e9..c6a8896 100644
--- a/core/LocDualContext.cpp
+++ b/core/LocDualContext.cpp
@@ -35,6 +35,7 @@
#include <msg_q.h>
#include <platform_lib_log_util.h>
#include <loc_log.h>
+#include <SystemStatus.h>
namespace loc_core {
@@ -56,6 +57,7 @@
ContextBase* LocDualContext::mFgContext = NULL;
ContextBase* LocDualContext::mBgContext = NULL;
ContextBase* LocDualContext::mInjectContext = NULL;
+SystemStatus* LocDualContext::mSystemStatus = NULL;
// the name must be shorter than 15 chars
const char* LocDualContext::mLocationHalName = "Loc_hal_worker";
#ifndef USE_GLIB
@@ -147,4 +149,14 @@
{
}
+SystemStatus* LocDualContext::getSystemStatus(void)
+{
+ pthread_mutex_lock(&LocDualContext::mGetLocContextMutex);
+ if (NULL == mSystemStatus) {
+ mSystemStatus = new SystemStatus();
+ }
+ pthread_mutex_unlock(&LocDualContext::mGetLocContextMutex);
+ return mSystemStatus;
+}
+
}
diff --git a/core/LocDualContext.h b/core/LocDualContext.h
index ce77a1a..7642152 100644
--- a/core/LocDualContext.h
+++ b/core/LocDualContext.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2014, 2017 The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -36,6 +36,8 @@
namespace loc_core {
+class SystemStatus;
+
class LocDualContext : public ContextBase {
static const MsgTask* mMsgTask;
static ContextBase* mFgContext;
@@ -45,6 +47,7 @@
const char* name, bool joinable = true);
static const MsgTask* getMsgTask(const char* name, bool joinable = true);
static pthread_mutex_t mGetLocContextMutex;
+ static SystemStatus* mSystemStatus;
protected:
LocDualContext(const MsgTask* msgTask,
@@ -69,6 +72,7 @@
}
static void injectFeatureConfig(ContextBase *context);
+ static SystemStatus* getSystemStatus(void);
};
}
diff --git a/core/Makefile.am b/core/Makefile.am
index 0a9d3e2..ccbff94 100644
--- a/core/Makefile.am
+++ b/core/Makefile.am
@@ -16,14 +16,16 @@
gps_extended_c.h \
gps_extended.h \
loc_core_log.h \
- LocAdapterProxyBase.h
+ LocAdapterProxyBase.h \
+ SystemStatus.h
libloc_core_la_c_sources = \
LocApiBase.cpp \
LocAdapterBase.cpp \
ContextBase.cpp \
LocDualContext.cpp \
- loc_core_log.cpp
+ loc_core_log.cpp \
+ SystemStatus.cpp
library_includedir = $(pkgincludedir)/core
diff --git a/core/SystemStatus.cpp b/core/SystemStatus.cpp
new file mode 100644
index 0000000..7791410
--- /dev/null
+++ b/core/SystemStatus.cpp
@@ -0,0 +1,1488 @@
+/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation, nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#define LOG_TAG "LocSvc_SystemStatus"
+
+#include <string>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+#include <pthread.h>
+#include <platform_lib_log_util.h>
+#include <SystemStatus.h>
+
+namespace loc_core
+{
+
+/******************************************************************************
+ SystemStatusNmeaBase - base class for all NMEA parsers
+******************************************************************************/
+class SystemStatusNmeaBase
+{
+protected:
+ std::vector<std::string> mField;
+ timespec setUtcTime(std::string sutctime);
+
+public:
+ static const uint32_t NMEA_MINSIZE = 6;
+ static const uint32_t NMEA_MAXSIZE = 256;
+
+ SystemStatusNmeaBase(const char *str_in, uint32_t len_in)
+ {
+ // check size and talker
+ if (len_in > NMEA_MAXSIZE || len_in < NMEA_MINSIZE || (str_in[0] != '$')) {
+ return;
+ }
+
+ std::string parser(str_in);
+ std::string::size_type index = 0;
+
+ // verify checksum field
+ index = parser.find("*");
+ if (index == std::string::npos) {
+ return;
+ }
+ parser[index] = ',';
+
+ // tokenize parser
+ while (1) {
+ std::string str;
+ index = parser.find(",");
+ if (index == std::string::npos) {
+ break;
+ }
+ str = parser.substr(0, index);
+ parser = parser.substr(index + 1);
+ mField.push_back(str);
+ }
+ }
+
+ virtual ~SystemStatusNmeaBase() { }
+};
+
+timespec SystemStatusNmeaBase::setUtcTime(std::string sutctime)
+{
+ timespec ts = { 0ULL, 0ULL };
+ uint64_t utctime_ns = atof(sutctime.c_str()) * 1000000000ULL;
+ ts.tv_nsec = utctime_ns % 1000000000ULL;
+ uint64_t utctime_s = utctime_ns / 1000000000ULL;
+
+ uint64_t hour = utctime_s / 10000ULL;
+ uint64_t min = (utctime_s / 100LL) % 100ULL;
+ uint64_t sec = utctime_s % 100ULL;
+ ts.tv_sec = hour * 3600ULL + min * 60ULL + sec;
+
+ timeval tv;
+ gettimeofday(&tv, NULL);
+ ts.tv_sec += (uint64_t(tv.tv_sec / (24ULL * 60ULL * 60ULL))) * (24ULL * 60ULL * 60ULL);
+ return ts;
+}
+
+/******************************************************************************
+ SystemStatusPQWM1
+******************************************************************************/
+class SystemStatusPQWM1
+{
+public:
+ timespec mUtcTime;
+ uint16_t mGpsWeek; // x1
+ uint32_t mGpsTowMs; // x2
+ uint8_t mTimeValid; // x3
+ uint8_t mTimeSource; // x4
+ int32_t mTimeUnc; // x5
+ int32_t mClockFreqBias; // x6
+ int32_t mClockFreqBiasUnc; // x7
+ uint8_t mXoState; // x8
+ int32_t mPgaGain; // x9
+ uint32_t mGpsBpAmpI; // xA
+ uint32_t mGpsBpAmpQ; // xB
+ uint32_t mAdcI; // xC
+ uint32_t mAdcQ; // xD
+ uint32_t mJammerGps; // xE
+ uint32_t mJammerGlo; // xF
+ uint32_t mJammerBds; // x10
+ uint32_t mJammerGal; // x11
+ uint32_t mRecErrorRecovery; // x12
+};
+
+// parser
+class SystemStatusPQWM1parser : public SystemStatusNmeaBase
+{
+private:
+ enum
+ {
+ eTalker = 0,
+ eGpsWeek = 1,
+ eGpsTowMs = 2,
+ eTimeValid = 3,
+ eTimeSource = 4,
+ eTimeUnc = 5,
+ eClockFreqBias = 6,
+ eClockFreqBiasUnc = 7,
+ eXoState = 8,
+ ePgaGain = 9,
+ eGpsBpAmpI = 10,
+ eGpsBpAmpQ = 11,
+ eAdcI = 12,
+ eAdcQ = 13,
+ eJammerGps = 14,
+ eJammerGlo = 15,
+ eJammerBds = 16,
+ eJammerGal = 17,
+ eRecErrorRecovery = 18,
+ eMax = eRecErrorRecovery
+ };
+ SystemStatusPQWM1 mM1;
+
+public:
+ inline uint16_t getGpsWeek() { return mM1.mGpsWeek; }
+ inline uint32_t getGpsTowMs() { return mM1.mGpsTowMs; }
+ inline uint8_t getTimeValid() { return mM1.mTimeValid; }
+ inline uint8_t getTimeSource() { return mM1.mTimeSource; }
+ inline int32_t getTimeUnc() { return mM1.mTimeUnc; }
+ inline int32_t getClockFreqBias() { return mM1.mClockFreqBias; }
+ inline int32_t getClockFreqBiasUnc() { return mM1.mClockFreqBiasUnc; }
+ inline uint8_t getXoState() { return mM1.mXoState;}
+ inline int32_t getPgaGain() { return mM1.mPgaGain; }
+ inline uint32_t getGpsBpAmpI() { return mM1.mGpsBpAmpI; }
+ inline uint32_t getGpsBpAmpQ() { return mM1.mGpsBpAmpQ; }
+ inline uint32_t getAdcI() { return mM1.mAdcI; }
+ inline uint32_t getAdcQ() { return mM1.mAdcQ; }
+ inline uint32_t getJammerGps() { return mM1.mJammerGps; }
+ inline uint32_t getJammerGlo() { return mM1.mJammerGlo; }
+ inline uint32_t getJammerBds() { return mM1.mJammerBds; }
+ inline uint32_t getJammerGal() { return mM1.mJammerGal; }
+ inline uint32_t getRecErrorRecovery() { return mM1.mRecErrorRecovery; }
+
+ SystemStatusPQWM1parser(const char *str_in, uint32_t len_in)
+ : SystemStatusNmeaBase(str_in, len_in)
+ {
+ if (mField.size() < eMax) {
+ return;
+ }
+ memset(&mM1, 0, sizeof(mM1));
+
+ timeval tv;
+ gettimeofday(&tv, NULL);
+ mM1.mUtcTime.tv_sec = tv.tv_sec;
+ mM1.mUtcTime.tv_nsec = tv.tv_usec * 1000UL;
+ mM1.mGpsWeek = atoi(mField[eGpsWeek].c_str());
+ mM1.mGpsTowMs = atoi(mField[eGpsTowMs].c_str());
+ mM1.mTimeValid = atoi(mField[eTimeValid].c_str());
+ mM1.mTimeSource = atoi(mField[eTimeSource].c_str());
+ mM1.mTimeUnc = atoi(mField[eTimeUnc].c_str());
+ mM1.mClockFreqBias = atoi(mField[eClockFreqBias].c_str());
+ mM1.mClockFreqBiasUnc = atoi(mField[eClockFreqBiasUnc].c_str());
+ mM1.mXoState = atoi(mField[eXoState].c_str());
+ mM1.mPgaGain = atoi(mField[ePgaGain].c_str());
+ mM1.mGpsBpAmpI = atoi(mField[eGpsBpAmpI].c_str());
+ mM1.mGpsBpAmpQ = atoi(mField[eGpsBpAmpQ].c_str());
+ mM1.mAdcI = atoi(mField[eAdcI].c_str());
+ mM1.mAdcQ = atoi(mField[eAdcQ].c_str());
+ mM1.mJammerGps = atoi(mField[eJammerGps].c_str());
+ mM1.mJammerGlo = atoi(mField[eJammerGlo].c_str());
+ mM1.mJammerBds = atoi(mField[eJammerBds].c_str());
+ mM1.mJammerGal = atoi(mField[eJammerGal].c_str());
+ mM1.mRecErrorRecovery = atoi(mField[eRecErrorRecovery].c_str());
+ }
+
+ inline SystemStatusPQWM1& get() { return mM1;} //getparser
+};
+
+/******************************************************************************
+ SystemStatusPQWP1
+******************************************************************************/
+class SystemStatusPQWP1
+{
+public:
+ timespec mUtcTime;
+ uint8_t mEpiValidity; // x4
+ float mEpiLat; // x5
+ float mEpiLon; // x6
+ float mEpiAlt; // x7
+ float mEpiHepe; // x8
+ float mEpiAltUnc; // x9
+ uint8_t mEpiSrc; // x10
+};
+
+class SystemStatusPQWP1parser : public SystemStatusNmeaBase
+{
+private:
+ enum
+ {
+ eTalker = 0,
+ eUtcTime = 1,
+ eEpiValidity = 2,
+ eEpiLat = 3,
+ eEpiLon = 4,
+ eEpiAlt = 5,
+ eEpiHepe = 6,
+ eEpiAltUnc = 7,
+ eEpiSrc = 8,
+ eMax = eEpiSrc
+ };
+ SystemStatusPQWP1 mP1;
+
+public:
+ inline timespec getUtcTime() { return mP1.mUtcTime; }
+ inline uint8_t getEpiValidity() { return mP1.mEpiValidity; }
+ inline float getEpiLat() { return mP1.mEpiLat; }
+ inline float getEpiLon() { return mP1.mEpiLon; }
+ inline float getEpiAlt() { return mP1.mEpiAlt; }
+ inline float getEpiHepe() { return mP1.mEpiHepe; }
+ inline float getEpiAltUnc() { return mP1.mEpiAltUnc; }
+ inline uint8_t getEpiSrc() { return mP1.mEpiSrc; }
+
+ SystemStatusPQWP1parser(const char *str_in, uint32_t len_in)
+ : SystemStatusNmeaBase(str_in, len_in)
+ {
+ if (mField.size() < eMax) {
+ return;
+ }
+ memset(&mP1, 0, sizeof(mP1));
+ mP1.mUtcTime = setUtcTime(mField[eUtcTime]);
+ mP1.mEpiValidity = strtol(mField[eEpiValidity].c_str(), NULL, 16);
+ mP1.mEpiLat = atof(mField[eEpiLat].c_str());
+ mP1.mEpiLon = atof(mField[eEpiLon].c_str());
+ mP1.mEpiAlt = atof(mField[eEpiAlt].c_str());
+ mP1.mEpiHepe = atoi(mField[eEpiHepe].c_str());
+ mP1.mEpiAltUnc = atof(mField[eEpiAltUnc].c_str());
+ mP1.mEpiSrc = atoi(mField[eEpiSrc].c_str());
+ }
+
+ inline SystemStatusPQWP1& get() { return mP1;}
+};
+
+/******************************************************************************
+ SystemStatusPQWP2
+******************************************************************************/
+class SystemStatusPQWP2
+{
+public:
+ timespec mUtcTime;
+ float mBestLat; // x4
+ float mBestLon; // x5
+ float mBestAlt; // x6
+ float mBestHepe; // x7
+ float mBestAltUnc; // x8
+};
+
+class SystemStatusPQWP2parser : public SystemStatusNmeaBase
+{
+private:
+ enum
+ {
+ eTalker = 0,
+ eUtcTime = 1,
+ eBestLat = 2,
+ eBestLon = 3,
+ eBestAlt = 4,
+ eBestHepe = 5,
+ eBestAltUnc = 6,
+ eMax = eBestAltUnc
+ };
+ SystemStatusPQWP2 mP2;
+
+public:
+ inline float getBestLat() { return mP2.mBestLat; }
+ inline float getBestLon() { return mP2.mBestLon; }
+ inline float getBestAlt() { return mP2.mBestAlt; }
+ inline float getBestHepe() { return mP2.mBestHepe; }
+ inline float getBestAltUnc() { return mP2.mBestAltUnc; }
+
+ SystemStatusPQWP2parser(const char *str_in, uint32_t len_in)
+ : SystemStatusNmeaBase(str_in, len_in)
+ {
+ if (mField.size() < eMax) {
+ return;
+ }
+ memset(&mP2, 0, sizeof(mP2));
+ mP2.mUtcTime = setUtcTime(mField[eUtcTime]);
+ mP2.mBestLat = atof(mField[eBestLat].c_str());
+ mP2.mBestLon = atof(mField[eBestLon].c_str());
+ mP2.mBestAlt = atof(mField[eBestAlt].c_str());
+ mP2.mBestHepe = atof(mField[eBestHepe].c_str());
+ mP2.mBestAltUnc = atof(mField[eBestAltUnc].c_str());
+ }
+
+ inline SystemStatusPQWP2& get() { return mP2;}
+};
+
+/******************************************************************************
+ SystemStatusPQWP3
+******************************************************************************/
+class SystemStatusPQWP3
+{
+public:
+ timespec mUtcTime;
+ uint8_t mXtraValidMask;
+ uint32_t mGpsXtraAge;
+ uint32_t mGloXtraAge;
+ uint32_t mBdsXtraAge;
+ uint32_t mGalXtraAge;
+ uint32_t mQzssXtraAge;
+ uint32_t mGpsXtraValid;
+ uint32_t mGloXtraValid;
+ uint64_t mBdsXtraValid;
+ uint64_t mGalXtraValid;
+ uint8_t mQzssXtraValid;
+};
+
+class SystemStatusPQWP3parser : public SystemStatusNmeaBase
+{
+private:
+ enum
+ {
+ eTalker = 0,
+ eUtcTime = 1,
+ eXtraValidMask = 2,
+ eGpsXtraAge = 3,
+ eGloXtraAge = 4,
+ eBdsXtraAge = 5,
+ eGalXtraAge = 6,
+ eQzssXtraAge = 7,
+ eGpsXtraValid = 8,
+ eGloXtraValid = 9,
+ eBdsXtraValid = 10,
+ eGalXtraValid = 11,
+ eQzssXtraValid = 12,
+ eMax = eQzssXtraValid
+ };
+ SystemStatusPQWP3 mP3;
+
+public:
+ inline uint8_t getXtraValid() { return mP3.mXtraValidMask; }
+ inline uint32_t getGpsXtraAge() { return mP3.mGpsXtraAge; }
+ inline uint32_t getGloXtraAge() { return mP3.mGloXtraAge; }
+ inline uint32_t getBdsXtraAge() { return mP3.mBdsXtraAge; }
+ inline uint32_t getGalXtraAge() { return mP3.mGalXtraAge; }
+ inline uint32_t getQzssXtraAge() { return mP3.mQzssXtraAge; }
+ inline uint32_t getGpsXtraValid() { return mP3.mGpsXtraValid; }
+ inline uint32_t getGloXtraValid() { return mP3.mGloXtraValid; }
+ inline uint64_t getBdsXtraValid() { return mP3.mBdsXtraValid; }
+ inline uint64_t getGalXtraValid() { return mP3.mGalXtraValid; }
+ inline uint8_t getQzssXtraValid() { return mP3.mQzssXtraValid; }
+
+ SystemStatusPQWP3parser(const char *str_in, uint32_t len_in)
+ : SystemStatusNmeaBase(str_in, len_in)
+ {
+ if (mField.size() < eMax) {
+ return;
+ }
+ memset(&mP3, 0, sizeof(mP3));
+ mP3.mUtcTime = setUtcTime(mField[eUtcTime]);
+ mP3.mXtraValidMask = strtol(mField[eXtraValidMask].c_str(), NULL, 16);
+ mP3.mGpsXtraAge = atoi(mField[eGpsXtraAge].c_str());
+ mP3.mGloXtraAge = atoi(mField[eGloXtraAge].c_str());
+ mP3.mBdsXtraAge = atoi(mField[eBdsXtraAge].c_str());
+ mP3.mGalXtraAge = atoi(mField[eGalXtraAge].c_str());
+ mP3.mQzssXtraAge = atoi(mField[eQzssXtraAge].c_str());
+ mP3.mGpsXtraValid = strtol(mField[eGpsXtraValid].c_str(), NULL, 16);
+ mP3.mGloXtraValid = strtol(mField[eGloXtraValid].c_str(), NULL, 16);
+ mP3.mBdsXtraValid = strtol(mField[eBdsXtraValid].c_str(), NULL, 16);
+ mP3.mGalXtraValid = strtol(mField[eGalXtraValid].c_str(), NULL, 16);
+ mP3.mQzssXtraValid = strtol(mField[eQzssXtraValid].c_str(), NULL, 16);
+ }
+
+ inline SystemStatusPQWP3& get() { return mP3;}
+};
+
+/******************************************************************************
+ SystemStatusPQWP4
+******************************************************************************/
+class SystemStatusPQWP4
+{
+public:
+ timespec mUtcTime;
+ uint32_t mGpsEpheValid;
+ uint32_t mGloEpheValid;
+ uint64_t mBdsEpheValid;
+ uint64_t mGalEpheValid;
+ uint8_t mQzssEpheValid;
+};
+
+class SystemStatusPQWP4parser : public SystemStatusNmeaBase
+{
+private:
+ enum
+ {
+ eTalker = 0,
+ eUtcTime = 1,
+ eGpsEpheValid = 2,
+ eGloEpheValid = 3,
+ eBdsEpheValid = 4,
+ eGalEpheValid = 5,
+ eQzssEpheValid = 6,
+ eMax = eQzssEpheValid
+ };
+ SystemStatusPQWP4 mP4;
+
+public:
+ inline uint32_t getGpsEpheValid() { return mP4.mGpsEpheValid; }
+ inline uint32_t getGloEpheValid() { return mP4.mGloEpheValid; }
+ inline uint64_t getBdsEpheValid() { return mP4.mBdsEpheValid; }
+ inline uint64_t getGalEpheValid() { return mP4.mGalEpheValid; }
+ inline uint8_t getQzssEpheValid() { return mP4.mQzssEpheValid; }
+
+ SystemStatusPQWP4parser(const char *str_in, uint32_t len_in)
+ : SystemStatusNmeaBase(str_in, len_in)
+ {
+ if (mField.size() < eMax) {
+ return;
+ }
+ memset(&mP4, 0, sizeof(mP4));
+ mP4.mUtcTime = setUtcTime(mField[eUtcTime]);
+ mP4.mGpsEpheValid = strtol(mField[eGpsEpheValid].c_str(), NULL, 16);
+ mP4.mGloEpheValid = strtol(mField[eGloEpheValid].c_str(), NULL, 16);
+ mP4.mBdsEpheValid = strtol(mField[eBdsEpheValid].c_str(), NULL, 16);
+ mP4.mGalEpheValid = strtol(mField[eGalEpheValid].c_str(), NULL, 16);
+ mP4.mQzssEpheValid = strtol(mField[eQzssEpheValid].c_str(), NULL, 16);
+ }
+
+ inline SystemStatusPQWP4& get() { return mP4;}
+};
+
+/******************************************************************************
+ SystemStatusPQWP5
+******************************************************************************/
+class SystemStatusPQWP5
+{
+public:
+ timespec mUtcTime;
+ uint32_t mGpsUnknownMask;
+ uint32_t mGloUnknownMask;
+ uint64_t mBdsUnknownMask;
+ uint64_t mGalUnknownMask;
+ uint8_t mQzssUnknownMask;
+ uint32_t mGpsGoodMask;
+ uint32_t mGloGoodMask;
+ uint64_t mBdsGoodMask;
+ uint64_t mGalGoodMask;
+ uint8_t mQzssGoodMask;
+ uint32_t mGpsBadMask;
+ uint32_t mGloBadMask;
+ uint64_t mBdsBadMask;
+ uint64_t mGalBadMask;
+ uint8_t mQzssBadMask;
+};
+
+class SystemStatusPQWP5parser : public SystemStatusNmeaBase
+{
+private:
+ enum
+ {
+ eTalker = 0,
+ eUtcTime = 1,
+ eGpsUnknownMask = 2,
+ eGloUnknownMask = 3,
+ eBdsUnknownMask = 4,
+ eGalUnknownMask = 5,
+ eQzssUnknownMask = 6,
+ eGpsGoodMask = 7,
+ eGloGoodMask = 8,
+ eBdsGoodMask = 9,
+ eGalGoodMask = 10,
+ eQzssGoodMask = 11,
+ eGpsBadMask = 12,
+ eGloBadMask = 13,
+ eBdsBadMask = 14,
+ eGalBadMask = 15,
+ eQzssBadMask = 16,
+ eMax = eQzssBadMask
+ };
+ SystemStatusPQWP5 mP5;
+
+public:
+ inline uint32_t getGpsUnknownMask() { return mP5.mGpsUnknownMask; }
+ inline uint32_t getGloUnknownMask() { return mP5.mGloUnknownMask; }
+ inline uint64_t getBdsUnknownMask() { return mP5.mBdsUnknownMask; }
+ inline uint64_t getGalUnknownMask() { return mP5.mGalUnknownMask; }
+ inline uint8_t getQzssUnknownMask() { return mP5.mQzssUnknownMask; }
+ inline uint32_t getGpsGoodMask() { return mP5.mGpsGoodMask; }
+ inline uint32_t getGloGoodMask() { return mP5.mGloGoodMask; }
+ inline uint64_t getBdsGoodMask() { return mP5.mBdsGoodMask; }
+ inline uint64_t getGalGoodMask() { return mP5.mGalGoodMask; }
+ inline uint8_t getQzssGoodMask() { return mP5.mQzssGoodMask; }
+ inline uint32_t getGpsBadMask() { return mP5.mGpsBadMask; }
+ inline uint32_t getGloBadMask() { return mP5.mGloBadMask; }
+ inline uint64_t getBdsBadMask() { return mP5.mBdsBadMask; }
+ inline uint64_t getGalBadMask() { return mP5.mGalBadMask; }
+ inline uint8_t getQzssBadMask() { return mP5.mQzssBadMask; }
+
+ SystemStatusPQWP5parser(const char *str_in, uint32_t len_in)
+ : SystemStatusNmeaBase(str_in, len_in)
+ {
+ if (mField.size() < eMax) {
+ return;
+ }
+ memset(&mP5, 0, sizeof(mP5));
+ mP5.mUtcTime = setUtcTime(mField[eUtcTime]);
+ mP5.mGpsUnknownMask = strtol(mField[eGpsUnknownMask].c_str(), NULL, 16);
+ mP5.mGloUnknownMask = strtol(mField[eGloUnknownMask].c_str(), NULL, 16);
+ mP5.mBdsUnknownMask = strtol(mField[eBdsUnknownMask].c_str(), NULL, 16);
+ mP5.mGalUnknownMask = strtol(mField[eGalUnknownMask].c_str(), NULL, 16);
+ mP5.mQzssUnknownMask = strtol(mField[eQzssUnknownMask].c_str(), NULL, 16);
+ mP5.mGpsGoodMask = strtol(mField[eGpsGoodMask].c_str(), NULL, 16);
+ mP5.mGloGoodMask = strtol(mField[eGloGoodMask].c_str(), NULL, 16);
+ mP5.mBdsGoodMask = strtol(mField[eBdsGoodMask].c_str(), NULL, 16);
+ mP5.mGalGoodMask = strtol(mField[eGalGoodMask].c_str(), NULL, 16);
+ mP5.mQzssGoodMask = strtol(mField[eQzssGoodMask].c_str(), NULL, 16);
+ mP5.mGpsBadMask = strtol(mField[eGpsBadMask].c_str(), NULL, 16);
+ mP5.mGloBadMask = strtol(mField[eGloBadMask].c_str(), NULL, 16);
+ mP5.mBdsBadMask = strtol(mField[eBdsBadMask].c_str(), NULL, 16);
+ mP5.mGalBadMask = strtol(mField[eGalBadMask].c_str(), NULL, 16);
+ mP5.mQzssBadMask = strtol(mField[eQzssBadMask].c_str(), NULL, 16);
+ }
+
+ inline SystemStatusPQWP5& get() { return mP5;}
+};
+
+/******************************************************************************
+ SystemStatusPQWP6parser
+******************************************************************************/
+class SystemStatusPQWP6
+{
+public:
+ timespec mUtcTime;
+ uint32_t mFixInfoMask;
+};
+
+class SystemStatusPQWP6parser : public SystemStatusNmeaBase
+{
+private:
+ enum
+ {
+ eTalker = 0,
+ eUtcTime = 1,
+ eFixInfoMask = 2,
+ eMax = eFixInfoMask
+ };
+ SystemStatusPQWP6 mP6;
+
+public:
+ inline uint32_t getFixInfoMask() { return mP6.mFixInfoMask; }
+
+ SystemStatusPQWP6parser(const char *str_in, uint32_t len_in)
+ : SystemStatusNmeaBase(str_in, len_in)
+ {
+ if (mField.size() < eMax) {
+ return;
+ }
+ memset(&mP6, 0, sizeof(mP6));
+ mP6.mUtcTime = setUtcTime(mField[eUtcTime]);
+ mP6.mFixInfoMask = strtol(mField[eFixInfoMask].c_str(), NULL, 16);
+ }
+
+ inline SystemStatusPQWP6& get() { return mP6;}
+};
+
+/******************************************************************************
+ SystemStatusPQWS1parser
+******************************************************************************/
+class SystemStatusPQWS1
+{
+public:
+ timespec mUtcTime;
+ uint32_t mFixInfoMask;
+ uint32_t mHepeLimit;
+};
+
+class SystemStatusPQWS1parser : public SystemStatusNmeaBase
+{
+private:
+ enum
+ {
+ eTalker = 0,
+ eUtcTime = 1,
+ eFixInfoMask = 2,
+ eHepeLimit = 3,
+ eMax = eHepeLimit
+ };
+ SystemStatusPQWS1 mS1;
+
+public:
+ inline uint16_t getFixInfoMask() { return mS1.mFixInfoMask; }
+ inline uint32_t getHepeLimit() { return mS1.mHepeLimit; }
+
+ SystemStatusPQWS1parser(const char *str_in, uint32_t len_in)
+ : SystemStatusNmeaBase(str_in, len_in)
+ {
+ if (mField.size() < eMax) {
+ return;
+ }
+ memset(&mS1, 0, sizeof(mS1));
+ mS1.mUtcTime = setUtcTime(mField[eUtcTime]);
+ mS1.mFixInfoMask = atoi(mField[eFixInfoMask].c_str());
+ mS1.mHepeLimit = atoi(mField[eHepeLimit].c_str());
+ }
+
+ inline SystemStatusPQWS1& get() { return mS1;}
+};
+
+/******************************************************************************
+ SystemStatusTimeAndClock
+******************************************************************************/
+SystemStatusTimeAndClock::SystemStatusTimeAndClock(const SystemStatusPQWM1& nmea) :
+ SystemStatusItemBase(nmea.mUtcTime),
+ mGpsWeek(nmea.mGpsWeek),
+ mGpsTowMs(nmea.mGpsTowMs),
+ mTimeValid(nmea.mTimeValid),
+ mTimeSource(nmea.mTimeSource),
+ mTimeUnc(nmea.mTimeUnc),
+ mClockFreqBias(nmea.mClockFreqBias),
+ mClockFreqBiasUnc(nmea.mClockFreqBiasUnc)
+{
+}
+
+bool SystemStatusTimeAndClock::equals(SystemStatusTimeAndClock& peer)
+{
+ if ((mGpsWeek != peer.mGpsWeek) ||
+ (mGpsTowMs != peer.mGpsTowMs) ||
+ (mTimeValid != peer.mTimeValid) ||
+ (mTimeSource != peer.mTimeSource) ||
+ (mTimeUnc != peer.mTimeUnc) ||
+ (mClockFreqBias != peer.mClockFreqBias) ||
+ (mClockFreqBiasUnc != peer.mClockFreqBiasUnc)) {
+ return false;
+ }
+ return true;
+}
+
+void SystemStatusTimeAndClock::dump()
+{
+ LOC_LOGV("TimeAndClock: u=%ld:%ld g=%d:%d v=%d s=%d u=%d b=%d bu=%d",
+ mUtcTime.tv_sec, mUtcTime.tv_nsec,
+ mGpsWeek,
+ mGpsTowMs,
+ mTimeValid,
+ mTimeSource,
+ mTimeUnc,
+ mClockFreqBias,
+ mClockFreqBiasUnc);
+ return;
+}
+
+/******************************************************************************
+ SystemStatusXoState
+******************************************************************************/
+SystemStatusXoState::SystemStatusXoState(const SystemStatusPQWM1& nmea) :
+ SystemStatusItemBase(nmea.mUtcTime),
+ mXoState(nmea.mXoState)
+{
+}
+
+bool SystemStatusXoState::equals(SystemStatusXoState& peer)
+{
+ if (mXoState != peer.mXoState) {
+ return false;
+ }
+ return true;
+}
+
+void SystemStatusXoState::dump()
+{
+ LOC_LOGV("XoState: u=%ld:%ld x=%d",
+ mUtcTime.tv_sec, mUtcTime.tv_nsec,
+ mXoState);
+ return;
+}
+
+/******************************************************************************
+ SystemStatusRfAndParams
+******************************************************************************/
+SystemStatusRfAndParams::SystemStatusRfAndParams(const SystemStatusPQWM1& nmea) :
+ SystemStatusItemBase(nmea.mUtcTime),
+ mPgaGain(nmea.mPgaGain),
+ mGpsBpAmpI(nmea.mGpsBpAmpI),
+ mGpsBpAmpQ(nmea.mGpsBpAmpQ),
+ mAdcI(nmea.mAdcI),
+ mAdcQ(nmea.mAdcQ),
+ mJammerGps(nmea.mJammerGps),
+ mJammerGlo(nmea.mJammerGlo),
+ mJammerBds(nmea.mJammerBds),
+ mJammerGal(nmea.mJammerGal)
+{
+}
+
+bool SystemStatusRfAndParams::equals(SystemStatusRfAndParams& peer)
+{
+ if ((mPgaGain != peer.mPgaGain) ||
+ (mGpsBpAmpI != peer.mGpsBpAmpI) ||
+ (mGpsBpAmpQ != peer.mGpsBpAmpQ) ||
+ (mAdcI != peer.mAdcI) ||
+ (mAdcQ != peer.mAdcQ) ||
+ (mJammerGps != peer.mJammerGps) ||
+ (mJammerGlo != peer.mJammerGlo) ||
+ (mJammerBds != peer.mJammerBds) ||
+ (mJammerGal != peer.mJammerGal)) {
+ return false;
+ }
+ return true;
+}
+
+void SystemStatusRfAndParams::dump()
+{
+ LOC_LOGV("RfAndParams: u=%ld:%ld p=%d bi=%d bq=%d ai=%d aq=%d gp=%d gl=%d bd=%d ga=%d",
+ mUtcTime.tv_sec, mUtcTime.tv_nsec,
+ mPgaGain,
+ mGpsBpAmpI,
+ mGpsBpAmpQ,
+ mAdcI,
+ mAdcQ,
+ mJammerGps,
+ mJammerGlo,
+ mJammerBds,
+ mJammerGal);
+ return;
+}
+
+/******************************************************************************
+ SystemStatusErrRecovery
+******************************************************************************/
+SystemStatusErrRecovery::SystemStatusErrRecovery(const SystemStatusPQWM1& nmea) :
+ SystemStatusItemBase(nmea.mUtcTime),
+ mRecErrorRecovery(nmea.mRecErrorRecovery)
+{
+}
+
+bool SystemStatusErrRecovery::equals(SystemStatusErrRecovery& peer)
+{
+ if (mRecErrorRecovery != peer.mRecErrorRecovery) {
+ return false;
+ }
+ return true;
+}
+
+void SystemStatusErrRecovery::dump()
+{
+ LOC_LOGV("ErrRecovery: u=%ld:%ld e=%d",
+ mUtcTime.tv_sec, mUtcTime.tv_nsec,
+ mRecErrorRecovery);
+ return;
+}
+
+/******************************************************************************
+ SystemStatusInjectedPosition
+******************************************************************************/
+SystemStatusInjectedPosition::SystemStatusInjectedPosition(const SystemStatusPQWP1& nmea) :
+ SystemStatusItemBase(nmea.mUtcTime),
+ mEpiValidity(nmea.mEpiValidity),
+ mEpiLat(nmea.mEpiLat),
+ mEpiLon(nmea.mEpiLon),
+ mEpiAlt(nmea.mEpiAlt),
+ mEpiHepe(nmea.mEpiHepe),
+ mEpiAltUnc(nmea.mEpiAltUnc),
+ mEpiSrc(nmea.mEpiSrc)
+{
+}
+
+bool SystemStatusInjectedPosition::equals(SystemStatusInjectedPosition& peer)
+{
+ if ((mEpiValidity != peer.mEpiValidity) ||
+ (mEpiLat != peer.mEpiLat) ||
+ (mEpiLon != peer.mEpiLon) ||
+ (mEpiAlt != peer.mEpiAlt) ||
+ (mEpiHepe != peer.mEpiHepe) ||
+ (mEpiAltUnc != peer.mEpiAltUnc) ||
+ (mEpiSrc != peer.mEpiSrc)) {
+ return false;
+ }
+ return true;
+}
+
+void SystemStatusInjectedPosition::dump()
+{
+ LOC_LOGV("InjectedPosition: u=%ld:%ld v=%x la=%f lo=%f al=%f he=%f au=%f es=%d",
+ mUtcTime.tv_sec, mUtcTime.tv_nsec,
+ mEpiValidity,
+ mEpiLat,
+ mEpiLon,
+ mEpiAlt,
+ mEpiHepe,
+ mEpiAltUnc,
+ mEpiSrc);
+ return;
+}
+
+/******************************************************************************
+ SystemStatusBestPosition
+******************************************************************************/
+SystemStatusBestPosition::SystemStatusBestPosition(const SystemStatusPQWP2& nmea) :
+ SystemStatusItemBase(nmea.mUtcTime),
+ mBestLat(nmea.mBestLat),
+ mBestLon(nmea.mBestLon),
+ mBestAlt(nmea.mBestAlt),
+ mBestHepe(nmea.mBestHepe),
+ mBestAltUnc(nmea.mBestAltUnc)
+{
+}
+
+bool SystemStatusBestPosition::equals(SystemStatusBestPosition& peer)
+{
+ if ((mBestLat != peer.mBestLat) ||
+ (mBestLon != peer.mBestLon) ||
+ (mBestAlt != peer.mBestAlt) ||
+ (mBestHepe != peer.mBestHepe) ||
+ (mBestAltUnc != peer.mBestAltUnc)) {
+ return false;
+ }
+ return true;
+}
+
+void SystemStatusBestPosition::dump()
+{
+ LOC_LOGV("BestPosition: u=%ld:%ld la=%f lo=%f al=%f he=%f au=%f",
+ mUtcTime.tv_sec, mUtcTime.tv_nsec,
+ mBestLat,
+ mBestLon,
+ mBestAlt,
+ mBestHepe,
+ mBestAltUnc);
+ return;
+}
+
+/******************************************************************************
+ SystemStatusXtra
+******************************************************************************/
+SystemStatusXtra::SystemStatusXtra(const SystemStatusPQWP3& nmea) :
+ SystemStatusItemBase(nmea.mUtcTime),
+ mXtraValidMask(nmea.mXtraValidMask),
+ mGpsXtraAge(nmea.mGpsXtraAge),
+ mGloXtraAge(nmea.mGloXtraAge),
+ mBdsXtraAge(nmea.mBdsXtraAge),
+ mGalXtraAge(nmea.mGalXtraAge),
+ mQzssXtraAge(nmea.mQzssXtraAge),
+ mGpsXtraValid(nmea.mGpsXtraValid),
+ mGloXtraValid(nmea.mGloXtraValid),
+ mBdsXtraValid(nmea.mBdsXtraValid),
+ mGalXtraValid(nmea.mGalXtraValid),
+ mQzssXtraValid(nmea.mQzssXtraValid)
+{
+}
+
+bool SystemStatusXtra::equals(SystemStatusXtra& peer)
+{
+ if ((mXtraValidMask != peer.mXtraValidMask) ||
+ (mGpsXtraAge != peer.mGpsXtraAge) ||
+ (mGloXtraAge != peer.mGloXtraAge) ||
+ (mBdsXtraAge != peer.mBdsXtraAge) ||
+ (mGalXtraAge != peer.mGalXtraAge) ||
+ (mQzssXtraAge != peer.mQzssXtraAge) ||
+ (mGpsXtraValid != peer.mGpsXtraValid) ||
+ (mGloXtraValid != peer.mGloXtraValid) ||
+ (mBdsXtraValid != peer.mBdsXtraValid) ||
+ (mGalXtraValid != peer.mGalXtraValid) ||
+ (mQzssXtraValid != peer.mQzssXtraValid)) {
+ return false;
+ }
+ return true;
+}
+
+void SystemStatusXtra::dump()
+{
+ LOC_LOGV("SystemStatusXtra: u=%ld:%ld m=%x a=%d:%d:%d:%d:%d v=%x:%x:%x:%x:%x",
+ mUtcTime.tv_sec, mUtcTime.tv_nsec,
+ mXtraValidMask,
+ mGpsXtraAge,
+ mGloXtraAge,
+ mBdsXtraAge,
+ mGalXtraAge,
+ mQzssXtraAge,
+ mGpsXtraValid,
+ mGloXtraValid,
+ mBdsXtraValid,
+ mGalXtraValid,
+ mQzssXtraValid);
+ return;
+}
+
+/******************************************************************************
+ SystemStatusEphemeris
+******************************************************************************/
+SystemStatusEphemeris::SystemStatusEphemeris(const SystemStatusPQWP4& nmea) :
+ SystemStatusItemBase(nmea.mUtcTime),
+ mGpsEpheValid(nmea.mGpsEpheValid),
+ mGloEpheValid(nmea.mGloEpheValid),
+ mBdsEpheValid(nmea.mBdsEpheValid),
+ mGalEpheValid(nmea.mGalEpheValid),
+ mQzssEpheValid(nmea.mQzssEpheValid)
+{
+}
+
+bool SystemStatusEphemeris::equals(SystemStatusEphemeris& peer)
+{
+ if ((mGpsEpheValid != peer.mGpsEpheValid) ||
+ (mGloEpheValid != peer.mGloEpheValid) ||
+ (mBdsEpheValid != peer.mBdsEpheValid) ||
+ (mGalEpheValid != peer.mGalEpheValid) ||
+ (mQzssEpheValid != peer.mQzssEpheValid)) {
+ return false;
+ }
+ return true;
+}
+
+void SystemStatusEphemeris::dump()
+{
+ LOC_LOGV("Ephemeris: u=%ld:%ld ev=%x:%x:%x:%x:%x",
+ mUtcTime.tv_sec, mUtcTime.tv_nsec,
+ mGpsEpheValid,
+ mGloEpheValid,
+ mBdsEpheValid,
+ mGalEpheValid,
+ mQzssEpheValid);
+ return;
+}
+
+/******************************************************************************
+ SystemStatusSvHealth
+******************************************************************************/
+SystemStatusSvHealth::SystemStatusSvHealth(const SystemStatusPQWP5& nmea) :
+ SystemStatusItemBase(nmea.mUtcTime),
+ mGpsUnknownMask(nmea.mGpsUnknownMask),
+ mGloUnknownMask(nmea.mGloUnknownMask),
+ mBdsUnknownMask(nmea.mBdsUnknownMask),
+ mGalUnknownMask(nmea.mGalUnknownMask),
+ mQzssUnknownMask(nmea.mQzssUnknownMask),
+ mGpsGoodMask(nmea.mGpsGoodMask),
+ mGloGoodMask(nmea.mGloGoodMask),
+ mBdsGoodMask(nmea.mBdsGoodMask),
+ mGalGoodMask(nmea.mGalGoodMask),
+ mQzssGoodMask(nmea.mQzssGoodMask),
+ mGpsBadMask(nmea.mGpsBadMask),
+ mGloBadMask(nmea.mGloBadMask),
+ mBdsBadMask(nmea.mBdsBadMask),
+ mGalBadMask(nmea.mGalBadMask),
+ mQzssBadMask(nmea.mQzssBadMask)
+{
+}
+
+bool SystemStatusSvHealth::equals(SystemStatusSvHealth& peer)
+{
+ if ((mGpsUnknownMask != peer.mGpsUnknownMask) ||
+ (mGloUnknownMask != peer.mGloUnknownMask) ||
+ (mBdsUnknownMask != peer.mBdsUnknownMask) ||
+ (mGalUnknownMask != peer.mGalUnknownMask) ||
+ (mQzssUnknownMask != peer.mQzssUnknownMask) ||
+ (mGpsGoodMask != peer.mGpsGoodMask) ||
+ (mGloGoodMask != peer.mGloGoodMask) ||
+ (mBdsGoodMask != peer.mBdsGoodMask) ||
+ (mGalGoodMask != peer.mGalGoodMask) ||
+ (mQzssGoodMask != peer.mQzssGoodMask) ||
+ (mGpsBadMask != peer.mGpsBadMask) ||
+ (mGloBadMask != peer.mGloBadMask) ||
+ (mBdsBadMask != peer.mBdsBadMask) ||
+ (mGalBadMask != peer.mGalBadMask) ||
+ (mQzssBadMask != peer.mQzssBadMask)) {
+ return false;
+ }
+ return true;
+}
+
+void SystemStatusSvHealth::dump()
+{
+ LOC_LOGV("SvHealth: u=%ld:%ld u=%x:%x:%x:%x:%x g=%x:%x:%x:%x:%x b=%x:%x:%x:%x:%x",
+ mUtcTime.tv_sec, mUtcTime.tv_nsec,
+ mGpsUnknownMask,
+ mGloUnknownMask,
+ mBdsUnknownMask,
+ mGalUnknownMask,
+ mQzssUnknownMask,
+ mGpsGoodMask,
+ mGloGoodMask,
+ mBdsGoodMask,
+ mGalGoodMask,
+ mQzssGoodMask,
+ mGpsBadMask,
+ mGloBadMask,
+ mBdsBadMask,
+ mGalBadMask,
+ mQzssBadMask);
+ return;
+}
+
+/******************************************************************************
+ SystemStatusPdr
+******************************************************************************/
+SystemStatusPdr::SystemStatusPdr(const SystemStatusPQWP6& nmea) :
+ SystemStatusItemBase(nmea.mUtcTime),
+ mFixInfoMask(nmea.mFixInfoMask)
+{
+}
+
+bool SystemStatusPdr::equals(SystemStatusPdr& peer)
+{
+ if (mFixInfoMask != peer.mFixInfoMask) {
+ return false;
+ }
+ return true;
+}
+
+void SystemStatusPdr::dump()
+{
+ LOC_LOGV("Pdr: u=%ld:%ld m=%x",
+ mUtcTime.tv_sec, mUtcTime.tv_nsec,
+ mFixInfoMask);
+ return;
+}
+
+/******************************************************************************
+ SystemStatusPositionFailure
+******************************************************************************/
+SystemStatusPositionFailure::SystemStatusPositionFailure(const SystemStatusPQWS1& nmea) :
+ SystemStatusItemBase(nmea.mUtcTime),
+ mFixInfoMask(nmea.mFixInfoMask),
+ mHepeLimit(nmea.mHepeLimit)
+{
+}
+
+bool SystemStatusPositionFailure::equals(SystemStatusPositionFailure& peer)
+{
+ if ((mFixInfoMask != peer.mFixInfoMask) ||
+ (mHepeLimit != peer.mHepeLimit)) {
+ return false;
+ }
+ return true;
+}
+
+void SystemStatusPositionFailure::dump()
+{
+ LOC_LOGV("PositionFailure: u=%ld:%ld m=%d h=%d",
+ mUtcTime.tv_sec, mUtcTime.tv_nsec,
+ mFixInfoMask,
+ mHepeLimit);
+ return;
+}
+
+/******************************************************************************
+ SystemStatusLocation
+******************************************************************************/
+bool SystemStatusLocation::equals(SystemStatusLocation& peer)
+{
+ if ((mLocation.gpsLocation.latitude != peer.mLocation.gpsLocation.latitude) ||
+ (mLocation.gpsLocation.longitude != peer.mLocation.gpsLocation.longitude) ||
+ (mLocation.gpsLocation.altitude != peer.mLocation.gpsLocation.altitude)) {
+ return false;
+ }
+ return true;
+}
+
+void SystemStatusLocation::dump()
+{
+ LOC_LOGV("Location: lat=%f lon=%f alt=%f spd=%f",
+ mLocation.gpsLocation.latitude,
+ mLocation.gpsLocation.longitude,
+ mLocation.gpsLocation.altitude,
+ mLocation.gpsLocation.speed);
+ return;
+}
+
+/******************************************************************************
+ SystemStatus
+******************************************************************************/
+pthread_mutex_t SystemStatus::mMutexSystemStatus = PTHREAD_MUTEX_INITIALIZER;
+
+SystemStatus::SystemStatus()
+{
+ mCache.mLocation.clear();
+
+ mCache.mTimeAndClock.clear();
+ mCache.mXoState.clear();
+ mCache.mRfAndParams.clear();
+ mCache.mErrRecovery.clear();
+
+ mCache.mInjectedPosition.clear();
+ mCache.mBestPosition.clear();
+ mCache.mXtra.clear();
+ mCache.mEphemeris.clear();
+ mCache.mSvHealth.clear();
+ mCache.mPdr.clear();
+ mCache.mPositionFailure.clear();
+}
+
+/******************************************************************************
+ SystemStatus - M1 functions
+******************************************************************************/
+bool SystemStatus::setTimeAndCLock(const SystemStatusPQWM1& nmea)
+{
+ SystemStatusTimeAndClock s(nmea);
+ if (mCache.mTimeAndClock.empty() || !mCache.mTimeAndClock.back().equals(s)) {
+ mCache.mTimeAndClock.push_back(s);
+ if (mCache.mTimeAndClock.size() > maxTimeAndClock) {
+ mCache.mTimeAndClock.erase(mCache.mTimeAndClock.begin());
+ }
+ }
+ return true;
+}
+
+bool SystemStatus::setXoState(const SystemStatusPQWM1& nmea)
+{
+ SystemStatusXoState s(nmea);
+ if (mCache.mXoState.empty() || !mCache.mXoState.back().equals(s)) {
+ mCache.mXoState.push_back(s);
+ if (mCache.mXoState.size() > maxXoState) {
+ mCache.mXoState.erase(mCache.mXoState.begin());
+ }
+ }
+ return true;
+}
+
+bool SystemStatus::setRfAndParams(const SystemStatusPQWM1& nmea)
+{
+ SystemStatusRfAndParams s(nmea);
+ if (mCache.mRfAndParams.empty() || !mCache.mRfAndParams.back().equals(s)) {
+ mCache.mRfAndParams.push_back(s);
+ if (mCache.mRfAndParams.size() > maxRfAndParams) {
+ mCache.mRfAndParams.erase(mCache.mRfAndParams.begin());
+ }
+ }
+ return true;
+}
+
+bool SystemStatus::setErrRecovery(const SystemStatusPQWM1& nmea)
+{
+ SystemStatusErrRecovery s(nmea);
+ if (mCache.mErrRecovery.empty() || !mCache.mErrRecovery.back().equals(s)) {
+ mCache.mErrRecovery.push_back(s);
+ if (mCache.mErrRecovery.size() > maxErrRecovery) {
+ mCache.mErrRecovery.erase(mCache.mErrRecovery.begin());
+ }
+ }
+ return true;
+}
+
+/******************************************************************************
+ SystemStatus - Px functions
+******************************************************************************/
+bool SystemStatus::setInjectedPosition(const SystemStatusPQWP1& nmea)
+{
+ SystemStatusInjectedPosition s(nmea);
+ if (mCache.mInjectedPosition.empty() || !mCache.mInjectedPosition.back().equals(s)) {
+ mCache.mInjectedPosition.push_back(s);
+ if (mCache.mInjectedPosition.size() > maxInjectedPosition) {
+ mCache.mInjectedPosition.erase(mCache.mInjectedPosition.begin());
+ }
+ }
+ return true;
+}
+
+bool SystemStatus::setBestPosition(const SystemStatusPQWP2& nmea)
+{
+ SystemStatusBestPosition s(nmea);
+ if (mCache.mBestPosition.empty() || !mCache.mBestPosition.back().equals(s)) {
+ mCache.mBestPosition.push_back(s);
+ if (mCache.mBestPosition.size() > maxBestPosition) {
+ mCache.mBestPosition.erase(mCache.mBestPosition.begin());
+ }
+ }
+ return true;
+}
+
+bool SystemStatus::setXtra(const SystemStatusPQWP3& nmea)
+{
+ SystemStatusXtra s(nmea);
+ if (mCache.mXtra.empty() || !mCache.mXtra.back().equals(s)) {
+ mCache.mXtra.push_back(s);
+ if (mCache.mXtra.size() > maxXtra) {
+ mCache.mXtra.erase(mCache.mXtra.begin());
+ }
+ }
+ return true;
+}
+
+bool SystemStatus::setEphemeris(const SystemStatusPQWP4& nmea)
+{
+ SystemStatusEphemeris s(nmea);
+ if (mCache.mEphemeris.empty() || !mCache.mEphemeris.back().equals(s)) {
+ mCache.mEphemeris.push_back(s);
+ if (mCache.mEphemeris.size() > maxEphemeris) {
+ mCache.mEphemeris.erase(mCache.mEphemeris.begin());
+ }
+ }
+ return true;
+}
+
+bool SystemStatus::setSvHealth(const SystemStatusPQWP5& nmea)
+{
+ SystemStatusSvHealth s(nmea);
+ if (mCache.mSvHealth.empty() || !mCache.mSvHealth.back().equals(s)) {
+ mCache.mSvHealth.push_back(s);
+ if (mCache.mSvHealth.size() > maxSvHealth) {
+ mCache.mSvHealth.erase(mCache.mSvHealth.begin());
+ }
+ }
+ return true;
+}
+
+bool SystemStatus::setPdr(const SystemStatusPQWP6& nmea)
+{
+ SystemStatusPdr s(nmea);
+ if (mCache.mPdr.empty() || !mCache.mPdr.back().equals(s)) {
+ mCache.mPdr.push_back(s);
+ if (mCache.mPdr.size() > maxPdr) {
+ mCache.mPdr.erase(mCache.mPdr.begin());
+ }
+ }
+ return true;
+}
+
+/******************************************************************************
+ SystemStatus - Sx functions
+******************************************************************************/
+bool SystemStatus::setPositionFailure(const SystemStatusPQWS1& nmea)
+{
+ SystemStatusPositionFailure s(nmea);
+ if (mCache.mPositionFailure.empty() || !mCache.mPositionFailure.back().equals(s)) {
+ mCache.mPositionFailure.push_back(s);
+ if (mCache.mPositionFailure.size() > maxPositionFailure) {
+ mCache.mPositionFailure.erase(mCache.mPositionFailure.begin());
+ }
+ }
+ return true;
+}
+
+/******************************************************************************
+@brief API to set report data into internal buffer
+
+@param[In] data pointer to the NMEA string
+@param[In] len length of the NMEA string
+
+@return true when successfully done
+******************************************************************************/
+static uint32_t cnt = 0;
+static uint32_t cnt_m1 = 0;
+static uint32_t cnt_p1 = 0;
+static uint32_t cnt_p2 = 0;
+static uint32_t cnt_p3 = 0;
+static uint32_t cnt_p4 = 0;
+static uint32_t cnt_p5 = 0;
+static uint32_t cnt_p6 = 0;
+static uint32_t cnt_s1 = 0;
+
+bool SystemStatus::setNmeaString(const char *data, uint32_t len)
+{
+ bool ret = false;
+ if (NULL == data
+ || (len < SystemStatusNmeaBase::NMEA_MINSIZE)
+ || (len > SystemStatusNmeaBase::NMEA_MAXSIZE)) {
+ return false;
+ }
+
+ char buf[SystemStatusNmeaBase::NMEA_MAXSIZE + 1] = { 0 };
+ strncpy(buf, data, len);
+ LOC_LOGI("setNmeaString-0321a: nmea=%s", buf);
+
+ pthread_mutex_lock(&mMutexSystemStatus);
+
+ // parse the received nmea strings here
+ if (0 == strncmp(data, "$PQWM1", SystemStatusNmeaBase::NMEA_MINSIZE)) {
+ SystemStatusPQWM1 s = SystemStatusPQWM1parser(buf, len).get();
+ ret = setTimeAndCLock(s);
+ ret |= setXoState(s);
+ ret |= setRfAndParams(s);
+ ret |= setErrRecovery(s);
+ cnt_m1++;
+ }
+ else if (0 == strncmp(data, "$PQWP1", SystemStatusNmeaBase::NMEA_MINSIZE)) {
+ ret = setInjectedPosition(SystemStatusPQWP1parser(buf, len).get());
+ cnt_p1++;
+ }
+ else if (0 == strncmp(data, "$PQWP2", SystemStatusNmeaBase::NMEA_MINSIZE)) {
+ ret = setBestPosition(SystemStatusPQWP2parser(buf, len).get());
+ cnt_p2++;
+ }
+ else if (0 == strncmp(data, "$PQWP3", SystemStatusNmeaBase::NMEA_MINSIZE)) {
+ ret = setXtra(SystemStatusPQWP3parser(buf, len).get());
+ cnt_p3++;
+ }
+ else if (0 == strncmp(data, "$PQWP4", SystemStatusNmeaBase::NMEA_MINSIZE)) {
+ ret = setEphemeris(SystemStatusPQWP4parser(buf, len).get());
+ cnt_p4++;
+ }
+ else if (0 == strncmp(data, "$PQWP5", SystemStatusNmeaBase::NMEA_MINSIZE)) {
+ ret = setSvHealth(SystemStatusPQWP5parser(buf, len).get());
+ cnt_p5++;
+ }
+ else if (0 == strncmp(data, "$PQWP6", SystemStatusNmeaBase::NMEA_MINSIZE)) {
+ ret = setPdr(SystemStatusPQWP6parser(buf, len).get());
+ cnt_p6++;
+ }
+ else if (0 == strncmp(data, "$PQWS1", SystemStatusNmeaBase::NMEA_MINSIZE)) {
+ ret = setPositionFailure(SystemStatusPQWS1parser(buf, len).get());
+ cnt_s1++;
+ }
+ else {
+ // do nothing
+ }
+ cnt++;
+ LOC_LOGV("setNmeaString: cnt=%d M:%d 1:%d 2:%d 3:%d 4:%d 5:%d 6:%d S:%d",
+ cnt,
+ cnt_m1,
+ cnt_p1,
+ cnt_p2,
+ cnt_p3,
+ cnt_p4,
+ cnt_p5,
+ cnt_p6,
+ cnt_s1);
+
+ pthread_mutex_unlock(&mMutexSystemStatus);
+ return ret;
+}
+
+/******************************************************************************
+@brief API to set report position data into internal buffer
+
+@param[In] UlpLocation
+
+@return true when successfully done
+******************************************************************************/
+bool SystemStatus::eventPosition(const UlpLocation& location,
+ const GpsLocationExtended& locationEx)
+{
+ timespec ts;
+ ts.tv_sec = location.gpsLocation.timestamp / 1000ULL;
+ ts.tv_nsec = (location.gpsLocation.timestamp % 1000ULL) * 1000000ULL;
+ SystemStatusLocation s(location, locationEx, ts);
+ if ((mCache.mLocation.empty()) || !mCache.mLocation.back().equals(s)) {
+ mCache.mLocation.push_back(s);
+ if (mCache.mLocation.size() > maxLocation) {
+ mCache.mLocation.erase(mCache.mLocation.begin());
+ }
+
+ LOC_LOGV("eventPosition - lat=%f lon=%f alt=%f speed=%f",
+ s.mLocation.gpsLocation.latitude,
+ s.mLocation.gpsLocation.longitude,
+ s.mLocation.gpsLocation.altitude,
+ s.mLocation.gpsLocation.speed);
+
+ }
+ return true;
+}
+
+/******************************************************************************
+@brief API to get report data into a given buffer
+
+@param[In] reference to report buffer
+@param[In] bool flag to identify latest only or entire buffer
+
+@return true when successfully done
+******************************************************************************/
+bool SystemStatus::getReport(SystemStatusReports& report, bool isLatestOnly) const
+{
+ pthread_mutex_lock(&mMutexSystemStatus);
+
+ if (isLatestOnly) {
+ // push back only the latest report and return it
+ report.mLocation.clear();
+ if (mCache.mLocation.size() >= 1) {
+ report.mLocation.push_back(mCache.mLocation.back());
+ report.mLocation.back().dump();
+ }
+
+ report.mTimeAndClock.clear();
+ if (mCache.mTimeAndClock.size() >= 1) {
+ report.mTimeAndClock.push_back(mCache.mTimeAndClock.back());
+ report.mTimeAndClock.back().dump();
+ }
+ report.mXoState.clear();
+ if (mCache.mXoState.size() >= 1) {
+ report.mXoState.push_back(mCache.mXoState.back());
+ report.mXoState.back().dump();
+ }
+ report.mRfAndParams.clear();
+ if (mCache.mRfAndParams.size() >= 1) {
+ report.mRfAndParams.push_back(mCache.mRfAndParams.back());
+ report.mRfAndParams.back().dump();
+ }
+ report.mErrRecovery.clear();
+ if (mCache.mErrRecovery.size() >= 1) {
+ report.mErrRecovery.push_back(mCache.mErrRecovery.back());
+ report.mErrRecovery.back().dump();
+ }
+
+ report.mInjectedPosition.clear();
+ if (mCache.mInjectedPosition.size() >= 1) {
+ report.mInjectedPosition.push_back(mCache.mInjectedPosition.back());
+ report.mInjectedPosition.back().dump();
+ }
+ report.mBestPosition.clear();
+ if (mCache.mBestPosition.size() >= 1) {
+ report.mBestPosition.push_back(mCache.mBestPosition.back());
+ report.mBestPosition.back().dump();
+ }
+ report.mXtra.clear();
+ if (mCache.mXtra.size() >= 1) {
+ report.mXtra.push_back(mCache.mXtra.back());
+ report.mXtra.back().dump();
+ }
+ report.mEphemeris.clear();
+ if (mCache.mEphemeris.size() >= 1) {
+ report.mEphemeris.push_back(mCache.mEphemeris.back());
+ report.mEphemeris.back().dump();
+ }
+ report.mSvHealth.clear();
+ if (mCache.mSvHealth.size() >= 1) {
+ report.mSvHealth.push_back(mCache.mSvHealth.back());
+ report.mSvHealth.back().dump();
+ }
+ report.mPdr.clear();
+ if (mCache.mPdr.size() >= 1) {
+ report.mPdr.push_back(mCache.mPdr.back());
+ report.mPdr.back().dump();
+ }
+ report.mPositionFailure.clear();
+ if (mCache.mPositionFailure.size() >= 1) {
+ report.mPositionFailure.push_back(mCache.mPositionFailure.back());
+ report.mPositionFailure.back().dump();
+ }
+ }
+ else {
+ // copy entire reports and return them
+ report.mLocation.clear();
+
+ report.mTimeAndClock.clear();
+ report.mXoState.clear();
+ report.mRfAndParams.clear();
+ report.mErrRecovery.clear();
+
+ report.mInjectedPosition.clear();
+ report.mBestPosition.clear();
+ report.mXtra.clear();
+ report.mEphemeris.clear();
+ report.mSvHealth.clear();
+ report.mPdr.clear();
+ report.mPositionFailure.clear();
+ report = mCache;
+ }
+
+ pthread_mutex_unlock(&mMutexSystemStatus);
+ return true;
+}
+
+} // namespace loc_core
+
diff --git a/core/SystemStatus.h b/core/SystemStatus.h
new file mode 100644
index 0000000..208c669
--- /dev/null
+++ b/core/SystemStatus.h
@@ -0,0 +1,306 @@
+/* Copyright (c) 2017, 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 __SYSTEM_STATUS__
+#define __SYSTEM_STATUS__
+
+#include <stdint.h>
+#include <vector>
+#include <gps_extended_c.h>
+
+#define GPS_MIN (1)
+#define SBAS_MIN (33)
+#define GLO_MIN (65)
+#define BDS_MIN (201)
+#define QZSS_MIN (193)
+#define GAL_MIN (301)
+
+namespace loc_core
+{
+
+/******************************************************************************
+ SystemStatus report data structure
+******************************************************************************/
+class SystemStatusItemBase
+{
+public:
+ timespec mUtcTime;
+ SystemStatusItemBase(timespec utctime) : mUtcTime(utctime) { };
+ virtual ~SystemStatusItemBase() { };
+ virtual void dump(void) { };
+};
+
+class SystemStatusLocation : public SystemStatusItemBase
+{
+public:
+ UlpLocation mLocation;
+ GpsLocationExtended mLocationEx;
+ SystemStatusLocation(const UlpLocation& location,
+ const GpsLocationExtended& locationEx,
+ const timespec& ts) :
+ SystemStatusItemBase(ts),
+ mLocation(location),
+ mLocationEx(locationEx){ };
+ bool equals(SystemStatusLocation& peer);
+ void dump(void);
+};
+
+class SystemStatusPQWM1;
+class SystemStatusTimeAndClock : public SystemStatusItemBase
+{
+public:
+ uint16_t mGpsWeek;
+ uint32_t mGpsTowMs;
+ uint8_t mTimeValid;
+ uint8_t mTimeSource;
+ int32_t mTimeUnc;
+ int32_t mClockFreqBias;
+ int32_t mClockFreqBiasUnc;
+ SystemStatusTimeAndClock(const SystemStatusPQWM1& nmea);
+ bool equals(SystemStatusTimeAndClock& peer);
+ void dump(void);
+};
+
+class SystemStatusXoState : public SystemStatusItemBase
+{
+public:
+ uint8_t mXoState;
+ SystemStatusXoState(const SystemStatusPQWM1& nmea);
+ bool equals(SystemStatusXoState& peer);
+ void dump(void);
+};
+
+class SystemStatusRfAndParams : public SystemStatusItemBase
+{
+public:
+ int32_t mPgaGain;
+ uint32_t mGpsBpAmpI;
+ uint32_t mGpsBpAmpQ;
+ uint32_t mAdcI;
+ uint32_t mAdcQ;
+ uint32_t mJammerGps;
+ uint32_t mJammerGlo;
+ uint32_t mJammerBds;
+ uint32_t mJammerGal;
+ SystemStatusRfAndParams(const SystemStatusPQWM1& nmea);
+ bool equals(SystemStatusRfAndParams& peer);
+ void dump(void);
+};
+
+class SystemStatusErrRecovery : public SystemStatusItemBase
+{
+public:
+ uint32_t mRecErrorRecovery;
+ SystemStatusErrRecovery(const SystemStatusPQWM1& nmea);
+ bool equals(SystemStatusErrRecovery& peer);
+ void dump(void);
+};
+
+class SystemStatusPQWP1;
+class SystemStatusInjectedPosition : public SystemStatusItemBase
+{
+public:
+ uint8_t mEpiValidity;
+ float mEpiLat;
+ float mEpiLon;
+ float mEpiAlt;
+ float mEpiHepe;
+ float mEpiAltUnc;
+ uint8_t mEpiSrc;
+ SystemStatusInjectedPosition(const SystemStatusPQWP1& nmea);
+ bool equals(SystemStatusInjectedPosition& peer);
+ void dump(void);
+};
+
+class SystemStatusPQWP2;
+class SystemStatusBestPosition : public SystemStatusItemBase
+{
+public:
+ float mBestLat;
+ float mBestLon;
+ float mBestAlt;
+ float mBestHepe;
+ float mBestAltUnc;
+ SystemStatusBestPosition(const SystemStatusPQWP2& nmea);
+ bool equals(SystemStatusBestPosition& peer);
+ void dump(void);
+};
+
+class SystemStatusPQWP3;
+class SystemStatusXtra : public SystemStatusItemBase
+{
+public:
+ uint8_t mXtraValidMask;
+ uint32_t mGpsXtraAge;
+ uint32_t mGloXtraAge;
+ uint32_t mBdsXtraAge;
+ uint32_t mGalXtraAge;
+ uint32_t mQzssXtraAge;
+ uint32_t mGpsXtraValid;
+ uint32_t mGloXtraValid;
+ uint64_t mBdsXtraValid;
+ uint64_t mGalXtraValid;
+ uint8_t mQzssXtraValid;
+ SystemStatusXtra(const SystemStatusPQWP3& nmea);
+ bool equals(SystemStatusXtra& peer);
+ void dump(void);
+};
+
+class SystemStatusPQWP4;
+class SystemStatusEphemeris : public SystemStatusItemBase
+{
+public:
+ uint32_t mGpsEpheValid;
+ uint32_t mGloEpheValid;
+ uint64_t mBdsEpheValid;
+ uint64_t mGalEpheValid;
+ uint8_t mQzssEpheValid;
+ SystemStatusEphemeris(const SystemStatusPQWP4& nmea);
+ bool equals(SystemStatusEphemeris& peer);
+ void dump(void);
+};
+
+class SystemStatusPQWP5;
+class SystemStatusSvHealth : public SystemStatusItemBase
+{
+public:
+ uint32_t mGpsUnknownMask;
+ uint32_t mGloUnknownMask;
+ uint64_t mBdsUnknownMask;
+ uint64_t mGalUnknownMask;
+ uint8_t mQzssUnknownMask;
+ uint32_t mGpsGoodMask;
+ uint32_t mGloGoodMask;
+ uint64_t mBdsGoodMask;
+ uint64_t mGalGoodMask;
+ uint8_t mQzssGoodMask;
+ uint32_t mGpsBadMask;
+ uint32_t mGloBadMask;
+ uint64_t mBdsBadMask;
+ uint64_t mGalBadMask;
+ uint8_t mQzssBadMask;
+ SystemStatusSvHealth(const SystemStatusPQWP5& nmea);
+ bool equals(SystemStatusSvHealth& peer);
+ void dump(void);
+};
+
+class SystemStatusPQWP6;
+class SystemStatusPdr : public SystemStatusItemBase
+{
+public:
+ uint32_t mFixInfoMask;
+ SystemStatusPdr(const SystemStatusPQWP6& nmea);
+ bool equals(SystemStatusPdr& peer);
+ void dump(void);
+};
+
+class SystemStatusPQWS1;
+class SystemStatusPositionFailure : public SystemStatusItemBase
+{
+public:
+ uint32_t mFixInfoMask;
+ uint32_t mHepeLimit;
+ SystemStatusPositionFailure(const SystemStatusPQWS1& nmea);
+ bool equals(SystemStatusPositionFailure& peer);
+ void dump(void);
+};
+
+/******************************************************************************
+ SystemStatusReports
+******************************************************************************/
+class SystemStatusReports
+{
+public:
+ std::vector<SystemStatusLocation> mLocation;
+
+ std::vector<SystemStatusTimeAndClock> mTimeAndClock;
+ std::vector<SystemStatusXoState> mXoState;
+ std::vector<SystemStatusRfAndParams> mRfAndParams;
+ std::vector<SystemStatusErrRecovery> mErrRecovery;
+
+ std::vector<SystemStatusInjectedPosition> mInjectedPosition;
+ std::vector<SystemStatusBestPosition> mBestPosition;
+ std::vector<SystemStatusXtra> mXtra;
+ std::vector<SystemStatusEphemeris> mEphemeris;
+ std::vector<SystemStatusSvHealth> mSvHealth;
+ std::vector<SystemStatusPdr> mPdr;
+ std::vector<SystemStatusPositionFailure> mPositionFailure;
+};
+
+/******************************************************************************
+ SystemStatus
+******************************************************************************/
+class SystemStatus
+{
+ static pthread_mutex_t mMutexSystemStatus;
+
+ static const uint32_t maxLocation = 5;
+
+ static const uint32_t maxTimeAndClock = 5;
+ static const uint32_t maxXoState = 5;
+ static const uint32_t maxRfAndParams = 5;
+ static const uint32_t maxErrRecovery = 5;
+
+ static const uint32_t maxInjectedPosition = 5;
+ static const uint32_t maxBestPosition = 5;
+ static const uint32_t maxXtra = 5;
+ static const uint32_t maxEphemeris = 5;
+ static const uint32_t maxSvHealth = 5;
+ static const uint32_t maxPdr = 5;
+ static const uint32_t maxPositionFailure = 5;
+
+ SystemStatusReports mCache;
+
+ bool setLocation(const UlpLocation& location);
+
+ bool setTimeAndCLock(const SystemStatusPQWM1& nmea);
+ bool setXoState(const SystemStatusPQWM1& nmea);
+ bool setRfAndParams(const SystemStatusPQWM1& nmea);
+ bool setErrRecovery(const SystemStatusPQWM1& nmea);
+
+ bool setInjectedPosition(const SystemStatusPQWP1& nmea);
+ bool setBestPosition(const SystemStatusPQWP2& nmea);
+ bool setXtra(const SystemStatusPQWP3& nmea);
+ bool setEphemeris(const SystemStatusPQWP4& nmea);
+ bool setSvHealth(const SystemStatusPQWP5& nmea);
+ bool setPdr(const SystemStatusPQWP6& nmea);
+ bool setPositionFailure(const SystemStatusPQWS1& nmea);
+
+public:
+ SystemStatus();
+ ~SystemStatus() { }
+
+ bool eventPosition(const UlpLocation& location,const GpsLocationExtended& locationEx);
+ bool setNmeaString(const char *data, uint32_t len);
+ bool getReport(SystemStatusReports& reports, bool isLatestonly = false) const;
+};
+
+} // namespace loc_core
+
+#endif //__SYSTEM_STATUS__
+
diff --git a/core/gps_extended_c.h b/core/gps_extended_c.h
index 55fd03e..1433768 100644
--- a/core/gps_extended_c.h
+++ b/core/gps_extended_c.h
@@ -87,6 +87,17 @@
#define LOC_AGPS_CERTIFICATE_MAX_LENGTH 2000
#define LOC_AGPS_CERTIFICATE_MAX_SLOTS 10
+typedef uint32_t LocPosTechMask;
+#define LOC_POS_TECH_MASK_DEFAULT ((LocPosTechMask)0x00000000)
+#define LOC_POS_TECH_MASK_SATELLITE ((LocPosTechMask)0x00000001)
+#define LOC_POS_TECH_MASK_CELLID ((LocPosTechMask)0x00000002)
+#define LOC_POS_TECH_MASK_WIFI ((LocPosTechMask)0x00000004)
+#define LOC_POS_TECH_MASK_SENSORS ((LocPosTechMask)0x00000008)
+#define LOC_POS_TECH_MASK_REFERENCE_LOCATION ((LocPosTechMask)0x00000010)
+#define LOC_POS_TECH_MASK_INJECTED_COARSE_POSITION ((LocPosTechMask)0x00000020)
+#define LOC_POS_TECH_MASK_AFLT ((LocPosTechMask)0x00000040)
+#define LOC_POS_TECH_MASK_HYBRID ((LocPosTechMask)0x00000080)
+
enum loc_registration_mask_status {
LOC_REGISTRATION_MASK_ENABLED,
LOC_REGISTRATION_MASK_DISABLED,
@@ -104,6 +115,7 @@
LocGpsLocation gpsLocation;
/* Provider indicator for HYBRID or GPS */
uint16_t position_source;
+ LocPosTechMask tech_mask;
/*allows HAL to pass additional information related to the location */
int rawDataSize; /* in # of bytes */
void * rawData;
@@ -266,6 +278,18 @@
#define GPS_LOCATION_EXTENDED_HAS_HOR_ELIP_UNC_AZIMUTH 0x0800
/** GpsLocationExtended has valid gnss sv used in position data */
#define GPS_LOCATION_EXTENDED_HAS_GNSS_SV_USED_DATA 0x1000
+/** GpsLocationExtended has valid navSolutionMask */
+#define GPS_LOCATION_EXTENDED_HAS_NAV_SOLUTION_MASK 0x2000
+
+typedef uint32_t LocNavSolutionMask;
+/* Bitmask to specify whether SBAS ionospheric correction is used */
+#define LOC_NAV_MASK_SBAS_CORRECTION_IONO ((LocNavSolutionMask)0x0001)
+/* Bitmask to specify whether SBAS fast correction is used */
+#define LOC_NAV_MASK_SBAS_CORRECTION_FAST ((LocNavSolutionMask)0x0002)
+/**< Bitmask to specify whether SBAS long-tem correction is used */
+#define LOC_NAV_MASK_SBAS_CORRECTION_LONG ((LocNavSolutionMask)0x0004)
+/**< Bitmask to specify whether SBAS integrity information is used */
+#define LOC_NAV_MASK_SBAS_INTEGRITY ((LocNavSolutionMask)0x0008)
/** GPS PRN Range */
#define GPS_SV_PRN_MIN 1
@@ -277,6 +301,17 @@
#define GAL_SV_PRN_MIN 301
#define GAL_SV_PRN_MAX 336
+typedef uint32_t LocPosTechMask;
+#define LOC_POS_TECH_MASK_DEFAULT ((LocPosTechMask)0x00000000)
+#define LOC_POS_TECH_MASK_SATELLITE ((LocPosTechMask)0x00000001)
+#define LOC_POS_TECH_MASK_CELLID ((LocPosTechMask)0x00000002)
+#define LOC_POS_TECH_MASK_WIFI ((LocPosTechMask)0x00000004)
+#define LOC_POS_TECH_MASK_SENSORS ((LocPosTechMask)0x00000008)
+#define LOC_POS_TECH_MASK_REFERENCE_LOCATION ((LocPosTechMask)0x00000010)
+#define LOC_POS_TECH_MASK_INJECTED_COARSE_POSITION ((LocPosTechMask)0x00000020)
+#define LOC_POS_TECH_MASK_AFLT ((LocPosTechMask)0x00000040)
+#define LOC_POS_TECH_MASK_HYBRID ((LocPosTechMask)0x00000080)
+
typedef enum {
LOC_RELIABILITY_NOT_SET = 0,
LOC_RELIABILITY_VERY_LOW = 1,
@@ -335,6 +370,10 @@
Gnss_ApTimeStampStructType timeStamp;
/** Gnss sv used in position data */
GnssSvUsedInPosition gnss_sv_used_ids;
+ /** Nav solution mask to indicate sbas corrections */
+ LocNavSolutionMask navSolutionMask;
+ /** Position technology used in computing this fix */
+ LocPosTechMask tech_mask;
} GpsLocationExtended;
enum loc_sess_status {
@@ -343,17 +382,6 @@
LOC_SESS_FAILURE
};
-typedef uint32_t LocPosTechMask;
-#define LOC_POS_TECH_MASK_DEFAULT ((LocPosTechMask)0x00000000)
-#define LOC_POS_TECH_MASK_SATELLITE ((LocPosTechMask)0x00000001)
-#define LOC_POS_TECH_MASK_CELLID ((LocPosTechMask)0x00000002)
-#define LOC_POS_TECH_MASK_WIFI ((LocPosTechMask)0x00000004)
-#define LOC_POS_TECH_MASK_SENSORS ((LocPosTechMask)0x00000008)
-#define LOC_POS_TECH_MASK_REFERENCE_LOCATION ((LocPosTechMask)0x00000010)
-#define LOC_POS_TECH_MASK_INJECTED_COARSE_POSITION ((LocPosTechMask)0x00000020)
-#define LOC_POS_TECH_MASK_AFLT ((LocPosTechMask)0x00000040)
-#define LOC_POS_TECH_MASK_HYBRID ((LocPosTechMask)0x00000080)
-
// Nmea sentence types mask
typedef uint32_t NmeaSentenceTypesMask;
#define LOC_NMEA_MASK_GGA_V02 ((NmeaSentenceTypesMask)0x00000001) /**< Enable GGA type */
@@ -373,14 +401,15 @@
#define LOC_NMEA_MASK_GAGGA_V02 ((NmeaSentenceTypesMask)0x00004000) /**< Enable GAGGA type */
#define LOC_NMEA_MASK_PQGSA_V02 ((NmeaSentenceTypesMask)0x00008000) /**< Enable PQGSA type */
#define LOC_NMEA_MASK_PQGSV_V02 ((NmeaSentenceTypesMask)0x00010000) /**< Enable PQGSV type */
+#define LOC_NMEA_MASK_DEBUG_V02 ((NmeaSentenceTypesMask)0x00020000) /**< Enable DEBUG type */
+
#define LOC_NMEA_ALL_SUPPORTED_MASK (LOC_NMEA_MASK_GGA_V02 | LOC_NMEA_MASK_RMC_V02 | \
LOC_NMEA_MASK_GSV_V02 | LOC_NMEA_MASK_GSA_V02 | LOC_NMEA_MASK_VTG_V02 | \
LOC_NMEA_MASK_PQXFI_V02 | LOC_NMEA_MASK_PSTIS_V02 | LOC_NMEA_MASK_GLGSV_V02 | \
LOC_NMEA_MASK_GNGSA_V02 | LOC_NMEA_MASK_GNGNS_V02 | LOC_NMEA_MASK_GARMC_V02 | \
LOC_NMEA_MASK_GAGSV_V02 | LOC_NMEA_MASK_GAGSA_V02 | LOC_NMEA_MASK_GAVTG_V02 | \
- LOC_NMEA_MASK_GAGGA_V02 | LOC_NMEA_MASK_PQGSA_V02 | LOC_NMEA_MASK_PQGSV_V02 )
-
-
+ LOC_NMEA_MASK_GAGGA_V02 | LOC_NMEA_MASK_PQGSA_V02 | LOC_NMEA_MASK_PQGSV_V02 | \
+ LOC_NMEA_MASK_DEBUG_V02 )
typedef enum {
LOC_ENG_IF_REQUEST_SENDER_ID_QUIPC = 0,
@@ -876,8 +905,10 @@
*/
uint64_t measurementStatus;
/**< Bitmask indicating SV measurement status.
- Valid bitmasks: \n
- @MASK()
+ Valid bitmasks: \n
+ If any MSB bit in 0xFFC0000000000000 DONT_USE is set, the measurement
+ must not be used by the client.
+ @MASK()
*/
uint16_t CNo;
/**< Carrier to Noise ratio \n
diff --git a/core/loc_gps.h b/core/loc_gps.h
index cdb1af6..2e495b8 100644
--- a/core/loc_gps.h
+++ b/core/loc_gps.h
@@ -2187,7 +2187,7 @@
* Deliver GNSS configuration contents to HAL.
* Parameters:
* config_data - a pointer to a char array which holds what usually is expected from
- file(/etc/gps.conf), i.e., a sequence of UTF8 strings separated by '\n'.
+ file(/vendor/etc/gps.conf), i.e., a sequence of UTF8 strings separated by '\n'.
* length - total number of UTF8 characters in configuraiton data.
*
* IMPORTANT:
diff --git a/etc/Android.mk b/etc/Android.mk
index 025d3f7..d9eb0e1 100644
--- a/etc/Android.mk
+++ b/etc/Android.mk
@@ -5,7 +5,7 @@
LOCAL_MODULE := gps.conf
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/
+LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/etc/
LOCAL_SRC_FILES := gps.conf
include $(BUILD_PREBUILT)
diff --git a/etc/gps.conf b/etc/gps.conf
index 4b48558..cc66792 100644
--- a/etc/gps.conf
+++ b/etc/gps.conf
@@ -138,43 +138,63 @@
# 0: disable
# 1: enable
AGPS_CONFIG_INJECT = 1
+
+##################################################
+# GNSS settings for automotive use cases
+# Configurations in following section are
+# specific to automotive use cases, others
+# please do not change, keep the default values
+##################################################
+
# AP Coarse Timestamp Uncertainty
##################################################
# default : 10
-# or as per clock uncertainty of product
+# AP time stamp uncertainty, until GNSS receiver
+# is able to acquire better timing information
AP_TIMESTAMP_UNCERTAINTY = 10
-#####################################
-# GNSS PPS settings
-#####################################
-#AP DR engine availability status
-# 0 : NO AP DR (default)
-# 1 : AP DR enabled
+##################################################
+# QDR engine availability status
+##################################################
+# 0 : NO QDR (default)
+# 1 : QDR enabled
+# This settings enables QDR Configuration for
+# automotive use case, if enabled then
+# DR_AP_Service needs to be enabled in izat.conf
#EXTERNAL_DR_ENABLED = 0
#####################################
-#DR_SYNC Pulse Availability
+# DR_SYNC Pulse Availability
#####################################
# 0 : DR_SYNC pulse not available (default)
# 1 : DR_SYNC pulse available
+# This configuration enables the driver to make use
+# of PPS events generated by DR_SYNC pulse
+# Standard Linux PPS driver needs to be enabled
DR_SYNC_ENABLED = 0
#####################################
-#PPS Device name
+# PPS Device name
#####################################
PPS_DEVICENAME = /dev/pps0
#####################################
-#AP Clock Accuracy
+# AP Clock Accuracy
#####################################
+# Quality of APPS processor clock (in PPM).
+# Value specified is used for calculation of
+# APPS time stamp uncertainty
AP_CLOCK_PPM = 100
#####################################
-#MAX ms difference to detect missing pulse
+# MAX ms difference to detect missing pulse
#####################################
+# Specifies time threshold in ms to validate any missing PPS pulses
MISSING_PULSE_TIME_DELTA = 900
#####################################
-#Propagation time uncertainty
+# Propagation time uncertainty
#####################################
+# This settings enables time uncertainty propagation
+# logic incase of missing PPS pulse
PROPAGATION_TIME_UNCERTAINTY = 1
diff --git a/gnss/GnssAdapter.cpp b/gnss/GnssAdapter.cpp
index e37a992..6621171 100644
--- a/gnss/GnssAdapter.cpp
+++ b/gnss/GnssAdapter.cpp
@@ -40,6 +40,7 @@
#include <string>
#include <loc_log.h>
#include <Agps.h>
+#include <SystemStatus.h>
using namespace loc_core;
@@ -113,6 +114,7 @@
void
GnssAdapter::convertLocation(Location& out, const LocGpsLocation& locGpsLocation,
+ const GpsLocationExtended& locationExtended,
const LocPosTechMask techMask)
{
out.size = sizeof(Location);
@@ -137,6 +139,18 @@
out.flags |= LOCATION_HAS_ACCURACY_BIT;
out.accuracy = locGpsLocation.accuracy;
}
+ if (GPS_LOCATION_EXTENDED_HAS_VERT_UNC & locationExtended.flags) {
+ out.flags |= LOCATION_HAS_VERTICAL_ACCURACY_BIT;
+ out.verticalAccuracy = locationExtended.vert_unc;
+ }
+ if (GPS_LOCATION_EXTENDED_HAS_SPEED_UNC & locationExtended.flags) {
+ out.flags |= LOCATION_HAS_SPEED_ACCURACY_BIT;
+ out.speedAccuracy = locationExtended.speed_unc;
+ }
+ if (GPS_LOCATION_EXTENDED_HAS_BEARING_UNC & locationExtended.flags) {
+ out.flags |= LOCATION_HAS_BEARING_ACCURACY_BIT;
+ out.bearingAccuracy = locationExtended.bearing_unc;
+ }
out.timestamp = locGpsLocation.timestamp;
if (LOC_POS_TECH_MASK_SATELLITE & techMask) {
out.techMask |= LOCATION_TECHNOLOGY_GNSS_BIT;
@@ -171,18 +185,6 @@
out.flags |= GNSS_LOCATION_INFO_MAGNETIC_DEVIATION_BIT;
out.magneticDeviation = locationExtended.magneticDeviation;
}
- if (GPS_LOCATION_EXTENDED_HAS_VERT_UNC & locationExtended.flags) {
- out.flags |= GNSS_LOCATION_INFO_VER_ACCURACY_BIT;
- out.verAccuracy = locationExtended.vert_unc;
- }
- if (GPS_LOCATION_EXTENDED_HAS_SPEED_UNC & locationExtended.flags) {
- out.flags |= GNSS_LOCATION_INFO_SPEED_ACCURACY_BIT;
- out.speedAccuracy = locationExtended.speed_unc;
- }
- if (GPS_LOCATION_EXTENDED_HAS_BEARING_UNC & locationExtended.flags) {
- out.flags |= GNSS_LOCATION_INFO_BEARING_ACCURACY_BIT;
- out.bearingAccuracy = locationExtended.bearing_unc;
- }
if (GPS_LOCATION_EXTENDED_HAS_HOR_RELIABILITY & locationExtended.flags) {
out.flags |= GNSS_LOCATION_INFO_HOR_RELIABILITY_BIT;
switch (locationExtended.horizontal_reliability) {
@@ -509,9 +511,16 @@
mAdapter.convertLppeCp(ContextBase::mGps_conf.LPPE_CP_TECHNOLOGY));
mApi.setLPPeProtocolUp(
mAdapter.convertLppeUp(ContextBase::mGps_conf.LPPE_UP_TECHNOLOGY));
+
+ // set nmea mask type
+ uint32_t mask = 0;
if (NMEA_PROVIDER_MP == ContextBase::mGps_conf.NMEA_PROVIDER) {
- mApi.setNMEATypes(LOC_NMEA_ALL_SUPPORTED_MASK);
+ mask = LOC_NMEA_ALL_SUPPORTED_MASK;
+ } else {
+ mask = LOC_NMEA_MASK_DEBUG_V02;
}
+ mApi.setNMEATypes(mask);
+
mApi.setXtraVersionCheck(ContextBase::mGps_conf.XTRA_VERSION_CHECK);
if (ContextBase::mSap_conf.GYRO_BIAS_RANDOM_WALK_VALID ||
ContextBase::mSap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY_VALID ||
@@ -999,8 +1008,7 @@
if (it->second.gnssSvCb != nullptr) {
mask |= LOC_API_ADAPTER_BIT_SATELLITE_REPORT;
}
- if (it->second.gnssNmeaCb != nullptr &&
- NMEA_PROVIDER_MP == ContextBase::mGps_conf.NMEA_PROVIDER) {
+ if (it->second.gnssNmeaCb != nullptr) {
mask |= LOC_API_ADAPTER_BIT_NMEA_1HZ_REPORT;
}
if (it->second.gnssMeasurementsCb != nullptr) {
@@ -1806,6 +1814,11 @@
mStatus(status),
mTechMask(techMask) {}
inline virtual void proc() const {
+ // extract bug report info - this returns true if consumed by systemstatus
+ SystemStatus* s = LocDualContext::getSystemStatus();
+ if (nullptr != s) {
+ s->eventPosition(mUlpLocation, mLocationExtended);
+ }
mAdapter.reportPosition(mUlpLocation, mLocationExtended, mStatus, mTechMask);
}
};
@@ -1858,7 +1871,7 @@
for (auto it=mClientData.begin(); it != mClientData.end(); ++it) {
if (nullptr != it->second.trackingCb) {
Location location = {};
- convertLocation(location, ulpLocation.gpsLocation, techMask);
+ convertLocation(location, ulpLocation.gpsLocation, locationExtended, techMask);
it->second.trackingCb(location);
}
if (nullptr != it->second.gnssLocationInfoCb) {
@@ -1923,27 +1936,30 @@
if (mGnssSvIdUsedInPosAvail) {
int numSv = svNotify.count;
int16_t gnssSvId = 0;
- int prnMin = 0;
uint64_t svUsedIdMask = 0;
for (int i=0; i < numSv; i++) {
gnssSvId = svNotify.gnssSvs[i].svId;
- if (gnssSvId <= GPS_SV_PRN_MAX) {
- svUsedIdMask = mGnssSvIdUsedInPosition.gps_sv_used_ids_mask;
- prnMin = GPS_SV_PRN_MIN;
- } else if ((gnssSvId >= GLO_SV_PRN_MIN) && (gnssSvId <= GLO_SV_PRN_MAX)) {
- svUsedIdMask = mGnssSvIdUsedInPosition.glo_sv_used_ids_mask;
- prnMin = GLO_SV_PRN_MIN;
- } else if ((gnssSvId >= BDS_SV_PRN_MIN) && (gnssSvId <= BDS_SV_PRN_MAX)) {
- svUsedIdMask = mGnssSvIdUsedInPosition.bds_sv_used_ids_mask;
- prnMin = BDS_SV_PRN_MIN;
- } else if ((gnssSvId >= GAL_SV_PRN_MIN) && (gnssSvId <= GAL_SV_PRN_MAX)) {
- svUsedIdMask = mGnssSvIdUsedInPosition.gal_sv_used_ids_mask;
- prnMin = GAL_SV_PRN_MIN;
+ switch (svNotify.gnssSvs[i].type) {
+ case GNSS_SV_TYPE_GPS:
+ svUsedIdMask = mGnssSvIdUsedInPosition.gps_sv_used_ids_mask;
+ break;
+ case GNSS_SV_TYPE_GLONASS:
+ svUsedIdMask = mGnssSvIdUsedInPosition.glo_sv_used_ids_mask;
+ break;
+ case GNSS_SV_TYPE_BEIDOU:
+ svUsedIdMask = mGnssSvIdUsedInPosition.bds_sv_used_ids_mask;
+ break;
+ case GNSS_SV_TYPE_GALILEO:
+ svUsedIdMask = mGnssSvIdUsedInPosition.gal_sv_used_ids_mask;
+ break;
+ default:
+ svUsedIdMask = 0;
+ break;
}
// If SV ID was used in previous position fix, then set USED_IN_FIX
// flag, else clear the USED_IN_FIX flag.
- if (svUsedIdMask & (1 << (gnssSvId - prnMin))) {
+ if (svUsedIdMask & (1 << (gnssSvId - 1))) {
svNotify.gnssSvs[i].gnssSvOptionsMask |= GNSS_SV_OPTIONS_USED_IN_FIX_BIT;
} else {
svNotify.gnssSvs[i].gnssSvOptionsMask &= ~GNSS_SV_OPTIONS_USED_IN_FIX_BIT;
@@ -1967,7 +1983,6 @@
void
GnssAdapter::reportNmeaEvent(const char* nmea, size_t length, bool fromUlp)
{
- //LOC_LOGD("%s]: fromUlp %u", __func__, fromUlp);
// if this event is not called from ULP, then try to call into ULP and return if successfull
if (!fromUlp) {
@@ -1994,7 +2009,16 @@
delete[] mNmea;
}
inline virtual void proc() const {
- mAdapter.reportNmea(mNmea, mLength);
+ // extract bug report info - this returns true if consumed by systemstatus
+ bool ret = false;
+ SystemStatus* s = LocDualContext::getSystemStatus();
+ if (nullptr != s) {
+ ret = s->setNmeaString(mNmea, mLength);
+ }
+ if (false == ret) {
+ // forward NMEA message to upper layer
+ mAdapter.reportNmea(mNmea, mLength);
+ }
}
};
@@ -3223,3 +3247,121 @@
sendMsg( new AgpsMsgAtlOpenFailed(&mAgpsManager, (AGpsExtType)agpsType));
}
+
+void GnssAdapter::convertSatelliteInfo(std::vector<GnssDebugSatelliteInfo>& out,
+ const GnssSvType& in_constellation,
+ const SystemStatusReports& in)
+{
+ GnssDebugSatelliteInfo s = {};
+ uint64_t mask = 0ULL;
+ float age = 0.0;
+ uint32_t svid_min = 0;
+ uint32_t mask_size = 0;
+
+ switch (in_constellation) {
+ case GNSS_SV_TYPE_GPS:
+ svid_min = GPS_MIN;
+ mask_size = 32;
+ break;
+ case GNSS_SV_TYPE_GLONASS:
+ svid_min = GLO_MIN;
+ mask_size = 32;
+ break;
+ case GNSS_SV_TYPE_BEIDOU:
+ svid_min = BDS_MIN;
+ mask_size = 64;
+ break;
+ case GNSS_SV_TYPE_QZSS:
+ svid_min = QZSS_MIN;
+ mask_size = 32;
+ break;
+ case GNSS_SV_TYPE_GALILEO:
+ svid_min = GAL_MIN;
+ mask_size = 64;
+ break;
+ default:
+ return;
+ }
+
+ if(!in.mEphemeris.empty()) {
+ mask = in.mEphemeris.back().mGpsEpheValid;
+ if(!in.mXtra.empty()) {
+ age = (float)(in.mXtra.back().mGpsXtraAge);
+ }
+ else {
+ age = 0.0;
+ }
+
+ for(uint32_t i=0; i<mask_size; i++) {
+ if (0 != (mask & (1<<i))) {
+ s.size = sizeof(s);
+ s.svid = i + svid_min;
+ s.constellation = in_constellation;
+ s.ephemerisType = 0;
+ s.ephemerisAgeSeconds = age;
+ out.push_back(s);
+ }
+ }
+ }
+
+ return;
+}
+
+bool GnssAdapter::getDebugReport(GnssDebugReport& r)
+{
+ LOC_LOGD("%s]: ", __func__);
+
+ SystemStatus* systemstatus = LocDualContext::getSystemStatus();
+ if (nullptr == systemstatus) {
+ return false;
+ }
+
+ SystemStatusReports reports = {};
+ systemstatus->getReport(reports, true);
+
+ r.size = sizeof(r);
+
+ // location block
+ r.mLocation.size = sizeof(r.mLocation);
+ if(!reports.mLocation.empty()) {
+ r.mLocation.mLocation.latitude = reports.mLocation.back().mLocation.gpsLocation.latitude;
+ r.mLocation.mLocation.longitude = reports.mLocation.back().mLocation.gpsLocation.longitude;
+ r.mLocation.mLocation.altitude = reports.mLocation.back().mLocation.gpsLocation.altitude;
+ r.mLocation.mLocation.speed = (double)(reports.mLocation.back().mLocation.gpsLocation.speed);
+ r.mLocation.mLocation.bearing = (double)(reports.mLocation.back().mLocation.gpsLocation.bearing);
+ r.mLocation.mLocation.accuracy = (double)(reports.mLocation.back().mLocation.gpsLocation.accuracy);
+
+ r.mLocation.verticalAccuracyMeters = reports.mLocation.back().mLocationEx.vert_unc;
+ r.mLocation.speedAccuracyMetersPerSecond = reports.mLocation.back().mLocationEx.speed_unc;
+ r.mLocation.bearingAccuracyDegrees = reports.mLocation.back().mLocationEx.bearing_unc;
+ }
+ else if(!reports.mBestPosition.empty()) {
+ r.mLocation.mLocation.latitude = (double)(reports.mBestPosition.back().mBestLat);
+ r.mLocation.mLocation.longitude = (double)(reports.mBestPosition.back().mBestLon);
+ r.mLocation.mLocation.altitude = reports.mBestPosition.back().mBestAlt;
+ }
+ LOC_LOGV("getDebugReport - lat=%f lon=%f alt=%f speed=%f",
+ r.mLocation.mLocation.latitude,
+ r.mLocation.mLocation.longitude,
+ r.mLocation.mLocation.altitude,
+ r.mLocation.mLocation.speed);
+
+ // time block
+ if(!reports.mBestPosition.empty()) {
+ r.mTime.size = sizeof(r.mTime);
+ r.mTime.timeEstimate = reports.mBestPosition.back().mUtcTime.tv_sec;
+ r.mTime.timeUncertaintyNs = (float)(reports.mTimeAndClock.back().mTimeUnc);
+ }
+ LOC_LOGV("getDebugReport - timeestimate=%lld", r.mTime.timeEstimate);
+
+ // satellite info block
+ convertSatelliteInfo(r.mSatelliteInfo, GNSS_SV_TYPE_GPS, reports);
+ convertSatelliteInfo(r.mSatelliteInfo, GNSS_SV_TYPE_GLONASS, reports);
+ convertSatelliteInfo(r.mSatelliteInfo, GNSS_SV_TYPE_BEIDOU, reports);
+ convertSatelliteInfo(r.mSatelliteInfo, GNSS_SV_TYPE_QZSS, reports);
+ convertSatelliteInfo(r.mSatelliteInfo, GNSS_SV_TYPE_GALILEO, reports);
+ LOC_LOGV("getDebugReport - satellite=%d", r.mSatelliteInfo.size());
+
+ return true;
+}
+
diff --git a/gnss/GnssAdapter.h b/gnss/GnssAdapter.h
index f5a5300..46afc06 100644
--- a/gnss/GnssAdapter.h
+++ b/gnss/GnssAdapter.h
@@ -34,6 +34,7 @@
#include <UlpProxyBase.h>
#include <LocationAPI.h>
#include <Agps.h>
+#include <SystemStatus.h>
#define MAX_URL_LEN 256
#define NMEA_SENTENCE_MAX_LENGTH 200
@@ -103,6 +104,7 @@
/*==== CONVERSION ===================================================================*/
static void convertOptions(LocPosMode& out, const LocationOptions& options);
static void convertLocation(Location& out, const LocGpsLocation& locGpsLocation,
+ const GpsLocationExtended& locationExtended,
const LocPosTechMask techMask);
static void convertLocationInfo(GnssLocationInfoNotification& out,
const GpsLocationExtended& locationExtended);
@@ -255,6 +257,9 @@
/*======== UTILITIES ================================================================*/
int nmeaPutChecksum(char *nmea, size_t maxSize);
+ /*======== GNSSDEBUG ================================================================*/
+ bool getDebugReport(GnssDebugReport& report);
+
/*==== CONVERSION ===================================================================*/
static uint32_t convertGpsLock(const GnssConfigGpsLock gpsLock);
static GnssConfigGpsLock convertGpsLock(const uint32_t gpsLock);
@@ -270,6 +275,9 @@
static GnssConfigLppeUserPlaneMask convertLppeUp(const uint32_t lppeUserPlaneMask);
static uint32_t convertAGloProt(const GnssConfigAGlonassPositionProtocolMask);
static uint32_t convertSuplMode(const GnssConfigSuplModeMask suplModeMask);
+ static void convertSatelliteInfo(std::vector<GnssDebugSatelliteInfo>& out,
+ const GnssSvType& in_constellation,
+ const SystemStatusReports& in);
void injectLocationCommand(double latitude, double longitude, float accuracy);
void injectTimeCommand(int64_t time, int64_t timeReference, int32_t uncertainty);
diff --git a/gnss/location_gnss.cpp b/gnss/location_gnss.cpp
index 0995f4b..018b7f7 100644
--- a/gnss/location_gnss.cpp
+++ b/gnss/location_gnss.cpp
@@ -58,6 +58,7 @@
static void agpsDataConnOpen(AGpsExtType agpsType, const char* apnName, int apnLen, int ipType);
static void agpsDataConnClosed(AGpsExtType agpsType);
static void agpsDataConnFailed(AGpsExtType agpsType);
+static void getDebugReport(GnssDebugReport& report);
static const GnssInterface gGnssInterface = {
sizeof(GnssInterface),
@@ -80,7 +81,8 @@
agpsInit,
agpsDataConnOpen,
agpsDataConnClosed,
- agpsDataConnFailed
+ agpsDataConnFailed,
+ getDebugReport,
};
#ifndef DEBUG_X86
@@ -239,3 +241,10 @@
gGnssAdapter->dataConnFailedCommand(agpsType);
}
}
+
+static void getDebugReport(GnssDebugReport& report) {
+
+ if (NULL != gGnssAdapter) {
+ gGnssAdapter->getDebugReport(report);
+ }
+}
diff --git a/location/LocationAPI.h b/location/LocationAPI.h
index cc15ddd..a41d772 100644
--- a/location/LocationAPI.h
+++ b/location/LocationAPI.h
@@ -29,6 +29,7 @@
#ifndef LOCATION_H
#define LOCATION_H
+#include <vector>
#include <stdint.h>
#include <functional>
@@ -52,11 +53,14 @@
// Flags to indicate which values are valid in a Location
typedef uint16_t LocationFlagsMask;
typedef enum {
- LOCATION_HAS_LAT_LONG_BIT = (1<<0), // location has valid latitude and longitude
- LOCATION_HAS_ALTITUDE_BIT = (1<<1), // location has valid altitude
- LOCATION_HAS_SPEED_BIT = (1<<2), // location has valid speed
- LOCATION_HAS_BEARING_BIT = (1<<3), // location has valid bearing
- LOCATION_HAS_ACCURACY_BIT = (1<<4), // location has valid accuracy
+ LOCATION_HAS_LAT_LONG_BIT = (1<<0), // location has valid latitude and longitude
+ LOCATION_HAS_ALTITUDE_BIT = (1<<1), // location has valid altitude
+ LOCATION_HAS_SPEED_BIT = (1<<2), // location has valid speed
+ LOCATION_HAS_BEARING_BIT = (1<<3), // location has valid bearing
+ LOCATION_HAS_ACCURACY_BIT = (1<<4), // location has valid accuracy
+ LOCATION_HAS_VERTICAL_ACCURACY_BIT = (1<<5), // location has valid vertical accuracy
+ LOCATION_HAS_SPEED_ACCURACY_BIT = (1<<6), // location has valid speed accuracy
+ LOCATION_HAS_BEARING_ACCURACY_BIT = (1<<7), // location has valid bearing accuracy
} LocationFlagsBits;
typedef uint16_t LocationTechnologyMask;
@@ -80,14 +84,11 @@
GNSS_LOCATION_INFO_ALTITUDE_MEAN_SEA_LEVEL_BIT = (1<<0), // valid altitude mean sea level
GNSS_LOCATION_INFO_DOP_BIT = (1<<1), // valid pdop, hdop, and vdop
GNSS_LOCATION_INFO_MAGNETIC_DEVIATION_BIT = (1<<2), // valid magnetic deviation
- GNSS_LOCATION_INFO_VER_ACCURACY_BIT = (1<<3), // valid vertical accuracy
- GNSS_LOCATION_INFO_SPEED_ACCURACY_BIT = (1<<4), // valid speed accuracy
- GNSS_LOCATION_INFO_BEARING_ACCURACY_BIT = (1<<5), // valid bearing accuracy
- GNSS_LOCATION_INFO_HOR_RELIABILITY_BIT = (1<<6), // valid horizontal reliability
- GNSS_LOCATION_INFO_VER_RELIABILITY_BIT = (1<<7), // valid vertical reliability
- GNSS_LOCATION_INFO_HOR_ACCURACY_ELIP_SEMI_MAJOR_BIT = (1<<8), // valid elipsode semi major
- GNSS_LOCATION_INFO_HOR_ACCURACY_ELIP_SEMI_MINOR_BIT = (1<<9), // valid elipsode semi minor
- GNSS_LOCATION_INFO_HOR_ACCURACY_ELIP_AZIMUTH_BIT = (1<<10),// valid accuracy elipsode azimuth
+ GNSS_LOCATION_INFO_HOR_RELIABILITY_BIT = (1<<3), // valid horizontal reliability
+ GNSS_LOCATION_INFO_VER_RELIABILITY_BIT = (1<<4), // valid vertical reliability
+ GNSS_LOCATION_INFO_HOR_ACCURACY_ELIP_SEMI_MAJOR_BIT = (1<<5), // valid elipsode semi major
+ GNSS_LOCATION_INFO_HOR_ACCURACY_ELIP_SEMI_MINOR_BIT = (1<<6), // valid elipsode semi minor
+ GNSS_LOCATION_INFO_HOR_ACCURACY_ELIP_AZIMUTH_BIT = (1<<7),// valid accuracy elipsode azimuth
} GnssLocationInfoFlagBits;
typedef enum {
@@ -393,6 +394,9 @@
float speed; // in meters per second
float bearing; // in degrees; range [0, 360)
float accuracy; // in meters
+ float verticalAccuracy; // in meters
+ float speedAccuracy; // in meters/second
+ float bearingAccuracy; // in degrees (0 to 359.999)
LocationTechnologyMask techMask;
} Location;
@@ -441,9 +445,6 @@
float hdop; // horizontal dilusion of precision
float vdop; // vertical dilusion of precision
float magneticDeviation; // magnetic deviation
- float verAccuracy; // vertical accuracy in meters
- float speedAccuracy; // speed accuracy in meters/second
- float bearingAccuracy; // bearing accuracy in degrees (0 to 359.999)
LocationReliability horReliability; // horizontal reliability
LocationReliability verReliability; // vertical reliability
float horUncEllipseSemiMajor; // horizontal elliptical accuracy semi-major axis
@@ -553,6 +554,35 @@
GnssConfigSuplModeMask suplModeMask; //bitwise OR of GnssConfigSuplModeBits
} GnssConfig;
+typedef struct {
+ size_t size; // set to sizeof
+ Location mLocation;
+ double verticalAccuracyMeters;
+ double speedAccuracyMetersPerSecond;
+ double bearingAccuracyDegrees;
+} GnssDebugLocation;
+
+typedef struct {
+ size_t size; // set to sizeof
+ int64_t timeEstimate;
+ float timeUncertaintyNs;
+} GnssDebugTime;
+
+typedef struct {
+ size_t size; // set to sizeof
+ uint32_t svid;
+ GnssSvType constellation;
+ uint32_t ephemerisType;
+ float ephemerisAgeSeconds;
+} GnssDebugSatelliteInfo;
+
+typedef struct {
+ size_t size; // set to sizeof
+ GnssDebugLocation mLocation;
+ GnssDebugTime mTime;
+ std::vector<GnssDebugSatelliteInfo> mSatelliteInfo;
+} GnssDebugReport;
+
/* Provides the capabilities of the system
capabilities callback is called once soon after createInstance is called */
typedef std::function<void(
diff --git a/location/LocationAPIClientBase.cpp b/location/LocationAPIClientBase.cpp
index da56440..6ced55a 100644
--- a/location/LocationAPIClientBase.cpp
+++ b/location/LocationAPIClientBase.cpp
@@ -409,17 +409,18 @@
delete requests;
}
uint32_t* sessions = mLocationAPI->addGeofences(count, options, data);
- LOC_LOGI("%s:%d] start new sessions: %p", __FUNCTION__, __LINE__, sessions);
- requests = new RequestQueue(-1);
- requests->push(new AddGeofencesRequest(*this));
- mRequestQueues[REQUEST_GEOFENCE] = requests;
+ if (sessions) {
+ LOC_LOGI("%s:%d] start new sessions: %p", __FUNCTION__, __LINE__, sessions);
+ requests = new RequestQueue(-1);
+ requests->push(new AddGeofencesRequest(*this));
+ mRequestQueues[REQUEST_GEOFENCE] = requests;
- for (size_t i = 0; i < count; i++) {
- mGeofenceBiDict.set(ids[i], sessions[i], options[i].breachTypeMask);
+ for (size_t i = 0; i < count; i++) {
+ mGeofenceBiDict.set(ids[i], sessions[i], options[i].breachTypeMask);
+ }
+ retVal = LOCATION_ERROR_SUCCESS;
}
pthread_mutex_unlock(&mMutex);
-
- retVal = LOCATION_ERROR_SUCCESS;
}
return retVal;
diff --git a/location/location_interface.h b/location/location_interface.h
index b084b65..86febd3 100644
--- a/location/location_interface.h
+++ b/location/location_interface.h
@@ -53,6 +53,7 @@
void (*agpsDataConnOpen)(short agpsType, const char* apnName, int apnLen, int ipType);
void (*agpsDataConnClosed)(short agpsType);
void (*agpsDataConnFailed)(short agpsType);
+ void (*getDebugReport)(GnssDebugReport& report);
};
struct FlpInterface {
diff --git a/utils/MsgTask.cpp b/utils/MsgTask.cpp
index 2163511..636dd4c 100644
--- a/utils/MsgTask.cpp
+++ b/utils/MsgTask.cpp
@@ -62,9 +62,9 @@
}
void MsgTask::destroy() {
+ LocThread* thread = mThread;
msg_q_unblock((void*)mQ);
- if (mThread) {
- LocThread* thread = mThread;
+ if (thread) {
mThread = NULL;
delete thread;
} else {
@@ -73,7 +73,11 @@
}
void MsgTask::sendMsg(const LocMsg* msg) const {
- msg_q_snd((void*)mQ, (void*)msg, LocMsgDestroy);
+ if (msg) {
+ msg_q_snd((void*)mQ, (void*)msg, LocMsgDestroy);
+ } else {
+ LOC_LOGE("%s: msg is NULL", __func__);
+ }
}
void MsgTask::prerun() {
diff --git a/utils/loc_target.cpp b/utils/loc_target.cpp
index 1016861..7e475eb 100644
--- a/utils/loc_target.cpp
+++ b/utils/loc_target.cpp
@@ -52,6 +52,9 @@
#define STR_SURF "Surf"
#define STR_MTP "MTP"
#define STR_APQ "apq"
+#define STR_SDC "sdc" // alternative string for APQ targets
+#define STR_MSM "msm"
+#define STR_SDM "sdm" // alternative string for MSM targets
#define STR_APQ_NO_WGR "baseband_apq_nowgr"
#define STR_AUTO "auto"
#define IS_STR_END(c) ((c) == '\0' || (c) == '\n' || (c) == '\r')
@@ -198,7 +201,7 @@
static const char hw_platform_dep[] =
"/sys/devices/system/soc/soc0/hw_platform";
static const char id_dep[] = "/sys/devices/system/soc/soc0/id";
- static const char mdm[] = "/dev/mdm"; // No such file or directory
+ static const char mdm[] = "/target"; // mdm target we are using
char rd_hw_platform[LINE_LEN];
char rd_id[LINE_LEN];
@@ -238,7 +241,8 @@
goto detected;
}
- if( !memcmp(baseband, STR_APQ, LENGTH(STR_APQ)) ){
+ if( !memcmp(baseband, STR_APQ, LENGTH(STR_APQ)) ||
+ !memcmp(baseband, STR_SDC, LENGTH(STR_SDC)) ){
if( !memcmp(rd_id, MPQ8064_ID_1, LENGTH(MPQ8064_ID_1))
&& IS_STR_END(rd_id[LENGTH(MPQ8064_ID_1)]) )
@@ -257,11 +261,17 @@
if (!read_a_line( mdm, rd_mdm, LINE_LEN))
gTarget = TARGET_MDM;
}
+
else if( (!memcmp(rd_id, MSM8930_ID_1, LENGTH(MSM8930_ID_1))
&& IS_STR_END(rd_id[LENGTH(MSM8930_ID_1)])) ||
(!memcmp(rd_id, MSM8930_ID_2, LENGTH(MSM8930_ID_2))
&& IS_STR_END(rd_id[LENGTH(MSM8930_ID_2)])) )
gTarget = TARGET_MSM_NO_SSC;
+
+ else if ( !memcmp(baseband, STR_MSM, LENGTH(STR_MSM)) ||
+ !memcmp(baseband, STR_SDM, LENGTH(STR_SDM)) )
+ gTarget = TARGET_DEFAULT;
+
else
gTarget = TARGET_UNKNOWN;
}
diff --git a/utils/platform_lib_abstractions/loc_pla/include/platform_lib_gettid.h b/utils/platform_lib_abstractions/loc_pla/include/platform_lib_gettid.h
index 9956937..340c3c5 100644
--- a/utils/platform_lib_abstractions/loc_pla/include/platform_lib_gettid.h
+++ b/utils/platform_lib_abstractions/loc_pla/include/platform_lib_gettid.h
@@ -34,6 +34,10 @@
#ifdef __cplusplus
extern "C" {
#endif
+#ifdef USE_GLIB
+const char* getprogname();
+#endif /* USE_GLIB */
+
pid_t platform_lib_abstraction_gettid();
#ifdef __cplusplus
}
diff --git a/utils/platform_lib_abstractions/loc_pla/include/platform_lib_macros.h b/utils/platform_lib_abstractions/loc_pla/include/platform_lib_macros.h
index c712122..d0795eb 100644
--- a/utils/platform_lib_abstractions/loc_pla/include/platform_lib_macros.h
+++ b/utils/platform_lib_abstractions/loc_pla/include/platform_lib_macros.h
@@ -66,6 +66,18 @@
#endif /* USE_GLIB */
+
+// Below are the location conf file paths
+extern const char LOC_PATH_GPS_CONF[];
+extern const char LOC_PATH_IZAT_CONF[];
+extern const char LOC_PATH_FLP_CONF[];
+extern const char LOC_PATH_LOWI_CONF[];
+extern const char LOC_PATH_SAP_CONF[];
+extern const char LOC_PATH_APDR_CONF[];
+extern const char LOC_PATH_XTWIFI_CONF[];
+extern const char LOC_PATH_QUIPC_CONF[];
+
+
#ifdef __cplusplus
}
#endif /*__cplusplus */
diff --git a/utils/platform_lib_abstractions/loc_pla/src/platform_lib_gettid.cpp b/utils/platform_lib_abstractions/loc_pla/src/platform_lib_gettid.cpp
index 8686327..1b7aa32 100644
--- a/utils/platform_lib_abstractions/loc_pla/src/platform_lib_gettid.cpp
+++ b/utils/platform_lib_abstractions/loc_pla/src/platform_lib_gettid.cpp
@@ -30,6 +30,12 @@
#ifdef USE_GLIB
#include <loc_stub_gettid.h>
+
+#include <errno.h>
+const char* getprogname() {
+ return program_invocation_short_name;
+}
+
#else
#include <unistd.h>
#endif /* USE_GLIB */
diff --git a/utils/platform_lib_abstractions/loc_pla/src/platform_lib_log_util.cpp b/utils/platform_lib_abstractions/loc_pla/src/platform_lib_log_util.cpp
index ef23201..3cb51a3 100644
--- a/utils/platform_lib_abstractions/loc_pla/src/platform_lib_log_util.cpp
+++ b/utils/platform_lib_abstractions/loc_pla/src/platform_lib_log_util.cpp
@@ -26,6 +26,7 @@
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "platform_lib_log_util.h"
+#include "platform_lib_macros.h"
char * get_timestamp(char *str, unsigned long buf_size)
{
@@ -40,3 +41,38 @@
return str;
}
+// Below are the location conf file paths
+#ifdef __ANDROID__
+
+#define LOC_PATH_GPS_CONF_STR "/vendor/etc/gps.conf"
+#define LOC_PATH_IZAT_CONF_STR "/vendor/etc/izat.conf"
+#define LOC_PATH_FLP_CONF_STR "/vendor/etc/flp.conf"
+#define LOC_PATH_LOWI_CONF_STR "/vendor/etc/lowi.conf"
+#define LOC_PATH_SAP_CONF_STR "/vendor/etc/sap.conf"
+#define LOC_PATH_APDR_CONF_STR "/vendor/etc/apdr.conf"
+#define LOC_PATH_XTWIFI_CONF_STR "/vendor/etc/xtwifi.conf"
+#define LOC_PATH_QUIPC_CONF_STR "/vendor/etc/quipc.conf"
+
+#else
+
+#define LOC_PATH_GPS_CONF_STR "/etc/gps.conf"
+#define LOC_PATH_IZAT_CONF_STR "/etc/izat.conf"
+#define LOC_PATH_FLP_CONF_STR "/etc/flp.conf"
+#define LOC_PATH_LOWI_CONF_STR "/etc/lowi.conf"
+#define LOC_PATH_SAP_CONF_STR "/etc/sap.conf"
+#define LOC_PATH_APDR_CONF_STR "/etc/apdr.conf"
+#define LOC_PATH_XTWIFI_CONF_STR "/etc/xtwifi.conf"
+#define LOC_PATH_QUIPC_CONF_STR "/etc/quipc.conf"
+
+#endif // __ANDROID__
+
+// Reference below arrays wherever needed to avoid duplicating
+// same conf path string over and again in location code.
+const char LOC_PATH_GPS_CONF[] = LOC_PATH_GPS_CONF_STR;
+const char LOC_PATH_IZAT_CONF[] = LOC_PATH_IZAT_CONF_STR;
+const char LOC_PATH_FLP_CONF[] = LOC_PATH_FLP_CONF_STR;
+const char LOC_PATH_LOWI_CONF[] = LOC_PATH_LOWI_CONF_STR;
+const char LOC_PATH_SAP_CONF[] = LOC_PATH_SAP_CONF_STR;
+const char LOC_PATH_APDR_CONF[] = LOC_PATH_APDR_CONF_STR;
+const char LOC_PATH_XTWIFI_CONF[] = LOC_PATH_XTWIFI_CONF_STR;
+const char LOC_PATH_QUIPC_CONF[] = LOC_PATH_QUIPC_CONF_STR;