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     // register health client to listen on battery change
101     loc_extn_battery_properties_listener_init(location_on_battery_status_changed);
102     // clear pending GnssConfig
103     memset(&mPendingConfig, 0, sizeof(GnssConfig));
104 
105     mGnssDeathRecipient = new GnssDeathRecipient(this);
106 }
107 
~Gnss()108 Gnss::~Gnss() {
109     ENTRY_LOG_CALLFLOW();
110     if (mApi != nullptr) {
111         delete mApi;
112         mApi = nullptr;
113     }
114     sGnss = nullptr;
115 }
116 
getApi()117 GnssAPIClient* Gnss::getApi() {
118     if (mApi == nullptr && (mGnssCbIface != nullptr || mGnssNiCbIface != nullptr)) {
119         mApi = new GnssAPIClient(mGnssCbIface, mGnssNiCbIface);
120         if (mApi == nullptr) {
121             LOC_LOGE("%s] faild to create GnssAPIClient", __FUNCTION__);
122             return mApi;
123         }
124 
125         if (mPendingConfig.size == sizeof(GnssConfig)) {
126             // we have pending GnssConfig
127             mApi->gnssConfigurationUpdate(mPendingConfig);
128             // clear size to invalid mPendingConfig
129             mPendingConfig.size = 0;
130             if (mPendingConfig.assistanceServer.hostName != nullptr) {
131                 free((void*)mPendingConfig.assistanceServer.hostName);
132             }
133         }
134     }
135     if (mApi == nullptr) {
136         LOC_LOGW("%s] GnssAPIClient is not ready", __FUNCTION__);
137     }
138     return mApi;
139 }
140 
getGnssInterface()141 const GnssInterface* Gnss::getGnssInterface() {
142     static bool getGnssInterfaceFailed = false;
143     if (nullptr == mGnssInterface && !getGnssInterfaceFailed) {
144         LOC_LOGD("%s]: loading libgnss.so::getGnssInterface ...", __func__);
145         getLocationInterface* getter = NULL;
146         const char *error = NULL;
147         dlerror();
148         void *handle = dlopen("libgnss.so", RTLD_NOW);
149         if (NULL == handle || (error = dlerror()) != NULL)  {
150             LOC_LOGW("dlopen for libgnss.so failed, error = %s", error);
151         } else {
152             getter = (getLocationInterface*)dlsym(handle, "getGnssInterface");
153             if ((error = dlerror()) != NULL)  {
154                 LOC_LOGW("dlsym for libgnss.so::getGnssInterface failed, error = %s", error);
155                 getter = NULL;
156             }
157         }
158 
159         if (NULL == getter) {
160             getGnssInterfaceFailed = true;
161         } else {
162             mGnssInterface = (const GnssInterface*)(*getter)();
163         }
164     }
165     return mGnssInterface;
166 }
167 
setCallback(const sp<V1_0::IGnssCallback> & callback)168 Return<bool> Gnss::setCallback(const sp<V1_0::IGnssCallback>& callback)  {
169     ENTRY_LOG_CALLFLOW();
170     if (mGnssCbIface != nullptr) {
171         mGnssCbIface->unlinkToDeath(mGnssDeathRecipient);
172     }
173     mGnssCbIface = callback;
174     if (mGnssCbIface != nullptr) {
175         mGnssCbIface->linkToDeath(mGnssDeathRecipient, 0 /*cookie*/);
176     }
177 
178     GnssAPIClient* api = getApi();
179     if (api != nullptr) {
180         api->gnssUpdateCallbacks(mGnssCbIface, mGnssNiCbIface);
181         api->gnssEnable(LOCATION_TECHNOLOGY_TYPE_GNSS);
182         api->requestCapabilities();
183     }
184     return true;
185 }
186 
setGnssNiCb(const sp<IGnssNiCallback> & callback)187 Return<bool> Gnss::setGnssNiCb(const sp<IGnssNiCallback>& callback) {
188     ENTRY_LOG_CALLFLOW();
189     mGnssNiCbIface = callback;
190     GnssAPIClient* api = getApi();
191     if (api != nullptr) {
192         api->gnssUpdateCallbacks(mGnssCbIface, mGnssNiCbIface);
193     }
194     return true;
195 }
196 
updateConfiguration(GnssConfig & gnssConfig)197 Return<bool> Gnss::updateConfiguration(GnssConfig& gnssConfig) {
198     ENTRY_LOG_CALLFLOW();
199     GnssAPIClient* api = getApi();
200     if (api) {
201         api->gnssConfigurationUpdate(gnssConfig);
202     } else if (gnssConfig.flags != 0) {
203         // api is not ready yet, update mPendingConfig with gnssConfig
204         mPendingConfig.size = sizeof(GnssConfig);
205 
206         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT) {
207             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT;
208             mPendingConfig.gpsLock = gnssConfig.gpsLock;
209         }
210         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT) {
211             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT;
212             mPendingConfig.suplVersion = gnssConfig.suplVersion;
213         }
214         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT) {
215             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT;
216             mPendingConfig.assistanceServer.size = sizeof(GnssConfigSetAssistanceServer);
217             mPendingConfig.assistanceServer.type = gnssConfig.assistanceServer.type;
218             if (mPendingConfig.assistanceServer.hostName != nullptr) {
219                 free((void*)mPendingConfig.assistanceServer.hostName);
220                 mPendingConfig.assistanceServer.hostName =
221                     strdup(gnssConfig.assistanceServer.hostName);
222             }
223             mPendingConfig.assistanceServer.port = gnssConfig.assistanceServer.port;
224         }
225         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT) {
226             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT;
227             mPendingConfig.lppProfile = gnssConfig.lppProfile;
228         }
229         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT) {
230             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT;
231             mPendingConfig.lppeControlPlaneMask = gnssConfig.lppeControlPlaneMask;
232         }
233         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT) {
234             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT;
235             mPendingConfig.lppeUserPlaneMask = gnssConfig.lppeUserPlaneMask;
236         }
237         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT) {
238             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT;
239             mPendingConfig.aGlonassPositionProtocolMask = gnssConfig.aGlonassPositionProtocolMask;
240         }
241         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT) {
242             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT;
243             mPendingConfig.emergencyPdnForEmergencySupl = gnssConfig.emergencyPdnForEmergencySupl;
244         }
245         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT) {
246             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT;
247             mPendingConfig.suplEmergencyServices = gnssConfig.suplEmergencyServices;
248         }
249         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_MODE_BIT) {
250             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_MODE_BIT;
251             mPendingConfig.suplModeMask = gnssConfig.suplModeMask;
252         }
253         if (gnssConfig.flags & GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT) {
254             mPendingConfig.flags |= GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT;
255             mPendingConfig.blacklistedSvIds = gnssConfig.blacklistedSvIds;
256         }
257     }
258     return true;
259 }
260 
start()261 Return<bool> Gnss::start()  {
262     ENTRY_LOG_CALLFLOW();
263     bool retVal = false;
264     GnssAPIClient* api = getApi();
265     if (api) {
266         retVal = api->gnssStart();
267     }
268     return retVal;
269 }
270 
stop()271 Return<bool> Gnss::stop()  {
272     ENTRY_LOG_CALLFLOW();
273     bool retVal = false;
274     GnssAPIClient* api = getApi();
275     if (api) {
276         retVal = api->gnssStop();
277     }
278     return retVal;
279 }
280 
cleanup()281 Return<void> Gnss::cleanup()  {
282     ENTRY_LOG_CALLFLOW();
283 
284     if (mApi != nullptr) {
285         mApi->gnssDisable();
286     }
287 
288     return Void();
289 }
290 
injectLocation(double latitudeDegrees,double longitudeDegrees,float accuracyMeters)291 Return<bool> Gnss::injectLocation(double latitudeDegrees,
292                                   double longitudeDegrees,
293                                   float accuracyMeters)  {
294     ENTRY_LOG_CALLFLOW();
295     const GnssInterface* gnssInterface = getGnssInterface();
296     if (nullptr != gnssInterface) {
297         gnssInterface->injectLocation(latitudeDegrees, longitudeDegrees, accuracyMeters);
298         return true;
299     } else {
300         return false;
301     }
302 }
303 
injectTime(int64_t timeMs,int64_t timeReferenceMs,int32_t uncertaintyMs)304 Return<bool> Gnss::injectTime(int64_t timeMs, int64_t timeReferenceMs,
305                               int32_t uncertaintyMs) {
306     ENTRY_LOG_CALLFLOW();
307     const GnssInterface* gnssInterface = getGnssInterface();
308     if (nullptr != gnssInterface) {
309         gnssInterface->injectTime(timeMs, timeReferenceMs, uncertaintyMs);
310         return true;
311     } else {
312         return false;
313     }
314 }
315 
deleteAidingData(V1_0::IGnss::GnssAidingData aidingDataFlags)316 Return<void> Gnss::deleteAidingData(V1_0::IGnss::GnssAidingData aidingDataFlags)  {
317     ENTRY_LOG_CALLFLOW();
318     GnssAPIClient* api = getApi();
319     if (api) {
320         api->gnssDeleteAidingData(aidingDataFlags);
321     }
322     return Void();
323 }
324 
setPositionMode(V1_0::IGnss::GnssPositionMode mode,V1_0::IGnss::GnssPositionRecurrence recurrence,uint32_t minIntervalMs,uint32_t preferredAccuracyMeters,uint32_t preferredTimeMs)325 Return<bool> Gnss::setPositionMode(V1_0::IGnss::GnssPositionMode mode,
326                                    V1_0::IGnss::GnssPositionRecurrence recurrence,
327                                    uint32_t minIntervalMs,
328                                    uint32_t preferredAccuracyMeters,
329                                    uint32_t preferredTimeMs)  {
330     ENTRY_LOG_CALLFLOW();
331     bool retVal = false;
332     GnssAPIClient* api = getApi();
333     if (api) {
334         retVal = api->gnssSetPositionMode(mode, recurrence, minIntervalMs,
335                 preferredAccuracyMeters, preferredTimeMs);
336     }
337     return retVal;
338 }
339 
getExtensionAGnss()340 Return<sp<V1_0::IAGnss>> Gnss::getExtensionAGnss()  {
341     ENTRY_LOG_CALLFLOW();
342     mAGnssIface = new AGnss(this);
343     return mAGnssIface;
344 }
345 
getExtensionGnssNi()346 Return<sp<V1_0::IGnssNi>> Gnss::getExtensionGnssNi()  {
347     ENTRY_LOG_CALLFLOW();
348     mGnssNi = new GnssNi(this);
349     return mGnssNi;
350 }
351 
getExtensionGnssMeasurement()352 Return<sp<V1_0::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement() {
353     ENTRY_LOG_CALLFLOW();
354     if (mGnssMeasurement == nullptr)
355         mGnssMeasurement = new GnssMeasurement();
356     return mGnssMeasurement;
357 }
358 
getExtensionGnssConfiguration()359 Return<sp<V1_0::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration()  {
360     ENTRY_LOG_CALLFLOW();
361     mGnssConfig = new GnssConfiguration(this);
362     return mGnssConfig;
363 }
364 
getExtensionGnssGeofencing()365 Return<sp<V1_0::IGnssGeofencing>> Gnss::getExtensionGnssGeofencing()  {
366     ENTRY_LOG_CALLFLOW();
367     mGnssGeofencingIface = new GnssGeofencing();
368     return mGnssGeofencingIface;
369 }
370 
getExtensionGnssBatching()371 Return<sp<V1_0::IGnssBatching>> Gnss::getExtensionGnssBatching()  {
372     mGnssBatching = new GnssBatching();
373     return mGnssBatching;
374 }
375 
getExtensionGnssDebug()376 Return<sp<V1_0::IGnssDebug>> Gnss::getExtensionGnssDebug() {
377     ENTRY_LOG_CALLFLOW();
378     mGnssDebug = new GnssDebug(this);
379     return mGnssDebug;
380 }
381 
getExtensionAGnssRil()382 Return<sp<V1_0::IAGnssRil>> Gnss::getExtensionAGnssRil() {
383     mGnssRil = new AGnssRil(this);
384     return mGnssRil;
385 }
386 
387 // Methods from ::android::hardware::gnss::V1_1::IGnss follow.
setCallback_1_1(const sp<V1_1::IGnssCallback> & callback)388 Return<bool> Gnss::setCallback_1_1(const sp<V1_1::IGnssCallback>& callback) {
389     ENTRY_LOG_CALLFLOW();
390     callback->gnssNameCb(getVersionString());
391     mGnssCbIface_1_1 = callback;
392     const GnssInterface* gnssInterface = getGnssInterface();
393     if (nullptr != gnssInterface) {
394         OdcpiRequestCallback cb = [this](const OdcpiRequestInfo& odcpiRequest) {
395             odcpiRequestCb(odcpiRequest);
396         };
397         gnssInterface->odcpiInit(cb);
398     }
399     return setCallback(callback);
400 }
401 
setPositionMode_1_1(V1_0::IGnss::GnssPositionMode mode,V1_0::IGnss::GnssPositionRecurrence recurrence,uint32_t minIntervalMs,uint32_t preferredAccuracyMeters,uint32_t preferredTimeMs,bool lowPowerMode)402 Return<bool> Gnss::setPositionMode_1_1(V1_0::IGnss::GnssPositionMode mode,
403         V1_0::IGnss::GnssPositionRecurrence recurrence,
404         uint32_t minIntervalMs,
405         uint32_t preferredAccuracyMeters,
406         uint32_t preferredTimeMs,
407         bool lowPowerMode) {
408     ENTRY_LOG_CALLFLOW();
409     bool retVal = false;
410     GnssAPIClient* api = getApi();
411     if (api) {
412         GnssPowerMode powerMode = lowPowerMode?
413                 GNSS_POWER_MODE_M4 : GNSS_POWER_MODE_M2;
414         retVal = api->gnssSetPositionMode(mode, recurrence, minIntervalMs,
415                 preferredAccuracyMeters, preferredTimeMs, powerMode, minIntervalMs);
416     }
417     return retVal;
418 }
419 
getExtensionGnssMeasurement_1_1()420 Return<sp<V1_1::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement_1_1() {
421     ENTRY_LOG_CALLFLOW();
422     if (mGnssMeasurement == nullptr)
423         mGnssMeasurement = new GnssMeasurement();
424     return mGnssMeasurement;
425 }
426 
getExtensionGnssConfiguration_1_1()427 Return<sp<V1_1::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration_1_1() {
428     ENTRY_LOG_CALLFLOW();
429     if (mGnssConfig == nullptr)
430         mGnssConfig = new GnssConfiguration(this);
431     return mGnssConfig;
432 }
433 
injectBestLocation(const GnssLocation & gnssLocation)434 Return<bool> Gnss::injectBestLocation(const GnssLocation& gnssLocation) {
435     ENTRY_LOG_CALLFLOW();
436     const GnssInterface* gnssInterface = getGnssInterface();
437     if (nullptr != gnssInterface) {
438         Location location = {};
439         convertGnssLocation(gnssLocation, location);
440         gnssInterface->odcpiInject(location);
441     }
442     return true;
443 }
444 
odcpiRequestCb(const OdcpiRequestInfo & request)445 void Gnss::odcpiRequestCb(const OdcpiRequestInfo& request) {
446     ENTRY_LOG_CALLFLOW();
447     if (mGnssCbIface_1_1 != nullptr) {
448         // For emergency mode, request DBH (Device based hybrid) location
449         // Mark Independent from GNSS flag to false.
450         if (ODCPI_REQUEST_TYPE_START == request.type) {
451             auto r = mGnssCbIface_1_1->gnssRequestLocationCb(!request.isEmergencyMode);
452             if (!r.isOk()) {
453                 LOC_LOGe("Error invoking gnssRequestLocationCb %s", r.description().c_str());
454             }
455         } else {
456             LOC_LOGv("Unsupported ODCPI request type: %d", request.type);
457         }
458     } else {
459         LOC_LOGe("ODCPI request not supported.");
460     }
461 }
462 
HIDL_FETCH_IGnss(const char * hal)463 V1_0::IGnss* HIDL_FETCH_IGnss(const char* hal) {
464     ENTRY_LOG_CALLFLOW();
465     V1_0::IGnss* iface = nullptr;
466     iface = new Gnss();
467     if (iface == nullptr) {
468         LOC_LOGE("%s]: failed to get %s", __FUNCTION__, hal);
469     }
470     return iface;
471 }
472 
473 }  // namespace implementation
474 }  // namespace V1_1
475 }  // namespace gnss
476 }  // namespace hardware
477 }  // namespace android
478