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