summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhaohuang <haohuang@codeaurora.org>2020-11-09 22:12:37 +0800
committerhaohuang <haohuang@codeaurora.org>2020-12-01 13:10:17 +0800
commit3dbdbe37aba5d1a73c3ae99e0a81d8f7d3e66698 (patch)
tree034cd77824d89ddb6f442ad4607bb7f08bafaf2d
parente437e1117e00aa9643f994e58e1f23ddbbdeb930 (diff)
A new class to estimate ElapsedRealTime in LocApiBase
1, Implement a method to estimate ElapsedRealTime if Qtimer is not valid. This method uses a default initial value and AP boot time/UTC time and Modem gps time/Measurement time. 2, Move the ElapsedRealTime calculation & estimation from Hidl API layer to LocApiV02 layer. Change-Id: I523d64d00d488cca0c053f9c636c34b01214f1a9 CRs-Fixed: 2817942
-rw-r--r--android/2.0/location_api/LocationUtil.cpp107
-rw-r--r--android/2.0/location_api/LocationUtil.h1
-rw-r--r--android/2.0/location_api/MeasurementAPIClient.cpp80
-rw-r--r--android/2.1/location_api/LocationUtil.cpp107
-rw-r--r--android/2.1/location_api/LocationUtil.h1
-rw-r--r--android/2.1/location_api/MeasurementAPIClient.cpp82
-rw-r--r--core/LocApiBase.cpp139
-rw-r--r--core/LocApiBase.h23
8 files changed, 200 insertions, 340 deletions
diff --git a/android/2.0/location_api/LocationUtil.cpp b/android/2.0/location_api/LocationUtil.cpp
index fe8d22c..0742f27 100644
--- a/android/2.0/location_api/LocationUtil.cpp
+++ b/android/2.0/location_api/LocationUtil.cpp
@@ -84,109 +84,22 @@ void convertGnssLocation(Location& in, V1_0::GnssLocation& out)
out.timestamp = static_cast<V1_0::GnssUtcTime>(in.timestamp);
}
-bool getCurrentTime(struct timespec& currentTime, int64_t& sinceBootTimeNanos)
-{
- struct timespec sinceBootTime;
- struct timespec sinceBootTimeTest;
- bool clockGetTimeSuccess = false;
- const uint32_t MAX_TIME_DELTA_VALUE_NANOS = 10000;
- const uint32_t MAX_GET_TIME_COUNT = 20;
- /* Attempt to get CLOCK_REALTIME and CLOCK_BOOTIME in succession without an interruption
- or context switch (for up to MAX_GET_TIME_COUNT times) to avoid errors in the calculation */
- for (uint32_t i = 0; i < MAX_GET_TIME_COUNT; i++) {
- if (clock_gettime(CLOCK_BOOTTIME, &sinceBootTime) != 0) {
- break;
- };
- if (clock_gettime(CLOCK_REALTIME, &currentTime) != 0) {
- break;
- }
- if (clock_gettime(CLOCK_BOOTTIME, &sinceBootTimeTest) != 0) {
- break;
- };
- sinceBootTimeNanos = sinceBootTime.tv_sec * 1000000000 + sinceBootTime.tv_nsec;
- int64_t sinceBootTimeTestNanos =
- sinceBootTimeTest.tv_sec * 1000000000 + sinceBootTimeTest.tv_nsec;
- int64_t sinceBootTimeDeltaNanos = sinceBootTimeTestNanos - sinceBootTimeNanos;
-
- /* sinceBootTime and sinceBootTimeTest should have a close value if there was no
- interruption or context switch between clock_gettime for CLOCK_BOOTIME and
- clock_gettime for CLOCK_REALTIME */
- if (sinceBootTimeDeltaNanos < MAX_TIME_DELTA_VALUE_NANOS) {
- clockGetTimeSuccess = true;
- break;
- } else {
- LOC_LOGd("Delta:%" PRIi64 "ns time too large, retry number #%u...",
- sinceBootTimeDeltaNanos, i + 1);
- }
- }
- return clockGetTimeSuccess;
-}
-
void convertGnssLocation(Location& in, V2_0::GnssLocation& out)
{
memset(&out, 0, sizeof(V2_0::GnssLocation));
convertGnssLocation(in, out.v1_0);
- struct timespec currentTime;
- int64_t sinceBootTimeNanos;
-
- if (getCurrentTime(currentTime, sinceBootTimeNanos)) {
- if (in.flags & LOCATION_HAS_ELAPSED_REAL_TIME) {
- uint64_t qtimerDiff = 0;
- uint64_t qTimerTickCount = getQTimerTickCount();
- if (qTimerTickCount >= in.elapsedRealTime) {
- qtimerDiff = qTimerTickCount - in.elapsedRealTime;
- }
- LOC_LOGv("sinceBootTimeNanos:%" PRIi64 " in.elapsedRealTime=%" PRIi64 ""
- " qTimerTickCount=%" PRIi64 " qtimerDiff=%" PRIi64 "",
- sinceBootTimeNanos, in.elapsedRealTime, qTimerTickCount, qtimerDiff);
- uint64_t qTimerDiffNanos = qTimerTicksToNanos(double(qtimerDiff));
-
- /* If the time difference between Qtimer on modem side and Qtimer on AP side
- is greater than one second we assume this is a dual-SoC device such as
- Kona and will try to get Qtimer on modem side and on AP side and
- will adjust our difference accordingly */
- if (qTimerDiffNanos > 1000000000) {
- uint64_t qtimerDelta = getQTimerDeltaNanos();
- if (qTimerDiffNanos >= qtimerDelta) {
- qTimerDiffNanos -= qtimerDelta;
- }
- }
-
- if (sinceBootTimeNanos >= qTimerDiffNanos) {
- out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIMESTAMP_NS;
- out.elapsedRealtime.timestampNs = sinceBootTimeNanos - qTimerDiffNanos;
- out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS;
- out.elapsedRealtime.timeUncertaintyNs = in.elapsedRealTimeUnc;
- }
- } else {
- int64_t currentTimeNanos = currentTime.tv_sec*1000000000 + currentTime.tv_nsec;
- int64_t locationTimeNanos = in.timestamp*1000000;
- LOC_LOGv("sinceBootTimeNanos:%" PRIi64 " currentTimeNanos:%" PRIi64 ""
- " locationTimeNanos:%" PRIi64 "",
- sinceBootTimeNanos, currentTimeNanos, locationTimeNanos);
- if (currentTimeNanos >= locationTimeNanos) {
- int64_t ageTimeNanos = currentTimeNanos - locationTimeNanos;
- LOC_LOGv("ageTimeNanos:%" PRIi64 ")", ageTimeNanos);
- // the max trusted propagation time 100ms for ageTimeNanos to avoid user setting
- // wrong time, it will affect elapsedRealtimeNanos
- if (ageTimeNanos <= 100000000) {
- out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIMESTAMP_NS;
- out.elapsedRealtime.timestampNs = sinceBootTimeNanos - ageTimeNanos;
- out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS;
- // time uncertainty is the max value between abs(AP_UTC - MP_UTC) and 100ms, to
- // verify if user change the sys time
- out.elapsedRealtime.timeUncertaintyNs =
- std::max(ageTimeNanos, (int64_t)100000000);
- }
- }
- }
+ if (in.flags & LOCATION_HAS_ELAPSED_REAL_TIME) {
+ out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIMESTAMP_NS;
+ out.elapsedRealtime.timestampNs = in.elapsedRealTime;
+ out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS;
+ out.elapsedRealtime.timeUncertaintyNs = in.elapsedRealTimeUnc;
+ LOC_LOGd("out.elapsedRealtime.timestampNs=%" PRIi64 ""
+ " out.elapsedRealtime.timeUncertaintyNs=%" PRIi64 ""
+ " out.elapsedRealtime.flags=0x%X",
+ out.elapsedRealtime.timestampNs,
+ out.elapsedRealtime.timeUncertaintyNs, out.elapsedRealtime.flags);
}
- LOC_LOGv("out.elapsedRealtime.timestampNs=%" PRIi64 ""
- " out.elapsedRealtime.timeUncertaintyNs=%" PRIi64 ""
- " out.elapsedRealtime.flags=0x%X",
- out.elapsedRealtime.timestampNs,
- out.elapsedRealtime.timeUncertaintyNs, out.elapsedRealtime.flags);
}
void convertGnssLocation(const V1_0::GnssLocation& in, Location& out)
diff --git a/android/2.0/location_api/LocationUtil.h b/android/2.0/location_api/LocationUtil.h
index 3c34514..70729e4 100644
--- a/android/2.0/location_api/LocationUtil.h
+++ b/android/2.0/location_api/LocationUtil.h
@@ -51,7 +51,6 @@ void convertGnssSvid(GnssMeasurementsData& in, int16_t& out);
void convertGnssEphemerisType(GnssEphemerisType& in, GnssDebug::SatelliteEphemerisType& out);
void convertGnssEphemerisSource(GnssEphemerisSource& in, GnssDebug::SatelliteEphemerisSource& out);
void convertGnssEphemerisHealth(GnssEphemerisHealth& in, GnssDebug::SatelliteEphemerisHealth& out);
-bool getCurrentTime(struct timespec& currentTime, int64_t& sinceBootTimeNanos);
} // namespace implementation
} // namespace V2_0
diff --git a/android/2.0/location_api/MeasurementAPIClient.cpp b/android/2.0/location_api/MeasurementAPIClient.cpp
index a32b1cd..425415f 100644
--- a/android/2.0/location_api/MeasurementAPIClient.cpp
+++ b/android/2.0/location_api/MeasurementAPIClient.cpp
@@ -437,78 +437,16 @@ static void convertGnssData_2_0(GnssMeasurementsNotification& in,
static void convertElapsedRealtimeNanos(GnssMeasurementsNotification& in,
::android::hardware::gnss::V2_0::ElapsedRealtime& elapsedRealtime)
{
- struct timespec currentTime;
- int64_t sinceBootTimeNanos;
-
- if (getCurrentTime(currentTime, sinceBootTimeNanos)) {
- if (in.clock.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_ELAPSED_REAL_TIME_BIT) {
- uint64_t qtimerDiff = 0;
- uint64_t qTimerTickCount = getQTimerTickCount();
- if (qTimerTickCount >= in.clock.elapsedRealTime) {
- qtimerDiff = qTimerTickCount - in.clock.elapsedRealTime;
- }
- LOC_LOGv("sinceBootTimeNanos:%" PRIi64 " in.clock.elapsedRealTime=%" PRIi64 ""
- " qTimerTickCount=%" PRIi64 " qtimerDiff=%" PRIi64 "",
- sinceBootTimeNanos, in.clock.elapsedRealTime, qTimerTickCount, qtimerDiff);
- uint64_t qTimerDiffNanos = qTimerTicksToNanos(double(qtimerDiff));
-
- /* If the time difference between Qtimer on modem side and Qtimer on AP side
- is greater than one second we assume this is a dual-SoC device such as
- Kona and will try to get Qtimer on modem side and on AP side and
- will adjust our difference accordingly */
- if (qTimerDiffNanos > 1000000000) {
- uint64_t qtimerDelta = getQTimerDeltaNanos();
- if (qTimerDiffNanos >= qtimerDelta) {
- qTimerDiffNanos -= qtimerDelta;
- }
- }
-
- if (sinceBootTimeNanos >= qTimerDiffNanos) {
- elapsedRealtime.flags |= V2_0::ElapsedRealtimeFlags::HAS_TIMESTAMP_NS;
- elapsedRealtime.timestampNs = sinceBootTimeNanos - qTimerDiffNanos;
- elapsedRealtime.flags |= V2_0::ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS;
- elapsedRealtime.timeUncertaintyNs = in.clock.elapsedRealTimeUnc;
- }
- } else {
- const uint32_t UTC_TO_GPS_SECONDS = 315964800;
-
- if (in.clock.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_LEAP_SECOND_BIT &&
- in.clock.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_FULL_BIAS_BIT &&
- in.clock.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_BIAS_BIT &&
- in.clock.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_BIAS_UNCERTAINTY_BIT) {
- int64_t currentTimeNanos = currentTime.tv_sec * 1000000000 + currentTime.tv_nsec;
- int64_t measTimeNanos = (int64_t)in.clock.timeNs - (int64_t)in.clock.fullBiasNs
- - (int64_t)in.clock.biasNs - (int64_t)in.clock.leapSecond * 1000000000
- + (int64_t)UTC_TO_GPS_SECONDS * 1000000000;
-
- LOC_LOGv("sinceBootTimeNanos:%" PRIi64 " currentTimeNanos:%" PRIi64 ""
- " measTimeNanos:%" PRIi64 "",
- sinceBootTimeNanos, currentTimeNanos, measTimeNanos);
- if (currentTimeNanos >= measTimeNanos) {
- int64_t ageTimeNanos = currentTimeNanos - measTimeNanos;
- LOC_LOGv("ageTimeNanos:%" PRIi64 ")", ageTimeNanos);
- // the max trusted propagation time 100ms for ageTimeNanos to avoid user
- // setting wrong time, it will affect elapsedRealtimeNanos
- if (ageTimeNanos <= 100000000) {
- elapsedRealtime.flags |= V2_0::ElapsedRealtimeFlags::HAS_TIMESTAMP_NS;
- elapsedRealtime.timestampNs = sinceBootTimeNanos - ageTimeNanos;
- elapsedRealtime.flags |=
- V2_0::ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS;
- // time uncertainty is the max value between abs(AP_UTC - MP_UTC) and 100ms,
- // to verify if user change the sys time
- elapsedRealtime.timeUncertaintyNs =
- std::max(ageTimeNanos, (int64_t)100000000);
- }
- }
- } else {
- LOC_LOGe("Failed to calculate elapsedRealtimeNanos timestamp");
- }
- }
+ if (in.clock.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_ELAPSED_REAL_TIME_BIT) {
+ elapsedRealtime.flags |= V2_0::ElapsedRealtimeFlags::HAS_TIMESTAMP_NS;
+ elapsedRealtime.timestampNs = in.clock.elapsedRealTime;
+ elapsedRealtime.flags |= V2_0::ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS;
+ elapsedRealtime.timeUncertaintyNs = in.clock.elapsedRealTimeUnc;
+ LOC_LOGd("elapsedRealtime.timestampNs=%" PRIi64 ""
+ " elapsedRealtime.timeUncertaintyNs=%" PRIi64 " elapsedRealtime.flags=0x%X",
+ elapsedRealtime.timestampNs,
+ elapsedRealtime.timeUncertaintyNs, elapsedRealtime.flags);
}
- LOC_LOGv("elapsedRealtime.timestampNs=%" PRIi64 ""
- " elapsedRealtime.timeUncertaintyNs=%" PRIi64 " elapsedRealtime.flags=0x%X",
- elapsedRealtime.timestampNs,
- elapsedRealtime.timeUncertaintyNs, elapsedRealtime.flags);
}
static void convertGnssMeasurementsCodeType(GnssMeasurementsCodeType& in,
diff --git a/android/2.1/location_api/LocationUtil.cpp b/android/2.1/location_api/LocationUtil.cpp
index 4371119..e5b49b2 100644
--- a/android/2.1/location_api/LocationUtil.cpp
+++ b/android/2.1/location_api/LocationUtil.cpp
@@ -85,109 +85,22 @@ void convertGnssLocation(Location& in, V1_0::GnssLocation& out)
out.timestamp = static_cast<V1_0::GnssUtcTime>(in.timestamp);
}
-bool getCurrentTime(struct timespec& currentTime, int64_t& sinceBootTimeNanos)
-{
- struct timespec sinceBootTime;
- struct timespec sinceBootTimeTest;
- bool clockGetTimeSuccess = false;
- const uint32_t MAX_TIME_DELTA_VALUE_NANOS = 10000;
- const uint32_t MAX_GET_TIME_COUNT = 20;
- /* Attempt to get CLOCK_REALTIME and CLOCK_BOOTIME in succession without an interruption
- or context switch (for up to MAX_GET_TIME_COUNT times) to avoid errors in the calculation */
- for (uint32_t i = 0; i < MAX_GET_TIME_COUNT; i++) {
- if (clock_gettime(CLOCK_BOOTTIME, &sinceBootTime) != 0) {
- break;
- };
- if (clock_gettime(CLOCK_REALTIME, &currentTime) != 0) {
- break;
- }
- if (clock_gettime(CLOCK_BOOTTIME, &sinceBootTimeTest) != 0) {
- break;
- };
- sinceBootTimeNanos = sinceBootTime.tv_sec * 1000000000 + sinceBootTime.tv_nsec;
- int64_t sinceBootTimeTestNanos =
- sinceBootTimeTest.tv_sec * 1000000000 + sinceBootTimeTest.tv_nsec;
- int64_t sinceBootTimeDeltaNanos = sinceBootTimeTestNanos - sinceBootTimeNanos;
-
- /* sinceBootTime and sinceBootTimeTest should have a close value if there was no
- interruption or context switch between clock_gettime for CLOCK_BOOTIME and
- clock_gettime for CLOCK_REALTIME */
- if (sinceBootTimeDeltaNanos < MAX_TIME_DELTA_VALUE_NANOS) {
- clockGetTimeSuccess = true;
- break;
- } else {
- LOC_LOGd("Delta:%" PRIi64 "ns time too large, retry number #%u...",
- sinceBootTimeDeltaNanos, i + 1);
- }
- }
- return clockGetTimeSuccess;
-}
-
void convertGnssLocation(Location& in, V2_0::GnssLocation& out)
{
memset(&out, 0, sizeof(V2_0::GnssLocation));
convertGnssLocation(in, out.v1_0);
- struct timespec currentTime;
- int64_t sinceBootTimeNanos;
-
- if (getCurrentTime(currentTime, sinceBootTimeNanos)) {
- if (in.flags & LOCATION_HAS_ELAPSED_REAL_TIME) {
- uint64_t qtimerDiff = 0;
- uint64_t qTimerTickCount = getQTimerTickCount();
- if (qTimerTickCount >= in.elapsedRealTime) {
- qtimerDiff = qTimerTickCount - in.elapsedRealTime;
- }
- LOC_LOGd("sinceBootTimeNanos:%" PRIi64 " in.elapsedRealTime=%" PRIi64 ""
- " qTimerTickCount=%" PRIi64 " qtimerDiff=%" PRIi64 "",
- sinceBootTimeNanos, in.elapsedRealTime, qTimerTickCount, qtimerDiff);
- uint64_t qTimerDiffNanos = qTimerTicksToNanos(double(qtimerDiff));
-
- /* If the time difference between Qtimer on modem side and Qtimer on AP side
- is greater than one second we assume this is a dual-SoC device such as
- Kona and will try to get Qtimer on modem side and on AP side and
- will adjust our difference accordingly */
- if (qTimerDiffNanos > 1000000000) {
- uint64_t qtimerDelta = getQTimerDeltaNanos();
- if (qTimerDiffNanos >= qtimerDelta) {
- qTimerDiffNanos -= qtimerDelta;
- }
- }
-
- if (sinceBootTimeNanos >= qTimerDiffNanos) {
- out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIMESTAMP_NS;
- out.elapsedRealtime.timestampNs = sinceBootTimeNanos - qTimerDiffNanos;
- out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS;
- out.elapsedRealtime.timeUncertaintyNs = in.elapsedRealTimeUnc;
- }
- } else {
- int64_t currentTimeNanos = currentTime.tv_sec*1000000000 + currentTime.tv_nsec;
- int64_t locationTimeNanos = in.timestamp*1000000;
- LOC_LOGd("sinceBootTimeNanos:%" PRIi64 " currentTimeNanos:%" PRIi64 ""
- " locationTimeNanos:%" PRIi64 "",
- sinceBootTimeNanos, currentTimeNanos, locationTimeNanos);
- if (currentTimeNanos >= locationTimeNanos) {
- int64_t ageTimeNanos = currentTimeNanos - locationTimeNanos;
- LOC_LOGd("ageTimeNanos:%" PRIi64 ")", ageTimeNanos);
- // the max trusted propagation time 100ms for ageTimeNanos to avoid user setting
- // wrong time, it will affect elapsedRealtimeNanos
- if (ageTimeNanos <= 100000000) {
- out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIMESTAMP_NS;
- out.elapsedRealtime.timestampNs = sinceBootTimeNanos - ageTimeNanos;
- out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS;
- // time uncertainty is the max value between abs(AP_UTC - MP_UTC) and 100ms, to
- // verify if user change the sys time
- out.elapsedRealtime.timeUncertaintyNs =
- std::max(ageTimeNanos, (int64_t)100000000);
- }
- }
- }
+ if (in.flags & LOCATION_HAS_ELAPSED_REAL_TIME) {
+ out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIMESTAMP_NS;
+ out.elapsedRealtime.timestampNs = in.elapsedRealTime;
+ out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS;
+ out.elapsedRealtime.timeUncertaintyNs = in.elapsedRealTimeUnc;
+ LOC_LOGd("out.elapsedRealtime.timestampNs=%" PRIi64 ""
+ " out.elapsedRealtime.timeUncertaintyNs=%" PRIi64 ""
+ " out.elapsedRealtime.flags=0x%X",
+ out.elapsedRealtime.timestampNs,
+ out.elapsedRealtime.timeUncertaintyNs, out.elapsedRealtime.flags);
}
- LOC_LOGd("out.elapsedRealtime.timestampNs=%" PRIi64 ""
- " out.elapsedRealtime.timeUncertaintyNs=%" PRIi64 ""
- " out.elapsedRealtime.flags=0x%X",
- out.elapsedRealtime.timestampNs,
- out.elapsedRealtime.timeUncertaintyNs, out.elapsedRealtime.flags);
}
void convertGnssLocation(const V1_0::GnssLocation& in, Location& out)
diff --git a/android/2.1/location_api/LocationUtil.h b/android/2.1/location_api/LocationUtil.h
index fde1595..2d95a2d 100644
--- a/android/2.1/location_api/LocationUtil.h
+++ b/android/2.1/location_api/LocationUtil.h
@@ -56,7 +56,6 @@ void convertGnssSvid(GnssMeasurementsData& in, int16_t& out);
void convertGnssEphemerisType(GnssEphemerisType& in, GnssDebug::SatelliteEphemerisType& out);
void convertGnssEphemerisSource(GnssEphemerisSource& in, GnssDebug::SatelliteEphemerisSource& out);
void convertGnssEphemerisHealth(GnssEphemerisHealth& in, GnssDebug::SatelliteEphemerisHealth& out);
-bool getCurrentTime(struct timespec& currentTime, int64_t& sinceBootTimeNanos);
void convertSingleSatCorrections(const SingleSatCorrection& in, GnssSingleSatCorrection& out);
void convertMeasurementCorrections(const MeasurementCorrectionsV1_0& in,
GnssMeasurementCorrections& out);
diff --git a/android/2.1/location_api/MeasurementAPIClient.cpp b/android/2.1/location_api/MeasurementAPIClient.cpp
index 5869774..0028074 100644
--- a/android/2.1/location_api/MeasurementAPIClient.cpp
+++ b/android/2.1/location_api/MeasurementAPIClient.cpp
@@ -623,80 +623,16 @@ static void convertGnssData_2_1(GnssMeasurementsNotification& in,
static void convertElapsedRealtimeNanos(GnssMeasurementsNotification& in,
::android::hardware::gnss::V2_0::ElapsedRealtime& elapsedRealtime)
{
- struct timespec currentTime;
- int64_t sinceBootTimeNanos;
-
- if (getCurrentTime(currentTime, sinceBootTimeNanos)) {
- if (in.clock.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_ELAPSED_REAL_TIME_BIT) {
- uint64_t qtimerDiff = 0;
- uint64_t qTimerTickCount = getQTimerTickCount();
- if (qTimerTickCount >= in.clock.elapsedRealTime) {
- qtimerDiff = qTimerTickCount - in.clock.elapsedRealTime;
- }
- LOC_LOGv("sinceBootTimeNanos:%" PRIi64 " in.clock.elapsedRealTime=%" PRIi64 ""
- " qTimerTickCount=%" PRIi64 " qtimerDiff=%" PRIi64 "",
- sinceBootTimeNanos, in.clock.elapsedRealTime, qTimerTickCount, qtimerDiff);
- uint64_t qTimerDiffNanos = qTimerTicksToNanos(double(qtimerDiff));
-
- /* If the time difference between Qtimer on modem side and Qtimer on AP side
- is greater than one second we assume this is a dual-SoC device such as
- Kona and will try to get Qtimer on modem side and on AP side and
- will adjust our difference accordingly */
- if (qTimerDiffNanos > 1000000000) {
- uint64_t qtimerDelta = getQTimerDeltaNanos();
- if (qTimerDiffNanos >= qtimerDelta) {
- qTimerDiffNanos -= qtimerDelta;
- }
- }
-
- if (sinceBootTimeNanos >= qTimerDiffNanos) {
- elapsedRealtime.flags |= V2_0::ElapsedRealtimeFlags::HAS_TIMESTAMP_NS;
- elapsedRealtime.timestampNs = sinceBootTimeNanos - qTimerDiffNanos;
- elapsedRealtime.flags |= V2_0::ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS;
- elapsedRealtime.timeUncertaintyNs = in.clock.elapsedRealTimeUnc;
- }
- } else {
- const uint32_t UTC_TO_GPS_SECONDS = 315964800;
-
- if (in.clock.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_LEAP_SECOND_BIT &&
- in.clock.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_FULL_BIAS_BIT &&
- in.clock.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_BIAS_BIT &&
- in.clock.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_BIAS_UNCERTAINTY_BIT) {
- int64_t currentTimeNanos = currentTime.tv_sec * 1000000000 + currentTime.tv_nsec;
- int64_t measTimeNanos = (int64_t)in.clock.timeNs - (int64_t)in.clock.fullBiasNs
- - (int64_t)in.clock.biasNs - (int64_t)in.clock.leapSecond * 1000000000
- + (int64_t)UTC_TO_GPS_SECONDS * 1000000000;
-
- LOC_LOGv("sinceBootTimeNanos:%" PRIi64 " currentTimeNanos:%" PRIi64 ""
- " measTimeNanos:%" PRIi64 "",
- sinceBootTimeNanos, currentTimeNanos, measTimeNanos);
- if (currentTimeNanos >= measTimeNanos) {
- int64_t ageTimeNanos = currentTimeNanos - measTimeNanos;
- LOC_LOGv("ageTimeNanos:%" PRIi64 ")", ageTimeNanos);
- // the max trusted propagation time 100ms for ageTimeNanos to avoid user
- // setting wrong time, it will affect elapsedRealtimeNanos
- if (ageTimeNanos <= 100000000) {
- elapsedRealtime.flags |= V2_0::ElapsedRealtimeFlags::HAS_TIMESTAMP_NS;
- elapsedRealtime.timestampNs = sinceBootTimeNanos - ageTimeNanos;
- elapsedRealtime.flags |=
- V2_0::ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS;
- // time uncertainty is 1 ms since it is calculated from utc time that
- // is in ms
- // time uncertainty is the max value between abs(AP_UTC - MP_UTC) and 100ms,
- // to verify if user change the sys time
- elapsedRealtime.timeUncertaintyNs =
- std::max(ageTimeNanos, (int64_t)100000000);
- }
- }
- } else {
- LOC_LOGe("Failed to calculate elapsedRealtimeNanos timestamp");
- }
- }
+ if (in.clock.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_ELAPSED_REAL_TIME_BIT) {
+ elapsedRealtime.flags |= V2_0::ElapsedRealtimeFlags::HAS_TIMESTAMP_NS;
+ elapsedRealtime.timestampNs = in.clock.elapsedRealTime;
+ elapsedRealtime.flags |= V2_0::ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS;
+ elapsedRealtime.timeUncertaintyNs = in.clock.elapsedRealTimeUnc;
+ LOC_LOGd("elapsedRealtime.timestampNs=%" PRIi64 ""
+ " elapsedRealtime.timeUncertaintyNs=%" PRIi64 " elapsedRealtime.flags=0x%X",
+ elapsedRealtime.timestampNs,
+ elapsedRealtime.timeUncertaintyNs, elapsedRealtime.flags);
}
- LOC_LOGv("elapsedRealtime.timestampNs=%" PRIi64 ""
- " elapsedRealtime.timeUncertaintyNs=%" PRIi64 " elapsedRealtime.flags=0x%X",
- elapsedRealtime.timestampNs,
- elapsedRealtime.timeUncertaintyNs, elapsedRealtime.flags);
}
} // namespace implementation
diff --git a/core/LocApiBase.cpp b/core/LocApiBase.cpp
index dbe4590..2413d05 100644
--- a/core/LocApiBase.cpp
+++ b/core/LocApiBase.cpp
@@ -36,6 +36,7 @@
#include <LocAdapterBase.h>
#include <log_util.h>
#include <LocContext.h>
+#include <loc_misc_utils.h>
namespace loc_core {
@@ -927,4 +928,142 @@ DEFAULT_IMPL()
void LocApiBase::
getConstellationMultiBandConfig(uint32_t sessionId, LocApiResponse* /*adapterResponse*/)
DEFAULT_IMPL()
+
+int64_t ElapsedRealtimeEstimator::getElapsedRealtimeEstimateNanos(int64_t curDataTimeNanos,
+ bool isCurDataTimeTrustable, uint32_t tbf) {
+ //The algorithm works follow below steps:
+ //When isCurDataTimeTrustable is meet (means Modem timestamp is already stable),
+ //1, Wait for mFixTimeStablizationThreshold fixes; While waiting for modem time
+ // stable, we set the traveltime to a default value;
+ //2, When the mFixTimeStablizationThreshold fix comes, we think now the mode time
+ // is already stable, calculate the initial AP-Modem clock diff(mCurrentClockDiff)
+ // using formula:
+ // mCurrentClockDiff = currentTimeNanos - locationTimeNanos - currentTravelTimeNanos
+ //3, since then, when the nth fix comes,
+ // 3.1 First update mCurrentClockDiff using below formula:
+ // mCurrentClockDiff = mCurrentClockDiff + (currentTimeNanos - sinceBootTimeNanos)
+ // - (mPrevUtcTimeNanos - mPrevBootTimeNanos)
+ // 3.2 Calculate currentTravelTimeNanos:
+ // currentTravelTimeNanos = currentTimeNanos - locationTimeNanos - mCurrentClockDiff
+ //4, It is possible that locationTimeNanos will jump,
+ // reset mFixTimeStablizationThreshold to default value, jump to step 2 to continue.
+
+ int64_t currentTravelTimeNanos = mInitialTravelTime;
+ struct timespec currentTime;
+ int64_t sinceBootTimeNanos;
+ if (getCurrentTime(currentTime, sinceBootTimeNanos)) {
+ if (isCurDataTimeTrustable) {
+ if (tbf > 0 && tbf != curDataTimeNanos - mPrevDataTimeNanos) {
+ mFixTimeStablizationThreshold = 5;
+ }
+ int64_t currentTimeNanos = currentTime.tv_sec*1000000000 + currentTime.tv_nsec;
+ LOC_LOGd("sinceBootTimeNanos:%" PRIi64 " currentTimeNanos:%" PRIi64 ""
+ " locationTimeNanos:%" PRIi64 "",
+ sinceBootTimeNanos, currentTimeNanos, curDataTimeNanos);
+ if (mFixTimeStablizationThreshold == 0) {
+ currentTravelTimeNanos = mInitialTravelTime;
+ mCurrentClockDiff = currentTimeNanos - curDataTimeNanos - currentTravelTimeNanos;
+ } else if (mFixTimeStablizationThreshold < 0) {
+ mCurrentClockDiff = mCurrentClockDiff + (currentTimeNanos - sinceBootTimeNanos)
+ - (mPrevUtcTimeNanos - mPrevBootTimeNanos);
+ currentTravelTimeNanos = currentTimeNanos - curDataTimeNanos - mCurrentClockDiff;
+ }
+
+ mPrevUtcTimeNanos = currentTimeNanos;
+ mPrevBootTimeNanos = sinceBootTimeNanos;
+ mPrevDataTimeNanos = curDataTimeNanos;
+ mFixTimeStablizationThreshold--;
+ }
+ } else {
+ return -1;
+ }
+ LOC_LOGd("Estimated travel time: %" PRIi64 "", currentTravelTimeNanos);
+ return (sinceBootTimeNanos - currentTravelTimeNanos);
+}
+
+void ElapsedRealtimeEstimator::reset() {
+ mCurrentClockDiff = 0;
+ mPrevDataTimeNanos = 0;
+ mPrevUtcTimeNanos = 0;
+ mPrevBootTimeNanos = 0;
+ mFixTimeStablizationThreshold = 5;
+}
+
+int64_t ElapsedRealtimeEstimator::getElapsedRealtimeQtimer(int64_t qtimerTicksAtOrigin) {
+ struct timespec currentTime;
+ int64_t sinceBootTimeNanos;
+ int64_t elapsedRealTimeNanos;
+
+ if (getCurrentTime(currentTime, sinceBootTimeNanos)) {
+ uint64_t qtimerDiff = 0;
+ uint64_t qTimerTickCount = getQTimerTickCount();
+ if (qTimerTickCount >= qtimerTicksAtOrigin) {
+ qtimerDiff = qTimerTickCount - qtimerTicksAtOrigin;
+ }
+ LOC_LOGd("sinceBootTimeNanos:%" PRIi64 " qtimerTicksAtOrigin=%" PRIi64 ""
+ " qTimerTickCount=%" PRIi64 " qtimerDiff=%" PRIi64 "",
+ sinceBootTimeNanos, qtimerTicksAtOrigin, qTimerTickCount, qtimerDiff);
+ uint64_t qTimerDiffNanos = qTimerTicksToNanos(double(qtimerDiff));
+
+ /* If the time difference between Qtimer on modem side and Qtimer on AP side
+ is greater than one second we assume this is a dual-SoC device such as
+ Kona and will try to get Qtimer on modem side and on AP side and
+ will adjust our difference accordingly */
+ if (qTimerDiffNanos > 1000000000) {
+ uint64_t qtimerDelta = getQTimerDeltaNanos();
+ if (qTimerDiffNanos >= qtimerDelta) {
+ qTimerDiffNanos -= qtimerDelta;
+ }
+ }
+
+ LOC_LOGd("Qtimer travel time: %" PRIi64 "", qTimerDiffNanos);
+ if (sinceBootTimeNanos >= qTimerDiffNanos) {
+ elapsedRealTimeNanos = sinceBootTimeNanos - qTimerDiffNanos;
+ } else {
+ elapsedRealTimeNanos = -1;
+ }
+ } else {
+ elapsedRealTimeNanos = -1;
+ }
+ return elapsedRealTimeNanos;
+}
+
+bool ElapsedRealtimeEstimator::getCurrentTime(
+ struct timespec& currentTime, int64_t& sinceBootTimeNanos)
+{
+ struct timespec sinceBootTime;
+ struct timespec sinceBootTimeTest;
+ bool clockGetTimeSuccess = false;
+ const uint32_t MAX_TIME_DELTA_VALUE_NANOS = 10000;
+ const uint32_t MAX_GET_TIME_COUNT = 20;
+ /* Attempt to get CLOCK_REALTIME and CLOCK_BOOTIME in succession without an interruption
+ or context switch (for up to MAX_GET_TIME_COUNT times) to avoid errors in the calculation */
+ for (uint32_t i = 0; i < MAX_GET_TIME_COUNT; i++) {
+ if (clock_gettime(CLOCK_BOOTTIME, &sinceBootTime) != 0) {
+ break;
+ };
+ if (clock_gettime(CLOCK_REALTIME, &currentTime) != 0) {
+ break;
+ }
+ if (clock_gettime(CLOCK_BOOTTIME, &sinceBootTimeTest) != 0) {
+ break;
+ };
+ sinceBootTimeNanos = sinceBootTime.tv_sec * 1000000000 + sinceBootTime.tv_nsec;
+ int64_t sinceBootTimeTestNanos =
+ sinceBootTimeTest.tv_sec * 1000000000 + sinceBootTimeTest.tv_nsec;
+ int64_t sinceBootTimeDeltaNanos = sinceBootTimeTestNanos - sinceBootTimeNanos;
+
+ /* sinceBootTime and sinceBootTimeTest should have a close value if there was no
+ interruption or context switch between clock_gettime for CLOCK_BOOTIME and
+ clock_gettime for CLOCK_REALTIME */
+ if (sinceBootTimeDeltaNanos < MAX_TIME_DELTA_VALUE_NANOS) {
+ clockGetTimeSuccess = true;
+ break;
+ } else {
+ LOC_LOGd("Delta:%" PRIi64 "ns time too large, retry number #%u...",
+ sinceBootTimeDeltaNanos, i + 1);
+ }
+ }
+ return clockGetTimeSuccess;
+}
} // namespace loc_core
diff --git a/core/LocApiBase.h b/core/LocApiBase.h
index 95c0a38..b58e60d 100644
--- a/core/LocApiBase.h
+++ b/core/LocApiBase.h
@@ -41,6 +41,8 @@
#else
#include <unordered_map>
#endif
+#include <inttypes.h>
+#include <functional>
using namespace loc_util;
@@ -344,6 +346,27 @@ public:
LocApiResponse* adapterResponse=nullptr);
};
+class ElapsedRealtimeEstimator {
+private:
+ int64_t mCurrentClockDiff;
+ int64_t mPrevUtcTimeNanos;
+ int64_t mPrevBootTimeNanos;
+ int64_t mFixTimeStablizationThreshold;
+ int64_t mInitialTravelTime;
+ int64_t mPrevDataTimeNanos;
+public:
+
+ ElapsedRealtimeEstimator(int64_t travelTimeNanosEstimate):
+ mInitialTravelTime(travelTimeNanosEstimate) {reset();}
+ int64_t getElapsedRealtimeEstimateNanos(int64_t curDataTimeNanos,
+ bool isCurDataTimeTrustable, uint32_t tbf);
+ inline int64_t getElapsedRealtimeUncNanos() { return 5000000;}
+ void reset();
+
+ static int64_t getElapsedRealtimeQtimer(int64_t qtimerTicksAtOrigin);
+ static bool getCurrentTime(struct timespec& currentTime, int64_t& sinceBootTimeNanos);
+};
+
typedef LocApiBase* (getLocApi_t)(LOC_API_ADAPTER_EVENT_MASK_T exMask,
ContextBase *context);