1 /* Copyright (c) 2011-2015, 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 <cutils/properties.h> 33 #include <LocEngAdapter.h> 34 #include "loc_eng_msg.h" 35 #include "loc_log.h" 36 37 using namespace loc_core; 38 39 LocInternalAdapter::LocInternalAdapter(LocEngAdapter* adapter) : 40 LocAdapterBase(adapter->getMsgTask()), 41 mLocEngAdapter(adapter) 42 { 43 } 44 void LocInternalAdapter::setPositionModeInt(LocPosMode& posMode) { 45 sendMsg(new LocEngPositionMode(mLocEngAdapter, posMode)); 46 } 47 void LocInternalAdapter::startFixInt() { 48 sendMsg(new LocEngStartFix(mLocEngAdapter)); 49 } 50 void LocInternalAdapter::stopFixInt() { 51 sendMsg(new LocEngStopFix(mLocEngAdapter)); 52 } 53 void LocInternalAdapter::getZppInt() { 54 sendMsg(new LocEngGetZpp(mLocEngAdapter)); 55 } 56 57 LocEngAdapter::LocEngAdapter(LOC_API_ADAPTER_EVENT_MASK_T mask, 58 void* owner, ContextBase* context, 59 LocThread::tCreate tCreator) : 60 LocAdapterBase(mask, 61 //Get the AFW context if VzW context has not already been intialized in 62 //loc_ext 63 context == NULL? 64 LocDualContext::getLocFgContext(tCreator, 65 NULL, 66 LocDualContext::mLocationHalName, 67 false) 68 :context), 69 mOwner(owner), mInternalAdapter(new LocInternalAdapter(this)), 70 mUlp(new UlpProxyBase()), mNavigating(false), 71 mSupportsAgpsRequests(false), 72 mSupportsPositionInjection(false), 73 mSupportsTimeInjection(false), 74 mPowerVote(0) 75 { 76 memset(&mFixCriteria, 0, sizeof(mFixCriteria)); 77 mFixCriteria.mode = LOC_POSITION_MODE_INVALID; 78 LOC_LOGD("LocEngAdapter created"); 79 } 80 81 inline 82 LocEngAdapter::~LocEngAdapter() 83 { 84 delete mInternalAdapter; 85 LOC_LOGV("LocEngAdapter deleted"); 86 } 87 88 void LocInternalAdapter::setUlpProxy(UlpProxyBase* ulp) { 89 struct LocSetUlpProxy : public LocMsg { 90 LocAdapterBase* mAdapter; 91 UlpProxyBase* mUlp; 92 inline LocSetUlpProxy(LocAdapterBase* adapter, UlpProxyBase* ulp) : 93 LocMsg(), mAdapter(adapter), mUlp(ulp) { 94 } 95 virtual void proc() const { 96 LOC_LOGV("%s] ulp %p adapter %p", __func__, 97 mUlp, mAdapter); 98 mAdapter->setUlpProxy(mUlp); 99 } 100 }; 101 102 sendMsg(new LocSetUlpProxy(mLocEngAdapter, ulp)); 103 } 104 105 void LocEngAdapter::setUlpProxy(UlpProxyBase* ulp) 106 { 107 if (ulp == mUlp) { 108 //This takes care of the case when double initalization happens 109 //and we get the same object back for UlpProxyBase . Do nothing 110 return; 111 } 112 113 LOC_LOGV("%s] %p", __func__, ulp); 114 if (NULL == ulp) { 115 LOC_LOGE("%s:%d]: ulp pointer is NULL", __func__, __LINE__); 116 ulp = new UlpProxyBase(); 117 } 118 119 if (LOC_POSITION_MODE_INVALID != mUlp->mPosMode.mode) { 120 // need to send this mode and start msg to ULP 121 ulp->sendFixMode(mUlp->mPosMode); 122 } 123 124 if(mUlp->mFixSet) { 125 ulp->sendStartFix(); 126 } 127 128 delete mUlp; 129 mUlp = ulp; 130 } 131 132 int LocEngAdapter::setGpsLockMsg(LOC_GPS_LOCK_MASK lockMask) 133 { 134 struct LocEngAdapterGpsLock : public LocMsg { 135 LocEngAdapter* mAdapter; 136 LOC_GPS_LOCK_MASK mLockMask; 137 inline LocEngAdapterGpsLock(LocEngAdapter* adapter, LOC_GPS_LOCK_MASK lockMask) : 138 LocMsg(), mAdapter(adapter), mLockMask(lockMask) 139 { 140 locallog(); 141 } 142 inline virtual void proc() const { 143 mAdapter->setGpsLock(mLockMask); 144 } 145 inline void locallog() const { 146 LOC_LOGV("LocEngAdapterGpsLock - mLockMask: %x", mLockMask); 147 } 148 inline virtual void log() const { 149 locallog(); 150 } 151 }; 152 sendMsg(new LocEngAdapterGpsLock(this, lockMask)); 153 return 0; 154 } 155 156 void LocEngAdapter::requestPowerVote() 157 { 158 if (getPowerVoteRight()) { 159 /* Power voting without engine lock: 160 * 101: vote down, 102-104 - vote up 161 * These codes are used not to confuse with actual engine lock 162 * functionality, that can't be used in SSR scenario, as it 163 * conflicts with initialization sequence. 164 */ 165 bool powerUp = getPowerVote(); 166 LOC_LOGV("LocEngAdapterVotePower - Vote Power: %d", (int)powerUp); 167 setGpsLock(powerUp ? 103 : 101); 168 } 169 } 170 171 void LocInternalAdapter::reportPosition(UlpLocation &location, 172 GpsLocationExtended &locationExtended, 173 void* locationExt, 174 enum loc_sess_status status, 175 LocPosTechMask loc_technology_mask) 176 { 177 sendMsg(new LocEngReportPosition(mLocEngAdapter, 178 location, 179 locationExtended, 180 locationExt, 181 status, 182 loc_technology_mask)); 183 } 184 185 186 void LocEngAdapter::reportPosition(UlpLocation &location, 187 GpsLocationExtended &locationExtended, 188 void* locationExt, 189 enum loc_sess_status status, 190 LocPosTechMask loc_technology_mask) 191 { 192 if (! mUlp->reportPosition(location, 193 locationExtended, 194 locationExt, 195 status, 196 loc_technology_mask )) { 197 mInternalAdapter->reportPosition(location, 198 locationExtended, 199 locationExt, 200 status, 201 loc_technology_mask); 202 } 203 } 204 205 void LocInternalAdapter::reportSv(GnssSvStatus &svStatus, 206 GpsLocationExtended &locationExtended, 207 void* svExt){ 208 sendMsg(new LocEngReportSv(mLocEngAdapter, svStatus, 209 locationExtended, svExt)); 210 } 211 212 void LocEngAdapter::reportSv(GnssSvStatus &svStatus, 213 GpsLocationExtended &locationExtended, 214 void* svExt) 215 { 216 217 // We want to send SV info to ULP to help it in determining GNSS 218 // signal strength ULP will forward the SV reports to HAL without 219 // any modifications 220 if (! mUlp->reportSv(svStatus, locationExtended, svExt)) { 221 mInternalAdapter->reportSv(svStatus, locationExtended, svExt); 222 } 223 } 224 225 void LocEngAdapter::setInSession(bool inSession) 226 { 227 mNavigating = inSession; 228 mLocApi->setInSession(inSession); 229 if (!mNavigating) { 230 mFixCriteria.mode = LOC_POSITION_MODE_INVALID; 231 } 232 } 233 234 void LocInternalAdapter::reportStatus(GpsStatusValue status) 235 { 236 sendMsg(new LocEngReportStatus(mLocEngAdapter, status)); 237 } 238 239 void LocEngAdapter::reportStatus(GpsStatusValue status) 240 { 241 if (!mUlp->reportStatus(status)) { 242 mInternalAdapter->reportStatus(status); 243 } 244 } 245 246 inline 247 void LocEngAdapter::reportNmea(const char* nmea, int length) 248 { 249 sendMsg(new LocEngReportNmea(mOwner, nmea, length)); 250 } 251 252 inline 253 bool LocEngAdapter::reportXtraServer(const char* url1, 254 const char* url2, 255 const char* url3, 256 const int maxlength) 257 { 258 if (mSupportsAgpsRequests) { 259 sendMsg(new LocEngReportXtraServer(mOwner, url1, 260 url2, url3, maxlength)); 261 } 262 return mSupportsAgpsRequests; 263 } 264 265 inline 266 bool LocEngAdapter::requestATL(int connHandle, AGpsType agps_type) 267 { 268 if (mSupportsAgpsRequests) { 269 sendMsg(new LocEngRequestATL(mOwner, 270 connHandle, agps_type)); 271 } 272 return mSupportsAgpsRequests; 273 } 274 275 inline 276 bool LocEngAdapter::releaseATL(int connHandle) 277 { 278 if (mSupportsAgpsRequests) { 279 sendMsg(new LocEngReleaseATL(mOwner, connHandle)); 280 } 281 return mSupportsAgpsRequests; 282 } 283 284 inline 285 bool LocEngAdapter::requestXtraData() 286 { 287 if (mSupportsAgpsRequests) { 288 sendMsg(new LocEngRequestXtra(mOwner)); 289 } 290 return mSupportsAgpsRequests; 291 } 292 293 inline 294 bool LocEngAdapter::requestTime() 295 { 296 if (mSupportsAgpsRequests) { 297 sendMsg(new LocEngRequestTime(mOwner)); 298 } 299 return mSupportsAgpsRequests; 300 } 301 302 inline 303 bool LocEngAdapter::requestNiNotify(GpsNiNotification ¬if, const void* data) 304 { 305 if (mSupportsAgpsRequests) { 306 notif.size = sizeof(notif); 307 notif.timeout = LOC_NI_NO_RESPONSE_TIME; 308 309 sendMsg(new LocEngRequestNi(mOwner, notif, data)); 310 } 311 return mSupportsAgpsRequests; 312 } 313 314 inline 315 bool LocEngAdapter::requestSuplES(int connHandle) 316 { 317 if (mSupportsAgpsRequests) 318 sendMsg(new LocEngRequestSuplEs(mOwner, connHandle)); 319 return mSupportsAgpsRequests; 320 } 321 322 inline 323 bool LocEngAdapter::reportDataCallOpened() 324 { 325 if(mSupportsAgpsRequests) 326 sendMsg(new LocEngSuplEsOpened(mOwner)); 327 return mSupportsAgpsRequests; 328 } 329 330 inline 331 bool LocEngAdapter::reportDataCallClosed() 332 { 333 if(mSupportsAgpsRequests) 334 sendMsg(new LocEngSuplEsClosed(mOwner)); 335 return mSupportsAgpsRequests; 336 } 337 338 inline 339 void LocEngAdapter::handleEngineDownEvent() 340 { 341 sendMsg(new LocEngDown(mOwner)); 342 } 343 344 inline 345 void LocEngAdapter::handleEngineUpEvent() 346 { 347 sendMsg(new LocEngUp(mOwner)); 348 } 349 350 enum loc_api_adapter_err LocEngAdapter::setTime(GpsUtcTime time, 351 int64_t timeReference, 352 int uncertainty) 353 { 354 loc_api_adapter_err result = LOC_API_ADAPTER_ERR_SUCCESS; 355 356 LOC_LOGD("%s:%d]: mSupportsTimeInjection is %d", 357 __func__, __LINE__, mSupportsTimeInjection); 358 359 if (mSupportsTimeInjection) { 360 LOC_LOGD("%s:%d]: Injecting time", __func__, __LINE__); 361 result = mLocApi->setTime(time, timeReference, uncertainty); 362 } else { 363 mSupportsTimeInjection = true; 364 } 365 return result; 366 } 367 368 enum loc_api_adapter_err LocEngAdapter::setXtraVersionCheck(int check) 369 { 370 enum loc_api_adapter_err ret; 371 ENTRY_LOG(); 372 enum xtra_version_check eCheck; 373 switch (check) { 374 case 0: 375 eCheck = DISABLED; 376 break; 377 case 1: 378 eCheck = AUTO; 379 break; 380 case 2: 381 eCheck = XTRA2; 382 break; 383 case 3: 384 eCheck = XTRA3; 385 break; 386 default: 387 eCheck = DISABLED; 388 } 389 ret = mLocApi->setXtraVersionCheck(eCheck); 390 EXIT_LOG(%d, ret); 391 return ret; 392 } 393 394 void LocEngAdapter::reportGnssMeasurementData(GnssData &gnssMeasurementData) 395 { 396 sendMsg(new LocEngReportGnssMeasurement(mOwner, 397 gnssMeasurementData)); 398 } 399 400 /* 401 Update Registration Mask 402 */ 403 void LocEngAdapter::updateRegistrationMask(LOC_API_ADAPTER_EVENT_MASK_T event, 404 loc_registration_mask_status isEnabled) 405 { 406 LOC_LOGD("entering %s", __func__); 407 int result = LOC_API_ADAPTER_ERR_FAILURE; 408 result = mLocApi->updateRegistrationMask(event, isEnabled); 409 if (result == LOC_API_ADAPTER_ERR_SUCCESS) { 410 LOC_LOGD("%s] update registration mask succeed.", __func__); 411 } else { 412 LOC_LOGE("%s] update registration mask failed.", __func__); 413 } 414 } 415 416 /* 417 Set Gnss Constellation Config 418 */ 419 bool LocEngAdapter::gnssConstellationConfig() 420 { 421 LOC_LOGD("entering %s", __func__); 422 bool result = false; 423 result = mLocApi->gnssConstellationConfig(); 424 return result; 425 } 426