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), mPowerVote(0) 74 { 75 memset(&mFixCriteria, 0, sizeof(mFixCriteria)); 76 mFixCriteria.mode = LOC_POSITION_MODE_INVALID; 77 LOC_LOGD("LocEngAdapter created"); 78 } 79 80 inline 81 LocEngAdapter::~LocEngAdapter() 82 { 83 delete mInternalAdapter; 84 LOC_LOGV("LocEngAdapter deleted"); 85 } 86 87 void LocInternalAdapter::setUlpProxy(UlpProxyBase* ulp) { 88 struct LocSetUlpProxy : public LocMsg { 89 LocAdapterBase* mAdapter; 90 UlpProxyBase* mUlp; 91 inline LocSetUlpProxy(LocAdapterBase* adapter, UlpProxyBase* ulp) : 92 LocMsg(), mAdapter(adapter), mUlp(ulp) { 93 } 94 virtual void proc() const { 95 LOC_LOGV("%s] ulp %p adapter %p", __func__, 96 mUlp, mAdapter); 97 mAdapter->setUlpProxy(mUlp); 98 } 99 }; 100 101 sendMsg(new LocSetUlpProxy(mLocEngAdapter, ulp)); 102 } 103 104 void LocEngAdapter::setUlpProxy(UlpProxyBase* ulp) 105 { 106 if (ulp == mUlp) { 107 //This takes care of the case when double initalization happens 108 //and we get the same object back for UlpProxyBase . Do nothing 109 return; 110 } 111 112 LOC_LOGV("%s] %p", __func__, ulp); 113 if (NULL == ulp) { 114 LOC_LOGE("%s:%d]: ulp pointer is NULL", __func__, __LINE__); 115 ulp = new UlpProxyBase(); 116 } 117 118 if (LOC_POSITION_MODE_INVALID != mUlp->mPosMode.mode) { 119 // need to send this mode and start msg to ULP 120 ulp->sendFixMode(mUlp->mPosMode); 121 } 122 123 if(mUlp->mFixSet) { 124 ulp->sendStartFix(); 125 } 126 127 delete mUlp; 128 mUlp = ulp; 129 } 130 131 int LocEngAdapter::setGpsLockMsg(LOC_GPS_LOCK_MASK lockMask) 132 { 133 struct LocEngAdapterGpsLock : public LocMsg { 134 LocEngAdapter* mAdapter; 135 LOC_GPS_LOCK_MASK mLockMask; 136 inline LocEngAdapterGpsLock(LocEngAdapter* adapter, LOC_GPS_LOCK_MASK lockMask) : 137 LocMsg(), mAdapter(adapter), mLockMask(lockMask) 138 { 139 locallog(); 140 } 141 inline virtual void proc() const { 142 mAdapter->setGpsLock(mLockMask); 143 } 144 inline void locallog() const { 145 LOC_LOGV("LocEngAdapterGpsLock - mLockMask: %x", mLockMask); 146 } 147 inline virtual void log() const { 148 locallog(); 149 } 150 }; 151 sendMsg(new LocEngAdapterGpsLock(this, lockMask)); 152 return 0; 153 } 154 155 void LocEngAdapter::requestPowerVote() 156 { 157 if (getPowerVoteRight()) { 158 /* Power voting without engine lock: 159 * 101: vote down, 102-104 - vote up 160 * These codes are used not to confuse with actual engine lock 161 * functionality, that can't be used in SSR scenario, as it 162 * conflicts with initialization sequence. 163 */ 164 bool powerUp = getPowerVote(); 165 LOC_LOGV("LocEngAdapterVotePower - Vote Power: %d", (int)powerUp); 166 setGpsLock(powerUp ? 103 : 101); 167 } 168 } 169 170 void LocInternalAdapter::reportPosition(UlpLocation &location, 171 GpsLocationExtended &locationExtended, 172 void* locationExt, 173 enum loc_sess_status status, 174 LocPosTechMask loc_technology_mask) 175 { 176 sendMsg(new LocEngReportPosition(mLocEngAdapter, 177 location, 178 locationExtended, 179 locationExt, 180 status, 181 loc_technology_mask)); 182 } 183 184 185 void LocEngAdapter::reportPosition(UlpLocation &location, 186 GpsLocationExtended &locationExtended, 187 void* locationExt, 188 enum loc_sess_status status, 189 LocPosTechMask loc_technology_mask) 190 { 191 if (! mUlp->reportPosition(location, 192 locationExtended, 193 locationExt, 194 status, 195 loc_technology_mask )) { 196 mInternalAdapter->reportPosition(location, 197 locationExtended, 198 locationExt, 199 status, 200 loc_technology_mask); 201 } 202 } 203 204 void LocInternalAdapter::reportSv(GpsSvStatus &svStatus, 205 GpsLocationExtended &locationExtended, 206 void* svExt){ 207 sendMsg(new LocEngReportSv(mLocEngAdapter, svStatus, 208 locationExtended, svExt)); 209 } 210 211 void LocEngAdapter::reportSv(GpsSvStatus &svStatus, 212 GpsLocationExtended &locationExtended, 213 void* svExt) 214 { 215 216 // We want to send SV info to ULP to help it in determining GNSS 217 // signal strength ULP will forward the SV reports to HAL without 218 // any modifications 219 if (! mUlp->reportSv(svStatus, locationExtended, svExt)) { 220 mInternalAdapter->reportSv(svStatus, locationExtended, svExt); 221 } 222 } 223 224 void LocEngAdapter::setInSession(bool inSession) 225 { 226 mNavigating = inSession; 227 mLocApi->setInSession(inSession); 228 if (!mNavigating) { 229 mFixCriteria.mode = LOC_POSITION_MODE_INVALID; 230 } 231 } 232 233 void LocInternalAdapter::reportStatus(GpsStatusValue status) 234 { 235 sendMsg(new LocEngReportStatus(mLocEngAdapter, status)); 236 } 237 238 void LocEngAdapter::reportStatus(GpsStatusValue status) 239 { 240 if (!mUlp->reportStatus(status)) { 241 mInternalAdapter->reportStatus(status); 242 } 243 } 244 245 inline 246 void LocEngAdapter::reportNmea(const char* nmea, int length) 247 { 248 sendMsg(new LocEngReportNmea(mOwner, nmea, length)); 249 } 250 251 inline 252 bool LocEngAdapter::reportXtraServer(const char* url1, 253 const char* url2, 254 const char* url3, 255 const int maxlength) 256 { 257 if (mSupportsAgpsRequests) { 258 sendMsg(new LocEngReportXtraServer(mOwner, url1, 259 url2, url3, maxlength)); 260 } 261 return mSupportsAgpsRequests; 262 } 263 264 inline 265 bool LocEngAdapter::requestATL(int connHandle, AGpsType agps_type) 266 { 267 if (mSupportsAgpsRequests) { 268 sendMsg(new LocEngRequestATL(mOwner, 269 connHandle, agps_type)); 270 } 271 return mSupportsAgpsRequests; 272 } 273 274 inline 275 bool LocEngAdapter::releaseATL(int connHandle) 276 { 277 if (mSupportsAgpsRequests) { 278 sendMsg(new LocEngReleaseATL(mOwner, connHandle)); 279 } 280 return mSupportsAgpsRequests; 281 } 282 283 inline 284 bool LocEngAdapter::requestXtraData() 285 { 286 if (mSupportsAgpsRequests) { 287 sendMsg(new LocEngRequestXtra(mOwner)); 288 } 289 return mSupportsAgpsRequests; 290 } 291 292 inline 293 bool LocEngAdapter::requestTime() 294 { 295 if (mSupportsAgpsRequests) { 296 sendMsg(new LocEngRequestTime(mOwner)); 297 } 298 return mSupportsAgpsRequests; 299 } 300 301 inline 302 bool LocEngAdapter::requestNiNotify(GpsNiNotification ¬if, const void* data) 303 { 304 if (mSupportsAgpsRequests) { 305 notif.size = sizeof(notif); 306 notif.timeout = LOC_NI_NO_RESPONSE_TIME; 307 308 sendMsg(new LocEngRequestNi(mOwner, notif, data)); 309 } 310 return mSupportsAgpsRequests; 311 } 312 313 inline 314 bool LocEngAdapter::requestSuplES(int connHandle) 315 { 316 if (mSupportsAgpsRequests) 317 sendMsg(new LocEngRequestSuplEs(mOwner, connHandle)); 318 return mSupportsAgpsRequests; 319 } 320 321 inline 322 bool LocEngAdapter::reportDataCallOpened() 323 { 324 if(mSupportsAgpsRequests) 325 sendMsg(new LocEngSuplEsOpened(mOwner)); 326 return mSupportsAgpsRequests; 327 } 328 329 inline 330 bool LocEngAdapter::reportDataCallClosed() 331 { 332 if(mSupportsAgpsRequests) 333 sendMsg(new LocEngSuplEsClosed(mOwner)); 334 return mSupportsAgpsRequests; 335 } 336 337 inline 338 void LocEngAdapter::handleEngineDownEvent() 339 { 340 sendMsg(new LocEngDown(mOwner)); 341 } 342 343 inline 344 void LocEngAdapter::handleEngineUpEvent() 345 { 346 sendMsg(new LocEngUp(mOwner)); 347 } 348