diff options
-rw-r--r-- | android/1.0/Gnss.cpp | 2 | ||||
-rw-r--r-- | android/1.0/location_api/GnssAPIClient.cpp | 1 | ||||
-rw-r--r-- | android/1.1/Gnss.cpp | 2 | ||||
-rw-r--r-- | android/1.1/location_api/GnssAPIClient.cpp | 1 | ||||
-rw-r--r-- | android/2.0/Gnss.cpp | 2 | ||||
-rw-r--r-- | android/2.0/location_api/GnssAPIClient.cpp | 1 | ||||
-rw-r--r-- | android/utils/Android.mk | 3 | ||||
-rw-r--r-- | android/utils/battery_listener.cpp | 70 | ||||
-rw-r--r-- | core/ContextBase.cpp | 3 | ||||
-rw-r--r-- | core/ContextBase.h | 1 | ||||
-rw-r--r-- | core/EngineHubProxyBase.h | 6 | ||||
-rw-r--r-- | core/LocApiBase.cpp | 2 | ||||
-rw-r--r-- | core/LocApiBase.h | 1 | ||||
-rw-r--r-- | gnss/GnssAdapter.cpp | 235 | ||||
-rw-r--r-- | gnss/GnssAdapter.h | 13 | ||||
-rw-r--r-- | gnss/location_gnss.cpp | 10 | ||||
-rw-r--r-- | location/location_interface.h | 1 | ||||
-rw-r--r-- | utils/gps_extended_c.h | 9 | ||||
-rw-r--r-- | utils/loc_nmea.cpp | 3 |
19 files changed, 275 insertions, 91 deletions
diff --git a/android/1.0/Gnss.cpp b/android/1.0/Gnss.cpp index d85e0a4..4aac432 100644 --- a/android/1.0/Gnss.cpp +++ b/android/1.0/Gnss.cpp @@ -56,6 +56,8 @@ void location_on_battery_status_changed(bool charging) { Gnss::Gnss() { ENTRY_LOG_CALLFLOW(); sGnss = this; + // initilize gnss interface at first in case needing notify battery status + sGnss->getGnssInterface()->initialize(); // register health client to listen on battery change loc_extn_battery_properties_listener_init(location_on_battery_status_changed); // clear pending GnssConfig diff --git a/android/1.0/location_api/GnssAPIClient.cpp b/android/1.0/location_api/GnssAPIClient.cpp index b9fe2b2..eb78591 100644 --- a/android/1.0/location_api/GnssAPIClient.cpp +++ b/android/1.0/location_api/GnssAPIClient.cpp @@ -174,7 +174,6 @@ bool GnssAPIClient::gnssSetPositionMode(IGnss::GnssPositionMode mode, // For MSA, we always treat it as SINGLE mode. mTrackingOptions.minInterval = SINGLE_SHOT_MIN_TRACKING_INTERVAL_MSEC; } - mTrackingOptions.minDistance = preferredAccuracyMeters; if (mode == IGnss::GnssPositionMode::STANDALONE) mTrackingOptions.mode = GNSS_SUPL_MODE_STANDALONE; else if (mode == IGnss::GnssPositionMode::MS_BASED) diff --git a/android/1.1/Gnss.cpp b/android/1.1/Gnss.cpp index bea556f..277dbc1 100644 --- a/android/1.1/Gnss.cpp +++ b/android/1.1/Gnss.cpp @@ -97,6 +97,8 @@ void location_on_battery_status_changed(bool charging) { Gnss::Gnss() { ENTRY_LOG_CALLFLOW(); sGnss = this; + // initilize gnss interface at first in case needing notify battery status + sGnss->getGnssInterface()->initialize(); // register health client to listen on battery change loc_extn_battery_properties_listener_init(location_on_battery_status_changed); // clear pending GnssConfig diff --git a/android/1.1/location_api/GnssAPIClient.cpp b/android/1.1/location_api/GnssAPIClient.cpp index 9a95fdf..be4d659 100644 --- a/android/1.1/location_api/GnssAPIClient.cpp +++ b/android/1.1/location_api/GnssAPIClient.cpp @@ -174,7 +174,6 @@ bool GnssAPIClient::gnssSetPositionMode(IGnss::GnssPositionMode mode, // For MSA, we always treat it as SINGLE mode. mTrackingOptions.minInterval = SINGLE_SHOT_MIN_TRACKING_INTERVAL_MSEC; } - mTrackingOptions.minDistance = preferredAccuracyMeters; if (mode == IGnss::GnssPositionMode::STANDALONE) mTrackingOptions.mode = GNSS_SUPL_MODE_STANDALONE; else if (mode == IGnss::GnssPositionMode::MS_BASED) diff --git a/android/2.0/Gnss.cpp b/android/2.0/Gnss.cpp index af76b72..2276c14 100644 --- a/android/2.0/Gnss.cpp +++ b/android/2.0/Gnss.cpp @@ -96,6 +96,8 @@ void location_on_battery_status_changed(bool charging) { Gnss::Gnss() { ENTRY_LOG_CALLFLOW(); sGnss = this; + // initilize gnss interface at first in case needing notify battery status + sGnss->getGnssInterface()->initialize(); // register health client to listen on battery change loc_extn_battery_properties_listener_init(location_on_battery_status_changed); // clear pending GnssConfig diff --git a/android/2.0/location_api/GnssAPIClient.cpp b/android/2.0/location_api/GnssAPIClient.cpp index a3cdd27..d505241 100644 --- a/android/2.0/location_api/GnssAPIClient.cpp +++ b/android/2.0/location_api/GnssAPIClient.cpp @@ -223,7 +223,6 @@ bool GnssAPIClient::gnssSetPositionMode(IGnss::GnssPositionMode mode, // For MSA, we always treat it as SINGLE mode. mTrackingOptions.minInterval = SINGLE_SHOT_MIN_TRACKING_INTERVAL_MSEC; } - mTrackingOptions.minDistance = preferredAccuracyMeters; if (mode == IGnss::GnssPositionMode::STANDALONE) mTrackingOptions.mode = GNSS_SUPL_MODE_STANDALONE; else if (mode == IGnss::GnssPositionMode::MS_BASED) diff --git a/android/utils/Android.mk b/android/utils/Android.mk index bbcf512..9cb6f7b 100644 --- a/android/utils/Android.mk +++ b/android/utils/Android.mk @@ -24,6 +24,9 @@ LOCAL_SHARED_LIBRARIES := \ android.hardware.power@1.2 \ libbase +LOCAL_HEADER_LIBRARIES := \ + libgps.utils_headers \ + LOCAL_STATIC_LIBRARIES := libhealthhalutils LOCAL_CFLAGS += -DBATTERY_LISTENER_ENABLED diff --git a/android/utils/battery_listener.cpp b/android/utils/battery_listener.cpp index a790702..8547e41 100644 --- a/android/utils/battery_listener.cpp +++ b/android/utils/battery_listener.cpp @@ -31,12 +31,15 @@ #undef LOG_TAG #endif #define LOG_TAG "LocSvc_BatteryListener" +#define LOG_NDEBUG 0 #include <android/hidl/manager/1.0/IServiceManager.h> #include <android/hardware/health/2.0/IHealth.h> #include <healthhalutils/HealthHalUtils.h> #include <hidl/HidlTransportSupport.h> #include <thread> +#include <log_util.h> + using android::hardware::interfacesEqual; using android::hardware::Return; using android::hardware::Void; @@ -99,24 +102,25 @@ status_t BatteryListenerImpl::init() } while(tries < GET_HEALTH_SVC_RETRY_CNT); if (mHealth == NULL) { - ALOGE("no health service found, retries %d", tries); + LOC_LOGe("no health service found, retries %d", tries); return NO_INIT; } else { - ALOGI("Get health service in %d tries", tries); + LOC_LOGi("Get health service in %d tries", tries); } mStatus = BatteryStatus::UNKNOWN; auto ret = mHealth->getChargeStatus([&](Result r, BatteryStatus status) { if (r != Result::SUCCESS) { - ALOGE("batterylistener: cannot get battery status"); + LOC_LOGe("batterylistener: cannot get battery status"); return; } mStatus = status; }); - if (!ret.isOk()) - ALOGE("batterylistener: get charge status transaction error"); - - if (mStatus == BatteryStatus::UNKNOWN) - ALOGW("batterylistener: init: invalid battery status"); + if (!ret.isOk()) { + LOC_LOGe("batterylistener: get charge status transaction error"); + } + if (mStatus == BatteryStatus::UNKNOWN) { + LOC_LOGw("batterylistener: init: invalid battery status"); + } mDone = false; mThread = std::make_unique<std::thread>([this]() { std::unique_lock<std::mutex> l(mLock); @@ -146,7 +150,7 @@ status_t BatteryListenerImpl::init() } default: bool c = statusToBool(local_status); - ALOGI("healthInfo cb thread: cb %s", c ? "CHARGING" : "NOT CHARGING"); + LOC_LOGi("healthInfo cb thread: cb %s", c ? "CHARGING" : "NOT CHARGING"); l.unlock(); mCb(c); l.lock(); @@ -156,13 +160,14 @@ status_t BatteryListenerImpl::init() }); auto reg = mHealth->registerCallback(this); if (!reg.isOk()) { - ALOGE("Transaction error in registeringCb to HealthHAL death: %s", + LOC_LOGe("Transaction error in registeringCb to HealthHAL death: %s", reg.description().c_str()); } auto linked = mHealth->linkToDeath(this, 0 /* cookie */); if (!linked.isOk() || linked == false) { - ALOGE("Transaction error in linking to HealthHAL death: %s", linked.description().c_str()); + LOC_LOGe("Transaction error in linking to HealthHAL death: %s", + linked.description().c_str()); } return NO_ERROR; } @@ -181,7 +186,7 @@ BatteryListenerImpl::~BatteryListenerImpl() mHealth->unlinkToDeath(this); auto r = mHealth->unlinkToDeath(this); if (!r.isOk() || r == false) { - ALOGE("Transaction error in unregister to HealthHAL death: %s", + LOC_LOGe("Transaction error in unregister to HealthHAL death: %s", r.description().c_str()); } } @@ -195,10 +200,10 @@ void BatteryListenerImpl::serviceDied(uint64_t cookie __unused, { std::lock_guard<std::mutex> _l(mLock); if (mHealth == NULL || !interfacesEqual(mHealth, who.promote())) { - ALOGE("health not initialized or unknown interface died"); + LOC_LOGe("health not initialized or unknown interface died"); return; } - ALOGI("health service died, reinit"); + LOC_LOGi("health service died, reinit"); mDone = true; } mThread->join(); @@ -212,9 +217,8 @@ void BatteryListenerImpl::serviceDied(uint64_t cookie __unused, // NOT_CHARGING and CHARGING concurrencies. // Replace single var by a list if this assumption is broken Return<void> BatteryListenerImpl::healthInfoChanged( - const hardware::health::V2_0::HealthInfo& info) -{ - ALOGV("healthInfoChanged: %d", info.legacy.batteryStatus); + const hardware::health::V2_0::HealthInfo& info) { + LOC_LOGv("healthInfoChanged: %d", info.legacy.batteryStatus); std::unique_lock<std::mutex> l(mLock); if (info.legacy.batteryStatus != mStatus) { mStatus = info.legacy.batteryStatus; @@ -224,29 +228,29 @@ Return<void> BatteryListenerImpl::healthInfoChanged( } static sp<BatteryListenerImpl> batteryListener; -status_t batteryPropertiesListenerInit(BatteryListenerImpl::cb_fn_t cb) -{ - ALOGV("batteryPropertiesListenerInit entry"); + +bool batteryPropertiesListenerIsCharging() { + return batteryListener->isCharging(); +} + +status_t batteryPropertiesListenerInit(BatteryListenerImpl::cb_fn_t cb) { batteryListener = new BatteryListenerImpl(cb); + bool isCharging = batteryPropertiesListenerIsCharging(); + LOC_LOGv("charging status: %s charging", isCharging ? "" : "not");; + if (isCharging) { + cb(isCharging); + } return NO_ERROR; } -status_t batteryPropertiesListenerDeinit() -{ +status_t batteryPropertiesListenerDeinit() { batteryListener.clear(); return OK; } -bool batteryPropertiesListenerIsCharging() -{ - return batteryListener->isCharging(); -} - } // namespace android -void loc_extn_battery_properties_listener_init(battery_status_change_fn_t fn) -{ - ALOGV("loc_extn_battery_properties_listener_init entry"); +void loc_extn_battery_properties_listener_init(battery_status_change_fn_t fn) { if (!sIsBatteryListened) { std::thread t1(android::batteryPropertiesListenerInit, [=](bool charging) { fn(charging); }); @@ -255,12 +259,10 @@ void loc_extn_battery_properties_listener_init(battery_status_change_fn_t fn) } } -void loc_extn_battery_properties_listener_deinit() -{ +void loc_extn_battery_properties_listener_deinit() { android::batteryPropertiesListenerDeinit(); } -bool loc_extn_battery_properties_is_charging() -{ +bool loc_extn_battery_properties_is_charging() { return android::batteryPropertiesListenerIsCharging(); } diff --git a/core/ContextBase.cpp b/core/ContextBase.cpp index 7434590..3b8ffc6 100644 --- a/core/ContextBase.cpp +++ b/core/ContextBase.cpp @@ -92,6 +92,7 @@ const loc_param_s_type ContextBase::mGps_conf_table[] = {"GNSS_DEPLOYMENT", &mGps_conf.GNSS_DEPLOYMENT, NULL, 'n'}, {"CUSTOM_NMEA_GGA_FIX_QUALITY_ENABLED", &mGps_conf.CUSTOM_NMEA_GGA_FIX_QUALITY_ENABLED, NULL, 'n'}, + {"NI_SUPL_DENY_ON_NFW_LOCKED", &mGps_conf.NI_SUPL_DENY_ON_NFW_LOCKED, NULL, 'n'}, }; const loc_param_s_type ContextBase::mSap_conf_table[] = @@ -191,6 +192,8 @@ void ContextBase::readConfig() /* default configuration QTI GNSS H/W */ mGps_conf.GNSS_DEPLOYMENT = 0; mGps_conf.CUSTOM_NMEA_GGA_FIX_QUALITY_ENABLED = 0; + /* default configuration for NI_SUPL_DENY_ON_NFW_LOCKED */ + mGps_conf.NI_SUPL_DENY_ON_NFW_LOCKED = 0; UTIL_READ_CONF(LOC_PATH_GPS_CONF, mGps_conf_table); UTIL_READ_CONF(LOC_PATH_SAP_CONF, mSap_conf_table); diff --git a/core/ContextBase.h b/core/ContextBase.h index 6701600..e63450f 100644 --- a/core/ContextBase.h +++ b/core/ContextBase.h @@ -75,6 +75,7 @@ typedef struct loc_gps_cfg_s uint32_t CP_MTLR_ES; uint32_t GNSS_DEPLOYMENT; uint32_t CUSTOM_NMEA_GGA_FIX_QUALITY_ENABLED; + uint32_t NI_SUPL_DENY_ON_NFW_LOCKED; } loc_gps_cfg_s_type; /* NOTE: the implementaiton of the parser casts number diff --git a/core/EngineHubProxyBase.h b/core/EngineHubProxyBase.h index ec881f6..2d30c5b 100644 --- a/core/EngineHubProxyBase.h +++ b/core/EngineHubProxyBase.h @@ -113,6 +113,9 @@ typedef std::function<void(const GnssSvNotification& svNotify, typedef std::function<void(const GnssAidingDataSvMask& svDataMask)> GnssAdapterReqAidingDataCb; +typedef std::function<void(bool nHzNeeded, bool nHzMeasNeeded)> + GnssAdapterUpdateNHzRequirementCb; + // potential parameters: message queue: MsgTask * msgTask; // callback function to report back dr and ppe position and sv report typedef EngineHubProxyBase* (getEngHubProxyFn)( @@ -120,7 +123,8 @@ typedef EngineHubProxyBase* (getEngHubProxyFn)( IOsObserver* osObserver, GnssAdapterReportEnginePositionsEventCb positionEventCb, GnssAdapterReportSvEventCb svEventCb, - GnssAdapterReqAidingDataCb reqAidingDataCb); + GnssAdapterReqAidingDataCb reqAidingDataCb, + GnssAdapterUpdateNHzRequirementCb updateNHzRequirementCb); } // namespace loc_core diff --git a/core/LocApiBase.cpp b/core/LocApiBase.cpp index 8c79cf7..595fa49 100644 --- a/core/LocApiBase.cpp +++ b/core/LocApiBase.cpp @@ -873,5 +873,7 @@ DEFAULT_IMPL() void LocApiBase::addToCallQueue(LocApiResponse* /*adapterResponse*/) DEFAULT_IMPL() +void LocApiBase::updateSystemPowerState(PowerStateType /*powerState*/) +DEFAULT_IMPL() } // namespace loc_core diff --git a/core/LocApiBase.h b/core/LocApiBase.h index 6dac585..3c85b09 100644 --- a/core/LocApiBase.h +++ b/core/LocApiBase.h @@ -312,6 +312,7 @@ public: void updateEvtMask(); void updateNmeaMask(uint32_t mask); + virtual void updateSystemPowerState(PowerStateType systemPowerState); }; typedef LocApiBase* (getLocApi_t)(LOC_API_ADAPTER_EVENT_MASK_T exMask, diff --git a/gnss/GnssAdapter.cpp b/gnss/GnssAdapter.cpp index 097fd6f..339f9a0 100644 --- a/gnss/GnssAdapter.cpp +++ b/gnss/GnssAdapter.cpp @@ -45,7 +45,6 @@ #include <loc_nmea.h> #include <Agps.h> #include <SystemStatus.h> - #include <vector> #define RAD2DEG (180.0 / M_PI) @@ -71,6 +70,8 @@ GnssAdapter::GnssAdapter() : true, nullptr, true), mEngHubProxy(new EngineHubProxyBase()), mLocPositionMode(), + mNHzNeeded(false), + mSPEAlreadyRunningAtHighestInterval(false), mGnssSvIdUsedInPosition(), mGnssSvIdUsedInPosAvail(false), mControlCallbacks(), @@ -98,7 +99,8 @@ GnssAdapter::GnssAdapter() : mIsE911Session(NULL), mGnssMbSvIdUsedInPosition{}, mGnssMbSvIdUsedInPosAvail(false), - mSupportNfwControl(true) + mSupportNfwControl(true), + mSystemPowerState(POWER_STATE_UNKNOWN) { LOC_LOGD("%s]: Constructor %p", __func__, this); mLocPositionMode.mode = LOC_POSITION_MODE_INVALID; @@ -173,6 +175,30 @@ GnssAdapter::convertOptions(LocPosMode& out, const TrackingOptions& trackingOpti 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 GnssAdapter::convertLocation(Location& out, const UlpLocation& ulpLocation, const GpsLocationExtended& locationExtended, @@ -1496,7 +1522,7 @@ GnssAdapter::convertToGnssSvIdConfig( LOC_LOGe("Invalid sv id %d for sv type %d", source.svId, source.constellation); } else { - *svMaskPtr |= (1 << (source.svId - initialSvId)); + *svMaskPtr |= (1ULL << (source.svId - initialSvId)); } } } @@ -2001,6 +2027,35 @@ GnssAdapter::blockCPICommand(double latitude, double longitude, } void +GnssAdapter::updateSystemPowerState(PowerStateType systemPowerState) { + if (POWER_STATE_UNKNOWN != systemPowerState) { + mSystemPowerState = systemPowerState; + mLocApi->updateSystemPowerState(mSystemPowerState); + } +} + +void +GnssAdapter::updateSystemPowerStateCommand(PowerStateType systemPowerState) { + LOC_LOGd("power event %d", systemPowerState); + + struct MsgUpdatePowerState : public LocMsg { + GnssAdapter& mAdapter; + PowerStateType mSystemPowerState; + + inline MsgUpdatePowerState(GnssAdapter& adapter, + PowerStateType systemPowerState) : + LocMsg(), + mAdapter(adapter), + mSystemPowerState(systemPowerState) {} + inline virtual void proc() const { + mAdapter.updateSystemPowerState(mSystemPowerState); + } + }; + + sendMsg(new MsgUpdatePowerState(*this, systemPowerState)); +} + +void GnssAdapter::addClientCommand(LocationAPI* client, const LocationCallbacks& callbacks) { LOC_LOGD("%s]: client %p", __func__, client); @@ -2064,7 +2119,9 @@ GnssAdapter::updateClientsEventMask() { LOC_API_ADAPTER_EVENT_MASK_T mask = 0; for (auto it=mClientData.begin(); it != mClientData.end(); ++it) { - if (it->second.trackingCb != nullptr || it->second.gnssLocationInfoCb != nullptr) { + if (it->second.trackingCb != nullptr || + it->second.gnssLocationInfoCb != nullptr || + it->second.engineLocationsInfoCb != nullptr) { mask |= LOC_API_ADAPTER_BIT_PARSED_POSITION_REPORT; } if (it->second.gnssSvCb != nullptr) { @@ -2092,13 +2149,16 @@ GnssAdapter::updateClientsEventMask() if((1 == ContextBase::mGps_conf.EXTERNAL_DR_ENABLED) || (true == initEngHubProxy())) { 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_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. + mask |= checkMask(LOC_API_ADAPTER_BIT_GNSS_NHZ_MEASUREMENT); + LOC_LOGd("Auto usecase, Enable MEAS/POLY/EPHEMERIS - mask 0x%" PRIx64 "", mask); } @@ -2136,9 +2196,10 @@ GnssAdapter::handleEngineUpEvent() mAdapter.broadcastCapabilities(mAdapter.getCapabilities()); // must be called only after capabilities are known mAdapter.setConfig(); - mAdapter.restartSessions(); mAdapter.gnssSvIdConfigUpdate(); mAdapter.gnssSvTypeConfigUpdate(); + mAdapter.updateSystemPowerState(mAdapter.getSystemPowerState()); + mAdapter.restartSessions(); for (auto msg: mAdapter.mPendingMsgs) { mAdapter.sendMsg(msg); } @@ -2158,13 +2219,31 @@ GnssAdapter::restartSessions() // odcpi session is no longer active after restart 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()) { // 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) { + 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) { @@ -2180,14 +2259,10 @@ GnssAdapter::restartSessions() } highestPowerTrackingOptions.setLocationOptions(smallestIntervalOptions); - 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*/) {})); + // want to run SPE session at a fixed min interval in some automotive scenarios + if(!checkAndSetSPEToRunforNHz(highestPowerTrackingOptions)) { + mLocApi->startTimeBasedTracking(highestPowerTrackingOptions, nullptr); + } } } @@ -2221,13 +2296,6 @@ GnssAdapter::notifyClientOfCachedLocationSystemInfo( } bool -GnssAdapter::hasTrackingCallback(LocationAPI* client) -{ - auto it = mClientData.find(client); - return (it != mClientData.end() && (it->second.trackingCb || it->second.gnssLocationInfoCb)); -} - -bool GnssAdapter::isTimeBasedTrackingSession(LocationAPI* client, uint32_t sessionId) { LocationSessionKey key(client, sessionId); @@ -2242,10 +2310,21 @@ GnssAdapter::isDistanceBasedTrackingSession(LocationAPI* client, uint32_t sessio } bool -GnssAdapter::hasMeasurementsCallback(LocationAPI* client) +GnssAdapter::hasCallbacksToStartTracking(LocationAPI* client) { + bool allowed = false; auto it = mClientData.find(client); - return (it != mClientData.end() && it->second.gnssMeasurementsCb); + if (it != mClientData.end()) { + if (it->second.trackingCb || it->second.gnssLocationInfoCb || + it->second.engineLocationsInfoCb || it->second.gnssMeasurementsCb) { + allowed = true; + } else { + LOC_LOGi("missing right callback to start tracking") + } + } else { + LOC_LOGi("client %p not found", client) + } + return allowed; } bool @@ -2413,8 +2492,7 @@ GnssAdapter::startTrackingCommand(LocationAPI* client, TrackingOptions& options) return; } LocationError err = LOCATION_ERROR_SUCCESS; - if (!mAdapter.hasTrackingCallback(mClient) && - !mAdapter.hasMeasurementsCallback(mClient)) { + if (!mAdapter.hasCallbacksToStartTracking(mClient)) { err = LOCATION_ERROR_CALLBACK_MISSING; } else if (0 == mOptions.size) { err = LOCATION_ERROR_INVALID_PARAMETER; @@ -2494,6 +2572,7 @@ GnssAdapter::startTimeBasedTrackingMultiplex(LocationAPI* client, uint32_t sessi multiplexedOptions.minInterval = options.minInterval; updateOptions = true; } + // if session we are starting has smaller powerMode then next smallest if (options.powerMode < multiplexedPowerMode) { multiplexedOptions.powerMode = options.powerMode; @@ -2527,15 +2606,24 @@ GnssAdapter::startTimeBasedTracking(LocationAPI* client, uint32_t sessionId, mEngHubProxy->gnssSetFixMode(locPosMode); mEngHubProxy->gnssStartFix(); - mLocApi->startTimeBasedTracking(trackingOptions, new LocApiResponse(*getContext(), - [this, client, sessionId] (LocationError err) { - if (LOCATION_ERROR_SUCCESS != err) { - eraseTrackingSession(client, sessionId); + // 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) { + if (LOCATION_ERROR_SUCCESS != err) { + eraseTrackingSession(client, sessionId); + } + + reportResponse(client, err, sessionId); } + )); + } else { + reportResponse(client, LOCATION_ERROR_SUCCESS, sessionId); + } - reportResponse(client, err, sessionId); - } - )); } void @@ -2549,16 +2637,23 @@ GnssAdapter::updateTracking(LocationAPI* client, uint32_t sessionId, mEngHubProxy->gnssSetFixMode(locPosMode); mEngHubProxy->gnssStartFix(); - mLocApi->startTimeBasedTracking(updatedOptions, new LocApiResponse(*getContext(), - [this, client, sessionId, oldOptions] (LocationError err) { - if (LOCATION_ERROR_SUCCESS != err) { - // restore the old LocationOptions - saveTrackingSession(client, sessionId, oldOptions); + // 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) { + if (LOCATION_ERROR_SUCCESS != err) { + // restore the old LocationOptions + saveTrackingSession(client, sessionId, oldOptions); + } + reportResponse(client, err, sessionId); } - - reportResponse(client, err, sessionId); - } - )); + )); + } else { + reportResponse(client, LOCATION_ERROR_SUCCESS, sessionId); + } } void @@ -2859,6 +2954,8 @@ GnssAdapter::stopTracking(LocationAPI* client, uint32_t id) [this, client, id] (LocationError err) { reportResponse(client, err, id); })); + + mSPEAlreadyRunningAtHighestInterval = false; } bool @@ -3079,21 +3176,35 @@ GnssAdapter::reportPositionEvent(const UlpLocation& ulpLocation, int msInWeek) { // this position is from QMI LOC API, then send report to engine hub - // if sending is successful, we return as we will wait for final report from engine hub - // if the position is called from engine hub, then send it out directly + // also, send out SPE fix promptly to the clients that have registered + // with SPE report + LOC_LOGd("reportPositionEvent, eng type: %d, unpro %d, sess status %d", + locationExtended.locOutputEngType, ulpLocation.unpropagatedPosition, + status); if (true == initEngHubProxy()){ + // send the SPE fix to engine hub mEngHubProxy->gnssReportPosition(ulpLocation, locationExtended, status); + // report out all SPE fix if it is not propagated, even for failed fix + if (false == ulpLocation.unpropagatedPosition) { + EngineLocationInfo engLocationInfo = {}; + engLocationInfo.location = ulpLocation; + engLocationInfo.locationExtended = locationExtended; + engLocationInfo.sessionStatus = status; + reportEnginePositionsEvent(1, &engLocationInfo); + } return; } + // unpropagated report: is only for engine hub to consume and no need + // to send out to the clients if (true == ulpLocation.unpropagatedPosition) { return; } - // Fix is from QMI, and it is not an - // unpropagated position and engine hub is not loaded, queue the msg - // when message is queued, the position can be dispatched to requesting client + // Fix is from QMI, and it is not an unpropagated position and engine hub + // is not loaded, queue the message when message is processed, the position + // can be dispatched to requesting client that registers for SPE report struct MsgReportPosition : public LocMsg { GnssAdapter& mAdapter; const UlpLocation mUlpLocation; @@ -3684,6 +3795,15 @@ GnssAdapter::requestNiNotifyEvent(const GnssNiNotification ¬ify, const void* else { mAdapter.requestNiNotify(mNotify, mData, false); } + } else if ((mAdapter.mSupportNfwControl || 0 == mAdapter.getAfwControlId()) && + GNSS_NI_TYPE_SUPL == mNotify.type && !bIsInEmergency && + !(GNSS_NI_OPTIONS_PRIVACY_OVERRIDE_BIT & mNotify.options) && + (GNSS_CONFIG_GPS_LOCK_NI & ContextBase::mGps_conf.GPS_LOCK) && + 1 == ContextBase::mGps_conf.NI_SUPL_DENY_ON_NFW_LOCKED) { + // If 'Q' Lock behavior OR 'P' Lock behavior and GNSS is Locked + // If an NI SUPL Request that does not have Privacy Override option comes when + // NFW is locked and config item NI_SUPL_DENY_ON_NFW_LOCKED = 1, then deny it + mApi.informNiResponse(GNSS_NI_RESPONSE_DENY, mData); } else { mAdapter.requestNiNotify(mNotify, mData, false); } @@ -5026,11 +5146,30 @@ GnssAdapter::initEngHubProxy() { 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"); if(getter != nullptr) { EngineHubProxyBase* hubProxy = (*getter) (mMsgTask, mSystemStatus->getOsObserver(), reportPositionEventCb, - reportSvEventCb, reqAidingDataCb); + reportSvEventCb, reqAidingDataCb, + updateNHzRequirementCb); if (hubProxy != nullptr) { mEngHubProxy = hubProxy; engHubLoadSuccessful = true; diff --git a/gnss/GnssAdapter.h b/gnss/GnssAdapter.h index 3ccdd96..37a4892 100644 --- a/gnss/GnssAdapter.h +++ b/gnss/GnssAdapter.h @@ -138,6 +138,8 @@ class GnssAdapter : public LocAdapterBase { /* ==== Engine Hub ===================================================================== */ EngineHubProxyBase* mEngHubProxy; + bool mNHzNeeded; + bool mSPEAlreadyRunningAtHighestInterval; /* ==== TRACKING ======================================================================= */ TrackingOptionsMap mTimeBasedTrackingSessions; @@ -187,6 +189,7 @@ class GnssAdapter : public LocAdapterBase { XtraSystemStatusObserver mXtraObserver; LocationSystemInfo mLocSystemInfo; std::vector<GnssSvIdSource> mBlacklistedSvIds; + PowerStateType mSystemPowerState; /* === Misc ===================================================================== */ BlockCPIInfo mBlockCPIInfo; @@ -228,6 +231,7 @@ public: virtual void handleEngineUpEvent(); /* ======== UTILITIES ================================================================== */ void restartSessions(); + void checkAndRestartTimeBasedSession(); /* ==== CLIENT ========================================================================= */ /* ======== COMMANDS ====(Called from Client Thread)==================================== */ @@ -243,10 +247,9 @@ public: /* ======== 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 hasCallbacksToStartTracking(LocationAPI* client); bool isTrackingSession(LocationAPI* client, uint32_t sessionId); void saveTrackingSession(LocationAPI* client, uint32_t sessionId, const TrackingOptions& trackingOptions); @@ -265,6 +268,7 @@ public: const TrackingOptions& trackingOptions); void updateTracking(LocationAPI* client, uint32_t sessionId, const TrackingOptions& updatedOptions, const TrackingOptions& oldOptions); + bool checkAndSetSPEToRunforNHz(TrackingOptions & out); /* ==== NI ============================================================================= */ /* ======== COMMANDS ====(Called from Client Thread)==================================== */ @@ -413,6 +417,8 @@ public: return false; } + void updateSystemPowerState(PowerStateType systemPowerState); + /*======== GNSSDEBUG ================================================================*/ bool getDebugReport(GnssDebugReport& report); /* get AGC information from system status and fill it */ @@ -459,11 +465,14 @@ public: void reportPowerStateIfChanged(); void savePowerStateCallback(powerStateCallback powerStateCb){ mPowerStateCb = powerStateCb; } bool getPowerState() { return mPowerOn; } + inline PowerStateType getSystemPowerState() { return mSystemPowerState; } + 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); + void updateSystemPowerStateCommand(PowerStateType systemPowerState); }; #endif //GNSS_ADAPTER_H diff --git a/gnss/location_gnss.cpp b/gnss/location_gnss.cpp index 76839b6..5380f05 100644 --- a/gnss/location_gnss.cpp +++ b/gnss/location_gnss.cpp @@ -79,6 +79,7 @@ static void odcpiInject(const Location& location); static void blockCPI(double latitude, double longitude, float accuracy, int blockDurationMsec, double latLonDiffThreshold); static void updateBatteryStatus(bool charging); +static void updateSystemPowerState(PowerStateType systemPowerState); static const GnssInterface gGnssInterface = { sizeof(GnssInterface), @@ -117,7 +118,8 @@ static const GnssInterface gGnssInterface = { nfwInit, getPowerStateChanges, injectLocationExt, - updateBatteryStatus + updateBatteryStatus, + updateSystemPowerState }; #ifndef DEBUG_X86 @@ -390,3 +392,9 @@ static void updateBatteryStatus(bool charging) { gGnssAdapter->getSystemStatus()->updatePowerConnectState(charging); } } + +static void updateSystemPowerState(PowerStateType systemPowerState) { + if (NULL != gGnssAdapter) { + gGnssAdapter->updateSystemPowerStateCommand(systemPowerState); + } +} diff --git a/location/location_interface.h b/location/location_interface.h index fb15bea..d08dfb3 100644 --- a/location/location_interface.h +++ b/location/location_interface.h @@ -88,6 +88,7 @@ struct GnssInterface { void (*getPowerStateChanges)(void* powerStateCb); void (*injectLocationExt)(const GnssLocationInfoNotification &locationInfo); void (*updateBatteryStatus)(bool charging); + void (*updateSystemPowerState)(PowerStateType systemPowerState); }; struct BatchingInterface { diff --git a/utils/gps_extended_c.h b/utils/gps_extended_c.h index 3ef49e3..62985d2 100644 --- a/utils/gps_extended_c.h +++ b/utils/gps_extended_c.h @@ -449,7 +449,7 @@ typedef uint32_t GnssAdditionalSystemInfoMask; #define QZSS_SV_PRN_MIN 193 #define QZSS_SV_PRN_MAX 197 #define BDS_SV_PRN_MIN 201 -#define BDS_SV_PRN_MAX 235 +#define BDS_SV_PRN_MAX 237 #define GAL_SV_PRN_MIN 301 #define GAL_SV_PRN_MAX 336 #define NAVIC_SV_PRN_MIN 401 @@ -2223,6 +2223,13 @@ typedef void (*LocAgpsOpenResultCb)(bool isSuccess, AGpsExtType agpsType, const typedef void (*LocAgpsCloseResultCb)(bool isSuccess, AGpsExtType agpsType, void* userDataPtr); +enum PowerStateType { + POWER_STATE_UNKNOWN = 0, + POWER_STATE_SUSPEND = 1, + POWER_STATE_RESUME = 2, + POWER_STATE_SHUTDOWN = 3 +}; + /* Shared resources of LocIpc */ #define LOC_IPC_HAL "/dev/socket/location/socket_hal" #define LOC_IPC_XTRA "/dev/socket/location/xtra/socket_xtra" diff --git a/utils/loc_nmea.cpp b/utils/loc_nmea.cpp index cf738ba..876620f 100644 --- a/utils/loc_nmea.cpp +++ b/utils/loc_nmea.cpp @@ -2056,7 +2056,8 @@ void loc_nmea_generate_sv(const GnssSvNotification &svNotify, { sv_cache_info.bds_used_mask |= (1ULL << (svNotify.gnssSvs[svNumber - 1].svId - 1)); } - if(GNSS_SIGNAL_BEIDOU_B2AI == svNotify.gnssSvs[svNumber - 1].gnssSignalTypeMask){ + if ((GNSS_SIGNAL_BEIDOU_B2AI == svNotify.gnssSvs[svNumber - 1].gnssSignalTypeMask) || + (GNSS_SIGNAL_BEIDOU_B2AQ == svNotify.gnssSvs[svNumber - 1].gnssSignalTypeMask)) { sv_cache_info.bds_b2_count++; } else { // GNSS_SIGNAL_BEIDOU_B1I or default |