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