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