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 
shutdown()56 void LocInternalAdapter::shutdown() {
57     sendMsg(new LocEngShutdown(mLocEngAdapter));
58 }
59 
LocEngAdapter(LOC_API_ADAPTER_EVENT_MASK_T mask,void * owner,ContextBase * context,MsgTask::tCreate tCreator)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
~LocEngAdapter()81 LocEngAdapter::~LocEngAdapter()
82 {
83     delete mInternalAdapter;
84     LOC_LOGV("LocEngAdapter deleted");
85 }
86 
setUlpProxy(UlpProxyBase * ulp)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 
setUlpProxy(UlpProxyBase * ulp)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 
setGpsLockMsg(LOC_GPS_LOCK_MASK lockMask)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 
requestPowerVote()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 
reportPosition(UlpLocation & location,GpsLocationExtended & locationExtended,void * locationExt,enum loc_sess_status status,LocPosTechMask loc_technology_mask)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 
reportPosition(UlpLocation & location,GpsLocationExtended & locationExtended,void * locationExt,enum loc_sess_status status,LocPosTechMask loc_technology_mask)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 
reportSv(GpsSvStatus & svStatus,GpsLocationExtended & locationExtended,void * svExt)204 void LocInternalAdapter::reportSv(GpsSvStatus &svStatus,
205                                   GpsLocationExtended &locationExtended,
206                                   void* svExt){
207     sendMsg(new LocEngReportSv(mLocEngAdapter, svStatus,
208                                locationExtended, svExt));
209 }
210 
reportSv(GpsSvStatus & svStatus,GpsLocationExtended & locationExtended,void * svExt)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 
setInSession(bool inSession)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 
reportStatus(GpsStatusValue status)233 void LocInternalAdapter::reportStatus(GpsStatusValue status)
234 {
235     sendMsg(new LocEngReportStatus(mLocEngAdapter, status));
236 }
237 
reportStatus(GpsStatusValue status)238 void LocEngAdapter::reportStatus(GpsStatusValue status)
239 {
240     if (!mUlp->reportStatus(status)) {
241         mInternalAdapter->reportStatus(status);
242     }
243 }
244 
245 inline
reportNmea(const char * nmea,int length)246 void LocEngAdapter::reportNmea(const char* nmea, int length)
247 {
248     sendMsg(new LocEngReportNmea(mOwner, nmea, length));
249 }
250 
251 inline
reportXtraServer(const char * url1,const char * url2,const char * url3,const int maxlength)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
requestATL(int connHandle,AGpsType agps_type)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
releaseATL(int connHandle)275 bool LocEngAdapter::releaseATL(int connHandle)
276 {
277     if (mSupportsAgpsRequests) {
278         sendMsg(new LocEngReleaseATL(mOwner, connHandle));
279     }
280     return mSupportsAgpsRequests;
281 }
282 
283 inline
requestXtraData()284 bool LocEngAdapter::requestXtraData()
285 {
286     if (mSupportsAgpsRequests) {
287         sendMsg(new LocEngRequestXtra(mOwner));
288     }
289     return mSupportsAgpsRequests;
290 }
291 
292 inline
requestTime()293 bool LocEngAdapter::requestTime()
294 {
295     if (mSupportsAgpsRequests) {
296         sendMsg(new LocEngRequestTime(mOwner));
297     }
298     return mSupportsAgpsRequests;
299 }
300 
301 inline
requestNiNotify(GpsNiNotification & notif,const void * data)302 bool LocEngAdapter::requestNiNotify(GpsNiNotification &notif, 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
requestSuplES(int connHandle)314 bool LocEngAdapter::requestSuplES(int connHandle)
315 {
316     if (mSupportsAgpsRequests)
317         sendMsg(new LocEngRequestSuplEs(mOwner, connHandle));
318     return mSupportsAgpsRequests;
319 }
320 
321 inline
reportDataCallOpened()322 bool LocEngAdapter::reportDataCallOpened()
323 {
324     if(mSupportsAgpsRequests)
325         sendMsg(new LocEngSuplEsOpened(mOwner));
326     return mSupportsAgpsRequests;
327 }
328 
329 inline
reportDataCallClosed()330 bool LocEngAdapter::reportDataCallClosed()
331 {
332     if(mSupportsAgpsRequests)
333         sendMsg(new LocEngSuplEsClosed(mOwner));
334     return mSupportsAgpsRequests;
335 }
336 
337 inline
handleEngineDownEvent()338 void LocEngAdapter::handleEngineDownEvent()
339 {
340     sendMsg(new LocEngDown(mOwner));
341 }
342 
343 inline
handleEngineUpEvent()344 void LocEngAdapter::handleEngineUpEvent()
345 {
346     sendMsg(new LocEngUp(mOwner));
347 }
348 
reportGpsMeasurementData(GpsData & gpsMeasurementData)349 void LocEngAdapter::reportGpsMeasurementData(GpsData &gpsMeasurementData)
350 {
351     sendMsg(new LocEngReportGpsMeasurement(mOwner,
352                                            gpsMeasurementData));
353 }
354 
355 /*
356   Update Registration Mask
357  */
updateRegistrationMask(LOC_API_ADAPTER_EVENT_MASK_T event,loc_registration_mask_status isEnabled)358 void LocEngAdapter::updateRegistrationMask(LOC_API_ADAPTER_EVENT_MASK_T event,
359                                            loc_registration_mask_status isEnabled)
360 {
361     LOC_LOGD("entering %s", __func__);
362     int result = LOC_API_ADAPTER_ERR_FAILURE;
363     result = mLocApi->updateRegistrationMask(event, isEnabled);
364     if (result == LOC_API_ADAPTER_ERR_SUCCESS) {
365         LOC_LOGD("%s] update registration mask succeed.", __func__);
366     } else {
367         LOC_LOGE("%s] update registration mask failed.", __func__);
368     }
369 }
370 
371 /*
372   Set Gnss Constellation Config
373  */
gnssConstellationConfig()374 bool LocEngAdapter::gnssConstellationConfig()
375 {
376     LOC_LOGD("entering %s", __func__);
377     bool result = false;
378     result = mLocApi->gnssConstellationConfig();
379     return result;
380 }
381