GPS: integrate GNSS engine hub with Gnss Adapter

Integrate GNSS engine hub with Gnss Adapter using dynamically
loadable .so file.

Change-Id: I0420a17628db96447c01b8821e54782f7d992aec
CRs-fixed: 2165862
This commit is contained in:
Bhavna Sharma 2018-01-29 14:32:06 +05:30
parent 07883c075d
commit 5b2f224349
4 changed files with 275 additions and 8 deletions

109
core/EngineHubProxyBase.h Normal file
View file

@ -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 &params) {
(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<void(const UlpLocation& ulpLocation,
const GpsLocationExtended& locationExtended,
enum loc_sess_status status,
LocPosTechMask techMask,
bool fromUlp)>
GnssAdapterReportPositionEventCb;
typedef std::function<void(const GnssSvNotification& svNotify, bool fromUlp)>
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

View file

@ -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 \

View file

@ -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 <vector>
#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;
}

View file

@ -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 <LocAdapterBase.h>
#include <LocDualContext.h>
#include <UlpProxyBase.h>
#include <EngineHubProxyBase.h>
#include <LocationAPI.h>
#include <Agps.h>
#include <SystemStatus.h>
@ -84,6 +85,9 @@ class GnssAdapter : public LocAdapterBase {
/* ==== ULP ============================================================================ */
UlpProxyBase* mUlpProxy;
/* ==== Engine Hub ===================================================================== */
EngineHubProxyBase* mEngHubProxy;
/* ==== CLIENT ========================================================================= */
typedef std::map<LocationAPI*, LocationCallbacks> 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