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
36using namespace loc_core;
37
38LocInternalAdapter::LocInternalAdapter(LocEngAdapter* adapter) :
39    LocAdapterBase(adapter->getMsgTask()),
40    mLocEngAdapter(adapter)
41{
42}
43void LocInternalAdapter::setPositionModeInt(LocPosMode& posMode) {
44    sendMsg(new LocEngPositionMode(mLocEngAdapter, posMode));
45}
46void LocInternalAdapter::startFixInt() {
47    sendMsg(new LocEngStartFix(mLocEngAdapter));
48}
49void LocInternalAdapter::stopFixInt() {
50    sendMsg(new LocEngStopFix(mLocEngAdapter));
51}
52void LocInternalAdapter::getZppInt() {
53    sendMsg(new LocEngGetZpp(mLocEngAdapter));
54}
55
56void LocInternalAdapter::shutdown() {
57    sendMsg(new LocEngShutdown(mLocEngAdapter));
58}
59
60LocEngAdapter::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
80inline
81LocEngAdapter::~LocEngAdapter()
82{
83    delete mInternalAdapter;
84    LOC_LOGV("LocEngAdapter deleted");
85}
86
87void 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
104void 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
131int 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
155void 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
170void 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
185void 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
204void LocInternalAdapter::reportSv(GpsSvStatus &svStatus,
205                                  GpsLocationExtended &locationExtended,
206                                  void* svExt){
207    sendMsg(new LocEngReportSv(mLocEngAdapter, svStatus,
208                               locationExtended, svExt));
209}
210
211void 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
224void 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
233void LocInternalAdapter::reportStatus(GpsStatusValue status)
234{
235    sendMsg(new LocEngReportStatus(mLocEngAdapter, status));
236}
237
238void LocEngAdapter::reportStatus(GpsStatusValue status)
239{
240    if (!mUlp->reportStatus(status)) {
241        mInternalAdapter->reportStatus(status);
242    }
243}
244
245inline
246void LocEngAdapter::reportNmea(const char* nmea, int length)
247{
248    sendMsg(new LocEngReportNmea(mOwner, nmea, length));
249}
250
251inline
252bool 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
264inline
265bool 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
274inline
275bool LocEngAdapter::releaseATL(int connHandle)
276{
277    if (mSupportsAgpsRequests) {
278        sendMsg(new LocEngReleaseATL(mOwner, connHandle));
279    }
280    return mSupportsAgpsRequests;
281}
282
283inline
284bool LocEngAdapter::requestXtraData()
285{
286    if (mSupportsAgpsRequests) {
287        sendMsg(new LocEngRequestXtra(mOwner));
288    }
289    return mSupportsAgpsRequests;
290}
291
292inline
293bool LocEngAdapter::requestTime()
294{
295    if (mSupportsAgpsRequests) {
296        sendMsg(new LocEngRequestTime(mOwner));
297    }
298    return mSupportsAgpsRequests;
299}
300
301inline
302bool 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
313inline
314bool LocEngAdapter::requestSuplES(int connHandle)
315{
316    if (mSupportsAgpsRequests)
317        sendMsg(new LocEngRequestSuplEs(mOwner, connHandle));
318    return mSupportsAgpsRequests;
319}
320
321inline
322bool LocEngAdapter::reportDataCallOpened()
323{
324    if(mSupportsAgpsRequests)
325        sendMsg(new LocEngSuplEsOpened(mOwner));
326    return mSupportsAgpsRequests;
327}
328
329inline
330bool LocEngAdapter::reportDataCallClosed()
331{
332    if(mSupportsAgpsRequests)
333        sendMsg(new LocEngSuplEsClosed(mOwner));
334    return mSupportsAgpsRequests;
335}
336
337inline
338void LocEngAdapter::handleEngineDownEvent()
339{
340    sendMsg(new LocEngDown(mOwner));
341}
342
343inline
344void LocEngAdapter::handleEngineUpEvent()
345{
346    sendMsg(new LocEngUp(mOwner));
347}
348
349void LocEngAdapter::reportGpsMeasurementData(GpsData &gpsMeasurementData)
350{
351    sendMsg(new LocEngReportGpsMeasurement(mOwner,
352                                           gpsMeasurementData));
353}
354
355/*
356  Update Registration Mask
357 */
358void 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 */
374bool LocEngAdapter::gnssConstellationConfig()
375{
376    LOC_LOGD("entering %s", __func__);
377    bool result = false;
378    result = mLocApi->gnssConstellationConfig();
379    return result;
380}
381