1 /*
2  * Copyright (c) 2017, The Linux Foundation. All rights reserved.
3  * Not a Contribution
4  */
5 /*
6  * Copyright (C) 2016 The Android Open Source Project
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 
21 #define LOG_TAG "LocSvc_GnssInterface"
22 
23 #include <log_util.h>
24 #include <dlfcn.h>
25 #include "Gnss.h"
26 typedef void* (getLocationInterface)();
27 
28 namespace android {
29 namespace hardware {
30 namespace gnss {
31 namespace V1_0 {
32 namespace implementation {
33 
serviceDied(uint64_t cookie,const wp<IBase> & who)34 void Gnss::GnssDeathRecipient::serviceDied(uint64_t cookie, const wp<IBase>& who) {
35     LOC_LOGE("%s] service died. cookie: %llu, who: %p",
36             __FUNCTION__, static_cast<unsigned long long>(cookie), &who);
37     if (mGnss != nullptr) {
38         mGnss->stop();
39         mGnss->cleanup();
40     }
41 }
42 
Gnss()43 Gnss::Gnss() {
44     ENTRY_LOG_CALLFLOW();
45     // clear pending GnssConfig
46     memset(&mPendingConfig, 0, sizeof(GnssConfig));
47 
48     mGnssDeathRecipient = new GnssDeathRecipient(this);
49 }
50 
~Gnss()51 Gnss::~Gnss() {
52     ENTRY_LOG_CALLFLOW();
53     if (mApi != nullptr) {
54         delete mApi;
55         mApi = nullptr;
56     }
57 }
58 
getApi()59 GnssAPIClient* Gnss::getApi() {
60     if (mApi == nullptr && (mGnssCbIface != nullptr || mGnssNiCbIface != nullptr)) {
61         mApi = new GnssAPIClient(mGnssCbIface, mGnssNiCbIface);
62         if (mApi == nullptr) {
63             LOC_LOGE("%s] faild to create GnssAPIClient", __FUNCTION__);
64             return mApi;
65         }
66 
67         if (mPendingConfig.size == sizeof(GnssConfig)) {
68             // we have pending GnssConfig
69             mApi->gnssConfigurationUpdate(mPendingConfig);
70             // clear size to invalid mPendingConfig
71             mPendingConfig.size = 0;
72             if (mPendingConfig.assistanceServer.hostName != nullptr) {
73                 free((void*)mPendingConfig.assistanceServer.hostName);
74             }
75         }
76     }
77     if (mApi == nullptr) {
78         LOC_LOGW("%s] GnssAPIClient is not ready", __FUNCTION__);
79     }
80     return mApi;
81 }
82 
getGnssInterface()83 GnssInterface* Gnss::getGnssInterface() {
84     static bool getGnssInterfaceFailed = false;
85     if (nullptr == mGnssInterface && !getGnssInterfaceFailed) {
86         LOC_LOGD("%s]: loading libgnss.so::getGnssInterface ...", __func__);
87         getLocationInterface* getter = NULL;
88         const char *error;
89         dlerror();
90         void *handle = dlopen("libgnss.so", RTLD_NOW);
91         if (NULL == handle || (error = dlerror()) != NULL)  {
92             LOC_LOGW("dlopen for libgnss.so failed, error = %s", error);
93         } else {
94             getter = (getLocationInterface*)dlsym(handle, "getGnssInterface");
95             if ((error = dlerror()) != NULL)  {
96                 LOC_LOGW("dlsym for libgnss.so::getGnssInterface failed, error = %s", error);
97                 getter = NULL;
98             }
99         }
100 
101         if (NULL == getter) {
102             getGnssInterfaceFailed = true;
103         } else {
104             mGnssInterface = (GnssInterface*)(*getter)();
105         }
106     }
107     return mGnssInterface;
108 }
109 
setCallback(const sp<IGnssCallback> & callback)110 Return<bool> Gnss::setCallback(const sp<IGnssCallback>& callback)  {
111     ENTRY_LOG_CALLFLOW();
112     if (mGnssCbIface != nullptr) {
113         mGnssCbIface->unlinkToDeath(mGnssDeathRecipient);
114     }
115     mGnssCbIface = callback;
116     if (mGnssCbIface != nullptr) {
117         mGnssCbIface->linkToDeath(mGnssDeathRecipient, 0 /*cookie*/);
118     }
119 
120     GnssAPIClient* api = getApi();
121     if (api != nullptr) {
122         api->gnssUpdateCallbacks(mGnssCbIface, mGnssNiCbIface);
123         api->locAPIEnable(LOCATION_TECHNOLOGY_TYPE_GNSS);
124     }
125     return true;
126 }
127 
setGnssNiCb(const sp<IGnssNiCallback> & callback)128 Return<bool> Gnss::setGnssNiCb(const sp<IGnssNiCallback>& callback) {
129     ENTRY_LOG_CALLFLOW();
130     mGnssNiCbIface = callback;
131     GnssAPIClient* api = getApi();
132     if (api != nullptr) {
133         api->gnssUpdateCallbacks(mGnssCbIface, mGnssNiCbIface);
134     }
135     return true;
136 }
137 
updateConfiguration(GnssConfig & gnssConfig)138 Return<bool> Gnss::updateConfiguration(GnssConfig& gnssConfig) {
139     ENTRY_LOG_CALLFLOW();
140     GnssAPIClient* api = getApi();
141     if (api) {
142         api->locAPIGnssUpdateConfig(gnssConfig);
143     } else if (gnssConfig.flags != 0) {
144         // api is not ready yet, update mPendingConfig with gnssConfig
145         mPendingConfig.size = sizeof(GnssConfig);
146 
147         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT) {
148             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT;
149             mPendingConfig.gpsLock = gnssConfig.gpsLock;
150         }
151         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT) {
152             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT;
153             mPendingConfig.suplVersion = gnssConfig.suplVersion;
154         }
155         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT) {
156             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT;
157             mPendingConfig.assistanceServer.size = sizeof(GnssConfigSetAssistanceServer);
158             mPendingConfig.assistanceServer.type = gnssConfig.assistanceServer.type;
159             if (mPendingConfig.assistanceServer.hostName != nullptr) {
160                 free((void*)mPendingConfig.assistanceServer.hostName);
161                 mPendingConfig.assistanceServer.hostName =
162                     strdup(gnssConfig.assistanceServer.hostName);
163             }
164             mPendingConfig.assistanceServer.port = gnssConfig.assistanceServer.port;
165         }
166         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT) {
167             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT;
168             mPendingConfig.lppProfile = gnssConfig.lppProfile;
169         }
170         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT) {
171             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT;
172             mPendingConfig.lppeControlPlaneMask = gnssConfig.lppeControlPlaneMask;
173         }
174         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT) {
175             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT;
176             mPendingConfig.lppeUserPlaneMask = gnssConfig.lppeUserPlaneMask;
177         }
178         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT) {
179             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT;
180             mPendingConfig.aGlonassPositionProtocolMask = gnssConfig.aGlonassPositionProtocolMask;
181         }
182         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT) {
183             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT;
184             mPendingConfig.emergencyPdnForEmergencySupl = gnssConfig.emergencyPdnForEmergencySupl;
185         }
186         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT) {
187             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT;
188             mPendingConfig.suplEmergencyServices = gnssConfig.suplEmergencyServices;
189         }
190         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_MODE_BIT) {
191             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_MODE_BIT;
192             mPendingConfig.suplModeMask = gnssConfig.suplModeMask;
193         }
194     }
195     return true;
196 }
197 
start()198 Return<bool> Gnss::start()  {
199     ENTRY_LOG_CALLFLOW();
200     bool retVal = false;
201     GnssAPIClient* api = getApi();
202     if (api) {
203         retVal = api->gnssStart();
204     }
205     return retVal;
206 }
207 
stop()208 Return<bool> Gnss::stop()  {
209     ENTRY_LOG_CALLFLOW();
210     bool retVal = false;
211     GnssAPIClient* api = getApi();
212     if (api) {
213         retVal = api->gnssStop();
214     }
215     return retVal;
216 }
217 
cleanup()218 Return<void> Gnss::cleanup()  {
219     ENTRY_LOG_CALLFLOW();
220 
221     if (mApi != nullptr) {
222         mApi->locAPIDisable();
223     }
224 
225     return Void();
226 }
227 
injectLocation(double latitudeDegrees,double longitudeDegrees,float accuracyMeters)228 Return<bool> Gnss::injectLocation(double latitudeDegrees,
229                                   double longitudeDegrees,
230                                   float accuracyMeters)  {
231     ENTRY_LOG_CALLFLOW();
232     GnssInterface* gnssInterface = getGnssInterface();
233     if (nullptr != gnssInterface) {
234         gnssInterface->injectLocation(latitudeDegrees, longitudeDegrees, accuracyMeters);
235         return true;
236     } else {
237         return false;
238     }
239 }
240 
injectTime(int64_t timeMs,int64_t timeReferenceMs,int32_t uncertaintyMs)241 Return<bool> Gnss::injectTime(int64_t timeMs, int64_t timeReferenceMs,
242                               int32_t uncertaintyMs) {
243     ENTRY_LOG_CALLFLOW();
244     GnssInterface* gnssInterface = getGnssInterface();
245     if (nullptr != gnssInterface) {
246         gnssInterface->injectTime(timeMs, timeReferenceMs, uncertaintyMs);
247         return true;
248     } else {
249         return false;
250     }
251 }
252 
deleteAidingData(IGnss::GnssAidingData aidingDataFlags)253 Return<void> Gnss::deleteAidingData(IGnss::GnssAidingData aidingDataFlags)  {
254     ENTRY_LOG_CALLFLOW();
255     GnssAPIClient* api = getApi();
256     if (api) {
257         api->gnssDeleteAidingData(aidingDataFlags);
258     }
259     return Void();
260 }
261 
setPositionMode(IGnss::GnssPositionMode mode,IGnss::GnssPositionRecurrence recurrence,uint32_t minIntervalMs,uint32_t preferredAccuracyMeters,uint32_t preferredTimeMs)262 Return<bool> Gnss::setPositionMode(IGnss::GnssPositionMode mode,
263                                    IGnss::GnssPositionRecurrence recurrence,
264                                    uint32_t minIntervalMs,
265                                    uint32_t preferredAccuracyMeters,
266                                    uint32_t preferredTimeMs)  {
267     ENTRY_LOG_CALLFLOW();
268     bool retVal = false;
269     GnssAPIClient* api = getApi();
270     if (api) {
271         retVal = api->gnssSetPositionMode(mode, recurrence, minIntervalMs,
272                 preferredAccuracyMeters, preferredTimeMs);
273     }
274     return retVal;
275 }
276 
getExtensionAGnss()277 Return<sp<IAGnss>> Gnss::getExtensionAGnss()  {
278     ENTRY_LOG_CALLFLOW();
279     mAGnssIface = new AGnss(this);
280     return mAGnssIface;
281 }
282 
getExtensionGnssNi()283 Return<sp<IGnssNi>> Gnss::getExtensionGnssNi()  {
284     ENTRY_LOG_CALLFLOW();
285     mGnssNi = new GnssNi(this);
286     return mGnssNi;
287 }
288 
getExtensionGnssMeasurement()289 Return<sp<IGnssMeasurement>> Gnss::getExtensionGnssMeasurement() {
290     ENTRY_LOG_CALLFLOW();
291     mGnssMeasurement = new GnssMeasurement();
292     return mGnssMeasurement;
293 }
294 
getExtensionGnssConfiguration()295 Return<sp<IGnssConfiguration>> Gnss::getExtensionGnssConfiguration()  {
296     ENTRY_LOG_CALLFLOW();
297     mGnssConfig = new GnssConfiguration(this);
298     return mGnssConfig;
299 }
300 
getExtensionGnssGeofencing()301 Return<sp<IGnssGeofencing>> Gnss::getExtensionGnssGeofencing()  {
302     ENTRY_LOG_CALLFLOW();
303     mGnssGeofencingIface = new GnssGeofencing();
304     return mGnssGeofencingIface;
305 }
306 
getExtensionGnssBatching()307 Return<sp<IGnssBatching>> Gnss::getExtensionGnssBatching()  {
308     mGnssBatching = new GnssBatching();
309     return mGnssBatching;
310 }
311 
HIDL_FETCH_IGnss(const char * hal)312 IGnss* HIDL_FETCH_IGnss(const char* hal) {
313     ENTRY_LOG_CALLFLOW();
314     IGnss* iface = nullptr;
315     iface = new Gnss();
316     if (iface == nullptr) {
317         LOC_LOGE("%s]: failed to get %s", __FUNCTION__, hal);
318     }
319     return iface;
320 }
321 
322 }  // namespace implementation
323 }  // namespace V1_0
324 }  // namespace gnss
325 }  // namespace hardware
326 }  // namespace android
327