sdm660-common: gps: Update gps hal from LA.UM.9.1.r1-10200-SMxxx0.0

Signed-off-by: clarencelol <clarencekuiek@icloud.com>
Signed-off-by: pix106 <sbordenave@gmail.com>
This commit is contained in:
clarencelol 2021-04-10 05:45:42 +02:00 committed by pix106
parent 49d1f0486e
commit 504dfee87f
45 changed files with 1398 additions and 481 deletions

View file

@ -54,6 +54,7 @@ Return<bool> AGnssRil::updateNetworkState(bool connected, NetworkType type, bool
const int NetworkType_BLUETOOTH = 7;
const int NetworkType_ETHERNET = 9;
const int NetworkType_PROXY = 16;
std::string apn("");
// for XTRA
if (nullptr != mGnss && ( nullptr != mGnss->getGnssInterface() )) {
@ -102,7 +103,7 @@ Return<bool> AGnssRil::updateNetworkState(bool connected, NetworkType type, bool
}
break;
}
mGnss->getGnssInterface()->updateConnectionStatus(connected, false, typeout, 0);
mGnss->getGnssInterface()->updateConnectionStatus(connected, typeout, false, 0, apn);
}
return true;
}

View file

@ -30,6 +30,7 @@
#define LOG_NDEBUG 0
#define LOG_TAG "LocSvc_BatchingAPIClient"
#include <inttypes.h>
#include <log_util.h>
#include <loc_cfg.h>
@ -153,7 +154,7 @@ void BatchingAPIClient::flushBatchedLocations()
void BatchingAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)
{
LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask);
LOC_LOGD("%s]: (%" PRIu64 ")", __FUNCTION__, capabilitiesMask);
mLocationCapabilitiesMask = capabilitiesMask;
}

View file

@ -31,6 +31,7 @@
#define LOG_TAG "LocSvc_GnssAPIClient"
#define SINGLE_SHOT_MIN_TRACKING_INTERVAL_MSEC (590 * 60 * 60 * 1000) // 590 hours
#include <inttypes.h>
#include <log_util.h>
#include <loc_cfg.h>
@ -299,7 +300,7 @@ void GnssAPIClient::requestCapabilities() {
// callbacks
void GnssAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)
{
LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask);
LOC_LOGD("%s]: (%" PRIu64 ")", __FUNCTION__, capabilitiesMask);
mLocationCapabilitiesMask = capabilitiesMask;
mLocationCapabilitiesCached = true;

View file

@ -157,7 +157,11 @@ void convertGnssSvid(GnssSv& in, int16_t& out)
out = in.svId;
break;
case GNSS_SV_TYPE_GLONASS:
if (!isGloSlotUnknown(in.svId)) { // OSN is known
out = in.svId - GLO_SV_PRN_MIN + 1;
} else { // OSN is not known, report FCN
out = in.gloFrequency + 92;
}
break;
case GNSS_SV_TYPE_QZSS:
out = in.svId;
@ -169,8 +173,6 @@ void convertGnssSvid(GnssSv& in, int16_t& out)
out = in.svId - GAL_SV_PRN_MIN + 1;
break;
case GNSS_SV_TYPE_NAVIC:
/*Android doesn't define Navic svid range yet, use Naviv svid [1, 14] now
will update this once Android give Navic svid definiitons */
out = in.svId - NAVIC_SV_PRN_MIN + 1;
break;
default:
@ -189,7 +191,7 @@ void convertGnssSvid(GnssMeasurementsData& in, int16_t& out)
out = in.svId;
break;
case GNSS_SV_TYPE_GLONASS:
if (in.svId != 255) { // OSN is known
if (!isGloSlotUnknown(in.svId)) { // OSN is known
out = in.svId - GLO_SV_PRN_MIN + 1;
} else { // OSN is not known, report FCN
out = in.gloFrequency + 92;
@ -205,8 +207,6 @@ void convertGnssSvid(GnssMeasurementsData& in, int16_t& out)
out = in.svId - GAL_SV_PRN_MIN + 1;
break;
case GNSS_SV_TYPE_NAVIC:
/*Android doesn't define Navic svid range yet, use Naviv svid [1, 14] now
will update this once Android give Navic svid definiitons */
out = in.svId - NAVIC_SV_PRN_MIN + 1;
break;
default:

View file

@ -54,6 +54,7 @@ Return<bool> AGnssRil::updateNetworkState(bool connected, NetworkType type, bool
const int NetworkType_BLUETOOTH = 7;
const int NetworkType_ETHERNET = 9;
const int NetworkType_PROXY = 16;
std::string apn("");
// for XTRA
if (nullptr != mGnss && ( nullptr != mGnss->getGnssInterface() )) {
@ -102,7 +103,7 @@ Return<bool> AGnssRil::updateNetworkState(bool connected, NetworkType type, bool
}
break;
}
mGnss->getGnssInterface()->updateConnectionStatus(connected, false, typeout, 0);
mGnss->getGnssInterface()->updateConnectionStatus(connected, typeout, false, 0, apn);
}
return true;
}

View file

@ -30,6 +30,7 @@
#define LOG_NDEBUG 0
#define LOG_TAG "LocSvc_BatchingAPIClient"
#include <inttypes.h>
#include <log_util.h>
#include <loc_cfg.h>
@ -153,7 +154,7 @@ void BatchingAPIClient::flushBatchedLocations()
void BatchingAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)
{
LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask);
LOC_LOGD("%s]: (%" PRIu64 ")", __FUNCTION__, capabilitiesMask);
mLocationCapabilitiesMask = capabilitiesMask;
}

View file

@ -31,6 +31,7 @@
#define LOG_TAG "LocSvc_GnssAPIClient"
#define SINGLE_SHOT_MIN_TRACKING_INTERVAL_MSEC (590 * 60 * 60 * 1000) // 590 hours
#include <inttypes.h>
#include <log_util.h>
#include <loc_cfg.h>
@ -299,7 +300,7 @@ void GnssAPIClient::requestCapabilities() {
// callbacks
void GnssAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)
{
LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask);
LOC_LOGD("%s]: (%" PRIu64 ")", __FUNCTION__, capabilitiesMask);
mLocationCapabilitiesMask = capabilitiesMask;
mLocationCapabilitiesCached = true;

View file

@ -157,7 +157,11 @@ void convertGnssSvid(GnssSv& in, int16_t& out)
out = in.svId;
break;
case GNSS_SV_TYPE_GLONASS:
if (!isGloSlotUnknown(in.svId)) { // OSN is known
out = in.svId - GLO_SV_PRN_MIN + 1;
} else { //OSN is not known, report FCN
out = in.gloFrequency + 92;
}
break;
case GNSS_SV_TYPE_QZSS:
out = in.svId;
@ -169,8 +173,6 @@ void convertGnssSvid(GnssSv& in, int16_t& out)
out = in.svId - GAL_SV_PRN_MIN + 1;
break;
case GNSS_SV_TYPE_NAVIC:
/*Android doesn't define Navic svid range yet, use Naviv svid [1, 14] now
will update this once Android give Navic svid definiitons */
out = in.svId - NAVIC_SV_PRN_MIN + 1;
break;
default:
@ -189,7 +191,7 @@ void convertGnssSvid(GnssMeasurementsData& in, int16_t& out)
out = in.svId;
break;
case GNSS_SV_TYPE_GLONASS:
if (in.svId != 255) { // OSN is known
if (!isGloSlotUnknown(in.svId)) { // OSN is known
out = in.svId - GLO_SV_PRN_MIN + 1;
} else { // OSN is not known, report FCN
out = in.gloFrequency + 92;
@ -205,8 +207,6 @@ void convertGnssSvid(GnssMeasurementsData& in, int16_t& out)
out = in.svId - GAL_SV_PRN_MIN + 1;
break;
case GNSS_SV_TYPE_NAVIC:
/*Android doesn't define Navic svid range yet, use Naviv svid [1, 14] now
will update this once Android give Navic svid definiitons */
out = in.svId - NAVIC_SV_PRN_MIN + 1;
break;
default:

View file

@ -54,6 +54,7 @@ Return<bool> AGnssRil::updateNetworkState(bool connected, NetworkType type, bool
const int NetworkType_BLUETOOTH = 7;
const int NetworkType_ETHERNET = 9;
const int NetworkType_PROXY = 16;
std::string apn("");
// for XTRA
if (nullptr != mGnss && ( nullptr != mGnss->getGnssInterface() )) {
@ -102,13 +103,13 @@ Return<bool> AGnssRil::updateNetworkState(bool connected, NetworkType type, bool
}
break;
}
mGnss->getGnssInterface()->updateConnectionStatus(connected, false, typeout, 0);
mGnss->getGnssInterface()->updateConnectionStatus(connected, typeout, false, 0, apn);
}
return true;
}
Return<bool> AGnssRil::updateNetworkState_2_0(const V2_0::IAGnssRil::NetworkAttributes& attributes) {
ENTRY_LOG_CALLFLOW();
std::string apn = attributes.apn;
if (nullptr != mGnss && (nullptr != mGnss->getGnssInterface())) {
int8_t typeout = loc_core::TYPE_UNKNOWN;
bool roaming = false;
@ -120,8 +121,9 @@ Return<bool> AGnssRil::updateNetworkState_2_0(const V2_0::IAGnssRil::NetworkAttr
if (attributes.capabilities & IAGnssRil::NetworkCapability::NOT_ROAMING) {
roaming = false;
}
LOC_LOGd("apn string received is: %s", apn.c_str());
mGnss->getGnssInterface()->updateConnectionStatus(attributes.isConnected,
typeout, roaming, (NetworkHandle) attributes.networkHandle);
typeout, roaming, (NetworkHandle) attributes.networkHandle, apn);
}
return true;
}

View file

@ -30,6 +30,7 @@
#define LOG_NDEBUG 0
#define LOG_TAG "LocSvc_BatchingAPIClient"
#include <inttypes.h>
#include <log_util.h>
#include <loc_cfg.h>
@ -191,7 +192,7 @@ void BatchingAPIClient::flushBatchedLocations()
void BatchingAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)
{
LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask);
LOC_LOGD("%s]: (%" PRIu64 ")", __FUNCTION__, capabilitiesMask);
mLocationCapabilitiesMask = capabilitiesMask;
}

View file

@ -31,6 +31,7 @@
#define LOG_TAG "LocSvc_GnssAPIClient"
#define SINGLE_SHOT_MIN_TRACKING_INTERVAL_MSEC (590 * 60 * 60 * 1000) // 590 hours
#include <inttypes.h>
#include <log_util.h>
#include <loc_cfg.h>
@ -349,7 +350,7 @@ void GnssAPIClient::requestCapabilities() {
// callbacks
void GnssAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)
{
LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask);
LOC_LOGD("%s]: (%" PRIu64 ")", __FUNCTION__, capabilitiesMask);
mLocationCapabilitiesMask = capabilitiesMask;
mLocationCapabilitiesCached = true;

View file

@ -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.timestampNs = in.elapsedRealTime;
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);
}
}
}
}
LOC_LOGv("out.elapsedRealtime.timestampNs=%" PRIi64 ""
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)
@ -304,7 +217,11 @@ void convertGnssSvid(GnssSv& in, int16_t& out)
out = in.svId;
break;
case GNSS_SV_TYPE_GLONASS:
if (!isGloSlotUnknown(in.svId)) { // OSN is known
out = in.svId - GLO_SV_PRN_MIN + 1;
} else { // OSN is not known, report FCN
out = in.gloFrequency + 92;
}
break;
case GNSS_SV_TYPE_QZSS:
out = in.svId;
@ -316,8 +233,6 @@ void convertGnssSvid(GnssSv& in, int16_t& out)
out = in.svId - GAL_SV_PRN_MIN + 1;
break;
case GNSS_SV_TYPE_NAVIC:
/*Android doesn't define Navic svid range yet, use Naviv svid [1, 14] now
will update this once Android give Navic svid definiitons */
out = in.svId - NAVIC_SV_PRN_MIN + 1;
break;
default:
@ -336,7 +251,7 @@ void convertGnssSvid(GnssMeasurementsData& in, int16_t& out)
out = in.svId;
break;
case GNSS_SV_TYPE_GLONASS:
if (in.svId != 255) { // OSN is known
if (!isGloSlotUnknown(in.svId)) { // OSN is known
out = in.svId - GLO_SV_PRN_MIN + 1;
} else { // OSN is not known, report FCN
out = in.gloFrequency + 92;
@ -352,8 +267,6 @@ void convertGnssSvid(GnssMeasurementsData& in, int16_t& out)
out = in.svId - GAL_SV_PRN_MIN + 1;
break;
case GNSS_SV_TYPE_NAVIC:
/*Android doesn't define Navic svid range yet, use Naviv svid [1, 14] now
will update this once Android give Navic svid definiitons */
out = in.svId - NAVIC_SV_PRN_MIN + 1;
break;
default:

View file

@ -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

View file

@ -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.timestampNs = in.clock.elapsedRealTime;
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");
}
}
}
LOC_LOGv("elapsedRealtime.timestampNs=%" PRIi64 ""
LOC_LOGd("elapsedRealtime.timestampNs=%" PRIi64 ""
" elapsedRealtime.timeUncertaintyNs=%" PRIi64 " elapsedRealtime.flags=0x%X",
elapsedRealtime.timestampNs,
elapsedRealtime.timeUncertaintyNs, elapsedRealtime.flags);
}
}
static void convertGnssMeasurementsCodeType(GnssMeasurementsCodeType& in,

View file

@ -54,6 +54,7 @@ Return<bool> AGnssRil::updateNetworkState(bool connected, NetworkType type, bool
const int NetworkType_BLUETOOTH = 7;
const int NetworkType_ETHERNET = 9;
const int NetworkType_PROXY = 16;
std::string apn("");
// for XTRA
if (nullptr != mGnss && ( nullptr != mGnss->getGnssInterface() )) {
@ -102,13 +103,13 @@ Return<bool> AGnssRil::updateNetworkState(bool connected, NetworkType type, bool
}
break;
}
mGnss->getGnssInterface()->updateConnectionStatus(connected, false, typeout, 0);
mGnss->getGnssInterface()->updateConnectionStatus(connected, typeout, false, 0, apn);
}
return true;
}
Return<bool> AGnssRil::updateNetworkState_2_0(const V2_0::IAGnssRil::NetworkAttributes& attributes) {
ENTRY_LOG_CALLFLOW();
std::string apn = attributes.apn;
if (nullptr != mGnss && (nullptr != mGnss->getGnssInterface())) {
int8_t typeout = loc_core::TYPE_UNKNOWN;
bool roaming = false;
@ -120,8 +121,9 @@ Return<bool> AGnssRil::updateNetworkState_2_0(const V2_0::IAGnssRil::NetworkAttr
if (attributes.capabilities & IAGnssRil::NetworkCapability::NOT_ROAMING) {
roaming = false;
}
LOC_LOGd("apn string received is: %s", apn.c_str());
mGnss->getGnssInterface()->updateConnectionStatus(attributes.isConnected,
typeout, roaming, (NetworkHandle) attributes.networkHandle);
typeout, roaming, (NetworkHandle) attributes.networkHandle, apn);
}
return true;
}

