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