Handle SPE session TBF and nHz subscription for automotive

1. Requirement is to run SPE session only at 100ms TBF
if any nHz capable engine subscribes for nHz measurement
or nHz position reports.
2. Second requirement is to subscribe for nHz measurement
only if an an actual nHz engine subscribes for nHz measurement

CRs-Fixed: 2540001

Change-Id: I5a2c93a9d880967ab59ce6cd12cd415c98f29e6c
This commit is contained in:
Bhavna Sharma 2019-10-02 16:29:38 -07:00 committed by Gerrit - the friendly Code Review server
parent 1a16cbc20c
commit 6bfa690c48
3 changed files with 118 additions and 30 deletions

View file

@ -113,6 +113,9 @@ typedef std::function<void(const GnssSvNotification& svNotify,
typedef std::function<void(const GnssAidingDataSvMask& svDataMask)> typedef std::function<void(const GnssAidingDataSvMask& svDataMask)>
GnssAdapterReqAidingDataCb; GnssAdapterReqAidingDataCb;
typedef std::function<void(bool nHzNeeded, bool nHzMeasNeeded)>
GnssAdapterUpdateNHzRequirementCb;
// potential parameters: message queue: MsgTask * msgTask; // potential parameters: message queue: MsgTask * msgTask;
// callback function to report back dr and ppe position and sv report // callback function to report back dr and ppe position and sv report
typedef EngineHubProxyBase* (getEngHubProxyFn)( typedef EngineHubProxyBase* (getEngHubProxyFn)(
@ -120,7 +123,8 @@ typedef EngineHubProxyBase* (getEngHubProxyFn)(
IOsObserver* osObserver, IOsObserver* osObserver,
GnssAdapterReportEnginePositionsEventCb positionEventCb, GnssAdapterReportEnginePositionsEventCb positionEventCb,
GnssAdapterReportSvEventCb svEventCb, GnssAdapterReportSvEventCb svEventCb,
GnssAdapterReqAidingDataCb reqAidingDataCb); GnssAdapterReqAidingDataCb reqAidingDataCb,
GnssAdapterUpdateNHzRequirementCb updateNHzRequirementCb);
} // namespace loc_core } // namespace loc_core

View file

@ -45,7 +45,6 @@
#include <loc_nmea.h> #include <loc_nmea.h>
#include <Agps.h> #include <Agps.h>
#include <SystemStatus.h> #include <SystemStatus.h>
#include <vector> #include <vector>
#define RAD2DEG (180.0 / M_PI) #define RAD2DEG (180.0 / M_PI)
@ -71,6 +70,8 @@ GnssAdapter::GnssAdapter() :
true, nullptr, true), true, nullptr, true),
mEngHubProxy(new EngineHubProxyBase()), mEngHubProxy(new EngineHubProxyBase()),
mLocPositionMode(), mLocPositionMode(),
mNHzNeeded(false),
mSPEAlreadyRunningAtHighestInterval(false),
mGnssSvIdUsedInPosition(), mGnssSvIdUsedInPosition(),
mGnssSvIdUsedInPosAvail(false), mGnssSvIdUsedInPosAvail(false),
mControlCallbacks(), mControlCallbacks(),
@ -173,6 +174,30 @@ GnssAdapter::convertOptions(LocPosMode& out, const TrackingOptions& trackingOpti
out.timeBetweenMeasurements = trackingOptions.tbm; out.timeBetweenMeasurements = trackingOptions.tbm;
} }
bool
GnssAdapter::checkAndSetSPEToRunforNHz(TrackingOptions & out) {
// first check if NHz meas is needed at all, if not, just return false
// if a NHz capable engine is subscribed for NHz measurement or NHz positions,
// always run the SPE only session at 100ms TBF.
// If SPE session is already set to highest interval, no need to start it again.
bool isSPERunningAtHighestInterval = false;
if (!mNHzNeeded) {
LOC_LOGd("No nHz session needed.");
} else if (mSPEAlreadyRunningAtHighestInterval) {
LOC_LOGd("SPE is already running at highest interval.");
isSPERunningAtHighestInterval = true;
} else if (out.minInterval > MIN_TRACKING_INTERVAL) {
out.minInterval = MIN_TRACKING_INTERVAL;
LOC_LOGd("nHz session is needed, starting SPE only session at 100ms TBF.");
mSPEAlreadyRunningAtHighestInterval = true;
}
return isSPERunningAtHighestInterval;
}
void void
GnssAdapter::convertLocation(Location& out, const UlpLocation& ulpLocation, GnssAdapter::convertLocation(Location& out, const UlpLocation& ulpLocation,
const GpsLocationExtended& locationExtended, const GpsLocationExtended& locationExtended,
@ -2089,13 +2114,16 @@ GnssAdapter::updateClientsEventMask()
if((1 == ContextBase::mGps_conf.EXTERNAL_DR_ENABLED) || if((1 == ContextBase::mGps_conf.EXTERNAL_DR_ENABLED) ||
(true == initEngHubProxy())) { (true == initEngHubProxy())) {
mask |= LOC_API_ADAPTER_BIT_GNSS_MEASUREMENT; mask |= LOC_API_ADAPTER_BIT_GNSS_MEASUREMENT;
mask |= LOC_API_ADAPTER_BIT_GNSS_NHZ_MEASUREMENT;
mask |= LOC_API_ADAPTER_BIT_GNSS_SV_POLYNOMIAL_REPORT; mask |= LOC_API_ADAPTER_BIT_GNSS_SV_POLYNOMIAL_REPORT;
mask |= LOC_API_ADAPTER_BIT_PARSED_UNPROPAGATED_POSITION_REPORT; mask |= LOC_API_ADAPTER_BIT_PARSED_UNPROPAGATED_POSITION_REPORT;
mask |= LOC_API_ADAPTER_BIT_GNSS_SV_EPHEMERIS_REPORT; mask |= LOC_API_ADAPTER_BIT_GNSS_SV_EPHEMERIS_REPORT;
mask |= LOC_API_ADAPTER_BIT_LOC_SYSTEM_INFO; mask |= LOC_API_ADAPTER_BIT_LOC_SYSTEM_INFO;
mask |= LOC_API_ADAPTER_BIT_EVENT_REPORT_INFO; mask |= LOC_API_ADAPTER_BIT_EVENT_REPORT_INFO;
// Nhz measurement bit is set based on callback from loc eng hub
// for Nhz engines.
mask |= checkMask(LOC_API_ADAPTER_BIT_GNSS_NHZ_MEASUREMENT);
LOC_LOGd("Auto usecase, Enable MEAS/POLY/EPHEMERIS - mask 0x%" PRIx64 "", LOC_LOGd("Auto usecase, Enable MEAS/POLY/EPHEMERIS - mask 0x%" PRIx64 "",
mask); mask);
} }
@ -2155,13 +2183,31 @@ GnssAdapter::restartSessions()
// odcpi session is no longer active after restart // odcpi session is no longer active after restart
mOdcpiRequestActive = false; mOdcpiRequestActive = false;
// SPE will be restarted now, so set this variable to false.
mSPEAlreadyRunningAtHighestInterval = false;
checkAndRestartTimeBasedSession();
for (auto it = mDistanceBasedTrackingSessions.begin();
it != mDistanceBasedTrackingSessions.end(); ++it) {
mLocApi->startDistanceBasedTracking(it->first.id, it->second,
new LocApiResponse(*getContext(),
[] (LocationError /*err*/) {}));
}
}
void GnssAdapter::checkAndRestartTimeBasedSession()
{
LOC_LOGD("%s]: ", __func__);
if (!mTimeBasedTrackingSessions.empty()) { if (!mTimeBasedTrackingSessions.empty()) {
// get the LocationOptions that has the smallest interval, which should be the active one // get the LocationOptions that has the smallest interval, which should be the active one
TrackingOptions smallestIntervalOptions; // size is zero until set for the first time TrackingOptions smallestIntervalOptions; // size is zero until set for the first time
TrackingOptions highestPowerTrackingOptions; TrackingOptions highestPowerTrackingOptions;
memset(&smallestIntervalOptions, 0, sizeof(smallestIntervalOptions)); memset(&smallestIntervalOptions, 0, sizeof(smallestIntervalOptions));
memset(&highestPowerTrackingOptions, 0, sizeof(highestPowerTrackingOptions)); memset(&highestPowerTrackingOptions, 0, sizeof(highestPowerTrackingOptions));
for (auto it = mTimeBasedTrackingSessions.begin(); it != mTimeBasedTrackingSessions.end(); ++it) { for (auto it = mTimeBasedTrackingSessions.begin();
it != mTimeBasedTrackingSessions.end(); ++it) {
// size of zero means we havent set it yet // size of zero means we havent set it yet
if (0 == smallestIntervalOptions.size || if (0 == smallestIntervalOptions.size ||
it->second.minInterval < smallestIntervalOptions.minInterval) { it->second.minInterval < smallestIntervalOptions.minInterval) {
@ -2177,14 +2223,10 @@ GnssAdapter::restartSessions()
} }
highestPowerTrackingOptions.setLocationOptions(smallestIntervalOptions); highestPowerTrackingOptions.setLocationOptions(smallestIntervalOptions);
// want to run SPE session at a fixed min interval in some automotive scenarios
if(!checkAndSetSPEToRunforNHz(highestPowerTrackingOptions)) {
mLocApi->startTimeBasedTracking(highestPowerTrackingOptions, nullptr); mLocApi->startTimeBasedTracking(highestPowerTrackingOptions, nullptr);
} }
for (auto it = mDistanceBasedTrackingSessions.begin();
it != mDistanceBasedTrackingSessions.end(); ++it) {
mLocApi->startDistanceBasedTracking(it->first.id, it->second,
new LocApiResponse(*getContext(),
[] (LocationError /*err*/) {}));
} }
} }
@ -2491,6 +2533,7 @@ GnssAdapter::startTimeBasedTrackingMultiplex(LocationAPI* client, uint32_t sessi
multiplexedOptions.minInterval = options.minInterval; multiplexedOptions.minInterval = options.minInterval;
updateOptions = true; updateOptions = true;
} }
// if session we are starting has smaller powerMode then next smallest // if session we are starting has smaller powerMode then next smallest
if (options.powerMode < multiplexedPowerMode) { if (options.powerMode < multiplexedPowerMode) {
multiplexedOptions.powerMode = options.powerMode; multiplexedOptions.powerMode = options.powerMode;
@ -2524,7 +2567,12 @@ GnssAdapter::startTimeBasedTracking(LocationAPI* client, uint32_t sessionId,
mEngHubProxy->gnssSetFixMode(locPosMode); mEngHubProxy->gnssSetFixMode(locPosMode);
mEngHubProxy->gnssStartFix(); mEngHubProxy->gnssStartFix();
mLocApi->startTimeBasedTracking(trackingOptions, new LocApiResponse(*getContext(), // want to run SPE session at a fixed min interval in some automotive scenarios
// use a local copy of TrackingOptions as the TBF may get modified in the
// checkAndSetSPEToRunforNHz function
TrackingOptions tempOptions(trackingOptions);
if (!checkAndSetSPEToRunforNHz(tempOptions)) {
mLocApi->startTimeBasedTracking(tempOptions, new LocApiResponse(*getContext(),
[this, client, sessionId] (LocationError err) { [this, client, sessionId] (LocationError err) {
if (LOCATION_ERROR_SUCCESS != err) { if (LOCATION_ERROR_SUCCESS != err) {
eraseTrackingSession(client, sessionId); eraseTrackingSession(client, sessionId);
@ -2533,6 +2581,10 @@ GnssAdapter::startTimeBasedTracking(LocationAPI* client, uint32_t sessionId,
reportResponse(client, err, sessionId); reportResponse(client, err, sessionId);
} }
)); ));
} else {
reportResponse(client, LOCATION_ERROR_SUCCESS, sessionId);
}
} }
void void
@ -2546,16 +2598,23 @@ GnssAdapter::updateTracking(LocationAPI* client, uint32_t sessionId,
mEngHubProxy->gnssSetFixMode(locPosMode); mEngHubProxy->gnssSetFixMode(locPosMode);
mEngHubProxy->gnssStartFix(); mEngHubProxy->gnssStartFix();
mLocApi->startTimeBasedTracking(updatedOptions, new LocApiResponse(*getContext(), // want to run SPE session at a fixed min interval in some automotive scenarios
// use a local copy of TrackingOptions as the TBF may get modified in the
// checkAndSetSPEToRunforNHz function
TrackingOptions tempOptions(updatedOptions);
if(!checkAndSetSPEToRunforNHz(tempOptions)) {
mLocApi->startTimeBasedTracking(tempOptions, new LocApiResponse(*getContext(),
[this, client, sessionId, oldOptions] (LocationError err) { [this, client, sessionId, oldOptions] (LocationError err) {
if (LOCATION_ERROR_SUCCESS != err) { if (LOCATION_ERROR_SUCCESS != err) {
// restore the old LocationOptions // restore the old LocationOptions
saveTrackingSession(client, sessionId, oldOptions); saveTrackingSession(client, sessionId, oldOptions);
} }
reportResponse(client, err, sessionId); reportResponse(client, err, sessionId);
} }
)); ));
} else {
reportResponse(client, LOCATION_ERROR_SUCCESS, sessionId);
}
} }
void void
@ -2856,6 +2915,8 @@ GnssAdapter::stopTracking(LocationAPI* client, uint32_t id)
[this, client, id] (LocationError err) { [this, client, id] (LocationError err) {
reportResponse(client, err, id); reportResponse(client, err, id);
})); }));
mSPEAlreadyRunningAtHighestInterval = false;
} }
bool bool
@ -5023,11 +5084,30 @@ GnssAdapter::initEngHubProxy() {
mLocApi->requestForAidingData(svDataMask); mLocApi->requestForAidingData(svDataMask);
}; };
GnssAdapterUpdateNHzRequirementCb updateNHzRequirementCb =
[this] (bool nHzNeeded, bool nHzMeasNeeded) {
if (nHzMeasNeeded &&
(!checkMask(LOC_API_ADAPTER_BIT_GNSS_NHZ_MEASUREMENT))) {
updateEvtMask(LOC_API_ADAPTER_BIT_GNSS_NHZ_MEASUREMENT,
LOC_REGISTRATION_MASK_ENABLED);
} else if (checkMask(LOC_API_ADAPTER_BIT_GNSS_NHZ_MEASUREMENT)) {
updateEvtMask(LOC_API_ADAPTER_BIT_GNSS_NHZ_MEASUREMENT,
LOC_REGISTRATION_MASK_DISABLED);
}
if (mNHzNeeded != nHzNeeded) {
mNHzNeeded = nHzNeeded;
checkAndRestartTimeBasedSession();
}
};
getEngHubProxyFn* getter = (getEngHubProxyFn*) dlsym(handle, "getEngHubProxy"); getEngHubProxyFn* getter = (getEngHubProxyFn*) dlsym(handle, "getEngHubProxy");
if(getter != nullptr) { if(getter != nullptr) {
EngineHubProxyBase* hubProxy = (*getter) (mMsgTask, mSystemStatus->getOsObserver(), EngineHubProxyBase* hubProxy = (*getter) (mMsgTask, mSystemStatus->getOsObserver(),
reportPositionEventCb, reportPositionEventCb,
reportSvEventCb, reqAidingDataCb); reportSvEventCb, reqAidingDataCb,
updateNHzRequirementCb);
if (hubProxy != nullptr) { if (hubProxy != nullptr) {
mEngHubProxy = hubProxy; mEngHubProxy = hubProxy;
engHubLoadSuccessful = true; engHubLoadSuccessful = true;

View file

@ -138,6 +138,8 @@ class GnssAdapter : public LocAdapterBase {
/* ==== Engine Hub ===================================================================== */ /* ==== Engine Hub ===================================================================== */
EngineHubProxyBase* mEngHubProxy; EngineHubProxyBase* mEngHubProxy;
bool mNHzNeeded;
bool mSPEAlreadyRunningAtHighestInterval;
/* ==== TRACKING ======================================================================= */ /* ==== TRACKING ======================================================================= */
TrackingOptionsMap mTimeBasedTrackingSessions; TrackingOptionsMap mTimeBasedTrackingSessions;
@ -228,6 +230,7 @@ public:
virtual void handleEngineUpEvent(); virtual void handleEngineUpEvent();
/* ======== UTILITIES ================================================================== */ /* ======== UTILITIES ================================================================== */
void restartSessions(); void restartSessions();
void checkAndRestartTimeBasedSession();
/* ==== CLIENT ========================================================================= */ /* ==== CLIENT ========================================================================= */
/* ======== COMMANDS ====(Called from Client Thread)==================================== */ /* ======== COMMANDS ====(Called from Client Thread)==================================== */
@ -265,6 +268,7 @@ public:
const TrackingOptions& trackingOptions); const TrackingOptions& trackingOptions);
void updateTracking(LocationAPI* client, uint32_t sessionId, void updateTracking(LocationAPI* client, uint32_t sessionId,
const TrackingOptions& updatedOptions, const TrackingOptions& oldOptions); const TrackingOptions& updatedOptions, const TrackingOptions& oldOptions);
bool checkAndSetSPEToRunforNHz(TrackingOptions & out);
/* ==== NI ============================================================================= */ /* ==== NI ============================================================================= */
/* ======== COMMANDS ====(Called from Client Thread)==================================== */ /* ======== COMMANDS ====(Called from Client Thread)==================================== */