View file

@ -30,6 +30,7 @@
#define LOG_NDEBUG 0
#define LOG_TAG "LocSvc_BatchingAPIClient"
#include <inttypes.h>
#include <log_util.h>
#include <loc_cfg.h>
@ -191,7 +192,7 @@ void BatchingAPIClient::flushBatchedLocations()
void BatchingAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)
{
LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask);
LOC_LOGD("%s]: (%" PRIu64 ")", __FUNCTION__, capabilitiesMask);
mLocationCapabilitiesMask = capabilitiesMask;
}

View file

@ -31,6 +31,7 @@
#define LOG_TAG "LocSvc_GnssAPIClient"
#define SINGLE_SHOT_MIN_TRACKING_INTERVAL_MSEC (590 * 60 * 60 * 1000) // 590 hours
#include <inttypes.h>
#include <log_util.h>
#include <loc_cfg.h>
@ -380,7 +381,7 @@ void GnssAPIClient::requestCapabilities() {
// callbacks
void GnssAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)
{
LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask);
LOC_LOGD("%s]: (%" PRIu64 ")", __FUNCTION__, capabilitiesMask);
mLocationCapabilitiesMask = capabilitiesMask;
mLocationCapabilitiesCached = true;

View file

@ -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.timestampNs = in.elapsedRealTime;
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);
}
}
}
}
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)
@ -305,7 +218,11 @@ void convertGnssSvid(GnssSv& in, int16_t& out)
out = in.svId;
break;
case GNSS_SV_TYPE_GLONASS:
if (!isGloSlotUnknown(in.svId)) { // OSN is known
out = in.svId - GLO_SV_PRN_MIN + 1;
} else { // OSN is not known, report FCN
out = in.gloFrequency + 92;
}
break;
case GNSS_SV_TYPE_QZSS:
out = in.svId;
@ -317,8 +234,6 @@ void convertGnssSvid(GnssSv& in, int16_t& out)
out = in.svId - GAL_SV_PRN_MIN + 1;
break;
case GNSS_SV_TYPE_NAVIC:
/*Android doesn't define Navic svid range yet, use Naviv svid [1, 14] now
will update this once Android give Navic svid definiitons */
out = in.svId - NAVIC_SV_PRN_MIN + 1;
break;
default:
@ -337,7 +252,7 @@ void convertGnssSvid(GnssMeasurementsData& in, int16_t& out)
out = in.svId;
break;
case GNSS_SV_TYPE_GLONASS:
if (in.svId != 255) { // OSN is known
if (!isGloSlotUnknown(in.svId)) { // OSN is known
out = in.svId - GLO_SV_PRN_MIN + 1;
} else { // OSN is not known, report FCN
out = in.gloFrequency + 92;
@ -353,8 +268,6 @@ void convertGnssSvid(GnssMeasurementsData& in, int16_t& out)
out = in.svId - GAL_SV_PRN_MIN + 1;
break;
case GNSS_SV_TYPE_NAVIC:
/*Android doesn't define Navic svid range yet, use Naviv svid [1, 14] now
will update this once Android give Navic svid definiitons */
out = in.svId - NAVIC_SV_PRN_MIN + 1;
break;
default:

View file

@ -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);

View file

@ -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.timestampNs = in.clock.elapsedRealTime;
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");
}
}
}
LOC_LOGv("elapsedRealtime.timestampNs=%" PRIi64 ""
LOC_LOGd("elapsedRealtime.timestampNs=%" PRIi64 ""
" elapsedRealtime.timeUncertaintyNs=%" PRIi64 " elapsedRealtime.flags=0x%X",
elapsedRealtime.timestampNs,
elapsedRealtime.timeUncertaintyNs, elapsedRealtime.flags);
}
}
} // namespace implementation

View file

@ -50,6 +50,7 @@ uint64_t ContextBase::sSupportedMsgMask = 0;
bool ContextBase::sGnssMeasurementSupported = false;
uint8_t ContextBase::sFeaturesSupported[MAX_FEATURE_LENGTH];
GnssNMEARptRate ContextBase::sNmeaReportRate = GNSS_NMEA_REPORT_RATE_NHZ;
LocationCapabilitiesMask ContextBase::sQwesFeatureMask = 0;
const loc_param_s_type ContextBase::mGps_conf_table[] =
{

View file

@ -35,6 +35,11 @@
#include <LocApiBase.h>
#include <LBSProxyBase.h>
#include <loc_cfg.h>
#ifdef NO_UNORDERED_SET_OR_MAP
#include <map>
#else
#include <unordered_map>
#endif
/* GPS.conf support */
/* NOTE: the implementaiton of the parser casts number
@ -160,6 +165,7 @@ public:
static uint8_t sFeaturesSupported[MAX_FEATURE_LENGTH];
static bool sGnssMeasurementSupported;
static GnssNMEARptRate sNmeaReportRate;
static LocationCapabilitiesMask sQwesFeatureMask;
void readConfig();
static uint32_t getCarrierCapabilities();
@ -192,6 +198,118 @@ public:
*/
static bool gnssConstellationConfig();
/*
set QWES feature status info
*/
static inline void setQwesFeatureStatus(
const std::unordered_map<LocationQwesFeatureType, bool> &featureMap) {
std::unordered_map<LocationQwesFeatureType, bool>::const_iterator itr;
static LocationQwesFeatureType locQwesFeatType[LOCATION_QWES_FEATURE_TYPE_MAX];
for (itr = featureMap.begin(); itr != featureMap.end(); ++itr) {
LOC_LOGi("Feature : %d isValid: %d", itr->first, itr->second);
locQwesFeatType[itr->first] = itr->second;
switch (itr->first) {
case LOCATION_QWES_FEATURE_TYPE_CARRIER_PHASE:
if (itr->second) {
sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_CARRIER_PHASE_BIT;
} else {
sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_CARRIER_PHASE_BIT;
}
break;
case LOCATION_QWES_FEATURE_TYPE_SV_POLYNOMIAL:
if (itr->second) {
sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_SV_POLYNOMIAL_BIT;
} else {
sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_SV_POLYNOMIAL_BIT;
}
break;
case LOCATION_QWES_FEATURE_TYPE_GNSS_SINGLE_FREQUENCY:
if (itr->second) {
sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_GNSS_SINGLE_FREQUENCY;
} else {
sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_GNSS_SINGLE_FREQUENCY;
}
break;
case LOCATION_QWES_FEATURE_TYPE_SV_EPH:
if (itr->second) {
sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_SV_EPHEMERIS_BIT;
} else {
sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_SV_EPHEMERIS_BIT;
}
break;
case LOCATION_QWES_FEATURE_TYPE_GNSS_MULTI_FREQUENCY:
if (itr->second) {
sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_GNSS_MULTI_FREQUENCY;
} else {
sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_GNSS_MULTI_FREQUENCY;
}
break;
case LOCATION_QWES_FEATURE_TYPE_PPE:
if (itr->second) {
sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_PPE;
} else {
sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_PPE;
}
break;
case LOCATION_QWES_FEATURE_TYPE_QDR2:
if (itr->second) {
sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_QDR2;
} else {
sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_QDR2;
}
break;
case LOCATION_QWES_FEATURE_TYPE_QDR3:
if (itr->second) {
sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_QDR3;
} else {
sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_QDR3;
}
break;
case LOCATION_QWES_FEATURE_TYPE_VPE:
if (itr->second) {
sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_VPE;
} else {
sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_VPE;
}
break;
}
}
// Set CV2X basic when time freq and tunc is set
// CV2X_BASIC = LOCATION_QWES_FEATURE_TYPE_TIME_FREQUENCY &
// LOCATION_QWES_FEATURE_TYPE_TIME_UNCERTAINTY
// Set CV2X premium when time freq and tunc is set
// CV2X_PREMIUM = CV2X_BASIC & LOCATION_QWES_FEATURE_TYPE_QDR3 &
// LOCATION_QWES_FEATURE_TYPE_CLOCK_ESTIMATE
bool cv2xBasicEnabled = (1 == locQwesFeatType[LOCATION_QWES_FEATURE_TYPE_TIME_FREQUENCY]) &&
(1 == locQwesFeatType[LOCATION_QWES_FEATURE_TYPE_TIME_UNCERTAINTY]);
bool cv2xPremiumEnabled = cv2xBasicEnabled &&
(1 == locQwesFeatType[LOCATION_QWES_FEATURE_TYPE_QDR3]) &&
(1 == locQwesFeatType[LOCATION_QWES_FEATURE_TYPE_CLOCK_ESTIMATE]);
LOC_LOGd("CV2X_BASIC:%d, CV2X_PREMIUM:%d", cv2xBasicEnabled, cv2xPremiumEnabled);
if (cv2xBasicEnabled) {
sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_CV2X_LOCATION_BASIC;
} else {
sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_CV2X_LOCATION_BASIC;
}
if (cv2xPremiumEnabled) {
sQwesFeatureMask |= LOCATION_CAPABILITIES_QWES_CV2X_LOCATION_PREMIUM;
} else {
sQwesFeatureMask &= ~LOCATION_CAPABILITIES_QWES_CV2X_LOCATION_PREMIUM;
}
}
/*
get QWES feature status info
*/
static inline LocationCapabilitiesMask getQwesFeatureStatus() {
return (ContextBase::sQwesFeatureMask);
}
};
struct LocApiResponse: LocMsg {

View file

@ -28,6 +28,11 @@
*/
#ifndef ENGINE_HUB_PROXY_BASE_H
#define ENGINE_HUB_PROXY_BASE_H
#ifdef NO_UNORDERED_SET_OR_MAP
#include <map>
#else
#include <unordered_map>
#endif
namespace loc_core {
@ -114,6 +119,13 @@ public:
(void) dreConfig;
return false;
}
inline virtual bool configEngineRunState(
PositioningEngineMask engType, LocEngineRunState engState) {
(void) engType;
(void) engState;
return false;
}
};
typedef std::function<void(int count, EngineLocationInfo* locationArr)>
@ -129,6 +141,9 @@ typedef std::function<void(const GnssAidingDataSvMask& svDataMask)>
typedef std::function<void(bool nHzNeeded, bool nHzMeasNeeded)>
GnssAdapterUpdateNHzRequirementCb;
typedef std::function<void(const std::unordered_map<LocationQwesFeatureType, bool> &featureMap)>
GnssAdapterUpdateQwesFeatureStatusCb;
// potential parameters: message queue: MsgTask * msgTask;
// callback function to report back dr and ppe position and sv report
typedef EngineHubProxyBase* (getEngHubProxyFn)(
@ -137,7 +152,8 @@ typedef EngineHubProxyBase* (getEngHubProxyFn)(
GnssAdapterReportEnginePositionsEventCb positionEventCb,
GnssAdapterReportSvEventCb svEventCb,
GnssAdapterReqAidingDataCb reqAidingDataCb,
GnssAdapterUpdateNHzRequirementCb updateNHzRequirementCb);
GnssAdapterUpdateNHzRequirementCb updateNHzRequirementCb,
GnssAdapterUpdateQwesFeatureStatusCb updateQwesFeatureStatusCb);
} // namespace loc_core

View file

@ -428,4 +428,12 @@ LocAdapterBase::requestCapabilitiesCommand(LocationAPI* client)
sendMsg(new MsgRequestCapabilities(*this, client));
}
void
LocAdapterBase::reportLatencyInfoEvent(const GnssLatencyInfo& /*gnssLatencyInfo*/)
DEFAULT_IMPL()
bool LocAdapterBase::
reportQwesCapabilities(const std::unordered_map<LocationQwesFeatureType, bool> &featureMap)
DEFAULT_IMPL(false)
} // namespace loc_core

View file

