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 LocEngAdapter::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 78 inline 79 LocEngAdapter::~LocEngAdapter() 80 { 81 delete mInternalAdapter; 82 LOC_LOGV("LocEngAdapter deleted"); 83 } 84 85 void 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 102 void 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 129 int 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 153 void 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 168 void 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 183 void 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 202 void LocInternalAdapter::reportSv(GpsSvStatus &svStatus, 203 GpsLocationExtended &locationExtended, 204 void* svExt){ 205 sendMsg(new LocEngReportSv(mLocEngAdapter, svStatus, 206 locationExtended, svExt)); 207 } 208 209 void 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 222 void 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 231 void LocInternalAdapter::reportStatus(GpsStatusValue status) 232 { 233 sendMsg(new LocEngReportStatus(mLocEngAdapter, status)); 234 } 235 236 void LocEngAdapter::reportStatus(GpsStatusValue status) 237 { 238 if (!mUlp->reportStatus(status)) { 239 mInternalAdapter->reportStatus(status); 240 } 241 } 242 243 inline 244 void LocEngAdapter::reportNmea(const char* nmea, int length) 245 { 246 sendMsg(new LocEngReportNmea(mOwner, nmea, length)); 247 } 248 249 inline 250 bool 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 262 inline 263 bool 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 272 inline 273 bool LocEngAdapter::releaseATL(int connHandle) 274 { 275 if (mSupportsAgpsRequests) { 276 sendMsg(new LocEngReleaseATL(mOwner, connHandle)); 277 } 278 return mSupportsAgpsRequests; 279 } 280 281 inline 282 bool LocEngAdapter::requestXtraData() 283 { 284 if (mSupportsAgpsRequests) { 285 sendMsg(new LocEngRequestXtra(mOwner)); 286 } 287 return mSupportsAgpsRequests; 288 } 289 290 inline 291 bool LocEngAdapter::requestTime() 292 { 293 if (mSupportsAgpsRequests) { 294 sendMsg(new LocEngRequestTime(mOwner)); 295 } 296 return mSupportsAgpsRequests; 297 } 298 299 inline 300 bool 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 311 inline 312 bool LocEngAdapter::requestSuplES(int connHandle) 313 { 314 if (mSupportsAgpsRequests) 315 sendMsg(new LocEngRequestSuplEs(mOwner, connHandle)); 316 return mSupportsAgpsRequests; 317 } 318 319 inline 320 bool LocEngAdapter::reportDataCallOpened() 321 { 322 if(mSupportsAgpsRequests) 323 sendMsg(new LocEngSuplEsOpened(mOwner)); 324 return mSupportsAgpsRequests; 325 } 326 327 inline 328 bool LocEngAdapter::reportDataCallClosed() 329 { 330 if(mSupportsAgpsRequests) 331 sendMsg(new LocEngSuplEsClosed(mOwner)); 332 return mSupportsAgpsRequests; 333 } 334 335 inline 336 void LocEngAdapter::handleEngineDownEvent() 337 { 338 sendMsg(new LocEngDown(mOwner)); 339 } 340 341 inline 342 void LocEngAdapter::handleEngineUpEvent() 343 { 344 sendMsg(new LocEngUp(mOwner)); 345 } 346 347 enum 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 365 enum 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 391 void LocEngAdapter::reportGpsMeasurementData(GpsData &gpsMeasurementData) 392 { 393 sendMsg(new LocEngReportGpsMeasurement(mOwner, 394 gpsMeasurementData)); 395 } 396 397 /* 398 Update Registration Mask 399 */ 400 void 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 */ 416 bool LocEngAdapter::gnssConstellationConfig() 417 { 418 LOC_LOGD("entering %s", __func__); 419 bool result = false; 420 result = mLocApi->gnssConstellationConfig(); 421 return result; 422 } 423