| /* 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; |
| } |