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 ¬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
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