@ -156,7 +156,7 @@ public:
return ContextBase::isFeatureSupported(featureVal);
}
uint32_t generateSessionId();
static uint32_t generateSessionId();
inline bool isAdapterMaster() {
return mIsMaster;
@ -236,6 +236,9 @@ public:
removeClientCompleteCallback rmClientCb);
void requestCapabilitiesCommand(LocationAPI* client);
virtual void reportLatencyInfoEvent(const GnssLatencyInfo& gnssLatencyInfo);
virtual bool reportQwesCapabilities(
const std::unordered_map<LocationQwesFeatureType, bool> &featureMap);
};
} // namespace loc_core

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2011-2014, 2016-2020 The Linux Foundation. All rights reserved.
/* Copyright (c) 2011-2014, 2016-2021 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,7 @@
#include <LocAdapterBase.h>
#include <log_util.h>
#include <LocContext.h>
#include <loc_misc_utils.h>
namespace loc_core {
@ -483,6 +484,14 @@ void LocApiBase::reportLocationSystemInfo(const LocationSystemInfo& locationSyst
TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportLocationSystemInfoEvent(locationSystemInfo));
}
void LocApiBase::reportQwesCapabilities
(
const std::unordered_map<LocationQwesFeatureType, bool> &featureMap
)
{
// loop through adapters, and deliver to all adapters.
TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportQwesCapabilities(featureMap));
}
void LocApiBase::requestXtraData()
{
// loop through adapters, and deliver to the first handling adapter.
@ -600,6 +609,12 @@ void LocApiBase::reportGnssConfig(uint32_t sessionId, const GnssConfig& gnssConf
TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportGnssConfigEvent(sessionId, gnssConfig));
}
void LocApiBase::reportLatencyInfo(GnssLatencyInfo& gnssLatencyInfo)
{
// loop through adapters, and deliver to the first handling adapter.
TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportLatencyInfoEvent(gnssLatencyInfo));
}
enum loc_api_adapter_err LocApiBase::
open(LOC_API_ADAPTER_EVENT_MASK_T /*mask*/)
DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS)
@ -913,4 +928,142 @@ DEFAULT_IMPL()
void LocApiBase::
getConstellationMultiBandConfig(uint32_t sessionId, LocApiResponse* /*adapterResponse*/)
DEFAULT_IMPL()
int64_t ElapsedRealtimeEstimator::getElapsedRealtimeEstimateNanos(int64_t curDataTimeNanos,
bool isCurDataTimeTrustable, int64_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 = (int64_t)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 = (int64_t)sinceBootTime.tv_sec * 1000000000 + sinceBootTime.tv_nsec;
int64_t sinceBootTimeTestNanos =
(int64_t)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

View file

@ -36,6 +36,13 @@
#include <MsgTask.h>
#include <LocSharedLock.h>
#include <log_util.h>
#ifdef NO_UNORDERED_SET_OR_MAP
#include <map>
#else
#include <unordered_map>
#endif
#include <inttypes.h>
#include <functional>
using namespace loc_util;
@ -194,6 +201,11 @@ public:
void reportGnssAdditionalSystemInfo(GnssAdditionalSystemInfo& additionalSystemInfo);
void sendNfwNotification(GnssNfwNotification& notification);
void reportGnssConfig(uint32_t sessionId, const GnssConfig& gnssConfig);
void reportLatencyInfo(GnssLatencyInfo& gnssLatencyInfo);
void reportQwesCapabilities
(
const std::unordered_map<LocationQwesFeatureType, bool> &featureMap
);
void geofenceBreach(size_t count, uint32_t* hwIds, Location& location,
GeofenceBreachType breachType, uint64_t timestamp);
@ -334,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, int64_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);

View file

@ -1291,7 +1291,7 @@ void SystemStatus::resetNetworkInfo() {
for (int i=0; i<mCache.mNetworkInfo.size(); ++i) {
// Reset all the cached NetworkInfo Items as disconnected
eventConnectionStatus(false, mCache.mNetworkInfo[i].mType, mCache.mNetworkInfo[i].mRoaming,
mCache.mNetworkInfo[i].mNetworkHandle);
mCache.mNetworkInfo[i].mNetworkHandle, mCache.mNetworkInfo[i].mApn);
}
}
@ -1732,11 +1732,12 @@ bool SystemStatus::setDefaultGnssEngineStates(void)
@return true when successfully done
******************************************************************************/
bool SystemStatus::eventConnectionStatus(bool connected, int8_t type,
bool roaming, NetworkHandle networkHandle)
bool roaming, NetworkHandle networkHandle,
string& apn)
{
// send networkinof dataitem to systemstatus observer clients
SystemStatusNetworkInfo s(type, "", "", connected, roaming,
(uint64_t) networkHandle);
(uint64_t) networkHandle, apn);
mSysStatusObsvr.notify({&s});
return true;

View file

