diff --git a/core/EngineHubProxyBase.h b/core/EngineHubProxyBase.h new file mode 100644 index 00000000..c17b2c29 --- /dev/null +++ b/core/EngineHubProxyBase.h @@ -0,0 +1,109 @@ +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation, nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +#ifndef ENGINE_HUB_PROXY_BASE_H +#define ENGINE_HUB_PROXY_BASE_H + +namespace loc_core { + +class EngineHubProxyBase { +public: + inline EngineHubProxyBase() { + } + inline virtual ~EngineHubProxyBase() {} + + // gnss session related functions + inline virtual bool gnssStartFix() { + LOC_LOGD("%s]: empty called ", __func__); + return false; + } + + inline virtual bool gnssStopFix() { + return false; + } + + inline virtual bool gnssSetFixMode(const LocPosMode ¶ms) { + (void) params; + return false; + } + + inline virtual bool gnssDeleteAidingData(const GnssAidingData &aidingData) { + (void) aidingData; + return false; + } + + // GNSS reports + inline virtual bool gnssReportPosition(const UlpLocation &location, + const GpsLocationExtended &locationExtended, + enum loc_sess_status status) { + (void) location; + (void) locationExtended; + (void) status; + return false; + } + + inline virtual bool gnssReportSv(const GnssSvNotification& svNotify) { + (void) svNotify; + return false; + } + + inline virtual bool gnssReportSvMeasurement(const GnssSvMeasurementSet& svMeasurementSet) { + (void) svMeasurementSet; + return false; + } + + inline virtual bool gnssReportSvPolynomial(const GnssSvPolynomial& svPolynomial) { + (void) svPolynomial; + return false; + } + + inline virtual bool gnssReportNmea(const char* nmea) { + (void) nmea; + return false; + } +}; + +typedef std::function + GnssAdapterReportPositionEventCb; + +typedef std::function + GnssAdapterReportSvEventCb; + +// potential parameters: message queue: MsgTask * msgTask; +// callback function to report back dr and ppe position and sv report +typedef EngineHubProxyBase* (getEngHubProxyFn)(const MsgTask * msgTask, + GnssAdapterReportPositionEventCb positionEventCb, + GnssAdapterReportSvEventCb svEventCb); + +} // namespace loc_core + +#endif // ENGINE_HUB_PROXY_BASE_H diff --git a/core/Makefile.am b/core/Makefile.am index dc540e9c..78ae76b0 100644 --- a/core/Makefile.am +++ b/core/Makefile.am @@ -20,6 +20,7 @@ libloc_core_la_h_sources = \ UlpProxyBase.h \ loc_core_log.h \ LocAdapterProxyBase.h \ + EngineHubProxyBase.h \ data-items/DataItemId.h \ data-items/IDataItemCore.h \ data-items/DataItemConcreteTypesBase.h \ diff --git a/gnss/GnssAdapter.cpp b/gnss/GnssAdapter.cpp index db4696f5..098c8aa0 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-2018, 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 @@ -47,6 +47,7 @@ #include #define RAD2DEG (180.0 / M_PI) +#define PROCESS_NAME_ENGINE_SERVICE "engine-service" using namespace loc_core; @@ -65,6 +66,7 @@ GnssAdapter::GnssAdapter() : LocDualContext::mLocationHalName, false)), mUlpProxy(new UlpProxyBase()), + mEngHubProxy(new EngineHubProxyBase()), mUlpPositionMode(), mGnssSvIdUsedInPosition(), mGnssSvIdUsedInPosAvail(false), @@ -146,6 +148,7 @@ GnssAdapter::GnssAdapter() : readConfigCommand(); setConfigCommand(); initDefaultAgpsCommand(); + initEngHubProxyCommand(); } void @@ -936,6 +939,7 @@ GnssAdapter::gnssDeleteAidingDataCommand(GnssAidingData& data) if ((nullptr != s) && (mData.deleteAll)) { s->setDefaultGnssEngineStates(); } + mAdapter.mEngHubProxy->gnssDeleteAidingData(mData); } }; @@ -1166,9 +1170,12 @@ GnssAdapter::updateClientsEventMask() /* ** For Automotive use cases we need to enable MEASUREMENT and POLY - ** when QDR is enabled + ** when QDR is enabled (e.g.: either enabled via conf file or + ** engine hub is loaded successfully). + ** Note: this need to be called from msg queue thread. */ - if(1 == ContextBase::mGps_conf.EXTERNAL_DR_ENABLED) { + if((1 == ContextBase::mGps_conf.EXTERNAL_DR_ENABLED) || + (true == initEngHubProxy())) { mask |= LOC_API_ADAPTER_BIT_GNSS_MEASUREMENT; mask |= LOC_API_ADAPTER_BIT_GNSS_SV_POLYNOMIAL_REPORT; @@ -1219,6 +1226,11 @@ GnssAdapter::restartSessions() LocPosMode locPosMode = {}; convertOptions(locPosMode, smallestIntervalOptions); + + // inform engine hub of the fix mode and start session + mEngHubProxy->gnssSetFixMode(locPosMode); + mEngHubProxy->gnssStartFix(); + mLocApi->startFix(locPosMode); } @@ -1508,6 +1520,10 @@ GnssAdapter::startTracking(const LocationOptions& options) // do nothing } if (!mUlpProxy->sendStartFix()) { + // inform engine hub that GNSS session is about to start + mEngHubProxy->gnssSetFixMode(locPosMode); + mEngHubProxy->gnssStartFix(); + loc_api_adapter_err apiErr = mLocApi->startFix(locPosMode); if (LOC_API_ADAPTER_ERR_SUCCESS == apiErr) { err = LOCATION_ERROR_SUCCESS; @@ -1539,6 +1555,7 @@ GnssAdapter::setPositionModeCommand(LocPosMode& locPosMode) inline virtual void proc() const { // saves the mode in adapter to be used when startTrackingCommand is called from ULP if (mAdapter.setUlpPositionMode(mLocPosMode)) { + mAdapter.mEngHubProxy->gnssSetFixMode(mLocPosMode); mApi.setPositionMode(mLocPosMode); } } @@ -1563,8 +1580,15 @@ GnssAdapter::startTrackingCommand() inline virtual void proc() const { // we get this call from ULP, so just call LocApi without multiplexing because // ulp would be doing the multiplexing for us if it is present - if (!mAdapter.isInSession()) { - LocPosMode& ulpPositionMode = mAdapter.getUlpPositionMode(); + LocPosMode& ulpPositionMode = mAdapter.getUlpPositionMode(); + + // TBD: once CR 2165853 is fixed, move below codes + // to inside condition of if (!mAdapter.isInSession()) + // + // inform engine hub of the fix mode and start session + mAdapter.mEngHubProxy->gnssSetFixMode(ulpPositionMode); + mAdapter.mEngHubProxy->gnssStartFix(); + if (!mAdapter.isInSession()) { mApi.startFix(ulpPositionMode); } } @@ -1737,6 +1761,9 @@ GnssAdapter::stopTracking() { LocationError err = LOCATION_ERROR_SUCCESS; if (!mUlpProxy->sendStopFix()) { + // inform engine hub that GNSS session has stopped + mEngHubProxy->gnssStopFix(); + loc_api_adapter_err apiErr = mLocApi->stopFix(); if (LOC_API_ADAPTER_ERR_SUCCESS == apiErr) { err = LOCATION_ERROR_SUCCESS; @@ -1762,6 +1789,9 @@ GnssAdapter::stopTrackingCommand() mAdapter(adapter), mApi(api) {} inline virtual void proc() const { + // inform engine hub that GNSS session has stopped + mAdapter.mEngHubProxy->gnssStopFix(); + // clear the position mode LocPosMode mLocPosMode = {}; mLocPosMode.mode = LOC_POSITION_MODE_INVALID; @@ -2014,8 +2044,12 @@ GnssAdapter::reportPositionEvent(const UlpLocation& ulpLocation, { LOC_LOGD("%s]: fromUlp %u status %u", __func__, fromUlp, status); - // if this event is not called from ULP, then try to call into ULP and return if successfull + // if this event is called from QMI LOC API, then try to call into ULP and return if successfull + // if the position is called from ULP or engine hub, then send it out directly if (!fromUlp) { + // report QMI position to engine hub, and engine hub will be + // distributing it to the registered plugins + mEngHubProxy->gnssReportPosition(ulpLocation, locationExtended, status); if (mUlpProxy->reportPosition(ulpLocation, locationExtended, status, techMask)) { return; @@ -2137,6 +2171,9 @@ GnssAdapter::reportSvEvent(const GnssSvNotification& svNotify, // if this event is not called from ULP, then try to call into ULP and return if successfull if (!fromUlp) { + // report QMI SV report to eng hub + mEngHubProxy->gnssReportSv(svNotify); + if (mUlpProxy->reportSv(svNotify)) { return; } @@ -2231,6 +2268,7 @@ GnssAdapter::reportNmeaEvent(const char* nmea, size_t length, bool fromUlp) { // if this event is not called from ULP, then try to call into ULP and return if successfull if (!fromUlp && !loc_nmea_is_debug(nmea, length)) { + mEngHubProxy->gnssReportNmea(nmea); if (mUlpProxy->reportNmea(nmea, length)) { return; } @@ -2501,6 +2539,7 @@ GnssAdapter::reportSvMeasurementEvent(GnssSvMeasurementSet &svMeasurementSet) // We send SvMeasurementSet to AmtProxy/ULPProxy to be forwarded as necessary. mUlpProxy->reportSvMeasurement(svMeasurementSet); + mEngHubProxy->gnssReportSvMeasurement(svMeasurementSet); } void @@ -2510,6 +2549,8 @@ GnssAdapter::reportSvPolynomialEvent(GnssSvPolynomial &svPolynomial) // We send SvMeasurementSet to AmtProxy/ULPProxy to be forwarded as necessary. mUlpProxy->reportSvPolynomial(svPolynomial); + + mEngHubProxy->gnssReportSvPolynomial(svPolynomial); } void GnssAdapter::initDefaultAgps() { @@ -3138,3 +3179,114 @@ static void agpsCloseResultCb (bool isSuccess, AGpsExtType agpsType, void* userD adapter->dataConnFailedCommand(agpsType); } } + +/* ==== Eng Hub Proxy ================================================================= */ +/* ======== UTILITIES ================================================================= */ +void +GnssAdapter::initEngHubProxyCommand() { + LOC_LOGD("%s]: ", __func__); + + struct MsgInitEngHubProxy : public LocMsg { + GnssAdapter* mAdapter; + inline MsgInitEngHubProxy(GnssAdapter* adapter) : + LocMsg(), + mAdapter(adapter) {} + inline virtual void proc() const { + mAdapter->initEngHubProxy(); + } + }; + + sendMsg(new MsgInitEngHubProxy(this)); +} + +bool +GnssAdapter::initEngHubProxy() { + static bool firstTime = true; + static bool engHubLoadSuccessful = false; + + const char *error = nullptr; + unsigned int processListLength = 0; + loc_process_info_s_type* processInfoList = nullptr; + + do { + // load eng hub only once + if (firstTime == false) { + break; + } + + int rc = loc_read_process_conf(LOC_PATH_IZAT_CONF, &processListLength, + &processInfoList); + if (rc != 0) { + LOC_LOGE("%s]: failed to parse conf file", __func__); + break; + } + + bool pluginDaemonEnabled = false; + // go over the conf table to see whether any plugin daemon is enabled + for (unsigned int i = 0; i < processListLength; i++) { + if ((strncmp(processInfoList[i].name[0], PROCESS_NAME_ENGINE_SERVICE, + strlen(PROCESS_NAME_ENGINE_SERVICE)) == 0) && + (processInfoList[i].proc_status == ENABLED)) { + pluginDaemonEnabled = true; + break; + } + } + + // no plugin daemon is enabled for this platform, no need to load eng hub .so + if (pluginDaemonEnabled == false) { + break; + } + + // load the engine hub .so, if the .so is not present + // all EngHubProxyBase calls will turn into no-op. + void *handle = nullptr; + if ((handle = dlopen("libloc_eng_hub.so", RTLD_NOW)) == nullptr) { + if ((error = dlerror()) != nullptr) { + LOC_LOGE("%s]: libloc_eng_hub.so not found %s !", __func__, error); + } + break; + } + + // prepare the callback functions + // callback function for engine hub to report back position event + GnssAdapterReportPositionEventCb reportPositionEventCb = + [this](const UlpLocation& ulpLocation, + const GpsLocationExtended& locationExtended, + enum loc_sess_status status, + LocPosTechMask techMask, + bool fromUlp) { + // report from engine hub on behalf of PPE will be treated as fromUlp + reportPositionEvent(ulpLocation, locationExtended, status, techMask, fromUlp); + }; + + // callback function for engine hub to report back sv event + GnssAdapterReportSvEventCb reportSvEventCb = + [this](const GnssSvNotification& svNotify, bool fromUlp) { + reportSvEvent(svNotify, fromUlp); + }; + + getEngHubProxyFn* getter = (getEngHubProxyFn*) dlsym(handle, "getEngHubProxy"); + if(getter != nullptr) { + EngineHubProxyBase* hubProxy = (*getter) (mMsgTask, reportPositionEventCb, + reportSvEventCb); + if (hubProxy != nullptr) { + mEngHubProxy = hubProxy; + engHubLoadSuccessful = true; + } + } + else { + LOC_LOGD("%s]: entered, did not find function", __func__); + } + } while (0); + + if (processInfoList != nullptr) { + free (processInfoList); + processInfoList = nullptr; + } + + LOC_LOGD("%s]: first time initialization %d, returned %d", + __func__, firstTime, engHubLoadSuccessful); + + firstTime = false; + return engHubLoadSuccessful; +} diff --git a/gnss/GnssAdapter.h b/gnss/GnssAdapter.h index 99ce5c9a..cf871ba3 100644 --- a/gnss/GnssAdapter.h +++ b/gnss/GnssAdapter.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2018, 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 @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -84,6 +85,9 @@ class GnssAdapter : public LocAdapterBase { /* ==== ULP ============================================================================ */ UlpProxyBase* mUlpProxy; + /* ==== Engine Hub ===================================================================== */ + EngineHubProxyBase* mEngHubProxy; + /* ==== CLIENT ========================================================================= */ typedef std::map ClientDataMap; ClientDataMap mClientData; @@ -198,6 +202,7 @@ public: void setControlCallbacksCommand(LocationControlCallbacks& controlCallbacks); void readConfigCommand(); void setConfigCommand(); + void initEngHubProxyCommand(); uint32_t* gnssUpdateConfigCommand(GnssConfig config); uint32_t gnssDeleteAidingDataCommand(GnssAidingData& data); void gnssUpdateXtraThrottleCommand(const bool enabled); @@ -221,6 +226,7 @@ public: bool resolveInAddress(const char* hostAddress, struct in_addr* inAddress); virtual bool isInSession() { return !mTrackingSessions.empty(); } void initDefaultAgps(); + bool initEngHubProxy(); /* ==== REPORTS ======================================================================== */ /* ======== EVENTS ====(Called from QMI/ULP Thread)===================================== */ @@ -286,7 +292,6 @@ public: void injectLocationCommand(double latitude, double longitude, float accuracy); void injectTimeCommand(int64_t time, int64_t timeReference, int32_t uncertainty); - }; #endif //GNSS_ADAPTER_H