diff --git a/android/2.0/Gnss.cpp b/android/2.0/Gnss.cpp index 0c9519fa..40331477 100644 --- a/android/2.0/Gnss.cpp +++ b/android/2.0/Gnss.cpp @@ -38,6 +38,8 @@ namespace gnss { namespace V2_0 { namespace implementation { +using ::android::hardware::gnss::visibility_control::V1_0::implementation::GnssVisibilityControl; + static std::string getVersionString() { static std::string version; if (!version.empty()) @@ -239,6 +241,10 @@ Return Gnss::updateConfiguration(GnssConfig& gnssConfig) { mPendingConfig.flags |= GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT; mPendingConfig.blacklistedSvIds = gnssConfig.blacklistedSvIds; } + if (gnssConfig.flags & GNSS_CONFIG_FLAGS_EMERGENCY_EXTENSION_SECONDS_BIT) { + mPendingConfig.flags |= GNSS_CONFIG_FLAGS_EMERGENCY_EXTENSION_SECONDS_BIT; + mPendingConfig.emergencyExtensionSeconds = gnssConfig.emergencyExtensionSeconds; + } } return true; } @@ -483,8 +489,9 @@ Return> Gnss::getExtensionVisibilityControl() { + ENTRY_LOG_CALLFLOW(); if (mVisibCtrl == nullptr) { - mVisibCtrl = new GnssVisibilityControl(); + mVisibCtrl = new GnssVisibilityControl(this); } return mVisibCtrl; } diff --git a/android/2.0/Gnss.h b/android/2.0/Gnss.h index b0a4f91f..dfae2a3e 100644 --- a/android/2.0/Gnss.h +++ b/android/2.0/Gnss.h @@ -55,7 +55,6 @@ using ::android::hardware::gnss::V1_0::GnssLocation; using ::android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrections; using ::android::hardware::gnss::measurement_corrections::V1_0::implementation::MeasurementCorrections; using ::android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControl; -using ::android::hardware::gnss::visibility_control::V1_0::implementation::GnssVisibilityControl; struct Gnss : public IGnss { Gnss(); @@ -131,7 +130,6 @@ struct Gnss : public IGnss { getExtensionVisibilityControl() override; - // These methods are not part of the IGnss base class. GnssAPIClient* getApi(); Return setGnssNiCb(const sp& niCb); diff --git a/android/2.0/GnssConfiguration.cpp b/android/2.0/GnssConfiguration.cpp index 93a843a6..eb98be1a 100644 --- a/android/2.0/GnssConfiguration.cpp +++ b/android/2.0/GnssConfiguration.cpp @@ -175,35 +175,9 @@ Return GnssConfiguration::setGlonassPositioningProtocol(uint8_t protocol) } Return GnssConfiguration::setGpsLock(uint8_t lock) { - if (mGnss == nullptr) { - LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__); - return false; - } - - GnssConfig config; - memset(&config, 0, sizeof(GnssConfig)); - config.size = sizeof(GnssConfig); - config.flags = GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT; - switch (lock) { - case 0: - config.gpsLock = GNSS_CONFIG_GPS_LOCK_NONE; - break; - case 1: - config.gpsLock = GNSS_CONFIG_GPS_LOCK_MO; - break; - case 2: - config.gpsLock = GNSS_CONFIG_GPS_LOCK_NI; - break; - case 3: - config.gpsLock = GNSS_CONFIG_GPS_LOCK_MO_AND_NI; - break; - default: - LOC_LOGE("%s]: invalid lock: %d.", __FUNCTION__, lock); - return false; - break; - } - - return mGnss->updateConfiguration(config); + /* we no longer set GPS lock here, there is + visibility control for this */ + return true; } Return GnssConfiguration::setEmergencySuplPdn(bool enabled) { @@ -308,8 +282,19 @@ bool GnssConfiguration::setBlacklistedSource( // Methods from ::android::hardware::gnss::V2_0::IGnssConfiguration follow. Return GnssConfiguration::setEsExtensionSec(uint32_t emergencyExtensionSeconds) { - //TODO emergencyExtensionSeconds is not supporded in GnssConfig yet - return false; + ENTRY_LOG_CALLFLOW(); + if (mGnss == nullptr) { + LOC_LOGe("mGnss is nullptr"); + return false; + } + + GnssConfig config; + memset(&config, 0, sizeof(GnssConfig)); + config.size = sizeof(GnssConfig); + config.flags = GNSS_CONFIG_FLAGS_EMERGENCY_EXTENSION_SECONDS_BIT; + config.emergencyExtensionSeconds = emergencyExtensionSeconds; + + return mGnss->updateConfiguration(config); } } // namespace implementation diff --git a/android/visibility_control/1.0/GnssVisibilityControl.cpp b/android/visibility_control/1.0/GnssVisibilityControl.cpp index 5608050e..82e465cc 100644 --- a/android/visibility_control/1.0/GnssVisibilityControl.cpp +++ b/android/visibility_control/1.0/GnssVisibilityControl.cpp @@ -48,11 +48,72 @@ using ::android::hardware::Return; using ::android::hardware::Void; using ::android::sp; -GnssVisibilityControl::GnssVisibilityControl() {} -GnssVisibilityControl::~GnssVisibilityControl() {} +static GnssVisibilityControl* spGnssVisibilityControl = nullptr; + +static void convertGnssNfwNotification(GnssNfwNotification& in, + IGnssVisibilityControlCallback::NfwNotification& out); + +GnssVisibilityControl::GnssVisibilityControl(Gnss* gnss) : mGnss(gnss) { + spGnssVisibilityControl = this; +} +GnssVisibilityControl::~GnssVisibilityControl() { + spGnssVisibilityControl = nullptr; +} + +void GnssVisibilityControl::nfwStatusCb(GnssNfwNotification notification) { + if (nullptr != spGnssVisibilityControl) { + spGnssVisibilityControl->statusCb(notification); + } +} + +static void convertGnssNfwNotification(GnssNfwNotification& in, + IGnssVisibilityControlCallback::NfwNotification& out) +{ + memset(&out, 0, sizeof(IGnssVisibilityControlCallback::NfwNotification)); + out.proxyAppPackageName = in.proxyAppPackageName; + out.protocolStack = (IGnssVisibilityControlCallback::NfwProtocolStack)in.protocolStack; + out.otherProtocolStackName = in.otherProtocolStackName; + out.requestor = (IGnssVisibilityControlCallback::NfwRequestor)in.requestor; + out.requestorId = in.requestorId; + out.responseType = (IGnssVisibilityControlCallback::NfwResponseType)in.responseType; + out.inEmergencyMode = in.inEmergencyMode; + out.isCachedLocation = in.isCachedLocation; +} + +void GnssVisibilityControl::statusCb(GnssNfwNotification notification) { + + if (mGnssVisibilityControlCbIface != nullptr) { + IGnssVisibilityControlCallback::NfwNotification nfwNotification; + + // Convert from one structure to another + convertGnssNfwNotification(notification, nfwNotification); + + auto r = mGnssVisibilityControlCbIface->nfwNotifyCb(nfwNotification); + if (!r.isOk()) { + LOC_LOGw("Error invoking NFW status cb %s", r.description().c_str()); + } + } else { + LOC_LOGw("setCallback has not been called yet"); + } +} // Methods from ::android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControl follow. Return GnssVisibilityControl::enableNfwLocationAccess(const hidl_vec<::android::hardware::hidl_string>& proxyApps) { + + if (nullptr == mGnss || nullptr == mGnss->getGnssInterface()) { + LOC_LOGe("Null GNSS interface"); + return false; + } + + /* If the vector is empty we need to disable all NFW clients + If there is at least one app in the vector we need to enable + all NFW clients */ + if (0 == proxyApps.size()) { + mGnss->getGnssInterface()->enableNfwLocationAccess(false); + } else { + mGnss->getGnssInterface()->enableNfwLocationAccess(true); + } + return true; } /** @@ -61,6 +122,18 @@ Return GnssVisibilityControl::enableNfwLocationAccess(const hidl_vec<::and * @param callback Handle to IGnssVisibilityControlCallback interface. */ Return GnssVisibilityControl::setCallback(const ::android::sp<::android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControlCallback>& callback) { + + if (nullptr == mGnss || nullptr == mGnss->getGnssInterface()) { + LOC_LOGe("Null GNSS interface"); + return false; + } + mGnssVisibilityControlCbIface = callback; + + NfwCbInfo cbInfo = {}; + cbInfo.visibilityControlCb = (void*)nfwStatusCb; + + mGnss->getGnssInterface()->nfwInit(cbInfo); + return true; } diff --git a/android/visibility_control/1.0/GnssVisibilityControl.h b/android/visibility_control/1.0/GnssVisibilityControl.h index 30233476..4eaea51e 100644 --- a/android/visibility_control/1.0/GnssVisibilityControl.h +++ b/android/visibility_control/1.0/GnssVisibilityControl.h @@ -34,7 +34,9 @@ #include #include +#include #include +#include "Gnss.h" namespace android { namespace hardware { @@ -50,9 +52,10 @@ using ::android::hardware::hidl_vec; using ::android::hardware::Return; using ::android::hardware::Void; using ::android::sp; +using ::android::hardware::gnss::V2_0::implementation::Gnss; struct GnssVisibilityControl : public IGnssVisibilityControl { - GnssVisibilityControl(); + GnssVisibilityControl(Gnss* gnss); ~GnssVisibilityControl(); // Methods from ::android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControl follow. @@ -64,6 +67,14 @@ struct GnssVisibilityControl : public IGnssVisibilityControl { */ Return setCallback(const ::android::sp<::android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControlCallback>& callback) override; + void statusCb(GnssNfwNotification notification); + + /* Data call setup callback passed down to GNSS HAL implementation */ + static void nfwStatusCb(GnssNfwNotification notification); + +private: + Gnss* mGnss = nullptr; + sp mGnssVisibilityControlCbIface = nullptr; }; diff --git a/core/LocAdapterBase.cpp b/core/LocAdapterBase.cpp index 22116e67..cea72fa9 100644 --- a/core/LocAdapterBase.cpp +++ b/core/LocAdapterBase.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2014, 2016-2018 The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2014, 2016-2019 The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -199,4 +199,8 @@ DEFAULT_IMPL(false) bool LocAdapterBase:: reportGnssAdditionalSystemInfoEvent(GnssAdditionalSystemInfo& /*additionalSystemInfo*/) DEFAULT_IMPL(false) + +void LocAdapterBase:: + reportNfwNotificationEvent(GnssNfwNotification& /*notification*/) +DEFAULT_IMPL() } // namespace loc_core diff --git a/core/LocAdapterBase.h b/core/LocAdapterBase.h index 722947af..af56cc9f 100644 --- a/core/LocAdapterBase.h +++ b/core/LocAdapterBase.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2014, 2016-2018 The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2014, 2016-2019 The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -171,6 +171,7 @@ public: virtual bool reportKlobucharIonoModelEvent(GnssKlobucharIonoModel& ionoModel); virtual bool reportGnssAdditionalSystemInfoEvent( GnssAdditionalSystemInfo& additionalSystemInfo); + virtual void reportNfwNotificationEvent(GnssNfwNotification& notification); }; } // namespace loc_core diff --git a/core/LocApiBase.cpp b/core/LocApiBase.cpp index 8fe84c21..fac81e77 100644 --- a/core/LocApiBase.cpp +++ b/core/LocApiBase.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2014, 2016-2018 The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2014, 2016-2019 The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -391,6 +391,13 @@ void LocApiBase::reportGnssAdditionalSystemInfo(GnssAdditionalSystemInfo& additi additionalSystemInfo)); } +void LocApiBase::sendNfwNotification(GnssNfwNotification& notification) +{ + // loop through adapters, and deliver to the first handling adapter. + TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportNfwNotificationEvent(notification)); + +} + void LocApiBase::reportSv(GnssSvNotification& svNotify) { const char* constellationString[] = { "Unknown", "GPS", "SBAS", "GLONASS", @@ -683,6 +690,10 @@ DEFAULT_IMPL(0) GnssConfigLppeUserPlaneMask LocApiBase::convertLppeUp(const uint32_t /*lppeUserPlaneMask*/) DEFAULT_IMPL(0) +LocationError LocApiBase::setEmergencyExtensionWindowSync( + const uint32_t /*emergencyExtensionSeconds*/) +DEFAULT_IMPL(LOCATION_ERROR_SUCCESS) + void LocApiBase:: getWwanZppFix() DEFAULT_IMPL() @@ -737,7 +748,6 @@ LocationError LocApiBase:: setPositionAssistedClockEstimatorMode(bool /*enabled*/) DEFAULT_IMPL(LOCATION_ERROR_SUCCESS) -LocationError LocApiBase:: - getGnssEnergyConsumed() +LocationError LocApiBase::getGnssEnergyConsumed() DEFAULT_IMPL(LOCATION_ERROR_SUCCESS) } // namespace loc_core diff --git a/core/LocApiBase.h b/core/LocApiBase.h index 70bebc31..f0bd5392 100644 --- a/core/LocApiBase.h +++ b/core/LocApiBase.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2014, 2016-2018 The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2014, 2016-2019 The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -189,6 +189,7 @@ public: void reportDeleteAidingDataEvent(GnssAidingData& aidingData); void reportKlobucharIonoModel(GnssKlobucharIonoModel& ionoModel); void reportGnssAdditionalSystemInfo(GnssAdditionalSystemInfo& additionalSystemInfo); + void sendNfwNotification(GnssNfwNotification& notification); // downward calls // All below functions are to be defined by adapter specific modules: @@ -265,6 +266,7 @@ public: virtual GnssConfigLppProfile convertLppProfile(const uint32_t lppProfile); virtual GnssConfigLppeControlPlaneMask convertLppeCp(const uint32_t lppeControlPlaneMask); virtual GnssConfigLppeUserPlaneMask convertLppeUp(const uint32_t lppeUserPlaneMask); + virtual LocationError setEmergencyExtensionWindowSync(const uint32_t emergencyExtensionSeconds); virtual void getWwanZppFix(); virtual void getBestAvailableZppFix(); diff --git a/gnss/GnssAdapter.cpp b/gnss/GnssAdapter.cpp index eee55e37..3f640ad6 100644 --- a/gnss/GnssAdapter.cpp +++ b/gnss/GnssAdapter.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -88,7 +88,8 @@ GnssAdapter::GnssAdapter() : mServerUrl(":"), mXtraObserver(mSystemStatus->getOsObserver(), mMsgTask), mBlockCPIInfo{}, - mLocSystemInfo{} + mLocSystemInfo{}, + mNfwCb(NULL) { LOC_LOGD("%s]: Constructor %p", __func__, this); mLocPositionMode.mode = LOC_POSITION_MODE_INVALID; @@ -658,7 +659,7 @@ GnssAdapter::setConfigCommand() GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT | GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT; gnssConfigRequested.gpsLock = GNSS_CONFIG_GPS_LOCK_NONE; - if (0 == adapter.getPowerVoteId()) { + if (0 == adapter.getAfwControlId() || NULL != adapter.mNfwCb) { gnssConfigRequested.gpsLock = gpsConf.GPS_LOCK; } @@ -910,6 +911,18 @@ std::vector GnssAdapter::gnssUpdateConfig(const std::string& oldS } index++; } + if (gnssConfigRequested.flags & + GNSS_CONFIG_FLAGS_EMERGENCY_EXTENSION_SECONDS_BIT) { + if (gnssConfigNeedEngineUpdate.flags & + GNSS_CONFIG_FLAGS_EMERGENCY_EXTENSION_SECONDS_BIT) { + err = mLocApi->setEmergencyExtensionWindowSync( + gnssConfigRequested.emergencyExtensionSeconds); + if (index < count) { + errsList[index] = err; + } + } + index++; + } return errsList; } @@ -982,10 +995,10 @@ GnssAdapter::gnssUpdateConfigCommand(GnssConfig config) if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT) { GnssConfigGpsLock newGpsLock = gnssConfigRequested.gpsLock; if (GNSS_CONFIG_GPS_LOCK_NONE == newGpsLock) { - newGpsLock = GNSS_CONFIG_GPS_LOCK_MO_AND_NI; + newGpsLock = GNSS_CONFIG_GPS_LOCK_MO; } if (newGpsLock == ContextBase::mGps_conf.GPS_LOCK || - 0 != mAdapter.getPowerVoteId()) { + 0 != mAdapter.getAfwControlId()) { gnssConfigNeedEngineUpdate.flags &= ~(GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT); } ContextBase::mGps_conf.GPS_LOCK = newGpsLock; @@ -1060,24 +1073,24 @@ GnssAdapter::gnssUpdateConfigCommand(GnssConfig config) ~(GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT); } index++; - } - if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT) { + } + if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT) { uint32_t newEP4ES = mAdapter.convertEP4ES( gnssConfigRequested.emergencyPdnForEmergencySupl); if (newEP4ES != ContextBase::mGps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL) { ContextBase::mGps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL = newEP4ES; } index++; - } - if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT) { + } + if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT) { uint32_t newSuplEs = mAdapter.convertSuplEs( gnssConfigRequested.suplEmergencyServices); if (newSuplEs != ContextBase::mGps_conf.SUPL_ES) { ContextBase::mGps_conf.SUPL_ES = newSuplEs; } index++; - } - if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_SUPL_MODE_BIT) { + } + if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_SUPL_MODE_BIT) { uint32_t newSuplMode = mAdapter.convertSuplMode(gnssConfigRequested.suplModeMask); if (newSuplMode != ContextBase::mGps_conf.SUPL_MODE) { ContextBase::mGps_conf.SUPL_MODE = newSuplMode; @@ -1299,6 +1312,12 @@ GnssAdapter::gnssGetConfigCommand(GnssConfigFlagsMask configMask) { errs[index++] = err; } } + if (mConfigMask & GNSS_CONFIG_FLAGS_EMERGENCY_EXTENSION_SECONDS_BIT) { + err = LOCATION_ERROR_NOT_SUPPORTED; + if (index < mCount) { + errs[index++] = LOCATION_ERROR_NOT_SUPPORTED; + } + } mAdapter.reportResponse(index, errs, mIds); delete[] errs; @@ -2802,21 +2821,24 @@ GnssAdapter::enableCommand(LocationTechnologyType techType) mTechType(techType) {} inline virtual void proc() const { LocationError err = LOCATION_ERROR_SUCCESS; - uint32_t powerVoteId = mAdapter.getPowerVoteId(); + uint32_t powerVoteId = mAdapter.getAfwControlId(); if (mTechType != LOCATION_TECHNOLOGY_TYPE_GNSS) { err = LOCATION_ERROR_INVALID_PARAMETER; } else if (powerVoteId > 0) { err = LOCATION_ERROR_ALREADY_STARTED; } else { mContext.modemPowerVote(true); - mAdapter.setPowerVoteId(mSessionId); + mAdapter.setAfwControlId(mSessionId); - mApi.sendMsg(new LocApiMsg([&mApi = mApi] () { - mApi.setGpsLockSync(GNSS_CONFIG_GPS_LOCK_NONE); - })); - - mAdapter.mXtraObserver.updateLockStatus( - GNSS_CONFIG_GPS_LOCK_NONE); + GnssConfigGpsLock gpsLock = GNSS_CONFIG_GPS_LOCK_NONE; + if (NULL != mAdapter.mNfwCb) { + ContextBase::mGps_conf.GPS_LOCK &= GNSS_CONFIG_GPS_LOCK_NI; + gpsLock = ContextBase::mGps_conf.GPS_LOCK; + } + mApi.sendMsg(new LocApiMsg([&mApi = mApi, gpsLock]() { + mApi.setGpsLockSync(gpsLock); + })); + mAdapter.mXtraObserver.updateLockStatus(gpsLock); } mAdapter.reportResponse(err, mSessionId); } @@ -2852,15 +2874,18 @@ GnssAdapter::disableCommand(uint32_t id) mSessionId(sessionId) {} inline virtual void proc() const { LocationError err = LOCATION_ERROR_SUCCESS; - uint32_t powerVoteId = mAdapter.getPowerVoteId(); + uint32_t powerVoteId = mAdapter.getAfwControlId(); if (powerVoteId != mSessionId) { err = LOCATION_ERROR_ID_UNKNOWN; } else { mContext.modemPowerVote(false); - mAdapter.setPowerVoteId(0); + mAdapter.setAfwControlId(0); - GnssConfigGpsLock gpsLock = - ContextBase::mGps_conf.GPS_LOCK; + if (NULL != mAdapter.mNfwCb) { + /* We need to disable MO (AFW) */ + ContextBase::mGps_conf.GPS_LOCK |= GNSS_CONFIG_GPS_LOCK_MO; + } + GnssConfigGpsLock gpsLock = ContextBase::mGps_conf.GPS_LOCK; mApi.sendMsg(new LocApiMsg([&mApi = mApi,gpsLock] () { mApi.setGpsLockSync(gpsLock); })); @@ -3824,6 +3849,52 @@ void GnssAdapter::initAgpsCommand(const AgpsCbInfo& cbInfo){ sendMsg(new AgpsMsgInit(cbInfo, *this)); } +void GnssAdapter::initNfwCommand(const NfwCbInfo& cbInfo) { + LOC_LOGi("GnssAdapter::initNfwCommand"); + + /* Message to initialize NFW */ + struct MsgInitNfw : public LocMsg { + const NfwCbInfo mCbInfo; + GnssAdapter& mAdapter; + + inline MsgInitNfw(const NfwCbInfo& cbInfo, + GnssAdapter& adapter) : + LocMsg(), mCbInfo(cbInfo), mAdapter(adapter) { + LOC_LOGv("MsgInitNfw"); + } + + inline virtual void proc() const { + LOC_LOGv("MsgInitNfw::proc()"); + mAdapter.initNfw(mCbInfo); + } + }; + + /* Send message to initialize NFW */ + sendMsg(new MsgInitNfw(cbInfo, *this)); +} + +void GnssAdapter::reportNfwNotificationEvent(GnssNfwNotification& notification) { + LOC_LOGi("GnssAdapter::reportNfwNotificationEvent"); + + struct MsgReportNfwNotification : public LocMsg { + const GnssNfwNotification mNotification; + GnssAdapter& mAdapter; + + inline MsgReportNfwNotification(const GnssNfwNotification& notification, + GnssAdapter& adapter) : + LocMsg(), mNotification(notification), mAdapter(adapter) { + LOC_LOGv("MsgReportNfwNotification"); + } + + inline virtual void proc() const { + LOC_LOGv("MsgReportNfwNotification::proc()"); + mAdapter.reportNfwNotification(mNotification); + } + }; + + sendMsg(new MsgReportNfwNotification(notification, *this)); +} + /* GnssAdapter::requestATL * Method triggered in QMI thread as part of handling below message: * eQMI_LOC_SERVER_REQUEST_OPEN_V02 @@ -4405,6 +4476,37 @@ GnssAdapter::getGnssEnergyConsumedCommand(GnssEnergyConsumedCallback energyConsu sendMsg(new MsgGetGnssEnergyConsumed(*this, *mLocApi, energyConsumedCb)); } +void +GnssAdapter::nfwControlCommand(bool enable) { + struct MsgenableNfwLocationAccess : public LocMsg { + GnssAdapter& mAdapter; + LocApiBase& mApi; + bool mEnable; + inline MsgenableNfwLocationAccess(GnssAdapter& adapter, LocApiBase& api, + bool enable) : + LocMsg(), + mAdapter(adapter), + mApi(api), + mEnable(enable) {} + inline virtual void proc() const { + GnssConfigGpsLock gpsLock; + + gpsLock = ContextBase::mGps_conf.GPS_LOCK; + if (mEnable) { + gpsLock &= ~GNSS_CONFIG_GPS_LOCK_NI; + } else { + gpsLock |= GNSS_CONFIG_GPS_LOCK_NI; + } + ContextBase::mGps_conf.GPS_LOCK = gpsLock; + mApi.sendMsg(new LocApiMsg([&mApi = mApi, gpsLock]() { + mApi.setGpsLockSync((GnssConfigGpsLock)gpsLock); + })); + } + }; + + sendMsg(new MsgenableNfwLocationAccess(*this, *mLocApi, enable)); +} + /* ==== Eng Hub Proxy ================================================================= */ /* ======== UTILITIES ================================================================= */ void diff --git a/gnss/GnssAdapter.h b/gnss/GnssAdapter.h index 1f72c43c..e304fe6e 100644 --- a/gnss/GnssAdapter.h +++ b/gnss/GnssAdapter.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -162,6 +162,12 @@ class GnssAdapter : public LocAdapterBase { AgpsCbInfo mAgpsCbInfo; void initAgps(const AgpsCbInfo& cbInfo); + /* ==== NFW =========================================================================== */ + NfwStatusCb mNfwCb; + inline void initNfw(const NfwCbInfo& cbInfo) { + mNfwCb = (NfwStatusCb)cbInfo.visibilityControlCb; + } + /* ==== ODCPI ========================================================================== */ OdcpiRequestCallback mOdcpiRequestCb; bool mOdcpiRequestActive; @@ -308,11 +314,13 @@ public: /* ======== COMMANDS ====(Called from Client Thread)==================================== */ void initDefaultAgpsCommand(); void initAgpsCommand(const AgpsCbInfo& cbInfo); + void initNfwCommand(const NfwCbInfo& cbInfo); void dataConnOpenCommand(AGpsExtType agpsType, const char* apnName, int apnLen, AGpsBearerType bearerType); void dataConnClosedCommand(AGpsExtType agpsType); void dataConnFailedCommand(AGpsExtType agpsType); void getGnssEnergyConsumedCommand(GnssEnergyConsumedCallback energyConsumedCb); + void nfwControlCommand(bool enable); /* ========= ODCPI ===================================================================== */ /* ======== COMMANDS ====(Called from Client Thread)==================================== */ @@ -325,8 +333,8 @@ public: LocationControlCallbacks& getControlCallbacks() { return mControlCallbacks; } void setControlCallbacks(const LocationControlCallbacks& controlCallbacks) { mControlCallbacks = controlCallbacks; } - void setPowerVoteId(uint32_t id) { mPowerVoteId = id; } - uint32_t getPowerVoteId() { return mPowerVoteId; } + void setAfwControlId(uint32_t id) { mPowerVoteId = id; } + uint32_t getAfwControlId() { return mPowerVoteId; } virtual bool isInSession() { return !mTrackingSessions.empty(); } void initDefaultAgps(); bool initEngHubProxy(); @@ -363,6 +371,7 @@ public: virtual bool reportKlobucharIonoModelEvent(GnssKlobucharIonoModel& ionoModel); virtual bool reportGnssAdditionalSystemInfoEvent( GnssAdditionalSystemInfo& additionalSystemInfo); + virtual void reportNfwNotificationEvent(GnssNfwNotification& notification); /* ======== UTILITIES ================================================================= */ bool needReport(const UlpLocation& ulpLocation, @@ -382,6 +391,11 @@ public: void invokeGnssEnergyConsumedCallback(uint64_t energyConsumedSinceFirstBoot); void saveGnssEnergyConsumedCallback(GnssEnergyConsumedCallback energyConsumedCb); void reportLocationSystemInfo(const LocationSystemInfo & locationSystemInfo); + inline void reportNfwNotification(const GnssNfwNotification& notification) { + if (NULL != mNfwCb) { + mNfwCb(notification); + } + } /*======== GNSSDEBUG ================================================================*/ bool getDebugReport(GnssDebugReport& report); diff --git a/gnss/location_gnss.cpp b/gnss/location_gnss.cpp index f9fbddc9..45ad292c 100644 --- a/gnss/location_gnss.cpp +++ b/gnss/location_gnss.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017, 2019 The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -67,6 +67,9 @@ static void agpsDataConnFailed(AGpsExtType agpsType); static void getDebugReport(GnssDebugReport& report); static void updateConnectionStatus(bool connected, int8_t type); static void getGnssEnergyConsumed(GnssEnergyConsumedCallback energyConsumedCb); +static void enableNfwLocationAccess(bool enable); +static void nfwInit(const NfwCbInfo& cbInfo); +static uint8_t getGpsLock(); static void odcpiInit(const OdcpiRequestCallback& callback); static void odcpiInject(const Location& location); @@ -106,7 +109,10 @@ static const GnssInterface gGnssInterface = { odcpiInit, odcpiInject, blockCPI, - getGnssEnergyConsumed + getGnssEnergyConsumed, + enableNfwLocationAccess, + nfwInit, + getGpsLock }; #ifndef DEBUG_X86 @@ -346,3 +352,29 @@ static void getGnssEnergyConsumed(GnssEnergyConsumedCallback energyConsumedCb) { gGnssAdapter->getGnssEnergyConsumedCommand(energyConsumedCb); } } + +static void enableNfwLocationAccess(bool enable) { + if (NULL != gGnssAdapter) { + gGnssAdapter->nfwControlCommand(enable); + } +} + +static void nfwInit(const NfwCbInfo& cbInfo) { + if (NULL != gGnssAdapter) { + gGnssAdapter->initNfwCommand(cbInfo); + } +} + +static uint8_t getGpsLock() { + if (NULL != gGnssAdapter) { + return ContextBase::mGps_conf.GPS_LOCK; + } else { + /* In case gGnssAdapter is NULL + just return 0x3 which means both + AFW and NFW are locked (the bits are NFW + for 2^1 and AFW for 2^0) */ + LOC_LOGe("gGnssAdapter is NULL"); + return 0x3; + } +} + diff --git a/location/LocationAPIClientBase.h b/location/LocationAPIClientBase.h index da87535a..fd22b040 100644 --- a/location/LocationAPIClientBase.h +++ b/location/LocationAPIClientBase.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017 The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -36,6 +36,7 @@ #include #include "LocationAPI.h" +#include #include #include @@ -252,6 +253,9 @@ public: inline virtual void onGnssLocationInfoCb( GnssLocationInfoNotification /*gnssLocationInfoNotification*/) {} + inline virtual void onGnssNfwStatusCb( + GnssNfwNotification /*notification*/) {} + inline virtual void onBatchingCb(size_t /*count*/, Location* /*location*/, BatchingOptions /*batchingOptions*/) {} inline virtual void onBatchingStatusCb(BatchingStatusInfo /*batchingStatus*/, diff --git a/location/LocationDataTypes.h b/location/LocationDataTypes.h index f60ba78b..0a2c0608 100644 --- a/location/LocationDataTypes.h +++ b/location/LocationDataTypes.h @@ -306,6 +306,7 @@ typedef enum { GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT = (1<<8), GNSS_CONFIG_FLAGS_SUPL_MODE_BIT = (1<<9), GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT = (1<<10), + GNSS_CONFIG_FLAGS_EMERGENCY_EXTENSION_SECONDS_BIT = (1<<11), } GnssConfigFlagsBits; typedef enum { @@ -1109,6 +1110,7 @@ struct GnssConfig{ GnssConfigSuplEmergencyServices suplEmergencyServices; GnssConfigSuplModeMask suplModeMask; //bitwise OR of GnssConfigSuplModeBits std::vector blacklistedSvIds; + uint32_t emergencyExtensionSeconds; inline bool equals(const GnssConfig& config) { if (flags == config.flags && @@ -1122,7 +1124,8 @@ struct GnssConfig{ emergencyPdnForEmergencySupl == config.emergencyPdnForEmergencySupl && suplEmergencyServices == config.suplEmergencyServices && suplModeMask == config.suplModeMask && - blacklistedSvIds == config.blacklistedSvIds) { + blacklistedSvIds == config.blacklistedSvIds && + emergencyExtensionSeconds == config.emergencyExtensionSeconds) { return true; } return false; diff --git a/location/location_interface.h b/location/location_interface.h index 480bbdb4..47dda870 100644 --- a/location/location_interface.h +++ b/location/location_interface.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017 The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -82,6 +82,9 @@ struct GnssInterface { void (*blockCPI)(double latitude, double longitude, float accuracy, int blockDurationMsec, double latLonDiffThreshold); void (*getGnssEnergyConsumed)(GnssEnergyConsumedCallback energyConsumedCb); + void (*enableNfwLocationAccess)(bool enable); + void (*nfwInit)(const NfwCbInfo& cbInfo); + uint8_t (*getGpsLock)(); }; struct FlpInterface { diff --git a/utils/gps_extended_c.h b/utils/gps_extended_c.h index abe4f680..64e2c39d 100644 --- a/utils/gps_extended_c.h +++ b/utils/gps_extended_c.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2018 The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -199,6 +199,11 @@ typedef struct { AgpsCbPriority cbPriority; } AgpsCbInfo; +typedef struct { + void* visibilityControlCb; + void* isInEmergencySession; +} NfwCbInfo; + /** GPS extended callback structure. */ typedef struct { /** set to sizeof(LocGpsCallbacks) */ @@ -2038,6 +2043,46 @@ struct AGnssExtStatusIpV6 { uint8_t ipV6Addr[16]; }; +/* +* Represents the the Nfw Notification structure +*/ +#define GNSS_MAX_NFW_STRING_LEN 20 + +typedef enum { + GNSS_NFW_CTRL_PLANE = 0, + GNSS_NFW_SUPL = 1, + GNSS_NFW_IMS = 10, + GNSS_NFW_SIM = 11, + GNSS_NFW_OTHER_PROTOCOL_STACK = 100 +} GnssNfwProtocolStack; + +typedef enum { + GNSS_NFW_CARRIER = 0, + GNSS_NFW_OEM = 10, + GNSS_NFW_MODEM_CHIPSET_VENDOR = 11, + GNSS_NFW_GNSS_CHIPSET_VENDOR = 12, + GNSS_NFW_OTHER_CHIPSET_VENDOR = 13, + GNSS_NFW_AUTOMOBILE_CLIENT = 20, + GNSS_NFW_OTHER_REQUESTOR = 100 +} GnssNfwRequestor; + +typedef enum { + GNSS_NFW_REJECTED = 0, + GNSS_NFW_ACCEPTED_NO_LOCATION_PROVIDED = 1, + GNSS_NFW_ACCEPTED_LOCATION_PROVIDED = 2, +} GnssNfwResponseType; + +typedef struct { + char proxyAppPackageName[GNSS_MAX_NFW_STRING_LEN]; + GnssNfwProtocolStack protocolStack; + char otherProtocolStackName[GNSS_MAX_NFW_STRING_LEN]; + GnssNfwRequestor requestor; + char requestorId[GNSS_MAX_NFW_STRING_LEN]; + GnssNfwResponseType responseType; + bool inEmergencyMode; + bool isCachedLocation; +} GnssNfwNotification; + /* ODCPI Request Info */ enum OdcpiRequestType { ODCPI_REQUEST_TYPE_START, @@ -2059,6 +2104,11 @@ typedef std::function OdcpiRequestCallbac */ typedef void (*AgnssStatusIpV4Cb)(AGnssExtStatusIpV4 status); +/* +* Callback with NFW information. +*/ +typedef void(*NfwStatusCb)(GnssNfwNotification notification); + /* * Callback with AGNSS(IpV6) status information. *