You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
422 lines
13 KiB
422 lines
13 KiB
/* Copyright (c) 2011-2014, 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. |
|
* |
|
*/ |
|
#define LOG_NDDEBUG 0 |
|
#define LOG_TAG "LocSvc_EngAdapter" |
|
|
|
#include <LocEngAdapter.h> |
|
#include "loc_eng_msg.h" |
|
#include "loc_log.h" |
|
|
|
using namespace loc_core; |
|
|
|
LocInternalAdapter::LocInternalAdapter(LocEngAdapter* adapter) : |
|
LocAdapterBase(adapter->getMsgTask()), |
|
mLocEngAdapter(adapter) |
|
{ |
|
} |
|
void LocInternalAdapter::setPositionModeInt(LocPosMode& posMode) { |
|
sendMsg(new LocEngPositionMode(mLocEngAdapter, posMode)); |
|
} |
|
void LocInternalAdapter::startFixInt() { |
|
sendMsg(new LocEngStartFix(mLocEngAdapter)); |
|
} |
|
void LocInternalAdapter::stopFixInt() { |
|
sendMsg(new LocEngStopFix(mLocEngAdapter)); |
|
} |
|
void LocInternalAdapter::getZppInt() { |
|
sendMsg(new LocEngGetZpp(mLocEngAdapter)); |
|
} |
|
|
|
LocEngAdapter::LocEngAdapter(LOC_API_ADAPTER_EVENT_MASK_T mask, |
|
void* owner, ContextBase* context, |
|
MsgTask::tCreate tCreator) : |
|
LocAdapterBase(mask, |
|
//Get the AFW context if VzW context has not already been intialized in |
|
//loc_ext |
|
context == NULL? |
|
LocDualContext::getLocFgContext(tCreator, |
|
LocDualContext::mLocationHalName) |
|
:context), |
|
mOwner(owner), mInternalAdapter(new LocInternalAdapter(this)), |
|
mUlp(new UlpProxyBase()), mNavigating(false), |
|
mSupportsAgpsRequests(false), |
|
mSupportsPositionInjection(false), |
|
mSupportsTimeInjection(false), |
|
mPowerVote(0) |
|
{ |
|
memset(&mFixCriteria, 0, sizeof(mFixCriteria)); |
|
mFixCriteria.mode = LOC_POSITION_MODE_INVALID; |
|
LOC_LOGD("LocEngAdapter created"); |
|
} |
|
|
|
inline |
|
LocEngAdapter::~LocEngAdapter() |
|
{ |
|
delete mInternalAdapter; |
|
LOC_LOGV("LocEngAdapter deleted"); |
|
} |
|
|
|
void LocInternalAdapter::setUlpProxy(UlpProxyBase* ulp) { |
|
struct LocSetUlpProxy : public LocMsg { |
|
LocAdapterBase* mAdapter; |
|
UlpProxyBase* mUlp; |
|
inline LocSetUlpProxy(LocAdapterBase* adapter, UlpProxyBase* ulp) : |
|
LocMsg(), mAdapter(adapter), mUlp(ulp) { |
|
} |
|
virtual void proc() const { |
|
LOC_LOGV("%s] ulp %p adapter %p", __func__, |
|
mUlp, mAdapter); |
|
mAdapter->setUlpProxy(mUlp); |
|
} |
|
}; |
|
|
|
sendMsg(new LocSetUlpProxy(mLocEngAdapter, ulp)); |
|
} |
|
|
|
void LocEngAdapter::setUlpProxy(UlpProxyBase* ulp) |
|
{ |
|
if (ulp == mUlp) { |
|
//This takes care of the case when double initalization happens |
|
//and we get the same object back for UlpProxyBase . Do nothing |
|
return; |
|
} |
|
|
|
LOC_LOGV("%s] %p", __func__, ulp); |
|
if (NULL == ulp) { |
|
LOC_LOGE("%s:%d]: ulp pointer is NULL", __func__, __LINE__); |
|
ulp = new UlpProxyBase(); |
|
} |
|
|
|
if (LOC_POSITION_MODE_INVALID != mUlp->mPosMode.mode) { |
|
// need to send this mode and start msg to ULP |
|
ulp->sendFixMode(mUlp->mPosMode); |
|
} |
|
|
|
if(mUlp->mFixSet) { |
|
ulp->sendStartFix(); |
|
} |
|
|
|
delete mUlp; |
|
mUlp = ulp; |
|
} |
|
|
|
int LocEngAdapter::setGpsLockMsg(LOC_GPS_LOCK_MASK lockMask) |
|
{ |
|
struct LocEngAdapterGpsLock : public LocMsg { |
|
LocEngAdapter* mAdapter; |
|
LOC_GPS_LOCK_MASK mLockMask; |
|
inline LocEngAdapterGpsLock(LocEngAdapter* adapter, LOC_GPS_LOCK_MASK lockMask) : |
|
LocMsg(), mAdapter(adapter), mLockMask(lockMask) |
|
{ |
|
locallog(); |
|
} |
|
inline virtual void proc() const { |
|
mAdapter->setGpsLock(mLockMask); |
|
} |
|
inline void locallog() const { |
|
LOC_LOGV("LocEngAdapterGpsLock - mLockMask: %x", mLockMask); |
|
} |
|
inline virtual void log() const { |
|
locallog(); |
|
} |
|
}; |
|
sendMsg(new LocEngAdapterGpsLock(this, lockMask)); |
|
return 0; |
|
} |
|
|
|
void LocEngAdapter::requestPowerVote() |
|
{ |
|
if (getPowerVoteRight()) { |
|
/* Power voting without engine lock: |
|
* 101: vote down, 102-104 - vote up |
|
* These codes are used not to confuse with actual engine lock |
|
* functionality, that can't be used in SSR scenario, as it |
|
* conflicts with initialization sequence. |
|
*/ |
|
bool powerUp = getPowerVote(); |
|
LOC_LOGV("LocEngAdapterVotePower - Vote Power: %d", (int)powerUp); |
|
setGpsLock(powerUp ? 103 : 101); |
|
} |
|
} |
|
|
|
void LocInternalAdapter::reportPosition(UlpLocation &location, |
|
GpsLocationExtended &locationExtended, |
|
void* locationExt, |
|
enum loc_sess_status status, |
|
LocPosTechMask loc_technology_mask) |
|
{ |
|
sendMsg(new LocEngReportPosition(mLocEngAdapter, |
|
location, |
|
locationExtended, |
|
locationExt, |
|
status, |
|
loc_technology_mask)); |
|
} |
|
|
|
|
|
void LocEngAdapter::reportPosition(UlpLocation &location, |
|
GpsLocationExtended &locationExtended, |
|
void* locationExt, |
|
enum loc_sess_status status, |
|
LocPosTechMask loc_technology_mask) |
|
{ |
|
if (! mUlp->reportPosition(location, |
|
locationExtended, |
|
locationExt, |
|
status, |
|
loc_technology_mask )) { |
|
mInternalAdapter->reportPosition(location, |
|
locationExtended, |
|
locationExt, |
|
status, |
|
loc_technology_mask); |
|
} |
|
} |
|
|
|
void LocInternalAdapter::reportSv(GpsSvStatus &svStatus, |
|
GpsLocationExtended &locationExtended, |
|
void* svExt){ |
|
sendMsg(new LocEngReportSv(mLocEngAdapter, svStatus, |
|
locationExtended, svExt)); |
|
} |
|
|
|
void LocEngAdapter::reportSv(GpsSvStatus &svStatus, |
|
GpsLocationExtended &locationExtended, |
|
void* svExt) |
|
{ |
|
|
|
// We want to send SV info to ULP to help it in determining GNSS |
|
// signal strength ULP will forward the SV reports to HAL without |
|
// any modifications |
|
if (! mUlp->reportSv(svStatus, locationExtended, svExt)) { |
|
mInternalAdapter->reportSv(svStatus, locationExtended, svExt); |
|
} |
|
} |
|
|
|
void LocEngAdapter::setInSession(bool inSession) |
|
{ |
|
mNavigating = inSession; |
|
mLocApi->setInSession(inSession); |
|
if (!mNavigating) { |
|
mFixCriteria.mode = LOC_POSITION_MODE_INVALID; |
|
} |
|
} |
|
|
|
void LocInternalAdapter::reportStatus(GpsStatusValue status) |
|
{ |
|
sendMsg(new LocEngReportStatus(mLocEngAdapter, status)); |
|
} |
|
|
|
void LocEngAdapter::reportStatus(GpsStatusValue status) |
|
{ |
|
if (!mUlp->reportStatus(status)) { |
|
mInternalAdapter->reportStatus(status); |
|
} |
|
} |
|
|
|
inline |
|
void LocEngAdapter::reportNmea(const char* nmea, int length) |
|
{ |
|
sendMsg(new LocEngReportNmea(mOwner, nmea, length)); |
|
} |
|
|
|
inline |
|
bool LocEngAdapter::reportXtraServer(const char* url1, |
|
const char* url2, |
|
const char* url3, |
|
const int maxlength) |
|
{ |
|
if (mSupportsAgpsRequests) { |
|
sendMsg(new LocEngReportXtraServer(mOwner, url1, |
|
url2, url3, maxlength)); |
|
} |
|
return mSupportsAgpsRequests; |
|
} |
|
|
|
inline |
|
bool LocEngAdapter::requestATL(int connHandle, AGpsType agps_type) |
|
{ |
|
if (mSupportsAgpsRequests) { |
|
sendMsg(new LocEngRequestATL(mOwner, |
|
connHandle, agps_type)); |
|
} |
|
return mSupportsAgpsRequests; |
|
} |
|
|
|
inline |
|
bool LocEngAdapter::releaseATL(int connHandle) |
|
{ |
|
if (mSupportsAgpsRequests) { |
|
sendMsg(new LocEngReleaseATL(mOwner, connHandle)); |
|
} |
|
return mSupportsAgpsRequests; |
|
} |
|
|
|
inline |
|
bool LocEngAdapter::requestXtraData() |
|
{ |
|
if (mSupportsAgpsRequests) { |
|
sendMsg(new LocEngRequestXtra(mOwner)); |
|
} |
|
return mSupportsAgpsRequests; |
|
} |
|
|
|
inline |
|
bool LocEngAdapter::requestTime() |
|
{ |
|
if (mSupportsAgpsRequests) { |
|
sendMsg(new LocEngRequestTime(mOwner)); |
|
} |
|
return mSupportsAgpsRequests; |
|
} |
|
|
|
inline |
|
bool LocEngAdapter::requestNiNotify(GpsNiNotification ¬if, const void* data) |
|
{ |
|
if (mSupportsAgpsRequests) { |
|
notif.size = sizeof(notif); |
|
notif.timeout = LOC_NI_NO_RESPONSE_TIME; |
|
|
|
sendMsg(new LocEngRequestNi(mOwner, notif, data)); |
|
} |
|
return mSupportsAgpsRequests; |
|
} |
|
|
|
inline |
|
bool LocEngAdapter::requestSuplES(int connHandle) |
|
{ |
|
if (mSupportsAgpsRequests) |
|
sendMsg(new LocEngRequestSuplEs(mOwner, connHandle)); |
|
return mSupportsAgpsRequests; |
|
} |
|
|
|
inline |
|
bool LocEngAdapter::reportDataCallOpened() |
|
{ |
|
if(mSupportsAgpsRequests) |
|
sendMsg(new LocEngSuplEsOpened(mOwner)); |
|
return mSupportsAgpsRequests; |
|
} |
|
|
|
inline |
|
bool LocEngAdapter::reportDataCallClosed() |
|
{ |
|
if(mSupportsAgpsRequests) |
|
sendMsg(new LocEngSuplEsClosed(mOwner)); |
|
return mSupportsAgpsRequests; |
|
} |
|
|
|
inline |
|
void LocEngAdapter::handleEngineDownEvent() |
|
{ |
|
sendMsg(new LocEngDown(mOwner)); |
|
} |
|
|
|
inline |
|
void LocEngAdapter::handleEngineUpEvent() |
|
{ |
|
sendMsg(new LocEngUp(mOwner)); |
|
} |
|
|
|
enum loc_api_adapter_err LocEngAdapter::setTime(GpsUtcTime time, |
|
int64_t timeReference, |
|
int uncertainty) |
|
{ |
|
loc_api_adapter_err result = LOC_API_ADAPTER_ERR_SUCCESS; |
|
|
|
LOC_LOGD("%s:%d]: mSupportsTimeInjection is %d", |
|
__func__, __LINE__, mSupportsTimeInjection); |
|
|
|
if (mSupportsTimeInjection) { |
|
LOC_LOGD("%s:%d]: Injecting time", __func__, __LINE__); |
|
result = mLocApi->setTime(time, timeReference, uncertainty); |
|
} else { |
|
mSupportsTimeInjection = true; |
|
} |
|
return result; |
|
} |
|
|
|
enum loc_api_adapter_err LocEngAdapter::setXtraVersionCheck(int check) |
|
{ |
|
enum loc_api_adapter_err ret; |
|
ENTRY_LOG(); |
|
enum xtra_version_check eCheck; |
|
switch (check) { |
|
case 0: |
|
eCheck = DISABLED; |
|
break; |
|
case 1: |
|
eCheck = AUTO; |
|
break; |
|
case 2: |
|
eCheck = XTRA2; |
|
break; |
|
case 3: |
|
eCheck = XTRA3; |
|
break; |
|
default: |
|
eCheck = DISABLED; |
|
} |
|
ret = mLocApi->setXtraVersionCheck(eCheck); |
|
EXIT_LOG(%d, ret); |
|
return ret; |
|
} |
|
|
|
void LocEngAdapter::reportGpsMeasurementData(GpsData &gpsMeasurementData) |
|
{ |
|
sendMsg(new LocEngReportGpsMeasurement(mOwner, |
|
gpsMeasurementData)); |
|
} |
|
|
|
/* |
|
Update Registration Mask |
|
*/ |
|
void LocEngAdapter::updateRegistrationMask(LOC_API_ADAPTER_EVENT_MASK_T event, |
|
loc_registration_mask_status isEnabled) |
|
{ |
|
LOC_LOGD("entering %s", __func__); |
|
int result = LOC_API_ADAPTER_ERR_FAILURE; |
|
result = mLocApi->updateRegistrationMask(event, isEnabled); |
|
if (result == LOC_API_ADAPTER_ERR_SUCCESS) { |
|
LOC_LOGD("%s] update registration mask succeed.", __func__); |
|
} else { |
|
LOC_LOGE("%s] update registration mask failed.", __func__); |
|
} |
|
} |
|
|
|
/* |
|
Set Gnss Constellation Config |
|
*/ |
|
bool LocEngAdapter::gnssConstellationConfig() |
|
{ |
|
LOC_LOGD("entering %s", __func__); |
|
bool result = false; |
|
result = mLocApi->gnssConstellationConfig(); |
|
return result; |
|
}
|
|
|