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 = NULL;
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         api->requestCapabilities();
125     }
126     return true;
127 }
128 
setGnssNiCb(const sp<IGnssNiCallback> & callback)129 Return<bool> Gnss::setGnssNiCb(const sp<IGnssNiCallback>& callback) {
130     ENTRY_LOG_CALLFLOW();
131     mGnssNiCbIface = callback;
132     GnssAPIClient* api = getApi();
133     if (api != nullptr) {
134         api->gnssUpdateCallbacks(mGnssCbIface, mGnssNiCbIface);
135     }
136     return true;
137 }
138 
updateConfiguration(GnssConfig & gnssConfig)139 Return<bool> Gnss::updateConfiguration(GnssConfig& gnssConfig) {
140     ENTRY_LOG_CALLFLOW();
141     GnssAPIClient* api = getApi();
142     if (api) {
143         api->locAPIGnssUpdateConfig(gnssConfig);
144     } else if (gnssConfig.flags != 0) {
145         // api is not ready yet, update mPendingConfig with gnssConfig
146         mPendingConfig.size = sizeof(GnssConfig);
147 
148         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT) {
149             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT;
150             mPendingConfig.gpsLock = gnssConfig.gpsLock;
151         }
152         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT) {
153             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT;
154             mPendingConfig.suplVersion = gnssConfig.suplVersion;
155         }
156         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT) {
157             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT;
158             mPendingConfig.assistanceServer.size = sizeof(GnssConfigSetAssistanceServer);
159             mPendingConfig.assistanceServer.type = gnssConfig.assistanceServer.type;
160             if (mPendingConfig.assistanceServer.hostName != nullptr) {
161                 free((void*)mPendingConfig.assistanceServer.hostName);
162                 mPendingConfig.assistanceServer.hostName =
163                     strdup(gnssConfig.assistanceServer.hostName);
164             }
165             mPendingConfig.assistanceServer.port = gnssConfig.assistanceServer.port;
166         }
167         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT) {
168             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT;
169             mPendingConfig.lppProfile = gnssConfig.lppProfile;
170         }
171         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT) {
172             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT;
173             mPendingConfig.lppeControlPlaneMask = gnssConfig.lppeControlPlaneMask;
174         }
175         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT) {
176             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT;
177             mPendingConfig.lppeUserPlaneMask = gnssConfig.lppeUserPlaneMask;
178         }
179         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT) {
180             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT;
181             mPendingConfig.aGlonassPositionProtocolMask = gnssConfig.aGlonassPositionProtocolMask;
182         }
183         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT) {
184             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT;
185             mPendingConfig.emergencyPdnForEmergencySupl = gnssConfig.emergencyPdnForEmergencySupl;
186         }
187         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT) {
188             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT;
189             mPendingConfig.suplEmergencyServices = gnssConfig.suplEmergencyServices;
190         }
191         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_MODE_BIT) {
192             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_MODE_BIT;
193             mPendingConfig.suplModeMask = gnssConfig.suplModeMask;
194         }
195     }
196     return true;
197 }
198 
start()199 Return<bool> Gnss::start()  {
200     ENTRY_LOG_CALLFLOW();
201     bool retVal = false;
202     GnssAPIClient* api = getApi();
203     if (api) {
204         retVal = api->gnssStart();
205     }
206     return retVal;
207 }
208 
stop()209 Return<bool> Gnss::stop()  {
210     ENTRY_LOG_CALLFLOW();
211     bool retVal = false;
212     GnssAPIClient* api = getApi();
213     if (api) {
214         retVal = api->gnssStop();
215     }
216     return retVal;
217 }
218 
cleanup()219 Return<void> Gnss::cleanup()  {
220     ENTRY_LOG_CALLFLOW();
221 
222     if (mApi != nullptr) {
223         mApi->locAPIDisable();
224     }
225 
226     return Void();
227 }
228 
injectLocation(double latitudeDegrees,double longitudeDegrees,float accuracyMeters)229 Return<bool> Gnss::injectLocation(double latitudeDegrees,
230                                   double longitudeDegrees,
231                                   float accuracyMeters)  {
232     ENTRY_LOG_CALLFLOW();
233     GnssInterface* gnssInterface = getGnssInterface();
234     if (nullptr != gnssInterface) {
235         gnssInterface->injectLocation(latitudeDegrees, longitudeDegrees, accuracyMeters);
236         return true;
237     } else {
238         return false;
239     }
240 }
241 
injectTime(int64_t timeMs,int64_t timeReferenceMs,int32_t uncertaintyMs)242 Return<bool> Gnss::injectTime(int64_t timeMs, int64_t timeReferenceMs,
243                               int32_t uncertaintyMs) {
244         return true;
245 }
246 
deleteAidingData(IGnss::GnssAidingData aidingDataFlags)247 Return<void> Gnss::deleteAidingData(IGnss::GnssAidingData aidingDataFlags)  {
248     ENTRY_LOG_CALLFLOW();
249     GnssAPIClient* api = getApi();
250     if (api) {
251         api->gnssDeleteAidingData(aidingDataFlags);
252     }
253     return Void();
254 }
255 
setPositionMode(IGnss::GnssPositionMode mode,IGnss::GnssPositionRecurrence recurrence,uint32_t minIntervalMs,uint32_t preferredAccuracyMeters,uint32_t preferredTimeMs)256 Return<bool> Gnss::setPositionMode(IGnss::GnssPositionMode mode,
257                                    IGnss::GnssPositionRecurrence recurrence,
258                                    uint32_t minIntervalMs,
259                                    uint32_t preferredAccuracyMeters,
260                                    uint32_t preferredTimeMs)  {
261     ENTRY_LOG_CALLFLOW();
262     bool retVal = false;
263     GnssAPIClient* api = getApi();
264     if (api) {
265         retVal = api->gnssSetPositionMode(mode, recurrence, minIntervalMs,
266                 preferredAccuracyMeters, preferredTimeMs);
267     }
268     return retVal;
269 }
270 
getExtensionAGnss()271 Return<sp<IAGnss>> Gnss::getExtensionAGnss()  {
272     ENTRY_LOG_CALLFLOW();
273     mAGnssIface = new AGnss(this);
274     return mAGnssIface;
275 }
276 
getExtensionGnssNi()277 Return<sp<IGnssNi>> Gnss::getExtensionGnssNi()  {
278     ENTRY_LOG_CALLFLOW();
279     mGnssNi = new GnssNi(this);
280     return mGnssNi;
281 }
282 
getExtensionGnssMeasurement()283 Return<sp<IGnssMeasurement>> Gnss::getExtensionGnssMeasurement() {
284     ENTRY_LOG_CALLFLOW();
285     mGnssMeasurement = new GnssMeasurement();
286     return mGnssMeasurement;
287 }
288 
getExtensionGnssConfiguration()289 Return<sp<IGnssConfiguration>> Gnss::getExtensionGnssConfiguration()  {
290     ENTRY_LOG_CALLFLOW();
291     mGnssConfig = new GnssConfiguration(this);
292     return mGnssConfig;
293 }
294 
getExtensionGnssGeofencing()295 Return<sp<IGnssGeofencing>> Gnss::getExtensionGnssGeofencing()  {
296     ENTRY_LOG_CALLFLOW();
297     mGnssGeofencingIface = new GnssGeofencing();
298     return mGnssGeofencingIface;
299 }
300 
getExtensionGnssBatching()301 Return<sp<IGnssBatching>> Gnss::getExtensionGnssBatching()  {
302     mGnssBatching = new GnssBatching();
303     return mGnssBatching;
304 }
305 
getExtensionGnssDebug()306 Return<sp<IGnssDebug>> Gnss::getExtensionGnssDebug() {
307     ENTRY_LOG_CALLFLOW();
308     mGnssDebug = new GnssDebug(this);
309     return mGnssDebug;
310 }
311 
getExtensionAGnssRil()312 Return<sp<IAGnssRil>> Gnss::getExtensionAGnssRil() {
313     mGnssRil = new AGnssRil(this);
314     return mGnssRil;
315 }
316 
HIDL_FETCH_IGnss(const char * hal)317 IGnss* HIDL_FETCH_IGnss(const char* hal) {
318     ENTRY_LOG_CALLFLOW();
319     IGnss* iface = nullptr;
320     iface = new Gnss();
321     if (iface == nullptr) {
322         LOC_LOGE("%s]: failed to get %s", __FUNCTION__, hal);
323     }
324     return iface;
325 }
326 
327 }  // namespace implementation
328 }  // namespace V1_0
329 }  // namespace gnss
330 }  // namespace hardware
331 }  // namespace android
332