1/* Copyright (c) 2011-2013, 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::setUlpProxy(UlpProxyBase* ulp) {
53    struct LocSetUlpProxy : public LocMsg {
54        LocAdapterBase* mAdapter;
55        UlpProxyBase* mUlp;
56        inline LocSetUlpProxy(LocAdapterBase* adapter, UlpProxyBase* ulp) :
57            LocMsg(), mAdapter(adapter), mUlp(ulp) {
58        }
59        virtual void proc() const {
60            LOC_LOGV("%s] ulp %p adapter %p", __func__,
61                     mUlp, mAdapter);
62            mAdapter->setUlpProxy(mUlp);
63        }
64    };
65
66    sendMsg(new LocSetUlpProxy(mLocEngAdapter, ulp));
67}
68
69LocEngAdapter::LocEngAdapter(LOC_API_ADAPTER_EVENT_MASK_T mask,
70                             void* owner,
71                             MsgTask::tCreate tCreator) :
72    LocAdapterBase(mask,
73                   LocDualContext::getLocFgContext(
74                         tCreator,
75                         LocDualContext::mLocationHalName)),
76    mOwner(owner), mInternalAdapter(new LocInternalAdapter(this)),
77    mUlp(new UlpProxyBase()), mNavigating(false),
78    mAgpsEnabled(false)
79{
80    memset(&mFixCriteria, 0, sizeof(mFixCriteria));
81    LOC_LOGD("LocEngAdapter created");
82}
83
84inline
85LocEngAdapter::~LocEngAdapter()
86{
87    delete mInternalAdapter;
88    LOC_LOGV("LocEngAdapter deleted");
89}
90
91void LocEngAdapter::setUlpProxy(UlpProxyBase* ulp)
92{
93    delete mUlp;
94    LOC_LOGV("%s] %p", __func__, ulp);
95    if (NULL == ulp) {
96        ulp = new UlpProxyBase();
97    }
98    mUlp = ulp;
99}
100
101void LocInternalAdapter::reportPosition(UlpLocation &location,
102                                        GpsLocationExtended &locationExtended,
103                                        void* locationExt,
104                                        enum loc_sess_status status,
105                                        LocPosTechMask loc_technology_mask)
106{
107    sendMsg(new LocEngReportPosition(mLocEngAdapter,
108                                     location,
109                                     locationExtended,
110                                     locationExt,
111                                     status,
112                                     loc_technology_mask));
113}
114
115
116void LocEngAdapter::reportPosition(UlpLocation &location,
117                                   GpsLocationExtended &locationExtended,
118                                   void* locationExt,
119                                   enum loc_sess_status status,
120                                   LocPosTechMask loc_technology_mask)
121{
122    if (! mUlp->reportPosition(location,
123                               locationExtended,
124                               locationExt,
125                               status,
126                               loc_technology_mask )) {
127        mInternalAdapter->reportPosition(location,
128                                         locationExtended,
129                                         locationExt,
130                                         status,
131                                         loc_technology_mask);
132    }
133}
134
135void LocInternalAdapter::reportSv(GpsSvStatus &svStatus,
136                                  GpsLocationExtended &locationExtended,
137                                  void* svExt){
138    sendMsg(new LocEngReportSv(mLocEngAdapter, svStatus,
139                               locationExtended, svExt));
140}
141
142void LocEngAdapter::reportSv(GpsSvStatus &svStatus,
143                             GpsLocationExtended &locationExtended,
144                             void* svExt)
145{
146
147    // We want to send SV info to ULP to help it in determining GNSS
148    // signal strength ULP will forward the SV reports to HAL without
149    // any modifications
150    if (! mUlp->reportSv(svStatus, locationExtended, svExt)) {
151        mInternalAdapter->reportSv(svStatus, locationExtended, svExt);
152    }
153}
154
155inline
156void LocEngAdapter::reportStatus(GpsStatusValue status)
157{
158    sendMsg(new LocEngReportStatus(mOwner, status));
159}
160
161inline
162void LocEngAdapter::reportNmea(const char* nmea, int length)
163{
164    sendMsg(new LocEngReportNmea(mOwner, nmea, length));
165}
166
167inline
168bool LocEngAdapter::reportXtraServer(const char* url1,
169                                        const char* url2,
170                                        const char* url3,
171                                        const int maxlength)
172{
173    if (mAgpsEnabled) {
174        sendMsg(new LocEngReportXtraServer(mOwner, url1,
175                                           url2, url3, maxlength));
176    }
177    return mAgpsEnabled;
178}
179
180inline
181bool LocEngAdapter::requestATL(int connHandle, AGpsType agps_type)
182{
183    if (mAgpsEnabled) {
184        sendMsg(new LocEngRequestATL(mOwner,
185                                     connHandle, agps_type));
186    }
187    return mAgpsEnabled;
188}
189
190inline
191bool LocEngAdapter::releaseATL(int connHandle)
192{
193    if (mAgpsEnabled) {
194        sendMsg(new LocEngReleaseATL(mOwner, connHandle));
195    }
196    return mAgpsEnabled;
197}
198
199inline
200bool LocEngAdapter::requestXtraData()
201{
202    if (mAgpsEnabled) {
203        sendMsg(new LocEngRequestXtra(mOwner));
204    }
205    return mAgpsEnabled;
206}
207
208inline
209bool LocEngAdapter::requestTime()
210{
211    if (mAgpsEnabled) {
212        sendMsg(new LocEngRequestTime(mOwner));
213    }
214    return mAgpsEnabled;
215}
216
217inline
218bool LocEngAdapter::requestNiNotify(GpsNiNotification &notif, const void* data)
219{
220    if (mAgpsEnabled) {
221        notif.size = sizeof(notif);
222        notif.timeout = LOC_NI_NO_RESPONSE_TIME;
223
224        sendMsg(new LocEngRequestNi(mOwner, notif, data));
225    }
226    return mAgpsEnabled;
227}
228
229inline
230bool LocEngAdapter::requestSuplES(int connHandle)
231{
232    sendMsg(new LocEngRequestSuplEs(mOwner, connHandle));
233    return true;
234}
235
236inline
237bool LocEngAdapter::reportDataCallOpened()
238{
239    sendMsg(new LocEngSuplEsOpened(mOwner));
240    return true;
241}
242
243inline
244bool LocEngAdapter::reportDataCallClosed()
245{
246    sendMsg(new LocEngSuplEsClosed(mOwner));
247    return true;
248}
249
250inline
251void LocEngAdapter::handleEngineDownEvent()
252{
253    sendMsg(new LocEngDown(mOwner));
254}
255
256inline
257void LocEngAdapter::handleEngineUpEvent()
258{
259    sendMsg(new LocEngUp(mOwner));
260}
261