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;
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 }
125 return true;
126 }
127
setGnssNiCb(const sp<IGnssNiCallback> & callback)128 Return<bool> Gnss::setGnssNiCb(const sp<IGnssNiCallback>& callback) {
129 ENTRY_LOG_CALLFLOW();
130 mGnssNiCbIface = callback;
131 GnssAPIClient* api = getApi();
132 if (api != nullptr) {
133 api->gnssUpdateCallbacks(mGnssCbIface, mGnssNiCbIface);
134 }
135 return true;
136 }
137
updateConfiguration(GnssConfig & gnssConfig)138 Return<bool> Gnss::updateConfiguration(GnssConfig& gnssConfig) {
139 ENTRY_LOG_CALLFLOW();
140 GnssAPIClient* api = getApi();
141 if (api) {
142 api->locAPIGnssUpdateConfig(gnssConfig);
143 } else if (gnssConfig.flags != 0) {
144 // api is not ready yet, update mPendingConfig with gnssConfig
145 mPendingConfig.size = sizeof(GnssConfig);
146
147 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT) {
148 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT;
149 mPendingConfig.gpsLock = gnssConfig.gpsLock;
150 }
151 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT) {
152 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT;
153 mPendingConfig.suplVersion = gnssConfig.suplVersion;
154 }
155 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT) {
156 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT;
157 mPendingConfig.assistanceServer.size = sizeof(GnssConfigSetAssistanceServer);
158 mPendingConfig.assistanceServer.type = gnssConfig.assistanceServer.type;
159 if (mPendingConfig.assistanceServer.hostName != nullptr) {
160 free((void*)mPendingConfig.assistanceServer.hostName);
161 mPendingConfig.assistanceServer.hostName =
162 strdup(gnssConfig.assistanceServer.hostName);
163 }
164 mPendingConfig.assistanceServer.port = gnssConfig.assistanceServer.port;
165 }
166 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT) {
167 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT;
168 mPendingConfig.lppProfile = gnssConfig.lppProfile;
169 }
170 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT) {
171 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT;
172 mPendingConfig.lppeControlPlaneMask = gnssConfig.lppeControlPlaneMask;
173 }
174 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT) {
175 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT;
176 mPendingConfig.lppeUserPlaneMask = gnssConfig.lppeUserPlaneMask;
177 }
178 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT) {
179 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT;
180 mPendingConfig.aGlonassPositionProtocolMask = gnssConfig.aGlonassPositionProtocolMask;
181 }
182 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT) {
183 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT;
184 mPendingConfig.emergencyPdnForEmergencySupl = gnssConfig.emergencyPdnForEmergencySupl;
185 }
186 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT) {
187 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT;
188 mPendingConfig.suplEmergencyServices = gnssConfig.suplEmergencyServices;
189 }
190 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_MODE_BIT) {
191 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_MODE_BIT;
192 mPendingConfig.suplModeMask = gnssConfig.suplModeMask;
193 }
194 }
195 return true;
196 }
197
start()198 Return<bool> Gnss::start() {
199 ENTRY_LOG_CALLFLOW();
200 bool retVal = false;
201 GnssAPIClient* api = getApi();
202 if (api) {
203 retVal = api->gnssStart();
204 }
205 return retVal;
206 }
207
stop()208 Return<bool> Gnss::stop() {
209 ENTRY_LOG_CALLFLOW();
210 bool retVal = false;
211 GnssAPIClient* api = getApi();
212 if (api) {
213 retVal = api->gnssStop();
214 }
215 return retVal;
216 }
217
cleanup()218 Return<void> Gnss::cleanup() {
219 ENTRY_LOG_CALLFLOW();
220
221 if (mApi != nullptr) {
222 mApi->locAPIDisable();
223 }
224
225 return Void();
226 }
227
injectLocation(double latitudeDegrees,double longitudeDegrees,float accuracyMeters)228 Return<bool> Gnss::injectLocation(double latitudeDegrees,
229 double longitudeDegrees,
230 float accuracyMeters) {
231 ENTRY_LOG_CALLFLOW();
232 GnssInterface* gnssInterface = getGnssInterface();
233 if (nullptr != gnssInterface) {
234 gnssInterface->injectLocation(latitudeDegrees, longitudeDegrees, accuracyMeters);
235 return true;
236 } else {
237 return false;
238 }
239 }
240
injectTime(int64_t timeMs,int64_t timeReferenceMs,int32_t uncertaintyMs)241 Return<bool> Gnss::injectTime(int64_t timeMs, int64_t timeReferenceMs,
242 int32_t uncertaintyMs) {
243 ENTRY_LOG_CALLFLOW();
244 GnssInterface* gnssInterface = getGnssInterface();
245 if (nullptr != gnssInterface) {
246 gnssInterface->injectTime(timeMs, timeReferenceMs, uncertaintyMs);
247 return true;
248 } else {
249 return false;
250 }
251 }
252
deleteAidingData(IGnss::GnssAidingData aidingDataFlags)253 Return<void> Gnss::deleteAidingData(IGnss::GnssAidingData aidingDataFlags) {
254 ENTRY_LOG_CALLFLOW();
255 GnssAPIClient* api = getApi();
256 if (api) {
257 api->gnssDeleteAidingData(aidingDataFlags);
258 }
259 return Void();
260 }
261
setPositionMode(IGnss::GnssPositionMode mode,IGnss::GnssPositionRecurrence recurrence,uint32_t minIntervalMs,uint32_t preferredAccuracyMeters,uint32_t preferredTimeMs)262 Return<bool> Gnss::setPositionMode(IGnss::GnssPositionMode mode,
263 IGnss::GnssPositionRecurrence recurrence,
264 uint32_t minIntervalMs,
265 uint32_t preferredAccuracyMeters,
266 uint32_t preferredTimeMs) {
267 ENTRY_LOG_CALLFLOW();
268 bool retVal = false;
269 GnssAPIClient* api = getApi();
270 if (api) {
271 retVal = api->gnssSetPositionMode(mode, recurrence, minIntervalMs,
272 preferredAccuracyMeters, preferredTimeMs);
273 }
274 return retVal;
275 }
276
getExtensionAGnss()277 Return<sp<IAGnss>> Gnss::getExtensionAGnss() {
278 ENTRY_LOG_CALLFLOW();
279 mAGnssIface = new AGnss(this);
280 return mAGnssIface;
281 }
282
getExtensionGnssNi()283 Return<sp<IGnssNi>> Gnss::getExtensionGnssNi() {
284 ENTRY_LOG_CALLFLOW();
285 mGnssNi = new GnssNi(this);
286 return mGnssNi;
287 }
288
getExtensionGnssMeasurement()289 Return<sp<IGnssMeasurement>> Gnss::getExtensionGnssMeasurement() {
290 ENTRY_LOG_CALLFLOW();
291 mGnssMeasurement = new GnssMeasurement();
292 return mGnssMeasurement;
293 }
294
getExtensionGnssConfiguration()295 Return<sp<IGnssConfiguration>> Gnss::getExtensionGnssConfiguration() {
296 ENTRY_LOG_CALLFLOW();
297 mGnssConfig = new GnssConfiguration(this);
298 return mGnssConfig;
299 }
300
getExtensionGnssGeofencing()301 Return<sp<IGnssGeofencing>> Gnss::getExtensionGnssGeofencing() {
302 ENTRY_LOG_CALLFLOW();
303 mGnssGeofencingIface = new GnssGeofencing();
304 return mGnssGeofencingIface;
305 }
306
getExtensionGnssBatching()307 Return<sp<IGnssBatching>> Gnss::getExtensionGnssBatching() {
308 mGnssBatching = new GnssBatching();
309 return mGnssBatching;
310 }
311
HIDL_FETCH_IGnss(const char * hal)312 IGnss* HIDL_FETCH_IGnss(const char* hal) {
313 ENTRY_LOG_CALLFLOW();
314 IGnss* iface = nullptr;
315 iface = new Gnss();
316 if (iface == nullptr) {
317 LOC_LOGE("%s]: failed to get %s", __FUNCTION__, hal);
318 }
319 return iface;
320 }
321
322 } // namespace implementation
323 } // namespace V1_0
324 } // namespace gnss
325 } // namespace hardware
326 } // namespace android
327