1 /* Copyright (c) 2011-2016, 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 
LocInternalAdapter(LocEngAdapter * adapter)39 LocInternalAdapter::LocInternalAdapter(LocEngAdapter* adapter) :
40     LocAdapterBase(adapter->getMsgTask()),
41     mLocEngAdapter(adapter)
42 {
43 }
setPositionModeInt(LocPosMode & posMode)44 void LocInternalAdapter::setPositionModeInt(LocPosMode& posMode) {
45     sendMsg(new LocEngPositionMode(mLocEngAdapter, posMode));
46 }
startFixInt()47 void LocInternalAdapter::startFixInt() {
48     sendMsg(new LocEngStartFix(mLocEngAdapter));
49 }
stopFixInt()50 void LocInternalAdapter::stopFixInt() {
51     sendMsg(new LocEngStopFix(mLocEngAdapter));
52 }
getZppInt()53 void LocInternalAdapter::getZppInt() {
54     sendMsg(new LocEngGetZpp(mLocEngAdapter));
55 }
56 
LocEngAdapter(LOC_API_ADAPTER_EVENT_MASK_T mask,void * owner,ContextBase * context,LocThread::tCreate tCreator)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
~LocEngAdapter()82 LocEngAdapter::~LocEngAdapter()
83 {
84     delete mInternalAdapter;
85     LOC_LOGV("LocEngAdapter deleted");
86 }
87 
setUlpProxy(UlpProxyBase * ulp)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 
setUlpProxy(UlpProxyBase * ulp)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 
setGpsLockMsg(LOC_GPS_LOCK_MASK lockMask)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 
requestPowerVote()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 
reportPosition(UlpLocation & location,GpsLocationExtended & locationExtended,void * locationExt,enum loc_sess_status status,LocPosTechMask loc_technology_mask)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 
reportPosition(UlpLocation & location,GpsLocationExtended & locationExtended,void * locationExt,enum loc_sess_status status,LocPosTechMask loc_technology_mask)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 
reportSv(GnssSvStatus & svStatus,GpsLocationExtended & locationExtended,void * svExt)205 void LocInternalAdapter::reportSv(GnssSvStatus &svStatus,
206                                   GpsLocationExtended &locationExtended,
207                                   void* svExt){
208     sendMsg(new LocEngReportSv(mLocEngAdapter, svStatus,
209                                locationExtended, svExt));
210 }
211 
reportSv(GnssSvStatus & svStatus,GpsLocationExtended & locationExtended,void * svExt)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 
setInSession(bool inSession)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 
reportStatus(GpsStatusValue status)234 void LocInternalAdapter::reportStatus(GpsStatusValue status)
235 {
236     sendMsg(new LocEngReportStatus(mLocEngAdapter, status));
237 }
238 
reportStatus(GpsStatusValue status)239 void LocEngAdapter::reportStatus(GpsStatusValue status)
240 {
241     if (!mUlp->reportStatus(status)) {
242         mInternalAdapter->reportStatus(status);
243     }
244 }
245 
246 inline
reportNmea(const char * nmea,int length)247 void LocEngAdapter::reportNmea(const char* nmea, int length)
248 {
249     sendMsg(new LocEngReportNmea(mOwner, nmea, length));
250 }
251 
252 inline
reportXtraServer(const char * url1,const char * url2,const char * url3,const int maxlength)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
requestATL(int connHandle,AGpsType agps_type)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
releaseATL(int connHandle)276 bool LocEngAdapter::releaseATL(int connHandle)
277 {
278     if (mSupportsAgpsRequests) {
279         sendMsg(new LocEngReleaseATL(mOwner, connHandle));
280     }
281     return mSupportsAgpsRequests;
282 }
283 
284 inline
requestXtraData()285 bool LocEngAdapter::requestXtraData()
286 {
287     if (mSupportsAgpsRequests) {
288         sendMsg(new LocEngRequestXtra(mOwner));
289     }
290     return mSupportsAgpsRequests;
291 }
292 
293 inline
requestTime()294 bool LocEngAdapter::requestTime()
295 {
296     if (mSupportsAgpsRequests) {
297         sendMsg(new LocEngRequestTime(mOwner));
298     }
299     return mSupportsAgpsRequests;
300 }
301 
302 inline
requestNiNotify(GpsNiNotification & notif,const void * data)303 bool LocEngAdapter::requestNiNotify(GpsNiNotification &notif, 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
requestSuplES(int connHandle)315 bool LocEngAdapter::requestSuplES(int connHandle)
316 {
317     if (mSupportsAgpsRequests)
318         sendMsg(new LocEngRequestSuplEs(mOwner, connHandle));
319     return mSupportsAgpsRequests;
320 }
321 
322 inline
reportDataCallOpened()323 bool LocEngAdapter::reportDataCallOpened()
324 {
325     if(mSupportsAgpsRequests)
326         sendMsg(new LocEngSuplEsOpened(mOwner));
327     return mSupportsAgpsRequests;
328 }
329 
330 inline
reportDataCallClosed()331 bool LocEngAdapter::reportDataCallClosed()
332 {
333     if(mSupportsAgpsRequests)
334         sendMsg(new LocEngSuplEsClosed(mOwner));
335     return mSupportsAgpsRequests;
336 }
337 
338 inline
handleEngineDownEvent()339 void LocEngAdapter::handleEngineDownEvent()
340 {
341     sendMsg(new LocEngDown(mOwner));
342 }
343 
344 inline
handleEngineUpEvent()345 void LocEngAdapter::handleEngineUpEvent()
346 {
347     sendMsg(new LocEngUp(mOwner));
348 }
349 
setTime(GpsUtcTime time,int64_t timeReference,int uncertainty)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     }
363     return result;
364 }
365 
setXtraVersionCheck(int check)366 enum loc_api_adapter_err LocEngAdapter::setXtraVersionCheck(int check)
367 {
368     enum loc_api_adapter_err ret;
369     ENTRY_LOG();
370     enum xtra_version_check eCheck;
371     switch (check) {
372     case 0:
373         eCheck = DISABLED;
374         break;
375     case 1:
376         eCheck = AUTO;
377         break;
378     case 2:
379         eCheck = XTRA2;
380         break;
381     case 3:
382         eCheck = XTRA3;
383         break;
384     default:
385         eCheck = DISABLED;
386     }
387     ret = mLocApi->setXtraVersionCheck(eCheck);
388     EXIT_LOG(%d, ret);
389     return ret;
390 }
391 
reportGnssMeasurementData(GnssData & gnssMeasurementData)392 void LocEngAdapter::reportGnssMeasurementData(GnssData &gnssMeasurementData)
393 {
394     sendMsg(new LocEngReportGnssMeasurement(mOwner,
395                                            gnssMeasurementData));
396 }
397 
398 /*
399   Update Registration Mask
400  */
updateRegistrationMask(LOC_API_ADAPTER_EVENT_MASK_T event,loc_registration_mask_status isEnabled)401 void LocEngAdapter::updateRegistrationMask(LOC_API_ADAPTER_EVENT_MASK_T event,
402                                            loc_registration_mask_status isEnabled)
403 {
404     LOC_LOGD("entering %s", __func__);
405     int result = LOC_API_ADAPTER_ERR_FAILURE;
406     result = mLocApi->updateRegistrationMask(event, isEnabled);
407     if (result == LOC_API_ADAPTER_ERR_SUCCESS) {
408         LOC_LOGD("%s] update registration mask succeed.", __func__);
409     } else {
410         LOC_LOGE("%s] update registration mask failed.", __func__);
411     }
412 }
413 
414 /*
415   Set Gnss Constellation Config
416  */
gnssConstellationConfig()417 bool LocEngAdapter::gnssConstellationConfig()
418 {
419     LOC_LOGD("entering %s", __func__);
420     bool result = false;
421     result = mLocApi->gnssConstellationConfig();
422     return result;
423 }
424