1/* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. 2 * 3 * Redistribution and use in source and binary forms, with or without 4 * modification, are permitted provided that the following conditions are 5 * met: 6 * * Redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer. 8 * * Redistributions in binary form must reproduce the above 9 * copyright notice, this list of conditions and the following 10 * disclaimer in the documentation and/or other materials provided 11 * with the distribution. 12 * * Neither the name of The Linux Foundation, nor the names of its 13 * contributors may be used to endorse or promote products derived 14 * from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 */ 29#define LOG_NDDEBUG 0 30#define LOG_TAG "LocSvc_EngAdapter" 31 32#include <LocEngAdapter.h> 33#include "loc_eng_msg.h" 34#include "loc_log.h" 35 36using namespace loc_core; 37 38LocInternalAdapter::LocInternalAdapter(LocEngAdapter* adapter) : 39 LocAdapterBase(adapter->getMsgTask()), 40 mLocEngAdapter(adapter) 41{ 42} 43void LocInternalAdapter::setPositionModeInt(LocPosMode& posMode) { 44 sendMsg(new LocEngPositionMode(mLocEngAdapter, posMode)); 45} 46void LocInternalAdapter::startFixInt() { 47 sendMsg(new LocEngStartFix(mLocEngAdapter)); 48} 49void LocInternalAdapter::stopFixInt() { 50 sendMsg(new LocEngStopFix(mLocEngAdapter)); 51} 52void LocInternalAdapter::getZppInt() { 53 sendMsg(new LocEngGetZpp(mLocEngAdapter)); 54} 55 56LocEngAdapter::LocEngAdapter(LOC_API_ADAPTER_EVENT_MASK_T mask, 57 void* owner, ContextBase* context, 58 MsgTask::tCreate tCreator) : 59 LocAdapterBase(mask, 60 //Get the AFW context if VzW context has not already been intialized in 61 //loc_ext 62 context == NULL? 63 LocDualContext::getLocFgContext(tCreator, 64 LocDualContext::mLocationHalName) 65 :context), 66 mOwner(owner), mInternalAdapter(new LocInternalAdapter(this)), 67 mUlp(new UlpProxyBase()), mNavigating(false), 68 mSupportsAgpsRequests(false), 69 mSupportsPositionInjection(false), 70 mSupportsTimeInjection(false), 71 mPowerVote(0) 72{ 73 memset(&mFixCriteria, 0, sizeof(mFixCriteria)); 74 mFixCriteria.mode = LOC_POSITION_MODE_INVALID; 75 LOC_LOGD("LocEngAdapter created"); 76} 77 78inline 79LocEngAdapter::~LocEngAdapter() 80{ 81 delete mInternalAdapter; 82 LOC_LOGV("LocEngAdapter deleted"); 83} 84 85void LocInternalAdapter::setUlpProxy(UlpProxyBase* ulp) { 86 struct LocSetUlpProxy : public LocMsg { 87 LocAdapterBase* mAdapter; 88 UlpProxyBase* mUlp; 89 inline LocSetUlpProxy(LocAdapterBase* adapter, UlpProxyBase* ulp) : 90 LocMsg(), mAdapter(adapter), mUlp(ulp) { 91 } 92 virtual void proc() const { 93 LOC_LOGV("%s] ulp %p adapter %p", __func__, 94 mUlp, mAdapter); 95 mAdapter->setUlpProxy(mUlp); 96 } 97 }; 98 99 sendMsg(new LocSetUlpProxy(mLocEngAdapter, ulp)); 100} 101 102void LocEngAdapter::setUlpProxy(UlpProxyBase* ulp) 103{ 104 if (ulp == mUlp) { 105 //This takes care of the case when double initalization happens 106 //and we get the same object back for UlpProxyBase . Do nothing 107 return; 108 } 109 110 LOC_LOGV("%s] %p", __func__, ulp); 111 if (NULL == ulp) { 112 LOC_LOGE("%s:%d]: ulp pointer is NULL", __func__, __LINE__); 113 ulp = new UlpProxyBase(); 114 } 115 116 if (LOC_POSITION_MODE_INVALID != mUlp->mPosMode.mode) { 117 // need to send this mode and start msg to ULP 118 ulp->sendFixMode(mUlp->mPosMode); 119 } 120 121 if(mUlp->mFixSet) { 122 ulp->sendStartFix(); 123 } 124 125 delete mUlp; 126 mUlp = ulp; 127} 128 129int LocEngAdapter::setGpsLockMsg(LOC_GPS_LOCK_MASK lockMask) 130{ 131 struct LocEngAdapterGpsLock : public LocMsg { 132 LocEngAdapter* mAdapter; 133 LOC_GPS_LOCK_MASK mLockMask; 134 inline LocEngAdapterGpsLock(LocEngAdapter* adapter, LOC_GPS_LOCK_MASK lockMask) : 135 LocMsg(), mAdapter(adapter), mLockMask(lockMask) 136 { 137 locallog(); 138 } 139 inline virtual void proc() const { 140 mAdapter->setGpsLock(mLockMask); 141 } 142 inline void locallog() const { 143 LOC_LOGV("LocEngAdapterGpsLock - mLockMask: %x", mLockMask); 144 } 145 inline virtual void log() const { 146 locallog(); 147 } 148 }; 149 sendMsg(new LocEngAdapterGpsLock(this, lockMask)); 150 return 0; 151} 152 153void LocEngAdapter::requestPowerVote() 154{ 155 if (getPowerVoteRight()) { 156 /* Power voting without engine lock: 157 * 101: vote down, 102-104 - vote up 158 * These codes are used not to confuse with actual engine lock 159 * functionality, that can't be used in SSR scenario, as it 160 * conflicts with initialization sequence. 161 */ 162 bool powerUp = getPowerVote(); 163 LOC_LOGV("LocEngAdapterVotePower - Vote Power: %d", (int)powerUp); 164 setGpsLock(powerUp ? 103 : 101); 165 } 166} 167 168void LocInternalAdapter::reportPosition(UlpLocation &location, 169 GpsLocationExtended &locationExtended, 170 void* locationExt, 171 enum loc_sess_status status, 172 LocPosTechMask loc_technology_mask) 173{ 174 sendMsg(new LocEngReportPosition(mLocEngAdapter, 175 location, 176 locationExtended, 177 locationExt, 178 status, 179 loc_technology_mask)); 180} 181 182 183void LocEngAdapter::reportPosition(UlpLocation &location, 184 GpsLocationExtended &locationExtended, 185 void* locationExt, 186 enum loc_sess_status status, 187 LocPosTechMask loc_technology_mask) 188{ 189 if (! mUlp->reportPosition(location, 190 locationExtended, 191 locationExt, 192 status, 193 loc_technology_mask )) { 194 mInternalAdapter->reportPosition(location, 195 locationExtended, 196 locationExt, 197 status, 198 loc_technology_mask); 199 } 200} 201 202void LocInternalAdapter::reportSv(GpsSvStatus &svStatus, 203 GpsLocationExtended &locationExtended, 204 void* svExt){ 205 sendMsg(new LocEngReportSv(mLocEngAdapter, svStatus, 206 locationExtended, svExt)); 207} 208 209void LocEngAdapter::reportSv(GpsSvStatus &svStatus, 210 GpsLocationExtended &locationExtended, 211 void* svExt) 212{ 213 214 // We want to send SV info to ULP to help it in determining GNSS 215 // signal strength ULP will forward the SV reports to HAL without 216 // any modifications 217 if (! mUlp->reportSv(svStatus, locationExtended, svExt)) { 218 mInternalAdapter->reportSv(svStatus, locationExtended, svExt); 219 } 220} 221 222void LocEngAdapter::setInSession(bool inSession) 223{ 224 mNavigating = inSession; 225 mLocApi->setInSession(inSession); 226 if (!mNavigating) { 227 mFixCriteria.mode = LOC_POSITION_MODE_INVALID; 228 } 229} 230 231void LocInternalAdapter::reportStatus(GpsStatusValue status) 232{ 233 sendMsg(new LocEngReportStatus(mLocEngAdapter, status)); 234} 235 236void LocEngAdapter::reportStatus(GpsStatusValue status) 237{ 238 if (!mUlp->reportStatus(status)) { 239 mInternalAdapter->reportStatus(status); 240 } 241} 242 243inline 244void LocEngAdapter::reportNmea(const char* nmea, int length) 245{ 246 sendMsg(new LocEngReportNmea(mOwner, nmea, length)); 247} 248 249inline 250bool LocEngAdapter::reportXtraServer(const char* url1, 251 const char* url2, 252 const char* url3, 253 const int maxlength) 254{ 255 if (mSupportsAgpsRequests) { 256 sendMsg(new LocEngReportXtraServer(mOwner, url1, 257 url2, url3, maxlength)); 258 } 259 return mSupportsAgpsRequests; 260} 261 262inline 263bool LocEngAdapter::requestATL(int connHandle, AGpsType agps_type) 264{ 265 if (mSupportsAgpsRequests) { 266 sendMsg(new LocEngRequestATL(mOwner, 267 connHandle, agps_type)); 268 } 269 return mSupportsAgpsRequests; 270} 271 272inline 273bool LocEngAdapter::releaseATL(int connHandle) 274{ 275 if (mSupportsAgpsRequests) { 276 sendMsg(new LocEngReleaseATL(mOwner, connHandle)); 277 } 278 return mSupportsAgpsRequests; 279} 280 281inline 282bool LocEngAdapter::requestXtraData() 283{ 284 if (mSupportsAgpsRequests) { 285 sendMsg(new LocEngRequestXtra(mOwner)); 286 } 287 return mSupportsAgpsRequests; 288} 289 290inline 291bool LocEngAdapter::requestTime() 292{ 293 if (mSupportsAgpsRequests) { 294 sendMsg(new LocEngRequestTime(mOwner)); 295 } 296 return mSupportsAgpsRequests; 297} 298 299inline 300bool LocEngAdapter::requestNiNotify(GpsNiNotification ¬if, const void* data) 301{ 302 if (mSupportsAgpsRequests) { 303 notif.size = sizeof(notif); 304 notif.timeout = LOC_NI_NO_RESPONSE_TIME; 305 306 sendMsg(new LocEngRequestNi(mOwner, notif, data)); 307 } 308 return mSupportsAgpsRequests; 309} 310 311inline 312bool LocEngAdapter::requestSuplES(int connHandle) 313{ 314 if (mSupportsAgpsRequests) 315 sendMsg(new LocEngRequestSuplEs(mOwner, connHandle)); 316 return mSupportsAgpsRequests; 317} 318 319inline 320bool LocEngAdapter::reportDataCallOpened() 321{ 322 if(mSupportsAgpsRequests) 323 sendMsg(new LocEngSuplEsOpened(mOwner)); 324 return mSupportsAgpsRequests; 325} 326 327inline 328bool LocEngAdapter::reportDataCallClosed() 329{ 330 if(mSupportsAgpsRequests) 331 sendMsg(new LocEngSuplEsClosed(mOwner)); 332 return mSupportsAgpsRequests; 333} 334 335inline 336void LocEngAdapter::handleEngineDownEvent() 337{ 338 sendMsg(new LocEngDown(mOwner)); 339} 340 341inline 342void LocEngAdapter::handleEngineUpEvent() 343{ 344 sendMsg(new LocEngUp(mOwner)); 345} 346 347enum loc_api_adapter_err LocEngAdapter::setTime(GpsUtcTime time, 348 int64_t timeReference, 349 int uncertainty) 350{ 351 loc_api_adapter_err result = LOC_API_ADAPTER_ERR_SUCCESS; 352 353 LOC_LOGD("%s:%d]: mSupportsTimeInjection is %d", 354 __func__, __LINE__, mSupportsTimeInjection); 355 356 if (mSupportsTimeInjection) { 357 LOC_LOGD("%s:%d]: Injecting time", __func__, __LINE__); 358 result = mLocApi->setTime(time, timeReference, uncertainty); 359 } else { 360 mSupportsTimeInjection = true; 361 } 362 return result; 363} 364 365enum loc_api_adapter_err LocEngAdapter::setXtraVersionCheck(int check) 366{ 367 enum loc_api_adapter_err ret; 368 ENTRY_LOG(); 369 enum xtra_version_check eCheck; 370 switch (check) { 371 case 0: 372 eCheck = DISABLED; 373 break; 374 case 1: 375 eCheck = AUTO; 376 break; 377 case 2: 378 eCheck = XTRA2; 379 break; 380 case 3: 381 eCheck = XTRA3; 382 break; 383 default: 384 eCheck = DISABLED; 385 } 386 ret = mLocApi->setXtraVersionCheck(eCheck); 387 EXIT_LOG(%d, ret); 388 return ret; 389} 390 391void LocEngAdapter::reportGpsMeasurementData(GpsData &gpsMeasurementData) 392{ 393 sendMsg(new LocEngReportGpsMeasurement(mOwner, 394 gpsMeasurementData)); 395} 396 397/* 398 Update Registration Mask 399 */ 400void LocEngAdapter::updateRegistrationMask(LOC_API_ADAPTER_EVENT_MASK_T event, 401 loc_registration_mask_status isEnabled) 402{ 403 LOC_LOGD("entering %s", __func__); 404 int result = LOC_API_ADAPTER_ERR_FAILURE; 405 result = mLocApi->updateRegistrationMask(event, isEnabled); 406 if (result == LOC_API_ADAPTER_ERR_SUCCESS) { 407 LOC_LOGD("%s] update registration mask succeed.", __func__); 408 } else { 409 LOC_LOGE("%s] update registration mask failed.", __func__); 410 } 411} 412 413/* 414 Set Gnss Constellation Config 415 */ 416bool LocEngAdapter::gnssConstellationConfig() 417{ 418 LOC_LOGD("entering %s", __func__); 419 bool result = false; 420 result = mLocApi->gnssConstellationConfig(); 421 return result; 422} 423