1 /*
2 * Copyright (c) 2017-2018, 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 #define LOG_NDEBUG 0
23
24 #include <fstream>
25 #include <log_util.h>
26 #include <dlfcn.h>
27 #include <cutils/properties.h>
28 #include "Gnss.h"
29 #include <LocationUtil.h>
30
31 #include "battery_listener.h"
32
33 typedef const GnssInterface* (getLocationInterface)();
34
35 #define IMAGES_INFO_FILE "/sys/devices/soc0/images"
36 #define DELIMITER ";"
37
38 namespace android {
39 namespace hardware {
40 namespace gnss {
41 namespace V1_1 {
42 namespace implementation {
43
44 static sp<Gnss> sGnss;
getVersionString()45 static std::string getVersionString() {
46 static std::string version;
47 if (!version.empty())
48 return version;
49
50 char value[PROPERTY_VALUE_MAX] = {0};
51 property_get("ro.hardware", value, "unknown");
52 version.append(value).append(DELIMITER);
53
54 std::ifstream in(IMAGES_INFO_FILE);
55 std::string s;
56 while(getline(in, s)) {
57 std::size_t found = s.find("CRM:");
58 if (std::string::npos == found) {
59 continue;
60 }
61
62 // skip over space characters after "CRM:"
63 const char* substr = s.c_str();
64 found += 4;
65 while (0 != substr[found] && isspace(substr[found])) {
66 found++;
67 }
68 if (s.find("11:") != found) {
69 continue;
70 }
71 s.erase(0, found + 3);
72
73 found = s.find_first_of("\r\n");
74 if (std::string::npos != found) {
75 s.erase(s.begin() + found, s.end());
76 }
77 version.append(s).append(DELIMITER);
78 }
79 return version;
80 }
81
serviceDied(uint64_t cookie,const wp<IBase> & who)82 void Gnss::GnssDeathRecipient::serviceDied(uint64_t cookie, const wp<IBase>& who) {
83 LOC_LOGE("%s] service died. cookie: %llu, who: %p",
84 __FUNCTION__, static_cast<unsigned long long>(cookie), &who);
85 if (mGnss != nullptr) {
86 mGnss->stop();
87 mGnss->cleanup();
88 }
89 }
90
location_on_battery_status_changed(bool charging)91 void location_on_battery_status_changed(bool charging) {
92 LOC_LOGd("battery status changed to %s charging", charging ? "" : "not");
93 if (sGnss != nullptr) {
94 sGnss->getGnssInterface()->updateBatteryStatus(charging);
95 }
96 }
Gnss()97 Gnss::Gnss() {
98 ENTRY_LOG_CALLFLOW();
99 sGnss = this;
100 // initilize gnss interface at first in case needing notify battery status
101 sGnss->getGnssInterface()->initialize();
102 // register health client to listen on battery change
103 loc_extn_battery_properties_listener_init(location_on_battery_status_changed);
104 // clear pending GnssConfig
105 memset(&mPendingConfig, 0, sizeof(GnssConfig));
106
107 mGnssDeathRecipient = new GnssDeathRecipient(this);
108 }
109
~Gnss()110 Gnss::~Gnss() {
111 ENTRY_LOG_CALLFLOW();
112 if (mApi != nullptr) {
113 delete mApi;
114 mApi = nullptr;
115 }
116 sGnss = nullptr;
117 }
118
getApi()119 GnssAPIClient* Gnss::getApi() {
120 if (mApi == nullptr && (mGnssCbIface != nullptr || mGnssNiCbIface != nullptr)) {
121 mApi = new GnssAPIClient(mGnssCbIface, mGnssNiCbIface);
122 if (mApi == nullptr) {
123 LOC_LOGE("%s] faild to create GnssAPIClient", __FUNCTION__);
124 return mApi;
125 }
126
127 if (mPendingConfig.size == sizeof(GnssConfig)) {
128 // we have pending GnssConfig
129 mApi->gnssConfigurationUpdate(mPendingConfig);
130 // clear size to invalid mPendingConfig
131 mPendingConfig.size = 0;
132 if (mPendingConfig.assistanceServer.hostName != nullptr) {
133 free((void*)mPendingConfig.assistanceServer.hostName);
134 }
135 }
136 }
137 if (mApi == nullptr) {
138 LOC_LOGW("%s] GnssAPIClient is not ready", __FUNCTION__);
139 }
140 return mApi;
141 }
142
getGnssInterface()143 const GnssInterface* Gnss::getGnssInterface() {
144 static bool getGnssInterfaceFailed = false;
145 if (nullptr == mGnssInterface && !getGnssInterfaceFailed) {
146 LOC_LOGD("%s]: loading libgnss.so::getGnssInterface ...", __func__);
147 getLocationInterface* getter = NULL;
148 const char *error = NULL;
149 dlerror();
150 void *handle = dlopen("libgnss.so", RTLD_NOW);
151 if (NULL == handle || (error = dlerror()) != NULL) {
152 LOC_LOGW("dlopen for libgnss.so failed, error = %s", error);
153 } else {
154 getter = (getLocationInterface*)dlsym(handle, "getGnssInterface");
155 if ((error = dlerror()) != NULL) {
156 LOC_LOGW("dlsym for libgnss.so::getGnssInterface failed, error = %s", error);
157 getter = NULL;
158 }
159 }
160
161 if (NULL == getter) {
162 getGnssInterfaceFailed = true;
163 } else {
164 mGnssInterface = (const GnssInterface*)(*getter)();
165 }
166 }
167 return mGnssInterface;
168 }
169
setCallback(const sp<V1_0::IGnssCallback> & callback)170 Return<bool> Gnss::setCallback(const sp<V1_0::IGnssCallback>& callback) {
171 ENTRY_LOG_CALLFLOW();
172 if (mGnssCbIface != nullptr) {
173 mGnssCbIface->unlinkToDeath(mGnssDeathRecipient);
174 }
175 mGnssCbIface = callback;
176 if (mGnssCbIface != nullptr) {
177 mGnssCbIface->linkToDeath(mGnssDeathRecipient, 0 /*cookie*/);
178 }
179
180 GnssAPIClient* api = getApi();
181 if (api != nullptr) {
182 api->gnssUpdateCallbacks(mGnssCbIface, mGnssNiCbIface);
183 api->gnssEnable(LOCATION_TECHNOLOGY_TYPE_GNSS);
184 api->requestCapabilities();
185 }
186 return true;
187 }
188
setGnssNiCb(const sp<IGnssNiCallback> & callback)189 Return<bool> Gnss::setGnssNiCb(const sp<IGnssNiCallback>& callback) {
190 ENTRY_LOG_CALLFLOW();
191 mGnssNiCbIface = callback;
192 GnssAPIClient* api = getApi();
193 if (api != nullptr) {
194 api->gnssUpdateCallbacks(mGnssCbIface, mGnssNiCbIface);
195 }
196 return true;
197 }
198
updateConfiguration(GnssConfig & gnssConfig)199 Return<bool> Gnss::updateConfiguration(GnssConfig& gnssConfig) {
200 ENTRY_LOG_CALLFLOW();
201 GnssAPIClient* api = getApi();
202 if (api) {
203 api->gnssConfigurationUpdate(gnssConfig);
204 } else if (gnssConfig.flags != 0) {
205 // api is not ready yet, update mPendingConfig with gnssConfig
206 mPendingConfig.size = sizeof(GnssConfig);
207
208 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT) {
209 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT;
210 mPendingConfig.gpsLock = gnssConfig.gpsLock;
211 }
212 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT) {
213 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT;
214 mPendingConfig.suplVersion = gnssConfig.suplVersion;
215 }
216 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT) {
217 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT;
218 mPendingConfig.assistanceServer.size = sizeof(GnssConfigSetAssistanceServer);
219 mPendingConfig.assistanceServer.type = gnssConfig.assistanceServer.type;
220 if (mPendingConfig.assistanceServer.hostName != nullptr) {
221 free((void*)mPendingConfig.assistanceServer.hostName);
222 mPendingConfig.assistanceServer.hostName =
223 strdup(gnssConfig.assistanceServer.hostName);
224 }
225 mPendingConfig.assistanceServer.port = gnssConfig.assistanceServer.port;
226 }
227 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT) {
228 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT;
229 mPendingConfig.lppProfile = gnssConfig.lppProfile;
230 }
231 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT) {
232 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT;
233 mPendingConfig.lppeControlPlaneMask = gnssConfig.lppeControlPlaneMask;
234 }
235 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT) {
236 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT;
237 mPendingConfig.lppeUserPlaneMask = gnssConfig.lppeUserPlaneMask;
238 }
239 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT) {
240 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT;
241 mPendingConfig.aGlonassPositionProtocolMask = gnssConfig.aGlonassPositionProtocolMask;
242 }
243 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT) {
244 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT;
245 mPendingConfig.emergencyPdnForEmergencySupl = gnssConfig.emergencyPdnForEmergencySupl;
246 }
247 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT) {
248 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT;
249 mPendingConfig.suplEmergencyServices = gnssConfig.suplEmergencyServices;
250 }
251 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_MODE_BIT) {
252 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_MODE_BIT;
253 mPendingConfig.suplModeMask = gnssConfig.suplModeMask;
254 }
255 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT) {
256 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT;
257 mPendingConfig.blacklistedSvIds = gnssConfig.blacklistedSvIds;
258 }
259 }
260 return true;
261 }
262
start()263 Return<bool> Gnss::start() {
264 ENTRY_LOG_CALLFLOW();
265 bool retVal = false;
266 GnssAPIClient* api = getApi();
267 if (api) {
268 retVal = api->gnssStart();
269 }
270 return retVal;
271 }
272
stop()273 Return<bool> Gnss::stop() {
274 ENTRY_LOG_CALLFLOW();
275 bool retVal = false;
276 GnssAPIClient* api = getApi();
277 if (api) {
278 retVal = api->gnssStop();
279 }
280 return retVal;
281 }
282
cleanup()283 Return<void> Gnss::cleanup() {
284 ENTRY_LOG_CALLFLOW();
285
286 if (mApi != nullptr) {
287 mApi->gnssDisable();
288 }
289
290 return Void();
291 }
292
injectLocation(double latitudeDegrees,double longitudeDegrees,float accuracyMeters)293 Return<bool> Gnss::injectLocation(double latitudeDegrees,
294 double longitudeDegrees,
295 float accuracyMeters) {
296 ENTRY_LOG_CALLFLOW();
297 const GnssInterface* gnssInterface = getGnssInterface();
298 if (nullptr != gnssInterface) {
299 gnssInterface->injectLocation(latitudeDegrees, longitudeDegrees, accuracyMeters);
300 return true;
301 } else {
302 return false;
303 }
304 }
305
injectTime(int64_t timeMs,int64_t timeReferenceMs,int32_t uncertaintyMs)306 Return<bool> Gnss::injectTime(int64_t timeMs, int64_t timeReferenceMs,
307 int32_t uncertaintyMs) {
308 return true;
309 }
310
deleteAidingData(V1_0::IGnss::GnssAidingData aidingDataFlags)311 Return<void> Gnss::deleteAidingData(V1_0::IGnss::GnssAidingData aidingDataFlags) {
312 ENTRY_LOG_CALLFLOW();
313 GnssAPIClient* api = getApi();
314 if (api) {
315 api->gnssDeleteAidingData(aidingDataFlags);
316 }
317 return Void();
318 }
319
setPositionMode(V1_0::IGnss::GnssPositionMode mode,V1_0::IGnss::GnssPositionRecurrence recurrence,uint32_t minIntervalMs,uint32_t preferredAccuracyMeters,uint32_t preferredTimeMs)320 Return<bool> Gnss::setPositionMode(V1_0::IGnss::GnssPositionMode mode,
321 V1_0::IGnss::GnssPositionRecurrence recurrence,
322 uint32_t minIntervalMs,
323 uint32_t preferredAccuracyMeters,
324 uint32_t preferredTimeMs) {
325 ENTRY_LOG_CALLFLOW();
326 bool retVal = false;
327 GnssAPIClient* api = getApi();
328 if (api) {
329 retVal = api->gnssSetPositionMode(mode, recurrence, minIntervalMs,
330 preferredAccuracyMeters, preferredTimeMs);
331 }
332 return retVal;
333 }
334
getExtensionAGnss()335 Return<sp<V1_0::IAGnss>> Gnss::getExtensionAGnss() {
336 ENTRY_LOG_CALLFLOW();
337 mAGnssIface = new AGnss(this);
338 return mAGnssIface;
339 }
340
getExtensionGnssNi()341 Return<sp<V1_0::IGnssNi>> Gnss::getExtensionGnssNi() {
342 ENTRY_LOG_CALLFLOW();
343 mGnssNi = new GnssNi(this);
344 return mGnssNi;
345 }
346
getExtensionGnssMeasurement()347 Return<sp<V1_0::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement() {
348 ENTRY_LOG_CALLFLOW();
349 if (mGnssMeasurement == nullptr)
350 mGnssMeasurement = new GnssMeasurement();
351 return mGnssMeasurement;
352 }
353
getExtensionGnssConfiguration()354 Return<sp<V1_0::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration() {
355 ENTRY_LOG_CALLFLOW();
356 mGnssConfig = new GnssConfiguration(this);
357 return mGnssConfig;
358 }
359
getExtensionGnssGeofencing()360 Return<sp<V1_0::IGnssGeofencing>> Gnss::getExtensionGnssGeofencing() {
361 ENTRY_LOG_CALLFLOW();
362 mGnssGeofencingIface = new GnssGeofencing();
363 return mGnssGeofencingIface;
364 }
365
getExtensionGnssBatching()366 Return<sp<V1_0::IGnssBatching>> Gnss::getExtensionGnssBatching() {
367 mGnssBatching = new GnssBatching();
368 return mGnssBatching;
369 }
370
getExtensionGnssDebug()371 Return<sp<V1_0::IGnssDebug>> Gnss::getExtensionGnssDebug() {
372 ENTRY_LOG_CALLFLOW();
373 mGnssDebug = new GnssDebug(this);
374 return mGnssDebug;
375 }
376
getExtensionAGnssRil()377 Return<sp<V1_0::IAGnssRil>> Gnss::getExtensionAGnssRil() {
378 mGnssRil = new AGnssRil(this);
379 return mGnssRil;
380 }
381
382 // Methods from ::android::hardware::gnss::V1_1::IGnss follow.
setCallback_1_1(const sp<V1_1::IGnssCallback> & callback)383 Return<bool> Gnss::setCallback_1_1(const sp<V1_1::IGnssCallback>& callback) {
384 ENTRY_LOG_CALLFLOW();
385 callback->gnssNameCb(getVersionString());
386 mGnssCbIface_1_1 = callback;
387 const GnssInterface* gnssInterface = getGnssInterface();
388 if (nullptr != gnssInterface) {
389 OdcpiRequestCallback cb = [this](const OdcpiRequestInfo& odcpiRequest) {
390 odcpiRequestCb(odcpiRequest);
391 };
392 gnssInterface->odcpiInit(cb);
393 }
394 return setCallback(callback);
395 }
396
setPositionMode_1_1(V1_0::IGnss::GnssPositionMode mode,V1_0::IGnss::GnssPositionRecurrence recurrence,uint32_t minIntervalMs,uint32_t preferredAccuracyMeters,uint32_t preferredTimeMs,bool lowPowerMode)397 Return<bool> Gnss::setPositionMode_1_1(V1_0::IGnss::GnssPositionMode mode,
398 V1_0::IGnss::GnssPositionRecurrence recurrence,
399 uint32_t minIntervalMs,
400 uint32_t preferredAccuracyMeters,
401 uint32_t preferredTimeMs,
402 bool lowPowerMode) {
403 ENTRY_LOG_CALLFLOW();
404 bool retVal = false;
405 GnssAPIClient* api = getApi();
406 if (api) {
407 GnssPowerMode powerMode = lowPowerMode?
408 GNSS_POWER_MODE_M4 : GNSS_POWER_MODE_M2;
409 retVal = api->gnssSetPositionMode(mode, recurrence, minIntervalMs,
410 preferredAccuracyMeters, preferredTimeMs, powerMode, minIntervalMs);
411 }
412 return retVal;
413 }
414
getExtensionGnssMeasurement_1_1()415 Return<sp<V1_1::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement_1_1() {
416 ENTRY_LOG_CALLFLOW();
417 if (mGnssMeasurement == nullptr)
418 mGnssMeasurement = new GnssMeasurement();
419 return mGnssMeasurement;
420 }
421
getExtensionGnssConfiguration_1_1()422 Return<sp<V1_1::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration_1_1() {
423 ENTRY_LOG_CALLFLOW();
424 if (mGnssConfig == nullptr)
425 mGnssConfig = new GnssConfiguration(this);
426 return mGnssConfig;
427 }
428
injectBestLocation(const GnssLocation & gnssLocation)429 Return<bool> Gnss::injectBestLocation(const GnssLocation& gnssLocation) {
430 ENTRY_LOG_CALLFLOW();
431 const GnssInterface* gnssInterface = getGnssInterface();
432 if (nullptr != gnssInterface) {
433 Location location = {};
434 convertGnssLocation(gnssLocation, location);
435 gnssInterface->odcpiInject(location);
436 }
437 return true;
438 }
439
odcpiRequestCb(const OdcpiRequestInfo & request)440 void Gnss::odcpiRequestCb(const OdcpiRequestInfo& request) {
441 ENTRY_LOG_CALLFLOW();
442 if (mGnssCbIface_1_1 != nullptr) {
443 // For emergency mode, request DBH (Device based hybrid) location
444 // Mark Independent from GNSS flag to false.
445 if (ODCPI_REQUEST_TYPE_START == request.type) {
446 auto r = mGnssCbIface_1_1->gnssRequestLocationCb(!request.isEmergencyMode);
447 if (!r.isOk()) {
448 LOC_LOGe("Error invoking gnssRequestLocationCb %s", r.description().c_str());
449 }
450 } else {
451 LOC_LOGv("Unsupported ODCPI request type: %d", request.type);
452 }
453 } else {
454 LOC_LOGe("ODCPI request not supported.");
455 }
456 }
457
HIDL_FETCH_IGnss(const char * hal)458 V1_0::IGnss* HIDL_FETCH_IGnss(const char* hal) {
459 ENTRY_LOG_CALLFLOW();
460 V1_0::IGnss* iface = nullptr;
461 iface = new Gnss();
462 if (iface == nullptr) {
463 LOC_LOGE("%s]: failed to get %s", __FUNCTION__, hal);
464 }
465 return iface;
466 }
467
468 } // namespace implementation
469 } // namespace V1_1
470 } // namespace gnss
471 } // namespace hardware
472 } // namespace android
473