summaryrefslogtreecommitdiff
path: root/gnss
diff options
context:
space:
mode:
authorDante Russo <drusso@codeaurora.org>2019-03-06 09:36:20 -0800
committerKevin Tang <zhikait@codeaurora.org>2019-03-27 14:54:49 -0700
commit5c1e23cf022ab1c06f4601bf0f2d8ca652784b87 (patch)
tree367ed17640c0bab1021feb10575645bd6d30c1ba /gnss
parent01869b4004179870db2160ed41283dce7fbbdcde (diff)
downloadgps-5c1e23cf022ab1c06f4601bf0f2d8ca652784b87.tar.gz
Batching and Geofence moved to GNSS HAL
Addition of BatchingAdapter and GeofenceAdapter. Deprecated Background LOC QMI Client and renamed LocDualContext renamed to LocContext. Moved some common Adapter functions into LocAdapterBase. Added Distance Based Tracking logic into GnssAdapter. Addition of flp.conf Deprecated GEOFENCE capabilities configuration in gps.conf CRs-fixed: 2342200 Change-Id: I6b6257c4cf296e5a8c56bc0b149e4de77cf6cdf9
Diffstat (limited to 'gnss')
-rw-r--r--gnss/GnssAdapter.cpp706
-rw-r--r--gnss/GnssAdapter.h78
-rw-r--r--gnss/XtraSystemStatusObserver.h2
-rw-r--r--gnss/location_gnss.cpp11
4 files changed, 447 insertions, 350 deletions
diff --git a/gnss/GnssAdapter.cpp b/gnss/GnssAdapter.cpp
index f6dff89..10f0255 100644
--- a/gnss/GnssAdapter.cpp
+++ b/gnss/GnssAdapter.cpp
@@ -50,6 +50,7 @@
#define RAD2DEG (180.0 / M_PI)
#define PROCESS_NAME_ENGINE_SERVICE "engine-service"
+#define MIN_TRACKING_INTERVAL (100) // 100 msec
using namespace loc_core;
@@ -63,9 +64,9 @@ static void agpsCloseResultCb (bool isSuccess, AGpsExtType agpsType, void* userD
GnssAdapter::GnssAdapter() :
LocAdapterBase(0,
- LocDualContext::getLocFgContext(NULL,
+ LocContext::getLocContext(NULL,
NULL,
- LocDualContext::mLocationHalName,
+ LocContext::mLocationHalName,
false), true, nullptr),
mEngHubProxy(new EngineHubProxyBase()),
mLocPositionMode(),
@@ -87,9 +88,13 @@ GnssAdapter::GnssAdapter() :
mSystemStatus(SystemStatus::getInstance(mMsgTask)),
mServerUrl(":"),
mXtraObserver(mSystemStatus->getOsObserver(), mMsgTask),
- mBlockCPIInfo{},
mLocSystemInfo{},
- mNfwCb(NULL)
+ mBlockCPIInfo{},
+ mNfwCb(NULL),
+ mPowerOn(false),
+ mAllowFlpNetworkFixes(0),
+ mGnssEnergyConsumedCb(nullptr),
+ mPowerStateCb(nullptr)
{
LOC_LOGD("%s]: Constructor %p", __func__, this);
mLocPositionMode.mode = LOC_POSITION_MODE_INVALID;
@@ -569,8 +574,21 @@ GnssAdapter::readConfigCommand()
mAdapter(adapter),
mContext(context) {}
inline virtual void proc() const {
- // reads config into mContext->mGps_conf
- mContext.readConfig();
+ static bool confReadDone = false;
+ if (!confReadDone) {
+ confReadDone = true;
+ // reads config into mContext->mGps_conf
+ mContext.readConfig();
+
+ uint32_t allowFlpNetworkFixes = 0;
+ static const loc_param_s_type flp_conf_param_table[] =
+ {
+ {"ALLOW_NETWORK_FIXES", &allowFlpNetworkFixes, NULL, 'n'},
+ };
+ UTIL_READ_CONF(LOC_PATH_FLP_CONF, flp_conf_param_table);
+ LOC_LOGd("allowFlpNetworkFixes %u", allowFlpNetworkFixes);
+ mAdapter->setAllowFlpNetworkFixes(allowFlpNetworkFixes);
+ }
}
};
@@ -625,7 +643,10 @@ GnssAdapter::setConfigCommand()
mAdapter(adapter),
mApi(api) {}
inline virtual void proc() const {
-
+ if (!mAdapter.isEngineCapabilitiesKnown()) {
+ mAdapter.mPendingMsgs.push_back(new MsgSetConfig(*this));
+ return;
+ }
// set nmea mask type
uint32_t mask = 0;
if (NMEA_PROVIDER_MP == ContextBase::mGps_conf.NMEA_PROVIDER) {
@@ -980,7 +1001,10 @@ GnssAdapter::gnssUpdateConfigCommand(GnssConfig config)
}
inline virtual void proc() const {
-
+ if (!mAdapter.isEngineCapabilitiesKnown()) {
+ mAdapter.mPendingMsgs.push_back(new MsgGnssUpdateConfig(*this));
+ return;
+ }
GnssAdapter& adapter = mAdapter;
size_t countOfConfigs = mCount;
GnssConfig gnssConfigRequested = mConfig;
@@ -1236,7 +1260,10 @@ GnssAdapter::gnssGetConfigCommand(GnssConfigFlagsMask configMask) {
delete[] mIds;
}
inline virtual void proc() const {
-
+ if (!mAdapter.isEngineCapabilitiesKnown()) {
+ mAdapter.mPendingMsgs.push_back(new MsgGnssGetConfig(*this));
+ return;
+ }
LocationError* errs = new LocationError[mCount];
LocationError err = LOCATION_ERROR_SUCCESS;
uint32_t index = 0;
@@ -1511,7 +1538,10 @@ GnssAdapter::gnssUpdateSvTypeConfigCommand(GnssSvTypeConfig config)
mApi(api),
mConfig(config) {}
inline virtual void proc() const {
-
+ if (!mAdapter->isEngineCapabilitiesKnown()) {
+ mAdapter->mPendingMsgs.push_back(new MsgGnssUpdateSvTypeConfig(*this));
+ return;
+ }
// Check if feature is supported
if (!ContextBase::isFeatureSupported(
LOC_SUPPORTED_FEATURE_CONSTELLATION_ENABLEMENT_V02)) {
@@ -1601,7 +1631,10 @@ GnssAdapter::gnssGetSvTypeConfigCommand(GnssSvTypeConfigCallback callback)
mApi(api),
mCallback(callback) {}
inline virtual void proc() const {
-
+ if (!mAdapter->isEngineCapabilitiesKnown()) {
+ mAdapter->mPendingMsgs.push_back(new MsgGnssGetSvTypeConfig(*this));
+ return;
+ }
if (!ContextBase::isFeatureSupported(
LOC_SUPPORTED_FEATURE_CONSTELLATION_ENABLEMENT_V02)) {
LOC_LOGe("Feature not supported.");
@@ -1630,7 +1663,10 @@ GnssAdapter::gnssResetSvTypeConfigCommand()
mAdapter(adapter),
mApi(api) {}
inline virtual void proc() const {
-
+ if (!mAdapter->isEngineCapabilitiesKnown()) {
+ mAdapter->mPendingMsgs.push_back(new MsgGnssResetSvTypeConfig(*this));
+ return;
+ }
if (!ContextBase::isFeatureSupported(
LOC_SUPPORTED_FEATURE_CONSTELLATION_ENABLEMENT_V02)) {
LOC_LOGe("Feature not supported.");
@@ -1877,43 +1913,32 @@ GnssAdapter::addClientCommand(LocationAPI* client, const LocationCallbacks& call
}
void
-GnssAdapter::removeClientCommand(LocationAPI* client,
- removeClientCompleteCallback rmClientCb)
+GnssAdapter::stopClientSessions(LocationAPI* client)
{
LOC_LOGD("%s]: client %p", __func__, client);
- struct MsgRemoveClient : public LocMsg {
- GnssAdapter& mAdapter;
- LocationAPI* mClient;
- removeClientCompleteCallback mRmClientCb;
- inline MsgRemoveClient(GnssAdapter& adapter,
- LocationAPI* client,
- removeClientCompleteCallback rmCb) :
- LocMsg(),
- mAdapter(adapter),
- mClient(client),
- mRmClientCb(rmCb){}
- inline virtual void proc() const {
- mAdapter.stopClientSessions(mClient);
- mAdapter.eraseClient(mClient);
- if (nullptr != mRmClientCb) {
- mRmClientCb(mClient);
- }
+ /* Time-based Tracking */
+ std::vector<LocationSessionKey> vTimeBasedTrackingClient;
+ for (auto it : mTimeBasedTrackingSessions) {
+ if (client == it.first.client) {
+ vTimeBasedTrackingClient.emplace_back(it.first.client, it.first.id);
}
- };
-
- sendMsg(new MsgRemoveClient(*this, client, rmClientCb));
-}
+ }
+ for (auto key : vTimeBasedTrackingClient) {
+ stopTimeBasedTrackingMultiplex(key.client, key.id);
+ }
-void
-GnssAdapter::stopClientSessions(LocationAPI* client)
-{
- LOC_LOGD("%s]: client %p", __func__, client);
- for (auto it = mTrackingSessions.begin(); it != mTrackingSessions.end();) {
+ /* Distance-based Tracking */
+ for (auto it = mDistanceBasedTrackingSessions.begin();
+ it != mDistanceBasedTrackingSessions.end(); /* no increment here*/) {
if (client == it->first.client) {
- stopTrackingMultiplex(it->first.client, it->first.id);
- it = mTrackingSessions.erase(it);
- continue;
+ mLocApi->stopDistanceBasedTracking(it->first.id, new LocApiResponse(*getContext(),
+ [this, client, id=it->first.id] (LocationError err) {
+ if (LOCATION_ERROR_SUCCESS == err) {
+ eraseTrackingSession(client, id);
+ }
+ }
+ ));
}
++it; // increment only when not erasing an iterator
}
@@ -1993,11 +2018,15 @@ GnssAdapter::handleEngineUpEvent()
LocMsg(),
mAdapter(adapter) {}
virtual void proc() const {
+ mAdapter.setEngineCapabilitiesKnown(true);
mAdapter.broadcastCapabilities(mAdapter.getCapabilities());
- // restart sessions
mAdapter.restartSessions();
mAdapter.gnssSvIdConfigUpdate();
mAdapter.gnssSvTypeConfigUpdate();
+ for (auto msg: mAdapter.mPendingMsgs) {
+ mAdapter.sendMsg(msg);
+ }
+ mAdapter.mPendingMsgs.clear();
}
};
@@ -2014,132 +2043,37 @@ GnssAdapter::restartSessions()
// odcpi session is no longer active after restart
mOdcpiRequestActive = false;
- if (mTrackingSessions.empty()) {
- return;
- }
-
- // 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 highestPowerTrackingOptions;
- memset(&smallestIntervalOptions, 0, sizeof(smallestIntervalOptions));
- memset(&highestPowerTrackingOptions, 0, sizeof(highestPowerTrackingOptions));
- for (auto it = mTrackingSessions.begin(); it != mTrackingSessions.end(); ++it) {
- // size of zero means we havent set it yet
- if (0 == smallestIntervalOptions.size ||
- it->second.minInterval < smallestIntervalOptions.minInterval) {
- smallestIntervalOptions = it->second;
- }
- GnssPowerMode powerMode = it->second.powerMode;
- // Size of zero means we havent set it yet
- if (0 == highestPowerTrackingOptions.size ||
- (GNSS_POWER_MODE_INVALID != powerMode &&
- powerMode < highestPowerTrackingOptions.powerMode)) {
- highestPowerTrackingOptions = it->second;
- }
- }
-
- LocPosMode locPosMode = {};
- highestPowerTrackingOptions.setLocationOptions(smallestIntervalOptions);
- convertOptions(locPosMode, highestPowerTrackingOptions);
- mLocApi->startFix(locPosMode, nullptr);
-}
-
-void
-GnssAdapter::requestCapabilitiesCommand(LocationAPI* client)
-{
- LOC_LOGD("%s]: ", __func__);
-
- struct MsgRequestCapabilities : public LocMsg {
- GnssAdapter& mAdapter;
- LocationAPI* mClient;
- inline MsgRequestCapabilities(GnssAdapter& adapter,
- LocationAPI* client) :
- LocMsg(),
- mAdapter(adapter),
- mClient(client) {}
- inline virtual void proc() const {
- LocationCallbacks callbacks = mAdapter.getClientCallbacks(mClient);
- if (callbacks.capabilitiesCb == nullptr) {
- LOC_LOGE("%s]: capabilitiesCb is NULL", __func__);
- return;
+ if (!mTimeBasedTrackingSessions.empty()) {
+ // 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 highestPowerTrackingOptions;
+ memset(&smallestIntervalOptions, 0, sizeof(smallestIntervalOptions));
+ memset(&highestPowerTrackingOptions, 0, sizeof(highestPowerTrackingOptions));
+ for (auto it = mTimeBasedTrackingSessions.begin(); it != mTimeBasedTrackingSessions.end(); ++it) {
+ // size of zero means we havent set it yet
+ if (0 == smallestIntervalOptions.size ||
+ it->second.minInterval < smallestIntervalOptions.minInterval) {
+ smallestIntervalOptions = it->second;
+ }
+ GnssPowerMode powerMode = it->second.powerMode;
+ // Size of zero means we havent set it yet
+ if (0 == highestPowerTrackingOptions.size ||
+ (GNSS_POWER_MODE_INVALID != powerMode &&
+ powerMode < highestPowerTrackingOptions.powerMode)) {
+ highestPowerTrackingOptions = it->second;
}
-
- LocationCapabilitiesMask mask = mAdapter.getCapabilities();
- callbacks.capabilitiesCb(mask);
}
- };
- if (ContextBase::isEngineCapabilitiesKnown()) {
- sendMsg(new MsgRequestCapabilities(*this, client));
+ highestPowerTrackingOptions.setLocationOptions(smallestIntervalOptions);
+ mLocApi->startTimeBasedTracking(highestPowerTrackingOptions, nullptr);
}
-}
-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;
+ for (auto it = mDistanceBasedTrackingSessions.begin();
+ it != mDistanceBasedTrackingSessions.end(); ++it) {
+ mLocApi->startDistanceBasedTracking(it->first.id, it->second,
+ new LocApiResponse(*getContext(),
+ [] (LocationError /*err*/) {}));
}
- 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;
- }
- return mask;
-}
-
-void
-GnssAdapter::broadcastCapabilities(LocationCapabilitiesMask mask)
-{
- for (auto clientData : mClientData) {
- if (nullptr != clientData.second.capabilitiesCb) {
- clientData.second.capabilitiesCb(mask);
- }
- }
-}
-
-LocationCallbacks
-GnssAdapter::getClientCallbacks(LocationAPI* client)
-{
- LocationCallbacks callbacks = {};
- auto it = mClientData.find(client);
- if (it != mClientData.end()) {
- callbacks = it->second;
- }
- return callbacks;
-}
-
-void
-GnssAdapter::saveClient(LocationAPI* client, const LocationCallbacks& callbacks)
-{
- mClientData[client] = callbacks;
- updateClientsEventMask();
}
void
@@ -2171,21 +2105,25 @@ GnssAdapter::notifyClientOfCachedLocationSystemInfo(
}
}
-void
-GnssAdapter::eraseClient(LocationAPI* client)
+bool
+GnssAdapter::hasTrackingCallback(LocationAPI* client)
{
auto it = mClientData.find(client);
- if (it != mClientData.end()) {
- mClientData.erase(it);
- }
- updateClientsEventMask();
+ return (it != mClientData.end() && (it->second.trackingCb || it->second.gnssLocationInfoCb));
}
bool
-GnssAdapter::hasTrackingCallback(LocationAPI* client)
+GnssAdapter::isTimeBasedTrackingSession(LocationAPI* client, uint32_t sessionId)
{
- auto it = mClientData.find(client);
- return (it != mClientData.end() && (it->second.trackingCb || it->second.gnssLocationInfoCb));
+ LocationSessionKey key(client, sessionId);
+ return (mTimeBasedTrackingSessions.find(key) != mTimeBasedTrackingSessions.end());
+}
+
+bool
+GnssAdapter::isDistanceBasedTrackingSession(LocationAPI* client, uint32_t sessionId)
+{
+ LocationSessionKey key(client, sessionId);
+ return (mDistanceBasedTrackingSessions.find(key) != mDistanceBasedTrackingSessions.end());
}
bool
@@ -2199,27 +2137,75 @@ bool
GnssAdapter::isTrackingSession(LocationAPI* client, uint32_t sessionId)
{
LocationSessionKey key(client, sessionId);
- return (mTrackingSessions.find(key) != mTrackingSessions.end());
+ return (mTimeBasedTrackingSessions.find(key) != mTimeBasedTrackingSessions.end());
+}
+
+void
+GnssAdapter::reportPowerStateIfChanged()
+{
+ bool newPowerOn = !mTimeBasedTrackingSessions.empty() ||
+ !mDistanceBasedTrackingSessions.empty();
+ if (newPowerOn != mPowerOn) {
+ mPowerOn = newPowerOn;
+ if (mPowerStateCb != nullptr) {
+ mPowerStateCb(mPowerOn);
+ }
+ }
+}
+
+void
+GnssAdapter::getPowerStateChangesCommand(void* powerStateCb)
+{
+ LOC_LOGD("%s]: ", __func__);
+
+ struct MsgReportLocation : public LocMsg {
+ GnssAdapter& mAdapter;
+ powerStateCallback mPowerStateCb;
+ inline MsgReportLocation(GnssAdapter& adapter,
+ powerStateCallback powerStateCb) :
+ LocMsg(),
+ mAdapter(adapter),
+ mPowerStateCb(powerStateCb) {}
+ inline virtual void proc() const {
+ mAdapter.savePowerStateCallback(mPowerStateCb);
+ mPowerStateCb(mAdapter.getPowerState());
+ }
+ };
+
+ sendMsg(new MsgReportLocation(*this, (powerStateCallback)powerStateCb));
}
void
GnssAdapter::saveTrackingSession(LocationAPI* client, uint32_t sessionId,
- const TrackingOptions& trackingOptions)
+ const TrackingOptions& options)
{
LocationSessionKey key(client, sessionId);
- mTrackingSessions[key] = trackingOptions;
+ if ((options.minDistance > 0) &&
+ ContextBase::isMessageSupported(LOC_API_ADAPTER_MESSAGE_DISTANCE_BASE_TRACKING)) {
+ mDistanceBasedTrackingSessions[key] = options;
+ } else {
+ mTimeBasedTrackingSessions[key] = options;
+ }
+ reportPowerStateIfChanged();
}
void
GnssAdapter::eraseTrackingSession(LocationAPI* client, uint32_t sessionId)
{
LocationSessionKey key(client, sessionId);
- auto itr = mTrackingSessions.find(key);
- if (itr != mTrackingSessions.end()) {
- mTrackingSessions.erase(itr);
+ auto it = mTimeBasedTrackingSessions.find(key);
+ if (it != mTimeBasedTrackingSessions.end()) {
+ mTimeBasedTrackingSessions.erase(it);
+ } else {
+ auto itr = mDistanceBasedTrackingSessions.find(key);
+ if (itr != mDistanceBasedTrackingSessions.end()) {
+ mDistanceBasedTrackingSessions.erase(itr);
+ }
}
+ reportPowerStateIfChanged();
}
+
bool GnssAdapter::setLocPositionMode(const LocPosMode& mode) {
if (!mLocPositionMode.equals(mode)) {
mLocPositionMode = mode;
@@ -2293,48 +2279,62 @@ GnssAdapter::startTrackingCommand(LocationAPI* client, TrackingOptions& options)
LocApiBase& mApi;
LocationAPI* mClient;
uint32_t mSessionId;
- mutable TrackingOptions mTrackingOptions;
+ mutable TrackingOptions mOptions;
inline MsgStartTracking(GnssAdapter& adapter,
LocApiBase& api,
LocationAPI* client,
uint32_t sessionId,
- TrackingOptions trackingOptions) :
+ TrackingOptions options) :
LocMsg(),
mAdapter(adapter),
mApi(api),
mClient(client),
mSessionId(sessionId),
- mTrackingOptions(trackingOptions) {}
+ mOptions(options) {}
inline virtual void proc() const {
+ // distance based tracking will need to know engine capabilities before it can start
+ if (!mAdapter.isEngineCapabilitiesKnown() && mOptions.minDistance > 0) {
+ mAdapter.mPendingMsgs.push_back(new MsgStartTracking(*this));
+ return;
+ }
LocationError err = LOCATION_ERROR_SUCCESS;
if (!mAdapter.hasTrackingCallback(mClient) &&
!mAdapter.hasMeasurementsCallback(mClient)) {
err = LOCATION_ERROR_CALLBACK_MISSING;
- } else if (0 == mTrackingOptions.size) {
+ } else if (0 == mOptions.size) {
err = LOCATION_ERROR_INVALID_PARAMETER;
} else {
- if (GNSS_POWER_MODE_INVALID != mTrackingOptions.powerMode &&
- !ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_AGPM_V02)) {
- LOC_LOGv("Ignoring power mode, feature not supported.");
- mTrackingOptions.powerMode = GNSS_POWER_MODE_INVALID;
- }
- if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_AGPM_V02) &&
- GNSS_POWER_MODE_M4 == mTrackingOptions.powerMode &&
- mTrackingOptions.tbm > TRACKING_TBM_THRESHOLD_MILLIS) {
- LOC_LOGd("TBM (%d) > %d Falling back to M2 power mode",
- mTrackingOptions.tbm, TRACKING_TBM_THRESHOLD_MILLIS);
- mTrackingOptions.powerMode = GNSS_POWER_MODE_M2;
+ if (mOptions.minInterval < MIN_TRACKING_INTERVAL) {
+ mOptions.minInterval = MIN_TRACKING_INTERVAL;
}
- if (mTrackingOptions.minInterval < MIN_TRACKING_INTERVAL) {
- mTrackingOptions.minInterval = MIN_TRACKING_INTERVAL;
- }
- // Api doesn't support multiple clients for time based tracking, so mutiplex
- bool reportToClientWithNoWait =
- mAdapter.startTrackingMultiplex(mClient, mSessionId, mTrackingOptions);
- mAdapter.saveTrackingSession(mClient, mSessionId, mTrackingOptions);
+ if (mOptions.minDistance > 0 &&
+ ContextBase::isMessageSupported(
+ LOC_API_ADAPTER_MESSAGE_DISTANCE_BASE_TRACKING)) {
+ mAdapter.saveTrackingSession(mClient, mSessionId, mOptions);
+ mApi.startDistanceBasedTracking(mSessionId, mOptions,
+ new LocApiResponse(*mAdapter.getContext(),
+ [&mAdapter = mAdapter, mSessionId = mSessionId, mClient = mClient]
+ (LocationError err) {
+ if (LOCATION_ERROR_SUCCESS != err) {
+ mAdapter.eraseTrackingSession(mClient, mSessionId);
+ }
+ mAdapter.reportResponse(mClient, err, mSessionId);
+ }));
+ } else {
+ if (GNSS_POWER_MODE_M4 == mOptions.powerMode &&
+ mOptions.tbm > TRACKING_TBM_THRESHOLD_MILLIS) {
+ LOC_LOGd("TBM (%d) > %d Falling back to M2 power mode",
+ mOptions.tbm, TRACKING_TBM_THRESHOLD_MILLIS);
+ mOptions.powerMode = GNSS_POWER_MODE_M2;
+ }
+ // Api doesn't support multiple clients for time based tracking, so mutiplex
+ bool reportToClientWithNoWait =
+ mAdapter.startTimeBasedTrackingMultiplex(mClient, mSessionId, mOptions);
+ mAdapter.saveTrackingSession(mClient, mSessionId, mOptions);
- if (reportToClientWithNoWait) {
- mAdapter.reportResponse(mClient, LOCATION_ERROR_SUCCESS, mSessionId);
+ if (reportToClientWithNoWait) {
+ mAdapter.reportResponse(mClient, LOCATION_ERROR_SUCCESS, mSessionId);
+ }
}
}
}
@@ -2346,13 +2346,13 @@ GnssAdapter::startTrackingCommand(LocationAPI* client, TrackingOptions& options)
}
bool
-GnssAdapter::startTrackingMultiplex(LocationAPI* client, uint32_t sessionId,
- const TrackingOptions& options)
+GnssAdapter::startTimeBasedTrackingMultiplex(LocationAPI* client, uint32_t sessionId,
+ const TrackingOptions& options)
{
bool reportToClientWithNoWait = true;
- if (mTrackingSessions.empty()) {
- startTracking(client, sessionId, options);
+ if (mTimeBasedTrackingSessions.empty()) {
+ startTimeBasedTracking(client, sessionId, options);
// need to wait for QMI callback
reportToClientWithNoWait = false;
} else {
@@ -2360,7 +2360,7 @@ GnssAdapter::startTrackingMultiplex(LocationAPI* client, uint32_t sessionId,
TrackingOptions multiplexedOptions = {}; // size is 0 until set for the first time
GnssPowerMode multiplexedPowerMode = GNSS_POWER_MODE_INVALID;
memset(&multiplexedOptions, 0, sizeof(multiplexedOptions));
- for (auto it = mTrackingSessions.begin(); it != mTrackingSessions.end(); ++it) {
+ for (auto it = mTimeBasedTrackingSessions.begin(); it != mTimeBasedTrackingSessions.end(); ++it) {
// if not set or there is a new smallest interval, then set the new interval
if (0 == multiplexedOptions.size ||
it->second.minInterval < multiplexedOptions.minInterval) {
@@ -2387,7 +2387,7 @@ GnssAdapter::startTrackingMultiplex(LocationAPI* client, uint32_t sessionId,
if (updateOptions) {
// restart time based tracking with the newly updated options
- startTracking(client, sessionId, multiplexedOptions);
+ startTimeBasedTracking(client, sessionId, multiplexedOptions);
// need to wait for QMI callback
reportToClientWithNoWait = false;
}
@@ -2398,12 +2398,12 @@ GnssAdapter::startTrackingMultiplex(LocationAPI* client, uint32_t sessionId,
}
void
-GnssAdapter::startTracking(LocationAPI* client, uint32_t sessionId,
+GnssAdapter::startTimeBasedTracking(LocationAPI* client, uint32_t sessionId,
const TrackingOptions& trackingOptions)
{
LOC_LOGd("minInterval %u minDistance %u mode %u powermode %u tbm %u",
- trackingOptions.minInterval, trackingOptions.minDistance,
- trackingOptions.mode, trackingOptions.powerMode, trackingOptions.tbm);
+ trackingOptions.minInterval, trackingOptions.minDistance,
+ trackingOptions.mode, trackingOptions.powerMode, trackingOptions.tbm);
LocPosMode locPosMode = {};
convertOptions(locPosMode, trackingOptions);
@@ -2412,7 +2412,7 @@ GnssAdapter::startTracking(LocationAPI* client, uint32_t sessionId,
mEngHubProxy->gnssSetFixMode(locPosMode);
mEngHubProxy->gnssStartFix();
- mLocApi->startFix(locPosMode, new LocApiResponse(*getContext(),
+ mLocApi->startTimeBasedTracking(trackingOptions, new LocApiResponse(*getContext(),
[this, client, sessionId] (LocationError err) {
if (LOCATION_ERROR_SUCCESS != err) {
eraseTrackingSession(client, sessionId);
@@ -2434,7 +2434,7 @@ GnssAdapter::updateTracking(LocationAPI* client, uint32_t sessionId,
mEngHubProxy->gnssSetFixMode(locPosMode);
mEngHubProxy->gnssStartFix();
- mLocApi->startFix(locPosMode, new LocApiResponse(*getContext(),
+ mLocApi->startTimeBasedTracking(updatedOptions, new LocApiResponse(*getContext(),
[this, client, sessionId, oldOptions] (LocationError err) {
if (LOCATION_ERROR_SUCCESS != err) {
// restore the old LocationOptions
@@ -2447,35 +2447,6 @@ GnssAdapter::updateTracking(LocationAPI* client, uint32_t sessionId,
}
void
-GnssAdapter::setPositionModeCommand(LocPosMode& locPosMode)
-{
- LOC_LOGD("%s]: min_interval %u mode %u",
- __func__, locPosMode.min_interval, locPosMode.mode);
-
- struct MsgSetPositionMode : public LocMsg {
- GnssAdapter& mAdapter;
- LocApiBase& mApi;
- LocPosMode mLocPosMode;
- inline MsgSetPositionMode(GnssAdapter& adapter,
- LocApiBase& api,
- LocPosMode& locPosMode) :
- LocMsg(),
- mAdapter(adapter),
- mApi(api),
- mLocPosMode(locPosMode) {}
- inline virtual void proc() const {
- // saves the mode in adapter to be used when startTrackingCommand is called from ULP
- if (mAdapter.setLocPositionMode(mLocPosMode)) {
- mAdapter.mEngHubProxy->gnssSetFixMode(mLocPosMode);
- mApi.setPositionMode(mLocPosMode);
- }
- }
- };
-
- sendMsg(new MsgSetPositionMode(*this, *mLocApi, locPosMode));
-}
-
-void
GnssAdapter::updateTrackingOptionsCommand(LocationAPI* client, uint32_t id,
TrackingOptions& options)
{
@@ -2487,52 +2458,108 @@ GnssAdapter::updateTrackingOptionsCommand(LocationAPI* client, uint32_t id,
LocApiBase& mApi;
LocationAPI* mClient;
uint32_t mSessionId;
- mutable TrackingOptions mTrackingOptions;
+ mutable TrackingOptions mOptions;
inline MsgUpdateTracking(GnssAdapter& adapter,
LocApiBase& api,
LocationAPI* client,
uint32_t sessionId,
- TrackingOptions trackingOptions) :
+ TrackingOptions options) :
LocMsg(),
mAdapter(adapter),
mApi(api),
mClient(client),
mSessionId(sessionId),
- mTrackingOptions(trackingOptions) {}
+ mOptions(options) {}
inline virtual void proc() const {
- if (mAdapter.isTrackingSession(mClient, mSessionId)) {
- LocationError err = LOCATION_ERROR_SUCCESS;
- if (0 == mTrackingOptions.size) {
- err = LOCATION_ERROR_INVALID_PARAMETER;
- } else {
- if (GNSS_POWER_MODE_INVALID != mTrackingOptions.powerMode &&
- !ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_AGPM_V02)) {
- LOC_LOGv("Ignoring power mode, feature not supported.");
- mTrackingOptions.powerMode = GNSS_POWER_MODE_INVALID;
- }
- if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_AGPM_V02) &&
- GNSS_POWER_MODE_M4 == mTrackingOptions.powerMode &&
- mTrackingOptions.tbm > TRACKING_TBM_THRESHOLD_MILLIS) {
- LOC_LOGd("TBM (%d) > %d Falling back to M2 power mode",
- mTrackingOptions.tbm, TRACKING_TBM_THRESHOLD_MILLIS);
- mTrackingOptions.powerMode = GNSS_POWER_MODE_M2;
- }
- if (mTrackingOptions.minInterval < MIN_TRACKING_INTERVAL) {
- mTrackingOptions.minInterval = MIN_TRACKING_INTERVAL;
+ // distance based tracking will need to know engine capabilities before it can start
+ if (!mAdapter.isEngineCapabilitiesKnown() && mOptions.minDistance > 0) {
+ mAdapter.mPendingMsgs.push_back(new MsgUpdateTracking(*this));
+ return;
+ }
+ LocationError err = LOCATION_ERROR_SUCCESS;
+ bool isTimeBased = mAdapter.isTimeBasedTrackingSession(mClient, mSessionId);
+ bool isDistanceBased = mAdapter.isDistanceBasedTrackingSession(mClient, mSessionId);
+ if (!isTimeBased && !isDistanceBased) {
+ err = LOCATION_ERROR_ID_UNKNOWN;
+ } else if (0 == mOptions.size) {
+ err = LOCATION_ERROR_INVALID_PARAMETER;
+ }
+ if (LOCATION_ERROR_SUCCESS != err) {
+ mAdapter.reportResponse(mClient, err, mSessionId);
+ } else {
+ if (GNSS_POWER_MODE_M4 == mOptions.powerMode &&
+ mOptions.tbm > TRACKING_TBM_THRESHOLD_MILLIS) {
+ LOC_LOGd("TBM (%d) > %d Falling back to M2 power mode",
+ mOptions.tbm, TRACKING_TBM_THRESHOLD_MILLIS);
+ mOptions.powerMode = GNSS_POWER_MODE_M2;
+ }
+ if (mOptions.minInterval < MIN_TRACKING_INTERVAL) {
+ mOptions.minInterval = MIN_TRACKING_INTERVAL;
+ }
+ // Now update session as required
+ if (isTimeBased && mOptions.minDistance > 0) {
+ // switch from time based to distance based
+ // Api doesn't support multiple clients for time based tracking, so mutiplex
+ bool reportToClientWithNoWait =
+ mAdapter.stopTimeBasedTrackingMultiplex(mClient, mSessionId);
+ // erases the time based Session
+ mAdapter.eraseTrackingSession(mClient, mSessionId);
+ if (reportToClientWithNoWait) {
+ mAdapter.reportResponse(mClient, LOCATION_ERROR_SUCCESS, mSessionId);
}
+ // saves as distance based Session
+ mAdapter.saveTrackingSession(mClient, mSessionId, mOptions);
+ mApi.startDistanceBasedTracking(mSessionId, mOptions,
+ new LocApiResponse(*mAdapter.getContext(),
+ [] (LocationError /*err*/) {}));
+ } else if (isDistanceBased && mOptions.minDistance == 0) {
+ // switch from distance based to time based
+ mAdapter.eraseTrackingSession(mClient, mSessionId);
+ mApi.stopDistanceBasedTracking(mSessionId, new LocApiResponse(
+ *mAdapter.getContext(),
+ [&mAdapter = mAdapter, mSessionId = mSessionId, mOptions = mOptions,
+ mClient = mClient] (LocationError /*err*/) {
+ // Api doesn't support multiple clients for time based tracking,
+ // so mutiplex
+ bool reportToClientWithNoWait =
+ mAdapter.startTimeBasedTrackingMultiplex(mClient, mSessionId,
+ mOptions);
+ mAdapter.saveTrackingSession(mClient, mSessionId, mOptions);
+
+ if (reportToClientWithNoWait) {
+ mAdapter.reportResponse(mClient, LOCATION_ERROR_SUCCESS, mSessionId);
+ }
+ }));
+ } else if (isTimeBased) {
+ // update time based tracking
// Api doesn't support multiple clients for time based tracking, so mutiplex
bool reportToClientWithNoWait =
- mAdapter.updateTrackingMultiplex(mClient, mSessionId, mTrackingOptions);
- mAdapter.saveTrackingSession(mClient, mSessionId, mTrackingOptions);
+ mAdapter.updateTrackingMultiplex(mClient, mSessionId, mOptions);
+ mAdapter.saveTrackingSession(mClient, mSessionId, mOptions);
if (reportToClientWithNoWait) {
mAdapter.reportResponse(mClient, err, mSessionId);
}
+ } else if (isDistanceBased) {
+ // restart distance based tracking
+ mApi.stopDistanceBasedTracking(mSessionId, new LocApiResponse(
+ *mAdapter.getContext(),
+ [&mAdapter = mAdapter, mSessionId = mSessionId, mOptions = mOptions,
+ mClient = mClient, &mApi = mApi] (LocationError err) {
+ if (LOCATION_ERROR_SUCCESS == err) {
+ mApi.startDistanceBasedTracking(mSessionId, mOptions,
+ new LocApiResponse(*mAdapter.getContext(),
+ [&mAdapter, mClient, mSessionId, mOptions]
+ (LocationError err) {
+ if (LOCATION_ERROR_SUCCESS == err) {
+ mAdapter.saveTrackingSession(mClient, mSessionId, mOptions);
+ }
+ mAdapter.reportResponse(mClient, err, mSessionId);
+ }));
+ }
+ }));
}
}
- // we do not reportResponse for the case where there is no existing tracking session
- // for the client and id being used, since updateTrackingCommand can be sent to both
- // GnssAdapter & FlpAdapter by LocationAPI and we want to avoid incorrect error response
}
};
@@ -2547,19 +2574,21 @@ GnssAdapter::updateTrackingMultiplex(LocationAPI* client, uint32_t id,
LocationSessionKey key(client, id);
// get the session we are updating
- auto it = mTrackingSessions.find(key);
+ auto it = mTimeBasedTrackingSessions.find(key);
// cache the clients existing LocationOptions
TrackingOptions oldOptions = it->second;
// if session we are updating exists and the minInterval or powerMode has changed
- if (it != mTrackingSessions.end() && (it->second.minInterval != trackingOptions.minInterval ||
+ if (it != mTimeBasedTrackingSessions.end() &&
+ (it->second.minInterval != trackingOptions.minInterval ||
it->second.powerMode != trackingOptions.powerMode)) {
// find the smallest interval and powerMode, other than the session we are updating
TrackingOptions multiplexedOptions = {}; // size is 0 until set for the first time
GnssPowerMode multiplexedPowerMode = GNSS_POWER_MODE_INVALID;
memset(&multiplexedOptions, 0, sizeof(multiplexedOptions));
- for (auto it2 = mTrackingSessions.begin(); it2 != mTrackingSessions.end(); ++it2) {
+ for (auto it2 = mTimeBasedTrackingSessions.begin();
+ it2 != mTimeBasedTrackingSessions.end(); ++it2) {
// if session is not the one we are updating and either interval
// is not set or there is a new smallest interval, then set the new interval
if (it2->first != key && (0 == multiplexedOptions.size ||
@@ -2586,7 +2615,7 @@ GnssAdapter::updateTrackingMultiplex(LocationAPI* client, uint32_t id,
updateOptions = true;
}
// if only one session exists, then tracking should be updated with it
- if (1 == mTrackingSessions.size()) {
+ if (1 == mTimeBasedTrackingSessions.size()) {
multiplexedOptions = trackingOptions;
updateOptions = true;
}
@@ -2621,19 +2650,33 @@ GnssAdapter::stopTrackingCommand(LocationAPI* client, uint32_t id)
mClient(client),
mSessionId(sessionId) {}
inline virtual void proc() const {
- if (mAdapter.isTrackingSession(mClient, mSessionId)) {
- // Api doesn't support multiple clients for time based tracking, so mutiplex
- bool reportToClientWithNoWait =
- mAdapter.stopTrackingMultiplex(mClient, mSessionId);
- mAdapter.eraseTrackingSession(mClient, mSessionId);
-
- if (reportToClientWithNoWait) {
- mAdapter.reportResponse(mClient, LOCATION_ERROR_SUCCESS, mSessionId);
+ bool isTimeBased = mAdapter.isTimeBasedTrackingSession(mClient, mSessionId);
+ bool isDistanceBased = mAdapter.isDistanceBasedTrackingSession(mClient, mSessionId);
+ if (isTimeBased || isDistanceBased) {
+ if (isTimeBased) {
+ // Api doesn't support multiple clients for time based tracking, so mutiplex
+ bool reportToClientWithNoWait =
+ mAdapter.stopTimeBasedTrackingMultiplex(mClient, mSessionId);
+ mAdapter.eraseTrackingSession(mClient, mSessionId);
+
+ if (reportToClientWithNoWait) {
+ mAdapter.reportResponse(mClient, LOCATION_ERROR_SUCCESS, mSessionId);
+ }
+ } else if (isDistanceBased) {
+ mApi.stopDistanceBasedTracking(mSessionId, new LocApiResponse(
+ *mAdapter.getContext(),
+ [&mAdapter = mAdapter, mSessionId = mSessionId, mClient = mClient]
+ (LocationError err) {
+ if (LOCATION_ERROR_SUCCESS == err) {
+ mAdapter.eraseTrackingSession(mClient, mSessionId);
+ }
+ mAdapter.reportResponse(mClient, err, mSessionId);
+ }));
}
+ } else {
+ mAdapter.reportResponse(mClient, LOCATION_ERROR_ID_UNKNOWN, mSessionId);
}
- // we do not reportResponse for the case where there is no existing tracking session
- // for the client and id being used, since stopTrackingCommand can be sent to both
- // GnssAdapter & FlpAdapter by LocationAPI and we want to avoid incorrect error response
+
}
};
@@ -2641,11 +2684,11 @@ GnssAdapter::stopTrackingCommand(LocationAPI* client, uint32_t id)
}
bool
-GnssAdapter::stopTrackingMultiplex(LocationAPI* client, uint32_t id)
+GnssAdapter::stopTimeBasedTrackingMultiplex(LocationAPI* client, uint32_t id)
{
bool reportToClientWithNoWait = true;
- if (1 == mTrackingSessions.size()) {
+ if (1 == mTimeBasedTrackingSessions.size()) {
stopTracking(client, id);
// need to wait for QMI callback
reportToClientWithNoWait = false;
@@ -2653,13 +2696,14 @@ GnssAdapter::stopTrackingMultiplex(LocationAPI* client, uint32_t id)
LocationSessionKey key(client, id);
// get the session we are stopping
- auto it = mTrackingSessions.find(key);
- if (it != mTrackingSessions.end()) {
+ auto it = mTimeBasedTrackingSessions.find(key);
+ if (it != mTimeBasedTrackingSessions.end()) {
// find the smallest interval and powerMode, other than the session we are stopping
TrackingOptions multiplexedOptions = {}; // size is 0 until set for the first time
GnssPowerMode multiplexedPowerMode = GNSS_POWER_MODE_INVALID;
memset(&multiplexedOptions, 0, sizeof(multiplexedOptions));
- for (auto it2 = mTrackingSessions.begin(); it2 != mTrackingSessions.end(); ++it2) {
+ for (auto it2 = mTimeBasedTrackingSessions.begin();
+ it2 != mTimeBasedTrackingSessions.end(); ++it2) {
// if session is not the one we are stopping and either interval
// is not set or there is a new smallest interval, then set the new interval
if (it2->first != key && (0 == multiplexedOptions.size ||
@@ -2679,7 +2723,7 @@ GnssAdapter::stopTrackingMultiplex(LocationAPI* client, uint32_t id)
it->second.powerMode < multiplexedPowerMode) {
multiplexedOptions.powerMode = multiplexedPowerMode;
// restart time based tracking with the newly updated options
- startTracking(client, id, multiplexedOptions);
+ startTimeBasedTracking(client, id, multiplexedOptions);
// need to wait for QMI callback
reportToClientWithNoWait = false;
}
@@ -2798,7 +2842,6 @@ GnssAdapter::gnssNiResponseCommand(GnssNiResponse response, void* rawRequest)
inline virtual ~MsgGnssNiResponse() {
}
inline virtual void proc() const {
- const void *rawPayload = mPayload;
mApi.informNiResponse(mResponse, mPayload);
}
};
@@ -3001,9 +3044,9 @@ GnssAdapter::reportPositionEvent(const UlpLocation& ulpLocation,
}
bool
-GnssAdapter::needReport(const UlpLocation& ulpLocation,
- enum loc_sess_status status,
- LocPosTechMask techMask) {
+GnssAdapter::needReportForGnssClient(const UlpLocation& ulpLocation,
+ enum loc_sess_status status,
+ LocPosTechMask techMask) {
bool reported = false;
// if engine hub is enabled, aka, any of the engine services is enabled,
@@ -3016,47 +3059,77 @@ GnssAdapter::needReport(const UlpLocation& ulpLocation,
return reported;
}
+bool
+GnssAdapter::needReportForFlpClient(enum loc_sess_status status,
+ LocPosTechMask techMask) {
+ if ((status == LOC_SESS_INTERMEDIATE) &&
+ !(techMask & LOC_POS_TECH_MASK_SENSORS) &&
+ (!getAllowFlpNetworkFixes())) {
+ return false;
+ } else {
+ return true;
+ }
+}
+
+bool
+GnssAdapter::isFlpClient(LocationCallbacks& locationCallbacks)
+{
+ return (locationCallbacks.gnssLocationInfoCb == nullptr &&
+ locationCallbacks.gnssSvCb == nullptr &&
+ locationCallbacks.gnssNmeaCb == nullptr &&
+ locationCallbacks.gnssDataCb == nullptr &&
+ locationCallbacks.gnssMeasurementsCb == nullptr);
+}
+
void
GnssAdapter::reportPosition(const UlpLocation& ulpLocation,
const GpsLocationExtended& locationExtended,
enum loc_sess_status status,
LocPosTechMask techMask)
{
- bool reported = needReport(ulpLocation, status, techMask);
- mGnssSvIdUsedInPosAvail = false;
- if (reported) {
- if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_GNSS_SV_USED_DATA) {
- mGnssSvIdUsedInPosAvail = true;
- mGnssSvIdUsedInPosition = locationExtended.gnss_sv_used_ids;
- }
+ bool reportToGnssClient = needReportForGnssClient(ulpLocation, status, techMask);
+ bool reportToFlpClient = needReportForFlpClient(status, techMask);
+ if (reportToGnssClient || reportToFlpClient) {
GnssLocationInfoNotification locationInfo = {};
convertLocationInfo(locationInfo, locationExtended);
convertLocation(locationInfo.location, ulpLocation, locationExtended, techMask);
for (auto it=mClientData.begin(); it != mClientData.end(); ++it) {
- if (nullptr != it->second.gnssLocationInfoCb) {
- it->second.gnssLocationInfoCb(locationInfo);
- } else if (nullptr != it->second.trackingCb) {
- it->second.trackingCb(locationInfo.location);
+ if ((reportToFlpClient && isFlpClient(it->second)) ||
+ (reportToGnssClient && !isFlpClient(it->second))) {
+ if (nullptr != it->second.gnssLocationInfoCb) {
+ it->second.gnssLocationInfoCb(locationInfo);
+ } else if (nullptr != it->second.trackingCb) {
+ it->second.trackingCb(locationInfo.location);
+ }
}
}
- // if engine hub is running and the fix is from sensor, e.g.: DRE,
- // inject DRE fix to modem
- if ((1 == ContextBase::mGps_conf.POSITION_ASSISTED_CLOCK_ESTIMATOR_ENABLED) &&
- (true == initEngHubProxy()) && (LOC_POS_TECH_MASK_SENSORS & techMask)) {
- mLocApi->injectPosition(locationInfo, false);
+ mGnssSvIdUsedInPosAvail = false;
+ if (reportToGnssClient) {
+ if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_GNSS_SV_USED_DATA) {
+ mGnssSvIdUsedInPosAvail = true;
+ mGnssSvIdUsedInPosition = locationExtended.gnss_sv_used_ids;
+ }
+
+ // if engine hub is running and the fix is from sensor, e.g.: DRE,
+ // inject DRE fix to modem
+ if ((1 == ContextBase::mGps_conf.POSITION_ASSISTED_CLOCK_ESTIMATOR_ENABLED) &&
+ (true == initEngHubProxy()) && (LOC_POS_TECH_MASK_SENSORS & techMask)) {
+ mLocApi->injectPosition(locationInfo, false);
+ }
}
}
- if (NMEA_PROVIDER_AP == ContextBase::mGps_conf.NMEA_PROVIDER && !mTrackingSessions.empty()) {
+ if (NMEA_PROVIDER_AP == ContextBase::mGps_conf.NMEA_PROVIDER &&
+ !mTimeBasedTrackingSessions.empty()) {
/*Only BlankNMEA sentence needs to be processed and sent, if both lat, long is 0 &
horReliability is not set. */
bool blank_fix = ((0 == ulpLocation.gpsLocation.latitude) &&
(0 == ulpLocation.gpsLocation.longitude) &&
(LOC_RELIABILITY_NOT_SET == locationExtended.horizontal_reliability));
- uint8_t generate_nmea = (reported && status != LOC_SESS_FAILURE && !blank_fix);
+ uint8_t generate_nmea = (reportToGnssClient && status != LOC_SESS_FAILURE && !blank_fix);
std::vector<std::string> nmeaArraystr;
loc_nmea_generate_pos(ulpLocation, locationExtended, mLocSystemInfo,
generate_nmea, nmeaArraystr);
@@ -3153,7 +3226,8 @@ GnssAdapter::reportSv(GnssSvNotification& svNotify)
}
}
- if (NMEA_PROVIDER_AP == ContextBase::mGps_conf.NMEA_PROVIDER && !mTrackingSessions.empty()) {
+ if (NMEA_PROVIDER_AP == ContextBase::mGps_conf.NMEA_PROVIDER &&
+ !mTimeBasedTrackingSessions.empty()) {
std::vector<std::string> nmeaArraystr;
loc_nmea_generate_sv(svNotify, nmeaArraystr);
stringstream ss;
@@ -3348,8 +3422,8 @@ GnssAdapter::reportLocationSystemInfo(const LocationSystemInfo & locationSystemI
LEAP_SECOND_SYS_INFO_CURRENT_LEAP_SECONDS_BIT;
dstLeapSecondSysInfo.leapSecondCurrent = srcLeapSecondSysInfo.leapSecondCurrent;
}
- // once leap second change event is complete, modem may send up event invalidate the leap second
- // change info while AP is still processing report during leap second transition
+ // once leap second change event is complete, modem may send up event invalidate the leap
+ // second change info while AP is still processing report during leap second transition
// so, we choose to keep this info around even though it is old
if (srcLeapSecondSysInfo.leapSecondInfoMask & LEAP_SECOND_SYS_INFO_LEAP_SECOND_CHANGE_BIT) {
dstLeapSecondSysInfo.leapSecondInfoMask |= LEAP_SECOND_SYS_INFO_LEAP_SECOND_CHANGE_BIT;
diff --git a/gnss/GnssAdapter.h b/gnss/GnssAdapter.h
index e304fe6..1ed1151 100644
--- a/gnss/GnssAdapter.h
+++ b/gnss/GnssAdapter.h
@@ -30,13 +30,14 @@
#define GNSS_ADAPTER_H
#include <LocAdapterBase.h>
-#include <LocDualContext.h>
+#include <LocContext.h>
#include <IOsObserver.h>
#include <EngineHubProxyBase.h>
#include <LocationAPI.h>
#include <Agps.h>
#include <SystemStatus.h>
#include <XtraSystemStatusObserver.h>
+#include <map>
#define MAX_URL_LEN 256
#define NMEA_SENTENCE_MAX_LENGTH 200
@@ -48,6 +49,9 @@
class GnssAdapter;
+typedef std::map<LocationSessionKey, LocationOptions> LocationSessionMap;
+typedef std::map<LocationSessionKey, TrackingOptions> TrackingOptionsMap;
+
class OdcpiTimer : public LocTimer {
public:
OdcpiTimer(GnssAdapter* adapter) :
@@ -128,19 +132,16 @@ typedef std::function<void(
uint64_t gnssEnergyConsumedFromFirstBoot
)> GnssEnergyConsumedCallback;
-typedef void (*removeClientCompleteCallback)(LocationAPI* client);
+typedef void (*powerStateCallback)(bool on);
class GnssAdapter : public LocAdapterBase {
/* ==== Engine Hub ===================================================================== */
EngineHubProxyBase* mEngHubProxy;
- /* ==== CLIENT ========================================================================= */
- typedef std::map<LocationAPI*, LocationCallbacks> ClientDataMap;
- ClientDataMap mClientData;
-
/* ==== TRACKING ======================================================================= */
- TrackingOptionsMap mTrackingSessions;
+ TrackingOptionsMap mTimeBasedTrackingSessions;
+ LocationSessionMap mDistanceBasedTrackingSessions;
LocPosMode mLocPositionMode;
GnssSvUsedInPosition mGnssSvIdUsedInPosition;
bool mGnssSvIdUsedInPosAvail;
@@ -185,9 +186,12 @@ class GnssAdapter : public LocAdapterBase {
/* === Misc ===================================================================== */
BlockCPIInfo mBlockCPIInfo;
+ bool mPowerOn;
+ uint32_t mAllowFlpNetworkFixes;
/* === Misc callback from QMI LOC API ============================================== */
GnssEnergyConsumedCallback mGnssEnergyConsumedCb;
+ powerStateCallback mPowerStateCb;
/*==== CONVERSION ===================================================================*/
static void convertOptions(LocPosMode& out, const TrackingOptions& trackingOptions);
@@ -200,6 +204,13 @@ class GnssAdapter : public LocAdapterBase {
/* ======== UTILITIES ================================================================== */
inline void initOdcpi(const OdcpiRequestCallback& callback);
inline void injectOdcpi(const Location& location);
+ static bool isFlpClient(LocationCallbacks& locationCallbacks);
+
+protected:
+
+ /* ==== CLIENT ========================================================================= */
+ virtual void updateClientsEventMask();
+ virtual void stopClientSessions(LocationAPI* client);
public:
@@ -214,21 +225,7 @@ public:
/* ==== CLIENT ========================================================================= */
/* ======== COMMANDS ====(Called from Client Thread)==================================== */
- void addClientCommand(LocationAPI* client, const LocationCallbacks& callbacks);
- void removeClientCommand(LocationAPI* client,
- removeClientCompleteCallback rmClientCb);
- void requestCapabilitiesCommand(LocationAPI* client);
- /* ======== UTILITIES ================================================================== */
- void saveClient(LocationAPI* client, const LocationCallbacks& callbacks);
- void eraseClient(LocationAPI* client);
- void notifyClientOfCachedLocationSystemInfo(LocationAPI* client,
- const LocationCallbacks& callbacks);
- void updateClientsEventMask();
- void stopClientSessions(LocationAPI* client);
- LocationCallbacks getClientCallbacks(LocationAPI* client);
- LocationCapabilitiesMask getCapabilities();
- void broadcastCapabilities(LocationCapabilitiesMask);
- void setSuplHostServer(const char* server, int port, LocServerType type);
+ virtual void addClientCommand(LocationAPI* client, const LocationCallbacks& callbacks);
/* ==== TRACKING ======================================================================= */
/* ======== COMMANDS ====(Called from Client Thread)==================================== */
@@ -237,11 +234,12 @@ public:
void updateTrackingOptionsCommand(
LocationAPI* client, uint32_t id, TrackingOptions& trackingOptions);
void stopTrackingCommand(LocationAPI* client, uint32_t id);
- virtual void setPositionModeCommand(LocPosMode& locPosMode);
/* ======== RESPONSES ================================================================== */
void reportResponse(LocationAPI* client, LocationError err, uint32_t sessionId);
/* ======== UTILITIES ================================================================== */
bool hasTrackingCallback(LocationAPI* client);
+ bool isTimeBasedTrackingSession(LocationAPI* client, uint32_t sessionId);
+ bool isDistanceBasedTrackingSession(LocationAPI* client, uint32_t sessionId);
bool hasMeasurementsCallback(LocationAPI* client);
bool isTrackingSession(LocationAPI* client, uint32_t sessionId);
void saveTrackingSession(LocationAPI* client, uint32_t sessionId,
@@ -251,16 +249,16 @@ public:
bool setLocPositionMode(const LocPosMode& mode);
LocPosMode& getLocPositionMode() { return mLocPositionMode; }
- bool startTrackingMultiplex(LocationAPI* client, uint32_t sessionId,
- const TrackingOptions& trackingOptions);
- void startTracking(LocationAPI* client, uint32_t sessionId,
- const TrackingOptions& trackingOptions);
- bool stopTrackingMultiplex(LocationAPI* client, uint32_t id);
+ bool startTimeBasedTrackingMultiplex(LocationAPI* client, uint32_t sessionId,
+ const TrackingOptions& trackingOptions);
+ void startTimeBasedTracking(LocationAPI* client, uint32_t sessionId,
+ const TrackingOptions& trackingOptions);
+ bool stopTimeBasedTrackingMultiplex(LocationAPI* client, uint32_t id);
void stopTracking(LocationAPI* client, uint32_t id);
bool updateTrackingMultiplex(LocationAPI* client, uint32_t id,
- const TrackingOptions& trackingOptions);
+ const TrackingOptions& trackingOptions);
void updateTracking(LocationAPI* client, uint32_t sessionId,
- const TrackingOptions& updatedOptions, const TrackingOptions& oldOptions);
+ const TrackingOptions& updatedOptions, const TrackingOptions& oldOptions);
/* ==== NI ============================================================================= */
/* ======== COMMANDS ====(Called from Client Thread)==================================== */
@@ -335,7 +333,9 @@ public:
{ mControlCallbacks = controlCallbacks; }
void setAfwControlId(uint32_t id) { mPowerVoteId = id; }
uint32_t getAfwControlId() { return mPowerVoteId; }
- virtual bool isInSession() { return !mTrackingSessions.empty(); }
+ void setPowerVoteId(uint32_t id) { mPowerVoteId = id; }
+ uint32_t getPowerVoteId() { return mPowerVoteId; }
+ virtual bool isInSession() { return !mTimeBasedTrackingSessions.empty(); }
void initDefaultAgps();
bool initEngHubProxy();
void odcpiTimerExpireEvent();
@@ -374,8 +374,9 @@ public:
virtual void reportNfwNotificationEvent(GnssNfwNotification& notification);
/* ======== UTILITIES ================================================================= */
- bool needReport(const UlpLocation& ulpLocation,
+ bool needReportForGnssClient(const UlpLocation& ulpLocation,
enum loc_sess_status status, LocPosTechMask techMask);
+ bool needReportForFlpClient(enum loc_sess_status status, LocPosTechMask techMask);
void reportPosition(const UlpLocation &ulpLocation,
const GpsLocationExtended &locationExtended,
enum loc_sess_status status,
@@ -433,6 +434,19 @@ public:
void injectTimeCommand(int64_t time, int64_t timeReference, int32_t uncertainty);
void blockCPICommand(double latitude, double longitude, float accuracy,
int blockDurationMsec, double latLonDiffThreshold);
+
+ /* ==== MISCELLANEOUS ================================================================== */
+ /* ======== COMMANDS ====(Called from Client Thread)==================================== */
+ void getPowerStateChangesCommand(void* powerStateCb);
+ /* ======== UTILITIES ================================================================== */
+ void reportPowerStateIfChanged();
+ void savePowerStateCallback(powerStateCallback powerStateCb){ mPowerStateCb = powerStateCb; }
+ bool getPowerState() { return mPowerOn; }
+ void setAllowFlpNetworkFixes(uint32_t allow) { mAllowFlpNetworkFixes = allow; }
+ uint32_t getAllowFlpNetworkFixes() { return mAllowFlpNetworkFixes; }
+ void setSuplHostServer(const char* server, int port, LocServerType type);
+ void notifyClientOfCachedLocationSystemInfo(LocationAPI* client,
+ const LocationCallbacks& callbacks);
};
#endif //GNSS_ADAPTER_H
diff --git a/gnss/XtraSystemStatusObserver.h b/gnss/XtraSystemStatusObserver.h
index cbbeda6..24f9776 100644
--- a/gnss/XtraSystemStatusObserver.h
+++ b/gnss/XtraSystemStatusObserver.h
@@ -46,7 +46,7 @@ public :
inline XtraSystemStatusObserver(IOsObserver* sysStatObs, const MsgTask* msgTask):
mSystemStatusObsrvr(sysStatObs), mMsgTask(msgTask),
mGpsLock(-1), mConnections(~0), mXtraThrottle(true), mReqStatusReceived(false),
- mDelayLocTimer(*this), mIsConnectivityStatusKnown (false) {
+ mIsConnectivityStatusKnown (false), mDelayLocTimer(*this) {
subscribe(true);
startListeningNonBlocking(LOC_IPC_HAL);
mDelayLocTimer.start(100 /*.1 sec*/, false);
diff --git a/gnss/location_gnss.cpp b/gnss/location_gnss.cpp
index 45ad292..23ec2cf 100644
--- a/gnss/location_gnss.cpp
+++ b/gnss/location_gnss.cpp
@@ -70,6 +70,7 @@ static void getGnssEnergyConsumed(GnssEnergyConsumedCallback energyConsumedCb);
static void enableNfwLocationAccess(bool enable);
static void nfwInit(const NfwCbInfo& cbInfo);
static uint8_t getGpsLock();
+static void getPowerStateChanges(void* powerStateCb);
static void odcpiInit(const OdcpiRequestCallback& callback);
static void odcpiInject(const Location& location);
@@ -112,7 +113,8 @@ static const GnssInterface gGnssInterface = {
getGnssEnergyConsumed,
enableNfwLocationAccess,
nfwInit,
- getGpsLock
+ getGpsLock,
+ getPowerStateChanges
};
#ifndef DEBUG_X86
@@ -378,3 +380,10 @@ static uint8_t getGpsLock() {
}
}
+static void getPowerStateChanges(void* powerStateCb)
+{
+ if (NULL != gGnssAdapter) {
+ gGnssAdapter->getPowerStateChangesCommand(powerStateCb);
+ }
+}
+