@ -482,12 +482,13 @@ class SystemStatusNetworkInfo : public SystemStatusItemBase,
NetworkInfoDataItemBase* mSrcObjPtr;
public:
inline SystemStatusNetworkInfo(
int32_t type=0,
std::string typeName="",
string subTypeName="",
bool connected=false,
bool roaming=false,
uint64_t networkHandle=NETWORK_HANDLE_UNKNOWN) :
int32_t type = 0,
std::string typeName = "",
string subTypeName = "",
bool connected = false,
bool roaming = false,
uint64_t networkHandle = NETWORK_HANDLE_UNKNOWN,
string apn = "") :
NetworkInfoDataItemBase(
(NetworkType)type,
type,
@ -496,7 +497,7 @@ public:
connected && (!roaming),
connected,
roaming,
networkHandle),
networkHandle, apn),
mSrcObjPtr(nullptr) {}
inline SystemStatusNetworkInfo(const NetworkInfoDataItemBase& itemBase) :
NetworkInfoDataItemBase(itemBase),
@ -508,14 +509,19 @@ public:
for (uint8_t i = 0; rtv && i < MAX_NETWORK_HANDLES; ++i) {
rtv &= (mAllNetworkHandles[i] == peer.mAllNetworkHandles[i]);
}
return rtv;
return peer.mApn.compare(mApn);
}
inline virtual SystemStatusItemBase& collate(SystemStatusItemBase& curInfo) {
uint64_t allTypes = (static_cast<SystemStatusNetworkInfo&>(curInfo)).mAllTypes;
string& apn = (static_cast<SystemStatusNetworkInfo&>(curInfo)).mApn;
// Replace current with cached table for now and then update
memcpy(mAllNetworkHandles,
(static_cast<SystemStatusNetworkInfo&>(curInfo)).getNetworkHandle(),
sizeof(mAllNetworkHandles));
// Update the apn for non-mobile type connections.
if (TYPE_MOBILE != mType && apn.compare("") != 0) {
mApn = apn;
}
if (mConnected) {
mAllTypes |= allTypes;
for (uint8_t i = 0; i < MAX_NETWORK_HANDLES; ++i) {
@ -577,8 +583,8 @@ public:
return *this;
}
inline void dump(void) override {
LOC_LOGD("NetworkInfo: mAllTypes=%" PRIx64 " connected=%u mType=%x",
mAllTypes, mConnected, mType);
LOC_LOGD("NetworkInfo: mAllTypes=%" PRIx64 " connected=%u mType=%x mApn=%s",
mAllTypes, mConnected, mType, mApn.c_str());
}
};
@ -907,7 +913,7 @@ public:
bool getReport(SystemStatusReports& reports, bool isLatestonly = false) const;
bool setDefaultGnssEngineStates(void);
bool eventConnectionStatus(bool connected, int8_t type,
bool roaming, NetworkHandle networkHandle);
bool roaming, NetworkHandle networkHandle, string& apn);
bool updatePowerConnectState(bool charging);
void resetNetworkInfo();
};

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2015-2017, 2019, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-2017, 2020, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@ -284,7 +284,7 @@ class NetworkInfoDataItemBase : public IDataItemCore {
public:
NetworkInfoDataItemBase(
NetworkType initialType, int32_t type, string typeName, string subTypeName,
bool available, bool connected, bool roaming, uint64_t networkHandle ):
bool available, bool connected, bool roaming, uint64_t networkHandle, string apn):
mAllTypes(typeToAllTypes(initialType)),
mType(type),
mTypeName(typeName),
@ -293,7 +293,7 @@ public:
mConnected(connected),
mRoaming(roaming),
mNetworkHandle(networkHandle),
mId(NETWORKINFO_DATA_ITEM_ID) {
mId(NETWORKINFO_DATA_ITEM_ID), mApn(apn) {
mAllNetworkHandles[0].networkHandle = networkHandle;
mAllNetworkHandles[0].networkType = initialType;
}
@ -318,6 +318,7 @@ public:
bool mRoaming;
NetworkInfoType mAllNetworkHandles[MAX_NETWORK_HANDLES];
uint64_t mNetworkHandle;
string mApn;
protected:
DataItemId mId;
inline uint64_t typeToAllTypes(NetworkType type) {

View file

@ -21,6 +21,7 @@ cc_library_shared {
"GnssAdapter.cpp",
"Agps.cpp",
"XtraSystemStatusObserver.cpp",
"NativeAgpsHandler.cpp",
],
cflags: ["-fno-short-enums"] + GNSS_CFLAGS,

View file

@ -77,6 +77,15 @@ static void agpsCloseResultCb (bool isSuccess, AGpsExtType agpsType, void* userD
typedef const CdfwInterface* (*getCdfwInterface)();
inline bool GnssReportLoggerUtil::isLogEnabled() {
return (mLogLatency != nullptr);
}
inline void GnssReportLoggerUtil::log(const GnssLatencyInfo& gnssLatencyMeasInfo) {
if (mLogLatency != nullptr) {
mLogLatency(gnssLatencyMeasInfo);
}
}
GnssAdapter::GnssAdapter() :
LocAdapterBase(0,
@ -110,8 +119,9 @@ GnssAdapter::GnssAdapter() :
mSystemStatus(SystemStatus::getInstance(mMsgTask)),
mServerUrl(":"),
mXtraObserver(mSystemStatus->getOsObserver(), mMsgTask),
mLocSystemInfo{},
mBlockCPIInfo{},
mDreIntEnabled(false),
mLocSystemInfo{},
mNfwCb(NULL),
mPowerOn(false),
mAllowFlpNetworkFixes(0),
@ -127,7 +137,8 @@ GnssAdapter::GnssAdapter() :
mLastDeleteAidingDataTime(0),
mDgnssState(0),
mSendNmeaConsent(false),
mDgnssLastNmeaBootTimeMilli(0)
mDgnssLastNmeaBootTimeMilli(0),
mNativeAgpsHandler(mSystemStatus->getOsObserver(), *this)
{
LOC_LOGD("%s]: Constructor %p", __func__, this);
mLocPositionMode.mode = LOC_POSITION_MODE_INVALID;
@ -346,7 +357,8 @@ uint16_t GnssAdapter::getNumSvUsed(uint64_t svUsedIdsMask,
void
GnssAdapter::convertLocationInfo(GnssLocationInfoNotification& out,
const GpsLocationExtended& locationExtended)
const GpsLocationExtended& locationExtended,
enum loc_sess_status status)
{
out.size = sizeof(GnssLocationInfoNotification);
if (GPS_LOCATION_EXTENDED_HAS_ALTITUDE_MEAN_SEA_LEVEL & locationExtended.flags) {
@ -650,6 +662,14 @@ GnssAdapter::convertLocationInfo(GnssLocationInfoNotification& out,
out.flags |= GNSS_LOCATION_INFO_DR_SOLUTION_STATUS_MASK_BIT;
out.drSolutionStatusMask = locationExtended.drSolutionStatusMask;
}
if (GPS_LOCATION_EXTENDED_HAS_ALTITUDE_ASSUMED & locationExtended.flags) {
out.flags |= GNSS_LOCATION_INFO_ALTITUDE_ASSUMED_BIT;
out.altitudeAssumed = locationExtended.altitudeAssumed;
}
out.flags |= GNSS_LOCATION_INFO_SESSION_STATUS_BIT;
out.sessionStatus = status;
}
inline uint32_t
@ -1536,8 +1556,8 @@ GnssAdapter::gnssGetConfigCommand(GnssConfigFlagsMask configMask) {
mAdapter(adapter),
mApi(api),
mConfigMask(configMask),
mIds(nullptr),
mCount(count) {
mCount(count),
mIds(nullptr) {
if (mCount > 0) {
mIds = new uint32_t[count];
if (mIds) {
@ -2458,7 +2478,10 @@ GnssAdapter::stopClientSessions(LocationAPI* client)
void
GnssAdapter::updateClientsEventMask()
{
LOC_API_ADAPTER_EVENT_MASK_T mask = 0;
// need to register for leap second info
// for proper nmea generation
LOC_API_ADAPTER_EVENT_MASK_T mask = LOC_API_ADAPTER_BIT_LOC_SYSTEM_INFO |
LOC_API_ADAPTER_BIT_EVENT_REPORT_INFO;
for (auto it=mClientData.begin(); it != mClientData.end(); ++it) {
if (it->second.trackingCb != nullptr ||
it->second.gnssLocationInfoCb != nullptr ||
@ -2493,8 +2516,6 @@ GnssAdapter::updateClientsEventMask()
mask |= LOC_API_ADAPTER_BIT_GNSS_SV_POLYNOMIAL_REPORT;
mask |= LOC_API_ADAPTER_BIT_PARSED_UNPROPAGATED_POSITION_REPORT;
mask |= LOC_API_ADAPTER_BIT_GNSS_SV_EPHEMERIS_REPORT;
mask |= LOC_API_ADAPTER_BIT_LOC_SYSTEM_INFO;
mask |= LOC_API_ADAPTER_BIT_EVENT_REPORT_INFO;
// Nhz measurement bit is set based on callback from loc eng hub
// for Nhz engines.
@ -2519,6 +2540,13 @@ GnssAdapter::updateClientsEventMask()
// always register for NI NOTIFY VERIFY to handle internally in HAL
mask |= LOC_API_ADAPTER_BIT_NI_NOTIFY_VERIFY_REQUEST;
// Enable the latency report
if (mask & LOC_API_ADAPTER_BIT_GNSS_MEASUREMENT) {
if (mLogger.isLogEnabled()) {
mask |= LOC_API_ADAPTER_BIT_LATENCY_INFORMATION;
}
}
updateEvtMask(mask, LOC_REGISTRATION_MASK_SET);
}
@ -2573,6 +2601,7 @@ GnssAdapter::restartSessions(bool modemSSR)
// inform engine hub that GNSS session is about to start
mEngHubProxy->gnssSetFixMode(mLocPositionMode);
mEngHubProxy->gnssStartFix();
checkUpdateDgnssNtrip(false);
}
checkAndRestartSPESession();
@ -2605,6 +2634,10 @@ GnssAdapter::suspendSessions()
// inform engine hub that GNSS session has stopped
mEngHubProxy->gnssStopFix();
mLocApi->stopFix(nullptr);
if (isDgnssNmeaRequired()) {
mDgnssState &= ~DGNSS_STATE_NO_NMEA_PENDING;
}
stopDgnssNtrip();
mSPEAlreadyRunningAtHighestInterval = false;
}
}
@ -2643,6 +2676,48 @@ void GnssAdapter::checkAndRestartTimeBasedSession()
}
}
LocationCapabilitiesMask
GnssAdapter::getCapabilities()
{
LocationCapabilitiesMask mask = 0;
uint32_t carrierCapabilities = ContextBase::getCarrierCapabilities();
// time based tracking always supported
mask |= LOCATION_CAPABILITIES_TIME_BASED_TRACKING_BIT;
// geofence always supported
mask |= LOCATION_CAPABILITIES_GEOFENCE_BIT;
if (carrierCapabilities & LOC_GPS_CAPABILITY_MSB) {
mask |= LOCATION_CAPABILITIES_GNSS_MSB_BIT;
}
if (LOC_GPS_CAPABILITY_MSA & carrierCapabilities) {
mask |= LOCATION_CAPABILITIES_GNSS_MSA_BIT;
}
if (ContextBase::isMessageSupported(LOC_API_ADAPTER_MESSAGE_DISTANCE_BASE_LOCATION_BATCHING)) {
mask |= LOCATION_CAPABILITIES_TIME_BASED_BATCHING_BIT |
LOCATION_CAPABILITIES_DISTANCE_BASED_BATCHING_BIT;
}
if (ContextBase::isMessageSupported(LOC_API_ADAPTER_MESSAGE_DISTANCE_BASE_TRACKING)) {
mask |= LOCATION_CAPABILITIES_DISTANCE_BASED_TRACKING_BIT;
}
if (ContextBase::isMessageSupported(LOC_API_ADAPTER_MESSAGE_OUTDOOR_TRIP_BATCHING)) {
mask |= LOCATION_CAPABILITIES_OUTDOOR_TRIP_BATCHING_BIT;
}
if (ContextBase::gnssConstellationConfig()) {
mask |= LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT;
}
if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_DEBUG_NMEA_V02)) {
mask |= LOCATION_CAPABILITIES_DEBUG_NMEA_BIT;
}
if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_CONSTELLATION_ENABLEMENT_V02)) {
mask |= LOCATION_CAPABILITIES_CONSTELLATION_ENABLEMENT_BIT;
}
if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_AGPM_V02)) {
mask |= LOCATION_CAPABILITIES_AGPM_BIT;
}
//Get QWES feature status mask
mask |= ContextBase::getQwesFeatureStatus();
return mask;
}
void
GnssAdapter::notifyClientOfCachedLocationSystemInfo(
LocationAPI* client, const LocationCallbacks& callbacks) {
@ -2759,7 +2834,6 @@ GnssAdapter::saveTrackingSession(LocationAPI* client, uint32_t sessionId,
mTimeBasedTrackingSessions[key] = options;
}
reportPowerStateIfChanged();
checkUpdateDgnssNtrip(false);
}
void
@ -2776,16 +2850,8 @@ GnssAdapter::eraseTrackingSession(LocationAPI* client, uint32_t sessionId)
}
}
reportPowerStateIfChanged();
if (mSendNmeaConsent && mStartDgnssNtripParams.ntripParams.requiresNmeaLocation) {
LOC_LOGd("requiresNmeaLocation");
mDgnssState &= ~DGNSS_STATE_NO_NMEA_PENDING;
mStartDgnssNtripParams.nmea.clear();
}
stopDgnssNtrip();
}
bool GnssAdapter::setLocPositionMode(const LocPosMode& mode) {
if (!mLocPositionMode.equals(mode)) {
mLocPositionMode = mode;
@ -3003,6 +3069,8 @@ GnssAdapter::startTimeBasedTracking(LocationAPI* client, uint32_t sessionId,
[this, client, sessionId] (LocationError err) {
if (LOCATION_ERROR_SUCCESS != err) {
eraseTrackingSession(client, sessionId);
} else {
checkUpdateDgnssNtrip(false);
}
reportResponse(client, err, sessionId);
@ -3344,6 +3412,11 @@ GnssAdapter::stopTracking(LocationAPI* client, uint32_t id)
reportResponse(client, err, id);
}));
if (isDgnssNmeaRequired()) {
mDgnssState &= ~DGNSS_STATE_NO_NMEA_PENDING;
}
stopDgnssNtrip();
mSPEAlreadyRunningAtHighestInterval = false;
}
@ -3814,6 +3887,62 @@ bool GnssAdapter::needToGenerateNmeaReport(const uint32_t &gpsTimeOfWeekMs,
return retVal;
}
void
GnssAdapter::logLatencyInfo()
{
if (0 == mGnssLatencyInfoQueue.size()) {
LOC_LOGv("mGnssLatencyInfoQueue.size is 0");
return;
}
mGnssLatencyInfoQueue.front().hlosQtimer5 = getQTimerTickCount();
if (0 == mGnssLatencyInfoQueue.front().hlosQtimer3) {
/* if SPE from engine hub is not reported then hlosQtimer3 = 0, set it
equal to hlosQtimer2 to make sense */
LOC_LOGv("hlosQtimer3 is 0, setting it to hlosQtimer2");
mGnssLatencyInfoQueue.front().hlosQtimer3 = mGnssLatencyInfoQueue.front().hlosQtimer2;
}
if (0 == mGnssLatencyInfoQueue.front().hlosQtimer4) {
/* if PPE from engine hub is not reported then hlosQtimer4 = 0, set it
equal to hlosQtimer3 to make sense */
LOC_LOGv("hlosQtimer4 is 0, setting it to hlosQtimer3");
mGnssLatencyInfoQueue.front().hlosQtimer4 = mGnssLatencyInfoQueue.front().hlosQtimer3;
}
if (mGnssLatencyInfoQueue.front().hlosQtimer4 < mGnssLatencyInfoQueue.front().hlosQtimer3) {
/* hlosQtimer3 is timestamped when SPE from engine hub is reported,
and hlosQtimer4 is timestamped when PPE from engine hub is reported.
The order is random though, hence making sure the timestamps are sorted */
LOC_LOGv("hlosQtimer4 is < hlosQtimer3, swapping them");
std::swap(mGnssLatencyInfoQueue.front().hlosQtimer3,
mGnssLatencyInfoQueue.front().hlosQtimer4);
}
LOC_LOGv("meQtimer1=%" PRIi64 " "
"meQtimer2=%" PRIi64 " "
"meQtimer3=%" PRIi64 " "
"peQtimer1=%" PRIi64 " "
"peQtimer2=%" PRIi64 " "
"peQtimer3=%" PRIi64 " "
"smQtimer1=%" PRIi64 " "
"smQtimer2=%" PRIi64 " "
"smQtimer3=%" PRIi64 " "
"locMwQtimer=%" PRIi64 " "
"hlosQtimer1=%" PRIi64 " "
"hlosQtimer2=%" PRIi64 " "
"hlosQtimer3=%" PRIi64 " "
"hlosQtimer4=%" PRIi64 " "
"hlosQtimer5=%" PRIi64 " ",
mGnssLatencyInfoQueue.front().meQtimer1, mGnssLatencyInfoQueue.front().meQtimer2,
mGnssLatencyInfoQueue.front().meQtimer3, mGnssLatencyInfoQueue.front().peQtimer1,
mGnssLatencyInfoQueue.front().peQtimer2, mGnssLatencyInfoQueue.front().peQtimer3,
mGnssLatencyInfoQueue.front().smQtimer1, mGnssLatencyInfoQueue.front().smQtimer2,
mGnssLatencyInfoQueue.front().smQtimer3, mGnssLatencyInfoQueue.front().locMwQtimer,
mGnssLatencyInfoQueue.front().hlosQtimer1, mGnssLatencyInfoQueue.front().hlosQtimer2,
mGnssLatencyInfoQueue.front().hlosQtimer3, mGnssLatencyInfoQueue.front().hlosQtimer4,
mGnssLatencyInfoQueue.front().hlosQtimer5);
mLogger.log(mGnssLatencyInfoQueue.front());
mGnssLatencyInfoQueue.pop();
LOC_LOGv("mGnssLatencyInfoQueue.size after pop=%zu", mGnssLatencyInfoQueue.size());
}
// only fused report (when engine hub is enabled) or
// SPE report (when engine hub is disabled) will reach this function
void
@ -3827,9 +3956,9 @@ GnssAdapter::reportPosition(const UlpLocation& ulpLocation,
if (reportToGnssClient || reportToFlpClient) {
GnssLocationInfoNotification locationInfo = {};
convertLocationInfo(locationInfo, locationExtended);
convertLocationInfo(locationInfo, locationExtended, status);
convertLocation(locationInfo.location, ulpLocation, locationExtended);
logLatencyInfo();
for (auto it=mClientData.begin(); it != mClientData.end(); ++it) {
if ((reportToFlpClient && isFlpClient(it->second)) ||
(reportToGnssClient && !isFlpClient(it->second))) {
@ -3911,6 +4040,25 @@ GnssAdapter::reportPosition(const UlpLocation& ulpLocation,
}
}
void
GnssAdapter::reportLatencyInfoEvent(const GnssLatencyInfo& gnssLatencyInfo)
{
struct MsgReportLatencyInfo : public LocMsg {
GnssAdapter& mAdapter;
GnssLatencyInfo mGnssLatencyInfo;
inline MsgReportLatencyInfo(GnssAdapter& adapter,
const GnssLatencyInfo& gnssLatencyInfo) :
mGnssLatencyInfo(gnssLatencyInfo),
mAdapter(adapter) {}
inline virtual void proc() const {
mAdapter.mGnssLatencyInfoQueue.push(mGnssLatencyInfo);
LOC_LOGv("mGnssLatencyInfoQueue.size after push=%zu",
mAdapter.mGnssLatencyInfoQueue.size());
}
};
sendMsg(new MsgReportLatencyInfo(*this, gnssLatencyInfo));
}
void
GnssAdapter::reportEnginePositions(unsigned int count,
const EngineLocationInfo* locationArr)
@ -3936,13 +4084,30 @@ GnssAdapter::reportEnginePositions(unsigned int count,
}
if (needReportEnginePositions) {
convertLocationInfo(locationInfo[i], engLocation->locationExtended);
convertLocationInfo(locationInfo[i], engLocation->locationExtended,
engLocation->sessionStatus);
convertLocation(locationInfo[i].location,
engLocation->location,
engLocation->locationExtended);
}
}
const EngineLocationInfo* engLocation = locationArr;
LOC_LOGv("engLocation->locationExtended.locOutputEngType=%d",
engLocation->locationExtended.locOutputEngType);
if (0 != mGnssLatencyInfoQueue.size()) {
if ((GPS_LOCATION_EXTENDED_HAS_OUTPUT_ENG_TYPE & engLocation->locationExtended.flags) &&
(LOC_OUTPUT_ENGINE_SPE == engLocation->locationExtended.locOutputEngType)) {
mGnssLatencyInfoQueue.front().hlosQtimer3 = getQTimerTickCount();
LOC_LOGv("SPE hlosQtimer3=%" PRIi64 " ", mGnssLatencyInfoQueue.front().hlosQtimer3);
}
if ((GPS_LOCATION_EXTENDED_HAS_OUTPUT_ENG_TYPE & engLocation->locationExtended.flags) &&
(LOC_OUTPUT_ENGINE_PPE == engLocation->locationExtended.locOutputEngType)) {
mGnssLatencyInfoQueue.front().hlosQtimer4 = getQTimerTickCount();
LOC_LOGv("PPE hlosQtimer4=%" PRIi64 " ", mGnssLatencyInfoQueue.front().hlosQtimer4);
}
}
if (needReportEnginePositions) {
for (auto it=mClientData.begin(); it != mClientData.end(); ++it) {
if (nullptr != it->second.engineLocationsInfoCb) {
@ -4709,6 +4874,31 @@ bool GnssAdapter::reportGnssAdditionalSystemInfoEvent(
return true;
}
bool GnssAdapter::reportQwesCapabilities(
const std::unordered_map<LocationQwesFeatureType, bool> &featureMap)
{
struct MsgReportQwesFeatureStatus : public LocMsg {
GnssAdapter& mAdapter;
const std::unordered_map<LocationQwesFeatureType, bool> mFeatureMap;
inline MsgReportQwesFeatureStatus(GnssAdapter& adapter,
const std::unordered_map<LocationQwesFeatureType, bool> &featureMap) :
LocMsg(),
mAdapter(adapter),
mFeatureMap(std::move(featureMap)) {}
inline virtual void proc() const {
LOC_LOGi("ReportQwesFeatureStatus before caps %" PRIx64 " ",
mAdapter.getCapabilities());
ContextBase::setQwesFeatureStatus(mFeatureMap);
LOC_LOGi("ReportQwesFeatureStatus After caps %" PRIx64 " ",
mAdapter.getCapabilities());
mAdapter.broadcastCapabilities(mAdapter.getCapabilities());
}
};
sendMsg(new MsgReportQwesFeatureStatus(*this, featureMap));
return true;
}
void GnssAdapter::initOdcpiCommand(const OdcpiRequestCallback& callback,
OdcpiPrioritytype priority)
{
@ -4838,23 +5028,20 @@ GnssAdapter::reportGnssEngEnergyConsumedEvent(uint64_t energyConsumedSinceFirstB
void GnssAdapter::initDefaultAgps() {
LOC_LOGD("%s]: ", __func__);
void *handle = nullptr;
if ((handle = dlopen("libloc_net_iface.so", RTLD_NOW)) == nullptr) {
LOC_LOGD("%s]: libloc_net_iface.so not found !", __func__);
return;
}
LocAgpsGetAgpsCbInfo getAgpsCbInfo = (LocAgpsGetAgpsCbInfo)
dlsym(handle, "LocNetIfaceAgps_getAgpsCbInfo");
if (getAgpsCbInfo == nullptr) {
LOC_LOGE("%s]: Failed to get method LocNetIfaceAgps_getStatusCb", __func__);
dlclose(handle);
return;
LocAgpsGetAgpsCbInfo getAgpsCbInfo =
(LocAgpsGetAgpsCbInfo)dlGetSymFromLib(handle, "libloc_net_iface.so",
"LocNetIfaceAgps_getAgpsCbInfo");
// Below step is to make sure we init nativeAgpsHandler
// for Android platforms only
AgpsCbInfo cbInfo = {};
if (nullptr != getAgpsCbInfo) {
cbInfo = getAgpsCbInfo(agpsOpenResultCb, agpsCloseResultCb, this);
} else {
cbInfo = mNativeAgpsHandler.getAgpsCbInfo();
}
AgpsCbInfo& cbInfo = getAgpsCbInfo(agpsOpenResultCb, agpsCloseResultCb, this);
if (cbInfo.statusV4Cb == nullptr) {
LOC_LOGE("%s]: statusV4Cb is nullptr!", __func__);
dlclose(handle);
@ -5926,7 +6113,7 @@ GnssAdapter::configLeverArmCommand(const LeverArmConfigInfo& configInfo) {
mSessionId(sessionId),
mConfigInfo(configInfo) {}
inline virtual void proc() const {
// save the lever ARM config info for translate position from GNSS antenna based
// save the lever ARM config info for translating position from GNSS antenna based
// to VRP based
if (mConfigInfo.leverArmValidMask & LEVER_ARM_TYPE_GNSS_TO_VRP_BIT) {
mAdapter.mLocConfigInfo.leverArmConfigInfo.leverArmValidMask |=
@ -6181,6 +6368,47 @@ uint32_t GnssAdapter::configDeadReckoningEngineParamsCommand(
return sessionId;
}
uint32_t GnssAdapter::configEngineRunStateCommand(
PositioningEngineMask engType, LocEngineRunState engState) {
// generated session id will be none-zero
uint32_t sessionId = generateSessionId();
LOC_LOGe("session id %u, eng type 0x%x, eng state %d, dre enabled %d",
sessionId, engType, engState, mDreIntEnabled);
struct MsgConfigEngineRunState : public LocMsg {
GnssAdapter& mAdapter;
uint32_t mSessionId;
PositioningEngineMask mEngType;
LocEngineRunState mEngState;
inline MsgConfigEngineRunState(GnssAdapter& adapter,
uint32_t sessionId,
PositioningEngineMask engType,
LocEngineRunState engState) :
LocMsg(),
mAdapter(adapter),
mSessionId(sessionId),
mEngType(engType),
mEngState(engState) {}
inline virtual void proc() const {
LocationError err = LOCATION_ERROR_NOT_SUPPORTED;
// Currently, only DR engine supports pause/resume request
if ((mEngType == DEAD_RECKONING_ENGINE) &&
(mAdapter.mDreIntEnabled == true)) {
if (true == mAdapter.mEngHubProxy->configEngineRunState(mEngType, mEngState)) {
err = LOCATION_ERROR_SUCCESS;
}
}
mAdapter.reportResponse(err, mSessionId);
}
};
sendMsg(new MsgConfigEngineRunState(*this, sessionId, engType, engState));
return sessionId;
}
void GnssAdapter::reportGnssConfigEvent(uint32_t sessionId, const GnssConfig& gnssConfig)
{
struct MsgReportGnssConfig : public LocMsg {
@ -6255,9 +6483,14 @@ GnssAdapter::initEngHubProxy() {
strlen(PROCESS_NAME_ENGINE_SERVICE)) == 0) &&
(processInfoList[i].proc_status == ENABLED)) {
pluginDaemonEnabled = true;
// check if this is DRE-INT engine
if ((processInfoList[i].args[1]!= nullptr) &&
(strncmp(processInfoList[i].args[1], "DRE-INT", sizeof("DRE-INT")) == 0)) {
mDreIntEnabled = true;
break;
}
}
}
// no plugin daemon is enabled for this platform,
// check if external engine is present for which we need
@ -6317,12 +6550,18 @@ GnssAdapter::initEngHubProxy() {
}
};
GnssAdapterUpdateQwesFeatureStatusCb updateQwesFeatureStatusCb =
[this] (const std::unordered_map<LocationQwesFeatureType, bool> &featureMap) {
reportQwesCapabilities(featureMap);
};
getEngHubProxyFn* getter = (getEngHubProxyFn*) dlsym(handle, "getEngHubProxy");
if(getter != nullptr) {
EngineHubProxyBase* hubProxy = (*getter) (mMsgTask, mSystemStatus->getOsObserver(),
reportPositionEventCb,
reportSvEventCb, reqAidingDataCb,
updateNHzRequirementCb);
updateNHzRequirementCb,
updateQwesFeatureStatusCb);
if (hubProxy != nullptr) {
mEngHubProxy = hubProxy;
engHubLoadSuccessful = true;
@ -6539,9 +6778,6 @@ void GnssAdapter::enablePPENtripStreamCommand(const GnssNtripConnectionParams& p
}
void GnssAdapter::handleEnablePPENtrip(const GnssNtripConnectionParams& params) {
LOC_LOGd("isInSession %d mDgnssState 0x%x", isInSession(), mDgnssState);
LOC_LOGd("%d %s %d %s %s %s %d mSendNmeaConsent %d",
params.useSSL, params.hostNameOrIp.data(), params.port,
params.mountPoint.data(), params.username.data(), params.password.data(),
@ -6555,7 +6791,8 @@ void GnssAdapter::handleEnablePPENtrip(const GnssNtripConnectionParams& params)
0 == pNtripParams->mountPoint.compare(params.mountPoint) &&
0 == pNtripParams->username.compare(params.username) &&
0 == pNtripParams->password.compare(params.password) &&
params.requiresNmeaLocation == params.requiresNmeaLocation) {
pNtripParams->requiresNmeaLocation == params.requiresNmeaLocation &&
mDgnssState & DGNSS_STATE_ENABLE_NTRIP_COMMAND) {
LOC_LOGd("received same Ntrip param");
return;
}
@ -6590,13 +6827,14 @@ void GnssAdapter::disablePPENtripStreamCommand() {
}
void GnssAdapter::handleDisablePPENtrip() {
mStartDgnssNtripParams.clear();
mDgnssState &= ~DGNSS_STATE_ENABLE_NTRIP_COMMAND;
mDgnssState |= DGNSS_STATE_NO_NMEA_PENDING;
stopDgnssNtrip();
}
void GnssAdapter::checkUpdateDgnssNtrip(bool isLocationValid) {
LOC_LOGd("isInSession %d mDgnssState 0x%x isLocationValid %d",
isInSession(), mDgnssState, isLocationValid);
if (isInSession()) {
uint64_t curBootTime = getBootTimeMilliSec();
if (mDgnssState == (DGNSS_STATE_ENABLE_NTRIP_COMMAND | DGNSS_STATE_NO_NMEA_PENDING)) {
@ -6615,12 +6853,11 @@ void GnssAdapter::checkUpdateDgnssNtrip(bool isLocationValid) {
}
void GnssAdapter::stopDgnssNtrip() {
LOC_LOGd("isInSession %d mDgnssState 0x%x", isInSession(), mDgnssState);
mStartDgnssNtripParams.nmea.clear();
if (mDgnssState & DGNSS_STATE_NTRIP_SESSION_STARTED) {
mDgnssState &= ~DGNSS_STATE_NTRIP_SESSION_STARTED;
mXtraObserver.stopDgnssSource();
} else {
LOC_LOGd("isInSession %d mDgnssState 0x%x",
isInSession(), mDgnssState);
}
}

View file

@ -39,6 +39,9 @@
#include <XtraSystemStatusObserver.h>
#include <map>
#include <functional>
#include <loc_misc_utils.h>
#include <queue>
#include <NativeAgpsHandler.h>
#define MAX_URL_LEN 256
#define NMEA_SENTENCE_MAX_LENGTH 200
@ -177,6 +180,23 @@ typedef uint16_t DGnssStateBitMask;
#define DGNSS_STATE_NO_NMEA_PENDING 0X02
#define DGNSS_STATE_NTRIP_SESSION_STARTED 0X04
class GnssReportLoggerUtil {
public:
typedef void (*LogGnssLatency)(const GnssLatencyInfo& gnssLatencyMeasInfo);
GnssReportLoggerUtil() : mLogLatency(nullptr) {
const char* libname = "liblocdiagiface.so";
void* libHandle = nullptr;
mLogLatency = (LogGnssLatency)dlGetSymFromLib(libHandle, libname, "LogGnssLatency");
}
bool isLogEnabled();
void log(const GnssLatencyInfo& gnssLatencyMeasInfo);
private:
LogGnssLatency mLogLatency;
};
class GnssAdapter : public LocAdapterBase {
/* ==== Engine Hub ===================================================================== */
@ -258,6 +278,12 @@ class GnssAdapter : public LocAdapterBase {
BlockCPIInfo mBlockCPIInfo;
bool mPowerOn;
uint32_t mAllowFlpNetworkFixes;
std::queue<GnssLatencyInfo> mGnssLatencyInfoQueue;
GnssReportLoggerUtil mLogger;
bool mDreIntEnabled;
/* === NativeAgpsHandler ======================================================== */
NativeAgpsHandler mNativeAgpsHandler;
/* === Misc callback from QMI LOC API ============================================== */
GnssEnergyConsumedCallback mGnssEnergyConsumedCb;
@ -268,7 +294,8 @@ class GnssAdapter : public LocAdapterBase {
static void convertLocation(Location& out, const UlpLocation& ulpLocation,
const GpsLocationExtended& locationExtended);
static void convertLocationInfo(GnssLocationInfoNotification& out,
const GpsLocationExtended& locationExtended);
const GpsLocationExtended& locationExtended,
loc_sess_status status);
static uint16_t getNumSvUsed(uint64_t svUsedIdsMask,
int totalSvCntInThisConstellation);
@ -290,6 +317,8 @@ protected:
/* ==== CLIENT ========================================================================= */
virtual void updateClientsEventMask();
virtual void stopClientSessions(LocationAPI* client);
inline void setNmeaReportRateConfig();
void logLatencyInfo();
public:
@ -434,6 +463,8 @@ public:
inline void antennaInfoCloseCommand() { mIsAntennaInfoInterfaceOpened = false; }
uint32_t configMinGpsWeekCommand(uint16_t minGpsWeek);
uint32_t configDeadReckoningEngineParamsCommand(const DeadReckoningEngineConfig& dreConfig);
uint32_t configEngineRunStateCommand(PositioningEngineMask engType,
LocEngineRunState engState);
/* ========= ODCPI ===================================================================== */
/* ======== COMMANDS ====(Called from Client Thread)==================================== */
@ -489,6 +520,11 @@ public:
virtual bool reportGnssAdditionalSystemInfoEvent(
GnssAdditionalSystemInfo& additionalSystemInfo);
virtual void reportNfwNotificationEvent(GnssNfwNotification& notification);
virtual void reportLatencyInfoEvent(const GnssLatencyInfo& gnssLatencyInfo);
virtual bool reportQwesCapabilities
(
const std::unordered_map<LocationQwesFeatureType, bool> &featureMap
);
/* ======== UTILITIES ================================================================= */
bool needReportForGnssClient(const UlpLocation& ulpLocation,
@ -589,6 +625,7 @@ public:
void setSuplHostServer(const char* server, int port, LocServerType type);
void notifyClientOfCachedLocationSystemInfo(LocationAPI* client,
const LocationCallbacks& callbacks);
LocationCapabilitiesMask getCapabilities();
void updateSystemPowerStateCommand(PowerStateType systemPowerState);
/*==== DGnss Usable Report Flag ====================================================*/

View file

@ -13,7 +13,8 @@ libgnss_la_SOURCES = \
location_gnss.cpp \
GnssAdapter.cpp \
XtraSystemStatusObserver.cpp \
Agps.cpp
Agps.cpp \
NativeAgpsHandler.cpp
if USE_GLIB
libgnss_la_CFLAGS = -DUSE_GLIB $(AM_CFLAGS) @GLIB_CFLAGS@

View file

@ -0,0 +1,127 @@
/* Copyright (c) 2020, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* 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_NativeAgpsHandler"
#include <LocAdapterBase.h>
#include <SystemStatus.h>
#include <DataItemId.h>
#include <DataItemsFactoryProxy.h>
#include <DataItemConcreteTypesBase.h>
#include <loc_log.h>
#include <NativeAgpsHandler.h>
#include <GnssAdapter.h>
using namespace loc_core;
// IDataItemObserver overrides
void NativeAgpsHandler::getName(string& name) {
name = "NativeAgpsHandler";
}
void NativeAgpsHandler::notify(const list<IDataItemCore*>& dlist) {
for (auto each : dlist) {
switch (each->getId()) {
case NETWORKINFO_DATA_ITEM_ID: {
NetworkInfoDataItemBase* networkInfo =
static_cast<NetworkInfoDataItemBase*>(each);
uint64_t mobileBit = (uint64_t )1 << loc_core::TYPE_MOBILE;
uint64_t allTypes = networkInfo->mAllTypes;
mConnected = ((networkInfo->mAllTypes & mobileBit) == mobileBit);
/**
* mApn Telephony preferred Access Point Name to use for
* carrier data connection when connected to a cellular network.
* Empty string, otherwise.
*/
mApn = networkInfo->mApn;
LOC_LOGd("updated mConnected:%d, mApn: %s", mConnected, mApn.c_str());
break;
}
default:
break;
}
}
}
NativeAgpsHandler* NativeAgpsHandler::sLocalHandle = nullptr;
NativeAgpsHandler::NativeAgpsHandler(IOsObserver* sysStatObs, GnssAdapter& adapter) :
mSystemStatusObsrvr(sysStatObs), mConnected(false), mAdapter(adapter) {
sLocalHandle = this;
list<DataItemId> subItemIdList = {NETWORKINFO_DATA_ITEM_ID};
mSystemStatusObsrvr->subscribe(subItemIdList, this);
}
NativeAgpsHandler::~NativeAgpsHandler() {
if (nullptr != mSystemStatusObsrvr) {
LOC_LOGd("Unsubscribe for network info.");
list<DataItemId> subItemIdList = {NETWORKINFO_DATA_ITEM_ID};
mSystemStatusObsrvr->unsubscribe(subItemIdList, this);
}
sLocalHandle = nullptr;
mSystemStatusObsrvr = nullptr;
}
AgpsCbInfo NativeAgpsHandler::getAgpsCbInfo() {
AgpsCbInfo nativeCbInfo = {};
nativeCbInfo.statusV4Cb = (void*)agnssStatusIpV4Cb;
nativeCbInfo.atlType = AGPS_ATL_TYPE_WWAN;
return nativeCbInfo;
}
void NativeAgpsHandler::agnssStatusIpV4Cb(AGnssExtStatusIpV4 statusInfo) {
if (nullptr != sLocalHandle) {
sLocalHandle->processATLRequestRelease(statusInfo);
} else {
LOC_LOGe("sLocalHandle is null");
}
}
void NativeAgpsHandler::processATLRequestRelease(AGnssExtStatusIpV4 statusInfo) {
if (LOC_AGPS_TYPE_WWAN_ANY == statusInfo.type) {
LOC_LOGd("status.type = %d status.apnTypeMask = 0x%X", statusInfo.type,
statusInfo.apnTypeMask);
switch (statusInfo.status) {
case LOC_GPS_REQUEST_AGPS_DATA_CONN:
if (mConnected) {
mAdapter.dataConnOpenCommand(LOC_AGPS_TYPE_WWAN_ANY, mApn.c_str(), mApn.size(),
AGPS_APN_BEARER_IPV4);
} else {
mAdapter.dataConnFailedCommand(LOC_AGPS_TYPE_WWAN_ANY);
}
break;
case LOC_GPS_RELEASE_AGPS_DATA_CONN:
mAdapter.dataConnClosedCommand(LOC_AGPS_TYPE_WWAN_ANY);
break;
default:
LOC_LOGe("Invalid Request: %d", statusInfo.status);
}
} else {
LOC_LOGe("mAgpsManger is null or invalid request type!");
}
}

View file

@ -0,0 +1,64 @@
/* Copyright (c) 2020, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* 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 NATIVEAGPSHANDLER_H
#define NATIVEAGPSHANDLER_H
#include <cinttypes>
#include <string.h>
#include <gps_extended_c.h>
#include <IDataItemObserver.h>
#include <IDataItemCore.h>
#include <IOsObserver.h>
using namespace std;
using loc_core::IOsObserver;
using loc_core::IDataItemObserver;
using loc_core::IDataItemCore;
class GnssAdapter;
class NativeAgpsHandler : public IDataItemObserver {
public:
NativeAgpsHandler(IOsObserver* sysStatObs, GnssAdapter& adapter);
~NativeAgpsHandler();
AgpsCbInfo getAgpsCbInfo();
// IDataItemObserver overrides
virtual void notify(const list<IDataItemCore*>& dlist);
inline virtual void getName(string& name);
private:
static NativeAgpsHandler* sLocalHandle;
static void agnssStatusIpV4Cb(AGnssExtStatusIpV4 statusInfo);
void processATLRequestRelease(AGnssExtStatusIpV4 statusInfo);
IOsObserver* mSystemStatusObsrvr;
bool mConnected;
string mApn;
GnssAdapter& mAdapter;
};
#endif // NATIVEAGPSHANDLER_H

View file

@ -66,8 +66,8 @@ static void agpsDataConnOpen(AGpsExtType agpsType, const char* apnName, int apnL
static void agpsDataConnClosed(AGpsExtType agpsType);
static void agpsDataConnFailed(AGpsExtType agpsType);
static void getDebugReport(GnssDebugReport& report);
static void updateConnectionStatus(bool connected, int8_t type, bool roaming = false,
NetworkHandle networkHandle = NETWORK_HANDLE_UNKNOWN);
static void updateConnectionStatus(bool connected, int8_t type, bool roaming,
NetworkHandle networkHandle, string& apn);
static void getGnssEnergyConsumed(GnssEnergyConsumedCallback energyConsumedCb);
static void enableNfwLocationAccess(bool enable);
static void nfwInit(const NfwCbInfo& cbInfo);
@ -103,6 +103,7 @@ static bool measCorrSetCorrections(const GnssMeasurementCorrections gnssMeasCorr
static void measCorrClose();
static uint32_t antennaInfoInit(const antennaInfoCb antennaInfoCallback);
static void antennaInfoClose();
static uint32_t configEngineRunState(PositioningEngineMask engType, LocEngineRunState engState);
static const GnssInterface gGnssInterface = {
sizeof(GnssInterface),
@ -160,7 +161,8 @@ static const GnssInterface gGnssInterface = {
disablePPENtripStream,
gnssUpdateSecondaryBandConfig,
gnssGetSecondaryBandConfig,
resetNetworkInfo
resetNetworkInfo,
configEngineRunState
};
#ifndef DEBUG_X86
@ -369,10 +371,11 @@ static void getDebugReport(GnssDebugReport& report) {
}
static void updateConnectionStatus(bool connected, int8_t type,
bool roaming, NetworkHandle networkHandle) {
bool roaming, NetworkHandle networkHandle,
string& apn) {
if (NULL != gGnssAdapter) {
gGnssAdapter->getSystemStatus()->eventConnectionStatus(
connected, type, roaming, networkHandle);
connected, type, roaming, networkHandle, apn);
}
}
@ -580,3 +583,11 @@ static void disablePPENtripStream(){
gGnssAdapter->disablePPENtripStreamCommand();
}
}
static uint32_t configEngineRunState(PositioningEngineMask engType, LocEngineRunState engState) {
if (NULL != gGnssAdapter) {
return gGnssAdapter->configEngineRunStateCommand(engType, engState);
} else {
return 0;
}
}

View file

@ -363,6 +363,44 @@ public:
LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
*/
virtual uint32_t configDeadReckoningEngineParams(const DeadReckoningEngineConfig& dreConfig)=0;
/** @brief
This API is used to instruct the specified engine to be in
the pause/resume state. <br/>
When the engine is placed in paused state, the engine will
stop. If there is an on-going session, engine will no longer
produce fixes. In the paused state, calling API to delete
aiding data from the paused engine may not have effect.
Request to delete Aiding data shall be issued after
engine resume. <br/>
Currently, only DRE engine will support pause/resume
request. responseCb() will return not supported when request
is made to pause/resume none-DRE engine. <br/>
Request to pause/resume DRE engine can be made with or
without an on-going session. With QDR engine, on resume,
GNSS position & heading re-acquisition is needed for DR
engine to engage. If DR engine is already in the requested
state, the request will be no-op. <br/>
@param
engType: the engine that is instructed to change its run
state. <br/>
engState: the new engine run state that the engine is
instructed to be in. <br/>
@return
A session id that will be returned in responseCallback to
match command with response. This effect is global for all
clients of LocationAPI responseCallback returns:
LOCATION_ERROR_SUCCESS if successful
LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
*/
virtual uint32_t configEngineRunState(PositioningEngineMask engType,
LocEngineRunState engState) = 0;
};
#endif /* ILOCATIONAPI_H */

View file

@ -39,6 +39,15 @@
typedef const GnssInterface* (getGnssInterface)();
typedef const GeofenceInterface* (getGeofenceInterface)();
typedef const BatchingInterface* (getBatchingInterface)();
typedef void (createOSFramework)();
typedef void (destroyOSFramework)();
// GTP services
typedef uint32_t (setOptInStatusGetter)(bool userConsent, responseCallback* callback);
typedef void (enableProviderGetter)();
typedef void (disableProviderGetter)();
typedef void (getSingleNetworkLocationGetter)(trackingCallback* callback);
typedef void (stopNetworkLocationGetter)(trackingCallback* callback);
typedef struct {
// bit mask of the adpaters that we need to wait for the removeClientCompleteCallback
@ -68,6 +77,7 @@ static pthread_mutex_t gDataMutex = PTHREAD_MUTEX_INITIALIZER;
static bool gGnssLoadFailed = false;
static bool gBatchingLoadFailed = false;
static bool gGeofenceLoadFailed = false;
static uint32_t gOSFrameworkRefCount = 0;
template <typename T1, typename T2>
static const T1* loadLocationInterface(const char* library, const char* name) {
@ -80,6 +90,28 @@ static const T1* loadLocationInterface(const char* library, const char* name) {
}
}
static void createOSFrameworkInstance() {
void* libHandle = nullptr;
createOSFramework* getter = (createOSFramework*)dlGetSymFromLib(libHandle,
"liblocationservice_glue.so", "createOSFramework");
if (getter != nullptr) {
(*getter)();
} else {
LOC_LOGe("dlGetSymFromLib failed for liblocationservice_glue.so");
}
}
static void destroyOSFrameworkInstance() {
void* libHandle = nullptr;
destroyOSFramework* getter = (destroyOSFramework*)dlGetSymFromLib(libHandle,
"liblocationservice_glue.so", "destroyOSFramework");
if (getter != nullptr) {
(*getter)();
} else {
LOC_LOGe("dlGetSymFromLib failed for liblocationservice_glue.so");
}
}
static bool needsGnssTrackingInfo(LocationCallbacks& locationCallbacks)
{
return (locationCallbacks.gnssLocationInfoCb != nullptr ||
@ -163,6 +195,7 @@ LocationAPI::createInstance (LocationCallbacks& locationCallbacks)
if (nullptr == locationCallbacks.capabilitiesCb ||
nullptr == locationCallbacks.responseCb ||
nullptr == locationCallbacks.collectiveResponseCb) {
LOC_LOGe("missing mandatory callback, return null");
return NULL;
}
@ -171,6 +204,11 @@ LocationAPI::createInstance (LocationCallbacks& locationCallbacks)
pthread_mutex_lock(&gDataMutex);
gOSFrameworkRefCount++;
if (1 == gOSFrameworkRefCount) {
createOSFrameworkInstance();
}
if (isGnssClient(locationCallbacks)) {
if (NULL == gData.gnssInterface && !gGnssLoadFailed) {
gData.gnssInterface =
@ -296,6 +334,11 @@ LocationAPI::destroy(locationApiDestroyCompleteCallback destroyCompleteCb)
__func__, __LINE__, this);
}
if (1 == gOSFrameworkRefCount) {
destroyOSFrameworkInstance();
}
gOSFrameworkRefCount--;
pthread_mutex_unlock(&gDataMutex);
if (invokeDestroyCb) {
if (!destroyCompleteCb) {
@ -606,6 +649,52 @@ LocationAPI::gnssNiResponse(uint32_t id, GnssNiResponse response)
pthread_mutex_unlock(&gDataMutex);
}
void LocationAPI::enableNetworkProvider() {
void* libHandle = nullptr;
enableProviderGetter* setter = (enableProviderGetter*)dlGetSymFromLib(libHandle,
"liblocationservice_glue.so", "enableNetworkProvider");
if (setter != nullptr) {
(*setter)();
} else {
LOC_LOGe("dlGetSymFromLib failed for liblocationservice_glue.so");
}
}
void LocationAPI::disableNetworkProvider() {
void* libHandle = nullptr;
disableProviderGetter* setter = (disableProviderGetter*)dlGetSymFromLib(libHandle,
"liblocationservice_glue.so", "disableNetworkProvider");
if (setter != nullptr) {
(*setter)();
} else {
LOC_LOGe("dlGetSymFromLib failed for liblocationservice_glue.so");
}
}
void LocationAPI::startNetworkLocation(trackingCallback* callback) {
void* libHandle = nullptr;
getSingleNetworkLocationGetter* setter =
(getSingleNetworkLocationGetter*)dlGetSymFromLib(libHandle,
"liblocationservice_glue.so", "startNetworkLocation");
if (setter != nullptr) {
(*setter)(callback);
} else {
LOC_LOGe("dlGetSymFromLib failed for liblocationservice_glue.so");
}
}
void LocationAPI::stopNetworkLocation(trackingCallback* callback) {
void* libHandle = nullptr;
stopNetworkLocationGetter* setter = (stopNetworkLocationGetter*)dlGetSymFromLib(libHandle,
"liblocationservice_glue.so", "stopNetworkLocation");
if (setter != nullptr) {
LOC_LOGe("called");
(*setter)(callback);
} else {
LOC_LOGe("dlGetSymFromLib failed for liblocationservice_glue.so");
}
}
LocationControlAPI*
LocationControlAPI::createInstance(LocationControlCallbacks& locationControlCallbacks)
{
@ -857,3 +946,31 @@ uint32_t LocationControlAPI::configDeadReckoningEngineParams(
pthread_mutex_unlock(&gDataMutex);
return id;
}
uint32_t LocationControlAPI::configEngineRunState(
PositioningEngineMask engType, LocEngineRunState engState) {
uint32_t id = 0;
pthread_mutex_lock(&gDataMutex);
if (gData.gnssInterface != NULL) {
id = gData.gnssInterface->configEngineRunState(engType, engState);
} else {
LOC_LOGe("No gnss interface available for Location Control API");
}
pthread_mutex_unlock(&gDataMutex);
return id;
}
uint32_t LocationControlAPI::setOptInStatus(bool userConsent) {
void* libHandle = nullptr;
uint32_t sessionId = 0;
setOptInStatusGetter* setter = (setOptInStatusGetter*)dlGetSymFromLib(libHandle,
"liblocationservice_glue.so", "setOptInStatus");
if (setter != nullptr) {
sessionId = (*setter)(userConsent, &gData.controlCallbacks.responseCb);
} else {
LOC_LOGe("dlGetSymFromLib failed for liblocationservice_glue.so");
}
return sessionId;
}

View file

@ -178,6 +178,20 @@ public:
LOCATION_ERROR_INVALID_PARAMETER if any parameters in GnssNiResponse are invalid
LOCATION_ERROR_ID_UNKNOWN if id does not match a gnssNiCallback */
virtual void gnssNiResponse(uint32_t id, GnssNiResponse response) override;
/* ================================== NETWORK PROVIDER =========================== */
/* enableNetworkProvider enables Network Provider */
virtual void enableNetworkProvider();
/* disableNetworkProvider disables Network Provider */
virtual void disableNetworkProvider();
/* startNetworkLocation start a single shot network location request */
virtual void startNetworkLocation(trackingCallback* callback);
/* stopNetworkLocation stop any ongoing network location request */
virtual void stopNetworkLocation(trackingCallback* callback);
};
typedef struct {
@ -442,6 +456,57 @@ public:
*/
virtual uint32_t configDeadReckoningEngineParams(
const DeadReckoningEngineConfig& dreConfig) override;
/** @brief
This API is used to instruct the specified engine to be in
the pause/resume state. <br/>
When the engine is placed in paused state, the engine will
stop. If there is an on-going session, engine will no longer
produce fixes. In the paused state, calling API to delete
aiding data from the paused engine may not have effect.
Request to delete Aiding data shall be issued after
engine resume. <br/>
Currently, only DRE engine will support pause/resume
request. responseCb() will return not supported when request
is made to pause/resume none-DRE engine. <br/>
Request to pause/resume DRE engine can be made with or
without an on-going session. With QDR engine, on resume, GNSS
position & heading re-acquisition is needed for DR engine to
engage. If DR engine is already in the requested state, the
request will be no-op. <br/>
@param
engType: the engine that is instructed to change its run
state. <br/>
engState: the new engine run state that the engine is
instructed to be in. <br/>
@return
A session id that will be returned in responseCallback to
match command with response. This effect is global for all
clients of LocationAPI responseCallback returns:
LOCATION_ERROR_SUCCESS if successful
LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
*/
virtual uint32_t configEngineRunState(PositioningEngineMask engType,
LocEngineRunState engState) override;
/** @brief
Set the EULA opt-in status from system user. This is used as consent to
use network-based positioning.
@param
userConsnt: user agrees to use GTP service or not.
@return
A session id that will be returned in responseCallback to
match command with response.
*/
virtual uint32_t setOptInStatus(bool userConsent);
};
#endif /* LOCATIONAPI_H */

View file

@ -61,7 +61,8 @@ typedef enum {
LOCATION_ERROR_ID_UNKNOWN,
LOCATION_ERROR_ALREADY_STARTED,
LOCATION_ERROR_GEOFENCES_AT_MAX,
LOCATION_ERROR_NOT_SUPPORTED
LOCATION_ERROR_NOT_SUPPORTED,
LOCATION_ERROR_TIMEOUT,
} LocationError;
// Flags to indicate which values are valid in a Location
@ -209,7 +210,9 @@ typedef enum {
GNSS_LOCATION_INFO_CONFORMITY_INDEX_BIT = (1<<28), // conformity index
GNSS_LOCATION_INFO_LLA_VRP_BASED_BIT = (1<<29), // VRP-based lat/long/alt
GNSS_LOCATION_INFO_ENU_VELOCITY_VRP_BASED_BIT = (1<<30), // VRP-based east/north/up vel
GNSS_LOCATION_INFO_DR_SOLUTION_STATUS_MASK_BIT = (1ULL<<31), // DR solution status
GNSS_LOCATION_INFO_DR_SOLUTION_STATUS_MASK_BIT = (1ULL<<31), // Valid DR solution status
GNSS_LOCATION_INFO_ALTITUDE_ASSUMED_BIT = (1ULL<<32), // Valid altitude assumed
GNSS_LOCATION_INFO_SESSION_STATUS_BIT = (1ULL<<33), // session status
} GnssLocationInfoFlagBits;
typedef enum {
@ -233,7 +236,8 @@ typedef enum {
GEOFENCE_STATUS_AVAILABILE_YES,
} GeofenceStatusAvailable;
typedef uint32_t LocationCapabilitiesMask;
// Set of masks for Modem and QWES capabilities.
typedef uint64_t LocationCapabilitiesMask;
typedef enum {
// supports startTracking API with minInterval param
LOCATION_CAPABILITIES_TIME_BASED_TRACKING_BIT = (1<<0),
@ -267,8 +271,86 @@ typedef enum {
LOCATION_CAPABILITIES_CONFORMITY_INDEX_BIT = (1<<14),
// support precise location edgnss
LOCATION_CAPABILITIES_EDGNSS_BIT = (1<<15),
// Modem supports Carrier Phase for Precise Positioning
// Measurement Engine (PPME).
LOCATION_CAPABILITIES_QWES_CARRIER_PHASE_BIT = (1<<16),
// Modem supports SV Polynomial for tightly coupled external
// DR support. This is a Standalone Feature.
LOCATION_CAPABILITIES_QWES_SV_POLYNOMIAL_BIT = (1<<17),
// Modem supports SV Ephemeris for tightly coupled external
// PPE engines. This is a Standalone Feature.
LOCATION_CAPABILITIES_QWES_SV_EPHEMERIS_BIT = (1<<18),
// Modem supports GNSS Single Frequency feature. This is a
// Standalone Feature.
LOCATION_CAPABILITIES_QWES_GNSS_SINGLE_FREQUENCY = (1<<19),
// Modem supports GNSS Multi Frequency feature. Multi Frequency
// enables Single frequency also.
LOCATION_CAPABILITIES_QWES_GNSS_MULTI_FREQUENCY = (1<<20),
// This mask indicates VPe license bundle is enabled. VEPP
// bundle include Carrier Phase and SV Polynomial features.
LOCATION_CAPABILITIES_QWES_VPE = (1<<21),
// This mask indicates support for CV2X Location basic features.
// This bundle includes features for GTS Time & Freq, C-TUNC
// (Constrained Time uncertainity.
LOCATION_CAPABILITIES_QWES_CV2X_LOCATION_BASIC = (1<<22),
// This mask indicates support for CV2X Location premium features.
// This bundle includes features for CV2X Location Basic features,
// QDR3 feature, and PACE. (Position Assisted Clock Estimator.
LOCATION_CAPABILITIES_QWES_CV2X_LOCATION_PREMIUM = (1<<23),
// This mask indicates that PPE (Precise Positioning Engine)
// library is enabled or Precise Positioning Framework (PPF)
// is available. This bundle includes features for Carrier
// Phase and SV Ephermeris.
LOCATION_CAPABILITIES_QWES_PPE = (1<<24),
// This mask indicates QDR2_C license bundle is enabled. This
// bundle includes features for SV Polynomial.
LOCATION_CAPABILITIES_QWES_QDR2 = (1<<25),
// This mask indicates QDR3_C license bundle is enabled. This
// bundle includes features for SV Polynomial.
LOCATION_CAPABILITIES_QWES_QDR3 = (1<<26),
} LocationCapabilitiesBits;
typedef uint8_t LocationQwesFeatureType;
typedef enum {
// Modem supports Carrier Phase for Precise Positioning
// Measurement Engine (PPME).
LOCATION_QWES_FEATURE_TYPE_CARRIER_PHASE = 1,
// Modem supports SV Polynomial for tightly coupled external
// DR support. This is a Standalone Feature.
LOCATION_QWES_FEATURE_TYPE_SV_POLYNOMIAL,
// Modem supports SV Ephemeris for tightly coupled external
// PPE support. This is a Standalone Feature.
LOCATION_QWES_FEATURE_TYPE_SV_EPH,
// Modem supports GNSS Single Frequency feature. This is a
// Standalone Feature.
LOCATION_QWES_FEATURE_TYPE_GNSS_SINGLE_FREQUENCY,
// Modem supports GNSS Multi Frequency feature. Multi Frequency
// enables Single frequency also.
LOCATION_QWES_FEATURE_TYPE_GNSS_MULTI_FREQUENCY,
// This indicates Time and Frequency status.
LOCATION_QWES_FEATURE_TYPE_TIME_FREQUENCY,
// This indicates Time Uncertainty status.
LOCATION_QWES_FEATURE_TYPE_TIME_UNCERTAINTY,
// This indicates Clock Estimate status.
LOCATION_QWES_FEATURE_TYPE_CLOCK_ESTIMATE,
// This mask indicates that PPE (Precise Positioning Engine)
// library is enabled or Precise Positioning Framework (PPF)
// is available. This bundle includes features for Carrier
// Phase and SV Ephermeris.
LOCATION_QWES_FEATURE_TYPE_PPE,
// This indicates QDR2_C license bundle is enabled. This
// bundle includes features for SV Polynomial.
LOCATION_QWES_FEATURE_TYPE_QDR2,
// This indicates QDR3_C license bundle is enabled. This
// bundle includes features for SV Polynomial.
LOCATION_QWES_FEATURE_TYPE_QDR3,
// This indicates VEPP license bundle is enabled. VEPP
// bundle include Carrier Phase and SV Polynomial features.
LOCATION_QWES_FEATURE_TYPE_VPE,
// Max value
LOCATION_QWES_FEATURE_TYPE_MAX
} LocationQwesFeatureTypes;
typedef enum {
LOCATION_TECHNOLOGY_TYPE_GNSS = 0,
} LocationTechnologyType;
@ -727,6 +809,16 @@ typedef enum {
(STANDARD_POSITIONING_ENGINE|DEAD_RECKONING_ENGINE| \
PRECISE_POSITIONING_ENGINE|VP_POSITIONING_ENGINE)
/** Specify the position engine running state. <br/> */
enum LocEngineRunState {
/** Request the position engine to be put into resume state.
* <br/> */
LOC_ENGINE_RUN_STATE_PAUSE = 1,
/** Request the position engine to be put into resume state.
* <br/> */
LOC_ENGINE_RUN_STATE_RESUME = 2,
};
typedef uint64_t GnssDataMask;
typedef enum {
// Jammer Indicator is available
@ -1094,6 +1186,12 @@ typedef struct {
float altitude; // altitude wrt to ellipsoid
} LLAInfo;
enum loc_sess_status {
LOC_SESS_SUCCESS,
LOC_SESS_INTERMEDIATE,
LOC_SESS_FAILURE
};
typedef struct {
uint32_t size; // set to sizeof(GnssLocationInfo)
Location location; // basic locaiton info, latitude, longitude, and etc
@ -1151,6 +1249,10 @@ typedef struct {
// VRR-based east, north, and up velocity
float enuVelocityVRPBased[3];
DrSolutionStatusMask drSolutionStatusMask;
// true: altitude is assumed, false: altitude is calculated
bool altitudeAssumed;
// location session status
loc_sess_status sessionStatus;
} GnssLocationInfoNotification;
typedef struct {
@ -1208,6 +1310,7 @@ typedef struct {
float carrierFrequencyHz; // carrier frequency of the signal tracked
GnssSignalTypeMask gnssSignalTypeMask; // Specifies GNSS signal type
double basebandCarrierToNoiseDbHz; // baseband signal strength
uint16_t gloFrequency; // GLONASS Frequency channel number
} GnssSv;
struct GnssConfigSetAssistanceServer {
@ -1619,6 +1722,11 @@ struct LocationSystemInfo {
LeapSecondSystemInfo leapSecondSysInfo;
};
// Specify the set of terrestrial technologies
enum TerrestrialTechMask {
TERRESTRIAL_TECH_GTP_WWAN = 1 << 0,
};
// Specify parameters related to lever arm
struct LeverArmParams {
// Offset along the vehicle forward axis
@ -1940,4 +2048,23 @@ typedef struct {
uint32_t port;
bool useSSL;
} GnssNtripConnectionParams;
typedef struct {
uint64_t meQtimer1;
uint64_t meQtimer2;
uint64_t meQtimer3;
uint64_t peQtimer1;
uint64_t peQtimer2;
uint64_t peQtimer3;
uint64_t smQtimer1;
uint64_t smQtimer2;
uint64_t smQtimer3;
uint64_t locMwQtimer;
uint64_t hlosQtimer1;
uint64_t hlosQtimer2;
uint64_t hlosQtimer3;
uint64_t hlosQtimer4;
uint64_t hlosQtimer5;
} GnssLatencyInfo;
#endif /* LOCATIONDATATYPES_H */

View file

@ -78,7 +78,7 @@ struct GnssInterface {
void (*agpsDataConnFailed)(AGpsExtType agpsType);
void (*getDebugReport)(GnssDebugReport& report);
void (*updateConnectionStatus)(bool connected, int8_t type, bool roaming,
NetworkHandle networkHandle);
NetworkHandle networkHandle, std::string& apn);
void (*odcpiInit)(const OdcpiRequestCallback& callback, OdcpiPrioritytype priority);
void (*odcpiInject)(const Location& location);
void (*blockCPI)(double latitude, double longitude, float accuracy,
@ -109,6 +109,8 @@ struct GnssInterface {
uint32_t (*gnssUpdateSecondaryBandConfig)(const GnssSvTypeConfig& secondaryBandConfig);
uint32_t (*gnssGetSecondaryBandConfig)();
void (*resetNetworkInfo)();
uint32_t (*configEngineRunState)(PositioningEngineMask engType,
LocEngineRunState engState);
};
struct BatchingInterface {

View file

@ -415,8 +415,12 @@ typedef uint64_t GpsLocationExtendedFlags;
#define GPS_LOCATION_EXTENDED_HAS_LLA_VRP_BASED 0x200000000000
/** GpsLocationExtended has the velocityVRPased. */
#define GPS_LOCATION_EXTENDED_HAS_ENU_VELOCITY_LLA_VRP_BASED 0x400000000000
/** GpsLocationExtended has upperTriangleFullCovMatrix. */
#define GPS_LOCATION_EXTENDED_HAS_UPPER_TRIANGLE_FULL_COV_MATRIX 0x800000000000
/** GpsLocationExtended has drSolutionStatusMask. */
#define GPS_LOCATION_EXTENDED_HAS_DR_SOLUTION_STATUS_MASK 0x1000000000000
/** GpsLocationExtended has altitudeAssumed. */
#define GPS_LOCATION_EXTENDED_HAS_ALTITUDE_ASSUMED 0x2000000000000
typedef uint32_t LocNavSolutionMask;
/* Bitmask to specify whether SBAS ionospheric correction is used */
@ -482,6 +486,7 @@ typedef uint32_t GnssAdditionalSystemInfoMask;
#define GAL_SV_PRN_MAX 336
#define NAVIC_SV_PRN_MIN 401
#define NAVIC_SV_PRN_MAX 414
#define GLO_SV_PRN_SLOT_UNKNOWN 255
/* Checking svIdOneBase can be set to the corresponding bit in mask */
#define svFitsMask(mask, svIdOneBase) \
@ -491,6 +496,7 @@ typedef uint32_t GnssAdditionalSystemInfoMask;
if (svFitsMask(mask, svIdOneBase)) mask |= (1ULL << ((svIdOneBase) - 1))
#define isValInRangeInclusive(val, min, max) ((val) >= (min) && (val) <= (max))
#define isGloSlotUnknown(val) ((val) == GLO_SV_PRN_SLOT_UNKNOWN)
typedef enum {
LOC_RELIABILITY_NOT_SET = 0,
@ -867,14 +873,14 @@ typedef struct {
*/
float upperTriangleFullCovMatrix[COV_MATRIX_SIZE];
DrSolutionStatusMask drSolutionStatusMask;
/** When this field is valid, it will indicates whether altitude
* is assumed or calculated.
* false: Altitude is calculated.
* true: Altitude is assumed; there may not be enough
* satellites to determine the precise altitude. */
bool altitudeAssumed;
} GpsLocationExtended;
enum loc_sess_status {
LOC_SESS_SUCCESS,
LOC_SESS_INTERMEDIATE,
LOC_SESS_FAILURE
};
// struct that contains complete position info from engine
typedef struct {
UlpLocation location;
@ -1009,6 +1015,7 @@ enum loc_api_adapter_event_index {
LOC_API_ADAPTER_LOC_SYSTEM_INFO, // Location system info event
LOC_API_ADAPTER_GNSS_NHZ_MEASUREMENT_REPORT, // GNSS SV nHz measurement report
LOC_API_ADAPTER_EVENT_REPORT_INFO, // Event report info
LOC_API_ADAPTER_LATENCY_INFORMATION_REPORT, // Latency information report
LOC_API_ADAPTER_EVENT_MAX
};
@ -1051,6 +1058,7 @@ enum loc_api_adapter_event_index {
#define LOC_API_ADAPTER_BIT_LOC_SYSTEM_INFO (1ULL<<LOC_API_ADAPTER_LOC_SYSTEM_INFO)
#define LOC_API_ADAPTER_BIT_GNSS_NHZ_MEASUREMENT (1ULL<<LOC_API_ADAPTER_GNSS_NHZ_MEASUREMENT_REPORT)
#define LOC_API_ADAPTER_BIT_EVENT_REPORT_INFO (1ULL<<LOC_API_ADAPTER_EVENT_REPORT_INFO)
#define LOC_API_ADAPTER_BIT_LATENCY_INFORMATION (1ULL<<LOC_API_ADAPTER_LATENCY_INFORMATION_REPORT)
typedef uint64_t LOC_API_ADAPTER_EVENT_MASK_T;
@ -1542,6 +1550,10 @@ typedef uint64_t GpsSvMeasHeaderFlags;
#define GNSS_SV_MEAS_HEADER_HAS_DGNSS_CORRECTION_SOURCE_ID 0x020000000
#define GNSS_SV_MEAS_HEADER_HAS_DGNSS_REF_STATION_ID 0x040000000
#define GNSS_SV_MEAS_HEADER_HAS_REF_COUNT_TICKS 0x080000000
#define GNSS_SV_MEAS_HEADER_HAS_GPSL1L2C_TIME_BIAS 0x100000000
#define GNSS_SV_MEAS_HEADER_HAS_GLOG1G2_TIME_BIAS 0x200000000
#define GNSS_SV_MEAS_HEADER_HAS_BDSB1IB1C_TIME_BIAS 0x400000000
#define GNSS_SV_MEAS_HEADER_HAS_GALE1E5B_TIME_BIAS 0x800000000
typedef struct
{
@ -1568,6 +1580,10 @@ typedef struct
Gnss_InterSystemBiasStructType gpsL1L5TimeBias;
Gnss_InterSystemBiasStructType galE1E5aTimeBias;
Gnss_InterSystemBiasStructType bdsB1iB2aTimeBias;
Gnss_InterSystemBiasStructType gpsL1L2cTimeBias;
Gnss_InterSystemBiasStructType gloG1G2TimeBias;
Gnss_InterSystemBiasStructType bdsB1iB1cTimeBias;
Gnss_InterSystemBiasStructType galE1E5bTimeBias;
GnssSystemTimeStructType gpsSystemTime;
GnssSystemTimeStructType galSystemTime;

View file

@ -307,15 +307,15 @@ void loc_convert_lla_gnss_to_vrp(double lla[3], float rollPitchYaw[3],
float rn = A6DOF_WGS_B * sf * sfr + lla[2];
float re = A6DOF_WGS_A * sfr + lla[2];
float deltaNED[3];
float deltaNEU[3];
// gps_pos_lla = imu_pos_lla + Cbn*la_b .* [1/geo.Rn; 1/(geo.Re*geo.cL); -1];
Matrix_MxV(cnb, leverArm, deltaNED);
Matrix_MxV(cnb, leverArm, deltaNEU);
// NED to lla conversion
lla[0] = lla[0] + deltaNED[0] / rn;
lla[1] = lla[1] + deltaNED[1] / (re * cl);
lla[2] = lla[2] - deltaNED[2];
lla[0] = lla[0] + deltaNEU[0] / rn;
lla[1] = lla[1] + deltaNEU[1] / (re * cl);
lla[2] = lla[2] + deltaNEU[2];
}
// Used for convert velocity from GSNS based to VRP based

View file

@ -36,6 +36,7 @@
#include <loc_cfg.h>
#define GLONASS_SV_ID_OFFSET 64
#define SBAS_SV_ID_OFFSET (87)
#define QZSS_SV_ID_OFFSET (192)
#define BDS_SV_ID_OFFSET (200)
#define GALILEO_SV_ID_OFFSET (300)
@ -113,7 +114,7 @@
typedef struct loc_nmea_sv_meta_s
{
char talker[3];
LocGnssConstellationType svType;
uint32_t svTypeMask;
uint64_t mask;
uint32_t svCount;
uint32_t totalSvUsedCount;
@ -292,6 +293,7 @@ static uint32_t convert_signalType_to_signalId(GnssSignalTypeMask signalType)
switch (signalType) {
case GNSS_SIGNAL_GPS_L1CA:
case GNSS_SIGNAL_SBAS_L1:
signalId = SIGNAL_ID_GPS_L1CA;
break;
case GNSS_SIGNAL_GPS_L2:
@ -404,7 +406,7 @@ static loc_nmea_sv_meta* loc_nmea_sv_meta_init(loc_nmea_sv_meta& sv_meta,
bool needCombine)
{
memset(&sv_meta, 0, sizeof(sv_meta));
sv_meta.svType = svType;
sv_meta.svTypeMask = (1 << svType);
switch (svType)
{
@ -413,6 +415,7 @@ static loc_nmea_sv_meta* loc_nmea_sv_meta_init(loc_nmea_sv_meta& sv_meta,
sv_meta.talker[1] = 'P';
sv_meta.mask = sv_cache_info.gps_used_mask;
sv_meta.systemId = SYSTEM_ID_GPS;
sv_meta.svTypeMask |= (1 << GNSS_SV_TYPE_SBAS);
switch (signalType) {
case GNSS_SIGNAL_GPS_L1CA:
sv_meta.svCount = sv_cache_info.gps_l1_count;
@ -631,7 +634,7 @@ static uint32_t loc_nmea_generate_GSA(const GpsLocationExtended &locationExtende
uint32_t svIdOffset = sv_meta_p->svIdOffset;
uint64_t mask = sv_meta_p->mask;
if(sv_meta_p->svType != GNSS_SV_TYPE_GLONASS) {
if (!(sv_meta_p->svTypeMask & (1 << GNSS_SV_TYPE_GLONASS))) {
svIdOffset = 0;
}
@ -764,7 +767,7 @@ static void loc_nmea_generate_GSV(const GnssSvNotification &svNotify,
return;
}
if (GNSS_SV_TYPE_GLONASS == sv_meta_p->svType) {
if ((1 << GNSS_SV_TYPE_GLONASS) & sv_meta_p->svTypeMask) {
svIdOffset = 0;
}
svNumber = 1;
@ -822,14 +825,23 @@ static void loc_nmea_generate_GSV(const GnssSvNotification &svNotify,
}
}
if (sv_meta_p->svType == svNotify.gnssSvs[svNumber - 1].type &&
if ((sv_meta_p->svTypeMask & (1 << svNotify.gnssSvs[svNumber - 1].type)) &&
sv_meta_p->signalId == convert_signalType_to_signalId(signalType))
{
length = snprintf(pMarker, lengthRemaining,",%02d,%02d,%03d,",
if (GNSS_SV_TYPE_SBAS == svNotify.gnssSvs[svNumber - 1].type) {
svIdOffset = SBAS_SV_ID_OFFSET;
}
if (GNSS_SV_TYPE_GLONASS == svNotify.gnssSvs[svNumber - 1].type &&
GLO_SV_PRN_SLOT_UNKNOWN == svNotify.gnssSvs[svNumber - 1].svId) {
length = snprintf(pMarker, lengthRemaining, ",,%02d,%03d,",
(int)(0.5 + svNotify.gnssSvs[svNumber - 1].elevation), //float to int
(int)(0.5 + svNotify.gnssSvs[svNumber - 1].azimuth)); //float to int
} else {
length = snprintf(pMarker, lengthRemaining, ",%02d,%02d,%03d,",
svNotify.gnssSvs[svNumber - 1].svId - svIdOffset,
(int)(0.5 + svNotify.gnssSvs[svNumber - 1].elevation), //float to int
(int)(0.5 + svNotify.gnssSvs[svNumber - 1].azimuth)); //float to int
}
if (length < 0 || length >= lengthRemaining)
{
LOC_LOGE("NMEA Error in string formatting");
@ -1458,7 +1470,7 @@ void loc_nmea_generate_pos(const UlpLocation &location,
float magTrack = location.gpsLocation.bearing;
if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_MAG_DEV)
{
float magTrack = location.gpsLocation.bearing - locationExtended.magneticDeviation;
magTrack = location.gpsLocation.bearing - locationExtended.magneticDeviation;
if (magTrack < 0.0)
magTrack += 360.0;
else if (magTrack > 360.0)
@ -2103,14 +2115,15 @@ void loc_nmea_generate_sv(const GnssSvNotification &svNotify,
//Count GPS SVs for saparating GPS from GLONASS and throw others
for (uint32_t svOffset = 0; svOffset < svNotify.count; svOffset++) {
if (GNSS_SV_TYPE_GPS == svNotify.gnssSvs[svOffset].type)
if ((GNSS_SV_TYPE_GPS == svNotify.gnssSvs[svOffset].type) ||
(GNSS_SV_TYPE_SBAS == svNotify.gnssSvs[svOffset].type))
{
if (GNSS_SIGNAL_GPS_L5 == svNotify.gnssSvs[svOffset].gnssSignalTypeMask) {
sv_cache_info.gps_l5_count++;
} else if (GNSS_SIGNAL_GPS_L2 == svNotify.gnssSvs[svOffset].gnssSignalTypeMask) {
sv_cache_info.gps_l2_count++;
} else {
// GNSS_SIGNAL_GPS_L1CA or default
// GNSS_SIGNAL_GPS_L1CA, GNSS_SIGNAL_SBAS_L1 or default
// If no signal type in report, it means default L1
sv_cache_info.gps_l1_count++;
}
@ -2151,6 +2164,14 @@ void loc_nmea_generate_sv(const GnssSvNotification &svNotify,
}
else if (GNSS_SV_TYPE_BEIDOU == svNotify.gnssSvs[svOffset].type)
{
// cache the used in fix mask, as it will be needed to send $PQGSA
// during the position report
if (GNSS_SV_OPTIONS_USED_IN_FIX_BIT ==
(svNotify.gnssSvs[svOffset].gnssSvOptionsMask &
GNSS_SV_OPTIONS_USED_IN_FIX_BIT))
{
setSvMask(sv_cache_info.bds_used_mask, svNotify.gnssSvs[svOffset].svId);
}
if ((GNSS_SIGNAL_BEIDOU_B2AI == svNotify.gnssSvs[svOffset].gnssSignalTypeMask) ||
(GNSS_SIGNAL_BEIDOU_B2AQ == svNotify.gnssSvs[svOffset].gnssSignalTypeMask)) {
sv_cache_info.bds_b2_count++;
@ -2267,6 +2288,7 @@ void loc_nmea_generate_sv(const GnssSvNotification &svNotify,
// -----------------------------
// ------$GBGSV (BEIDOU:B1C)----
// -----------------------------
loc_nmea_generate_GSV(svNotify, sentence, sizeof(sentence),
loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_BEIDOU,
GNSS_SIGNAL_BEIDOU_B1C, false), nmeaArraystr);