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 
LocInternalAdapter(LocEngAdapter * adapter)38 LocInternalAdapter::LocInternalAdapter(LocEngAdapter* adapter) :
39     LocAdapterBase(adapter->getMsgTask()),
40     mLocEngAdapter(adapter)
41 {
42 }
setPositionModeInt(LocPosMode & posMode)43 void LocInternalAdapter::setPositionModeInt(LocPosMode& posMode) {
44     sendMsg(new LocEngPositionMode(mLocEngAdapter, posMode));
45 }
startFixInt()46 void LocInternalAdapter::startFixInt() {
47     sendMsg(new LocEngStartFix(mLocEngAdapter));
48 }
stopFixInt()49 void LocInternalAdapter::stopFixInt() {
50     sendMsg(new LocEngStopFix(mLocEngAdapter));
51 }
getZppInt()52 void LocInternalAdapter::getZppInt() {
53     sendMsg(new LocEngGetZpp(mLocEngAdapter));
54 }
55 
LocEngAdapter(LOC_API_ADAPTER_EVENT_MASK_T mask,void * owner,ContextBase * context,MsgTask::tCreate tCreator)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
~LocEngAdapter()79 LocEngAdapter::~LocEngAdapter()
80 {
81     delete mInternalAdapter;
82     LOC_LOGV("LocEngAdapter deleted");
83 }
84 
setUlpProxy(UlpProxyBase * ulp)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 
setUlpProxy(UlpProxyBase * ulp)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 
setGpsLockMsg(LOC_GPS_LOCK_MASK lockMask)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 
requestPowerVote()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 
reportPosition(UlpLocation & location,GpsLocationExtended & locationExtended,void * locationExt,enum loc_sess_status status,LocPosTechMask loc_technology_mask)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 
reportPosition(UlpLocation & location,GpsLocationExtended & locationExtended,void * locationExt,enum loc_sess_status status,LocPosTechMask loc_technology_mask)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 
reportSv(GpsSvStatus & svStatus,GpsLocationExtended & locationExtended,void * svExt)202 void LocInternalAdapter::reportSv(GpsSvStatus &svStatus,
203                                   GpsLocationExtended &locationExtended,
204                                   void* svExt){
205     sendMsg(new LocEngReportSv(mLocEngAdapter, svStatus,
206                                locationExtended, svExt));
207 }
208 
reportSv(GpsSvStatus & svStatus,GpsLocationExtended & locationExtended,void * svExt)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 
setInSession(bool inSession)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 
reportStatus(GpsStatusValue status)231 void LocInternalAdapter::reportStatus(GpsStatusValue status)
232 {
233     sendMsg(new LocEngReportStatus(mLocEngAdapter, status));
234 }
235 
reportStatus(GpsStatusValue status)236 void LocEngAdapter::reportStatus(GpsStatusValue status)
237 {
238     if (!mUlp->reportStatus(status)) {
239         mInternalAdapter->reportStatus(status);
240     }
241 }
242 
243 inline
reportNmea(const char * nmea,int length)244 void LocEngAdapter::reportNmea(const char* nmea, int length)
245 {
246     sendMsg(new LocEngReportNmea(mOwner, nmea, length));
247 }
248 
249 inline
reportXtraServer(const char * url1,const char * url2,const char * url3,const int maxlength)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
requestATL(int connHandle,AGpsType agps_type)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
releaseATL(int connHandle)273 bool LocEngAdapter::releaseATL(int connHandle)
274 {
275     if (mSupportsAgpsRequests) {
276         sendMsg(new LocEngReleaseATL(mOwner, connHandle));
277     }
278     return mSupportsAgpsRequests;
279 }
280 
281 inline
requestXtraData()282 bool LocEngAdapter::requestXtraData()
283 {
284     if (mSupportsAgpsRequests) {
285         sendMsg(new LocEngRequestXtra(mOwner));
286     }
287     return mSupportsAgpsRequests;
288 }
289 
290 inline
requestTime()291 bool LocEngAdapter::requestTime()
292 {
293     if (mSupportsAgpsRequests) {
294         sendMsg(new LocEngRequestTime(mOwner));
295     }
296     return mSupportsAgpsRequests;
297 }
298 
299 inline
requestNiNotify(GpsNiNotification & notif,const void * data)300 bool LocEngAdapter::requestNiNotify(GpsNiNotification &notif, 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
requestSuplES(int connHandle)312 bool LocEngAdapter::requestSuplES(int connHandle)
313 {
314     if (mSupportsAgpsRequests)
315         sendMsg(new LocEngRequestSuplEs(mOwner, connHandle));
316     return mSupportsAgpsRequests;
317 }
318 
319 inline
reportDataCallOpened()320 bool LocEngAdapter::reportDataCallOpened()
321 {
322     if(mSupportsAgpsRequests)
323         sendMsg(new LocEngSuplEsOpened(mOwner));
324     return mSupportsAgpsRequests;
325 }
326 
327 inline
reportDataCallClosed()328 bool LocEngAdapter::reportDataCallClosed()
329 {
330     if(mSupportsAgpsRequests)
331         sendMsg(new LocEngSuplEsClosed(mOwner));
332     return mSupportsAgpsRequests;
333 }
334 
335 inline
handleEngineDownEvent()336 void LocEngAdapter::handleEngineDownEvent()
337 {
338     sendMsg(new LocEngDown(mOwner));
339 }
340 
341 inline
handleEngineUpEvent()342 void LocEngAdapter::handleEngineUpEvent()
343 {
344     sendMsg(new LocEngUp(mOwner));
345 }
346 
setTime(GpsUtcTime time,int64_t timeReference,int uncertainty)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 
setXtraVersionCheck(int check)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 
reportGpsMeasurementData(GpsData & gpsMeasurementData)391 void LocEngAdapter::reportGpsMeasurementData(GpsData &gpsMeasurementData)
392 {
393     sendMsg(new LocEngReportGpsMeasurement(mOwner,
394                                            gpsMeasurementData));
395 }
396 
397 /*
398   Update Registration Mask
399  */
updateRegistrationMask(LOC_API_ADAPTER_EVENT_MASK_T event,loc_registration_mask_status isEnabled)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  */
gnssConstellationConfig()416 bool LocEngAdapter::gnssConstellationConfig()
417 {
418     LOC_LOGD("entering %s", __func__);
419     bool result = false;
420     result = mLocApi->gnssConstellationConfig();
421     return result;
422 }
423