1 /* Copyright (c) 2017, The Linux Foundation. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation, nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29
30 #define LOG_NDEBUG 0
31 #define LOG_TAG "LocSvc_GnssAPIClient"
32
33 #include <log_util.h>
34 #include <loc_cfg.h>
35
36 #include "LocationUtil.h"
37 #include "GnssAPIClient.h"
38 #include <LocDualContext.h>
39
40 namespace android {
41 namespace hardware {
42 namespace gnss {
43 namespace V1_0 {
44 namespace implementation {
45
46 static void convertGnssSvStatus(GnssSvNotification& in, IGnssCallback::GnssSvStatus& out);
47
GnssAPIClient(const sp<IGnssCallback> & gpsCb,const sp<IGnssNiCallback> & niCb)48 GnssAPIClient::GnssAPIClient(const sp<IGnssCallback>& gpsCb,
49 const sp<IGnssNiCallback>& niCb) :
50 LocationAPIClientBase(),
51 mGnssCbIface(nullptr),
52 mGnssNiCbIface(nullptr),
53 mControlClient(new LocationAPIControlClient()),
54 mLocationCapabilitiesMask(0),
55 mLocationCapabilitiesCached(false)
56 {
57 LOC_LOGD("%s]: (%p %p)", __FUNCTION__, &gpsCb, &niCb);
58
59 // set default LocationOptions.
60 memset(&mLocationOptions, 0, sizeof(LocationOptions));
61 mLocationOptions.size = sizeof(LocationOptions);
62 mLocationOptions.minInterval = 1000;
63 mLocationOptions.minDistance = 0;
64 mLocationOptions.mode = GNSS_SUPL_MODE_STANDALONE;
65
66 gnssUpdateCallbacks(gpsCb, niCb);
67 }
68
~GnssAPIClient()69 GnssAPIClient::~GnssAPIClient()
70 {
71 LOC_LOGD("%s]: ()", __FUNCTION__);
72 if (mControlClient) {
73 delete mControlClient;
74 mControlClient = nullptr;
75 }
76 }
77
78 // for GpsInterface
gnssUpdateCallbacks(const sp<IGnssCallback> & gpsCb,const sp<IGnssNiCallback> & niCb)79 void GnssAPIClient::gnssUpdateCallbacks(const sp<IGnssCallback>& gpsCb,
80 const sp<IGnssNiCallback>& niCb)
81 {
82 LOC_LOGD("%s]: (%p %p)", __FUNCTION__, &gpsCb, &niCb);
83
84 mMutex.lock();
85 mGnssCbIface = gpsCb;
86 mGnssNiCbIface = niCb;
87 mMutex.unlock();
88
89 LocationCallbacks locationCallbacks;
90 memset(&locationCallbacks, 0, sizeof(LocationCallbacks));
91 locationCallbacks.size = sizeof(LocationCallbacks);
92
93 locationCallbacks.trackingCb = nullptr;
94 if (mGnssCbIface != nullptr) {
95 locationCallbacks.trackingCb = [this](Location location) {
96 onTrackingCb(location);
97 };
98 }
99
100 locationCallbacks.batchingCb = nullptr;
101 locationCallbacks.geofenceBreachCb = nullptr;
102 locationCallbacks.geofenceStatusCb = nullptr;
103 locationCallbacks.gnssLocationInfoCb = nullptr;
104
105 locationCallbacks.gnssNiCb = nullptr;
106 loc_core::ContextBase* context =
107 loc_core::LocDualContext::getLocFgContext(
108 NULL, NULL,
109 loc_core::LocDualContext::mLocationHalName, false);
110 if (mGnssNiCbIface != nullptr && !context->hasAgpsExtendedCapabilities()) {
111 LOC_LOGD("Registering NI CB");
112 locationCallbacks.gnssNiCb = [this](uint32_t id, GnssNiNotification gnssNiNotification) {
113 onGnssNiCb(id, gnssNiNotification);
114 };
115 }
116
117 locationCallbacks.gnssSvCb = nullptr;
118 if (mGnssCbIface != nullptr) {
119 locationCallbacks.gnssSvCb = [this](GnssSvNotification gnssSvNotification) {
120 onGnssSvCb(gnssSvNotification);
121 };
122 }
123
124 locationCallbacks.gnssNmeaCb = nullptr;
125 if (mGnssCbIface != nullptr) {
126 locationCallbacks.gnssNmeaCb = [this](GnssNmeaNotification gnssNmeaNotification) {
127 onGnssNmeaCb(gnssNmeaNotification);
128 };
129 }
130
131 locationCallbacks.gnssMeasurementsCb = nullptr;
132
133 locAPISetCallbacks(locationCallbacks);
134 }
135
gnssStart()136 bool GnssAPIClient::gnssStart()
137 {
138 LOC_LOGD("%s]: ()", __FUNCTION__);
139 bool retVal = true;
140 locAPIStartTracking(mLocationOptions);
141 return retVal;
142 }
143
gnssStop()144 bool GnssAPIClient::gnssStop()
145 {
146 LOC_LOGD("%s]: ()", __FUNCTION__);
147 bool retVal = true;
148 locAPIStopTracking();
149 return retVal;
150 }
151
gnssSetPositionMode(IGnss::GnssPositionMode mode,IGnss::GnssPositionRecurrence recurrence,uint32_t minIntervalMs,uint32_t preferredAccuracyMeters,uint32_t preferredTimeMs)152 bool GnssAPIClient::gnssSetPositionMode(IGnss::GnssPositionMode mode,
153 IGnss::GnssPositionRecurrence recurrence, uint32_t minIntervalMs,
154 uint32_t preferredAccuracyMeters, uint32_t preferredTimeMs)
155 {
156 LOC_LOGD("%s]: (%d %d %d %d %d)", __FUNCTION__,
157 (int)mode, recurrence, minIntervalMs, preferredAccuracyMeters, preferredTimeMs);
158 bool retVal = true;
159 memset(&mLocationOptions, 0, sizeof(LocationOptions));
160 mLocationOptions.size = sizeof(LocationOptions);
161 mLocationOptions.minInterval = minIntervalMs;
162 mLocationOptions.minDistance = preferredAccuracyMeters;
163 if (mode == IGnss::GnssPositionMode::STANDALONE)
164 mLocationOptions.mode = GNSS_SUPL_MODE_STANDALONE;
165 else if (mode == IGnss::GnssPositionMode::MS_BASED)
166 mLocationOptions.mode = GNSS_SUPL_MODE_MSB;
167 else if (mode == IGnss::GnssPositionMode::MS_ASSISTED)
168 mLocationOptions.mode = GNSS_SUPL_MODE_MSA;
169 else {
170 LOC_LOGD("%s]: invalid GnssPositionMode: %d", __FUNCTION__, (int)mode);
171 retVal = false;
172 }
173 locAPIUpdateTrackingOptions(mLocationOptions);
174 return retVal;
175 }
176
177 // for GpsNiInterface
gnssNiRespond(int32_t notifId,IGnssNiCallback::GnssUserResponseType userResponse)178 void GnssAPIClient::gnssNiRespond(int32_t notifId,
179 IGnssNiCallback::GnssUserResponseType userResponse)
180 {
181 LOC_LOGD("%s]: (%d %d)", __FUNCTION__, notifId, static_cast<int>(userResponse));
182 GnssNiResponse data = GNSS_NI_RESPONSE_IGNORE;
183 if (userResponse == IGnssNiCallback::GnssUserResponseType::RESPONSE_ACCEPT)
184 data = GNSS_NI_RESPONSE_ACCEPT;
185 else if (userResponse == IGnssNiCallback::GnssUserResponseType::RESPONSE_DENY)
186 data = GNSS_NI_RESPONSE_DENY;
187 else if (userResponse == IGnssNiCallback::GnssUserResponseType::RESPONSE_NORESP)
188 data = GNSS_NI_RESPONSE_NO_RESPONSE;
189 else {
190 LOC_LOGD("%s]: invalid GnssUserResponseType: %d", __FUNCTION__, (int)userResponse);
191 return;
192 }
193 locAPIGnssNiResponse(notifId, data);
194 }
195
196 // these apis using LocationAPIControlClient
gnssDeleteAidingData(IGnss::GnssAidingData aidingDataFlags)197 void GnssAPIClient::gnssDeleteAidingData(IGnss::GnssAidingData aidingDataFlags)
198 {
199 LOC_LOGD("%s]: (%02hx)", __FUNCTION__, aidingDataFlags);
200 if (mControlClient == nullptr) {
201 return;
202 }
203 GnssAidingData data;
204 memset(&data, 0, sizeof (GnssAidingData));
205 data.sv.svTypeMask = GNSS_AIDING_DATA_SV_TYPE_GPS_BIT |
206 GNSS_AIDING_DATA_SV_TYPE_GLONASS_BIT |
207 GNSS_AIDING_DATA_SV_TYPE_QZSS_BIT |
208 GNSS_AIDING_DATA_SV_TYPE_BEIDOU_BIT |
209 GNSS_AIDING_DATA_SV_TYPE_GALILEO_BIT;
210
211 if (aidingDataFlags == IGnss::GnssAidingData::DELETE_ALL)
212 data.deleteAll = true;
213 else {
214 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_EPHEMERIS)
215 data.sv.svMask |= GNSS_AIDING_DATA_SV_EPHEMERIS_BIT;
216 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_ALMANAC)
217 data.sv.svMask |= GNSS_AIDING_DATA_SV_ALMANAC_BIT;
218 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_POSITION)
219 data.common.mask |= GNSS_AIDING_DATA_COMMON_POSITION_BIT;
220 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_TIME)
221 data.common.mask |= GNSS_AIDING_DATA_COMMON_TIME_BIT;
222 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_IONO)
223 data.sv.svMask |= GNSS_AIDING_DATA_SV_IONOSPHERE_BIT;
224 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_UTC)
225 data.common.mask |= GNSS_AIDING_DATA_COMMON_UTC_BIT;
226 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_HEALTH)
227 data.sv.svMask |= GNSS_AIDING_DATA_SV_HEALTH_BIT;
228 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_SVDIR)
229 data.sv.svMask |= GNSS_AIDING_DATA_SV_DIRECTION_BIT;
230 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_SVSTEER)
231 data.sv.svMask |= GNSS_AIDING_DATA_SV_STEER_BIT;
232 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_SADATA)
233 data.sv.svMask |= GNSS_AIDING_DATA_SV_SA_DATA_BIT;
234 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_RTI)
235 data.common.mask |= GNSS_AIDING_DATA_COMMON_RTI_BIT;
236 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_CELLDB_INFO)
237 data.common.mask |= GNSS_AIDING_DATA_COMMON_CELLDB_BIT;
238 }
239 mControlClient->locAPIGnssDeleteAidingData(data);
240 }
241
gnssEnable(LocationTechnologyType techType)242 void GnssAPIClient::gnssEnable(LocationTechnologyType techType)
243 {
244 LOC_LOGD("%s]: (%0d)", __FUNCTION__, techType);
245 if (mControlClient == nullptr) {
246 return;
247 }
248 mControlClient->locAPIEnable(techType);
249 }
250
gnssDisable()251 void GnssAPIClient::gnssDisable()
252 {
253 LOC_LOGD("%s]: ()", __FUNCTION__);
254 if (mControlClient == nullptr) {
255 return;
256 }
257 mControlClient->locAPIDisable();
258 }
259
gnssConfigurationUpdate(const GnssConfig & gnssConfig)260 void GnssAPIClient::gnssConfigurationUpdate(const GnssConfig& gnssConfig)
261 {
262 LOC_LOGD("%s]: (%02x)", __FUNCTION__, gnssConfig.flags);
263 if (mControlClient == nullptr) {
264 return;
265 }
266 mControlClient->locAPIGnssUpdateConfig(gnssConfig);
267 }
268
requestCapabilities()269 void GnssAPIClient::requestCapabilities() {
270 // only send capablities if it's already cached, otherwise the first time LocationAPI
271 // is initialized, capabilities will be sent by LocationAPI
272 if (mLocationCapabilitiesCached) {
273 onCapabilitiesCb(mLocationCapabilitiesMask);
274 }
275 }
276
277 // callbacks
onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)278 void GnssAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)
279 {
280 LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask);
281 mLocationCapabilitiesMask = capabilitiesMask;
282 mLocationCapabilitiesCached = true;
283
284 mMutex.lock();
285 auto gnssCbIface(mGnssCbIface);
286 mMutex.unlock();
287
288 if (gnssCbIface != nullptr) {
289 uint32_t data = 0;
290 if ((capabilitiesMask & LOCATION_CAPABILITIES_TIME_BASED_TRACKING_BIT) ||
291 (capabilitiesMask & LOCATION_CAPABILITIES_TIME_BASED_BATCHING_BIT) ||
292 (capabilitiesMask & LOCATION_CAPABILITIES_DISTANCE_BASED_TRACKING_BIT) ||
293 (capabilitiesMask & LOCATION_CAPABILITIES_DISTANCE_BASED_BATCHING_BIT))
294 data |= IGnssCallback::Capabilities::SCHEDULING;
295 if (capabilitiesMask & LOCATION_CAPABILITIES_GEOFENCE_BIT)
296 data |= IGnssCallback::Capabilities::GEOFENCING;
297 if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT)
298 data |= IGnssCallback::Capabilities::MEASUREMENTS;
299 if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MSB_BIT)
300 data |= IGnssCallback::Capabilities::MSB;
301 if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MSA_BIT)
302 data |= IGnssCallback::Capabilities::MSA;
303 auto r = gnssCbIface->gnssSetCapabilitesCb(data);
304 if (!r.isOk()) {
305 LOC_LOGE("%s] Error from gnssSetCapabilitesCb description=%s",
306 __func__, r.description().c_str());
307 }
308 }
309 if (gnssCbIface != nullptr) {
310 IGnssCallback::GnssSystemInfo gnssInfo;
311 if (capabilitiesMask & LOCATION_CAPABILITIES_DEBUG_NMEA_BIT) {
312 gnssInfo.yearOfHw = 2017;
313 } else if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT) {
314 gnssInfo.yearOfHw = 2016;
315 } else {
316 gnssInfo.yearOfHw = 2015;
317 }
318 LOC_LOGV("%s:%d] set_system_info_cb (%d)", __FUNCTION__, __LINE__, gnssInfo.yearOfHw);
319 auto r = gnssCbIface->gnssSetSystemInfoCb(gnssInfo);
320 if (!r.isOk()) {
321 LOC_LOGE("%s] Error from gnssSetSystemInfoCb description=%s",
322 __func__, r.description().c_str());
323 }
324 }
325 }
326
onTrackingCb(Location location)327 void GnssAPIClient::onTrackingCb(Location location)
328 {
329 LOC_LOGD("%s]: (flags: %02x)", __FUNCTION__, location.flags);
330 mMutex.lock();
331 auto gnssCbIface(mGnssCbIface);
332 mMutex.unlock();
333
334 if (gnssCbIface != nullptr) {
335 GnssLocation gnssLocation;
336 convertGnssLocation(location, gnssLocation);
337 auto r = gnssCbIface->gnssLocationCb(gnssLocation);
338 if (!r.isOk()) {
339 LOC_LOGE("%s] Error from gnssLocationCb description=%s",
340 __func__, r.description().c_str());
341 }
342 }
343 }
344
onGnssNiCb(uint32_t id,GnssNiNotification gnssNiNotification)345 void GnssAPIClient::onGnssNiCb(uint32_t id, GnssNiNotification gnssNiNotification)
346 {
347 LOC_LOGD("%s]: (id: %d)", __FUNCTION__, id);
348 mMutex.lock();
349 auto gnssNiCbIface(mGnssNiCbIface);
350 mMutex.unlock();
351
352 if (gnssNiCbIface == nullptr) {
353 LOC_LOGE("%s]: mGnssNiCbIface is nullptr", __FUNCTION__);
354 return;
355 }
356
357 IGnssNiCallback::GnssNiNotification notificationGnss = {};
358
359 notificationGnss.notificationId = id;
360
361 if (gnssNiNotification.type == GNSS_NI_TYPE_VOICE)
362 notificationGnss.niType = IGnssNiCallback::GnssNiType::VOICE;
363 else if (gnssNiNotification.type == GNSS_NI_TYPE_SUPL)
364 notificationGnss.niType = IGnssNiCallback::GnssNiType::UMTS_SUPL;
365 else if (gnssNiNotification.type == GNSS_NI_TYPE_CONTROL_PLANE)
366 notificationGnss.niType = IGnssNiCallback::GnssNiType::UMTS_CTRL_PLANE;
367 else if (gnssNiNotification.type == GNSS_NI_TYPE_EMERGENCY_SUPL)
368 notificationGnss.niType = IGnssNiCallback::GnssNiType::EMERGENCY_SUPL;
369
370 if (gnssNiNotification.options & GNSS_NI_OPTIONS_NOTIFICATION_BIT)
371 notificationGnss.notifyFlags |= IGnssNiCallback::GnssNiNotifyFlags::NEED_NOTIFY;
372 if (gnssNiNotification.options & GNSS_NI_OPTIONS_VERIFICATION_BIT)
373 notificationGnss.notifyFlags |= IGnssNiCallback::GnssNiNotifyFlags::NEED_VERIFY;
374 if (gnssNiNotification.options & GNSS_NI_OPTIONS_PRIVACY_OVERRIDE_BIT)
375 notificationGnss.notifyFlags |= IGnssNiCallback::GnssNiNotifyFlags::PRIVACY_OVERRIDE;
376
377 notificationGnss.timeoutSec = gnssNiNotification.timeout;
378
379 if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_ACCEPT)
380 notificationGnss.defaultResponse = IGnssNiCallback::GnssUserResponseType::RESPONSE_ACCEPT;
381 else if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_DENY)
382 notificationGnss.defaultResponse = IGnssNiCallback::GnssUserResponseType::RESPONSE_DENY;
383 else if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_NO_RESPONSE ||
384 gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_IGNORE)
385 notificationGnss.defaultResponse = IGnssNiCallback::GnssUserResponseType::RESPONSE_NORESP;
386
387 notificationGnss.requestorId = gnssNiNotification.requestor;
388
389 notificationGnss.notificationMessage = gnssNiNotification.message;
390
391 if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_NONE)
392 notificationGnss.requestorIdEncoding =
393 IGnssNiCallback::GnssNiEncodingType::ENC_NONE;
394 else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_GSM_DEFAULT)
395 notificationGnss.requestorIdEncoding =
396 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_GSM_DEFAULT;
397 else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_UTF8)
398 notificationGnss.requestorIdEncoding =
399 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UTF8;
400 else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_UCS2)
401 notificationGnss.requestorIdEncoding =
402 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UCS2;
403
404 if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_NONE)
405 notificationGnss.notificationIdEncoding =
406 IGnssNiCallback::GnssNiEncodingType::ENC_NONE;
407 else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_GSM_DEFAULT)
408 notificationGnss.notificationIdEncoding =
409 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_GSM_DEFAULT;
410 else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_UTF8)
411 notificationGnss.notificationIdEncoding =
412 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UTF8;
413 else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_UCS2)
414 notificationGnss.notificationIdEncoding =
415 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UCS2;
416
417 gnssNiCbIface->niNotifyCb(notificationGnss);
418 }
419
onGnssSvCb(GnssSvNotification gnssSvNotification)420 void GnssAPIClient::onGnssSvCb(GnssSvNotification gnssSvNotification)
421 {
422 LOC_LOGD("%s]: (count: %zu)", __FUNCTION__, gnssSvNotification.count);
423 mMutex.lock();
424 auto gnssCbIface(mGnssCbIface);
425 mMutex.unlock();
426
427 if (gnssCbIface != nullptr) {
428 IGnssCallback::GnssSvStatus svStatus;
429 convertGnssSvStatus(gnssSvNotification, svStatus);
430 auto r = gnssCbIface->gnssSvStatusCb(svStatus);
431 if (!r.isOk()) {
432 LOC_LOGE("%s] Error from gnssSvStatusCb description=%s",
433 __func__, r.description().c_str());
434 }
435 }
436 }
437
onGnssNmeaCb(GnssNmeaNotification gnssNmeaNotification)438 void GnssAPIClient::onGnssNmeaCb(GnssNmeaNotification gnssNmeaNotification)
439 {
440 mMutex.lock();
441 auto gnssCbIface(mGnssCbIface);
442 mMutex.unlock();
443
444 if (gnssCbIface != nullptr) {
445 android::hardware::hidl_string nmeaString;
446 nmeaString.setToExternal(gnssNmeaNotification.nmea, gnssNmeaNotification.length);
447 auto r = gnssCbIface->gnssNmeaCb(
448 static_cast<GnssUtcTime>(gnssNmeaNotification.timestamp), nmeaString);
449 if (!r.isOk()) {
450 LOC_LOGE("%s] Error from gnssNmeaCb nmea=%s length=%zu description=%s", __func__,
451 gnssNmeaNotification.nmea, gnssNmeaNotification.length, r.description().c_str());
452 }
453 }
454 }
455
onStartTrackingCb(LocationError error)456 void GnssAPIClient::onStartTrackingCb(LocationError error)
457 {
458 LOC_LOGD("%s]: (%d)", __FUNCTION__, error);
459 mMutex.lock();
460 auto gnssCbIface(mGnssCbIface);
461 mMutex.unlock();
462
463 if (error == LOCATION_ERROR_SUCCESS && gnssCbIface != nullptr) {
464 auto r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_ON);
465 if (!r.isOk()) {
466 LOC_LOGE("%s] Error from gnssStatusCb ENGINE_ON description=%s",
467 __func__, r.description().c_str());
468 }
469 r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_BEGIN);
470 if (!r.isOk()) {
471 LOC_LOGE("%s] Error from gnssStatusCb SESSION_BEGIN description=%s",
472 __func__, r.description().c_str());
473 }
474 }
475 }
476
onStopTrackingCb(LocationError error)477 void GnssAPIClient::onStopTrackingCb(LocationError error)
478 {
479 LOC_LOGD("%s]: (%d)", __FUNCTION__, error);
480 mMutex.lock();
481 auto gnssCbIface(mGnssCbIface);
482 mMutex.unlock();
483
484 if (error == LOCATION_ERROR_SUCCESS && gnssCbIface != nullptr) {
485 auto r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_END);
486 if (!r.isOk()) {
487 LOC_LOGE("%s] Error from gnssStatusCb SESSION_END description=%s",
488 __func__, r.description().c_str());
489 }
490 r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_OFF);
491 if (!r.isOk()) {
492 LOC_LOGE("%s] Error from gnssStatusCb ENGINE_OFF description=%s",
493 __func__, r.description().c_str());
494 }
495 }
496 }
497
convertGnssSvStatus(GnssSvNotification & in,IGnssCallback::GnssSvStatus & out)498 static void convertGnssSvStatus(GnssSvNotification& in, IGnssCallback::GnssSvStatus& out)
499 {
500 memset(&out, 0, sizeof(IGnssCallback::GnssSvStatus));
501 out.numSvs = in.count;
502 if (out.numSvs > static_cast<uint32_t>(GnssMax::SVS_COUNT)) {
503 LOC_LOGW("%s]: Too many satellites %zd. Clamps to %d.",
504 __FUNCTION__, out.numSvs, GnssMax::SVS_COUNT);
505 out.numSvs = static_cast<uint32_t>(GnssMax::SVS_COUNT);
506 }
507 for (size_t i = 0; i < out.numSvs; i++) {
508 IGnssCallback::GnssSvInfo& info = out.gnssSvList[i];
509 info.svid = in.gnssSvs[i].svId;
510 convertGnssConstellationType(in.gnssSvs[i].type, info.constellation);
511 info.cN0Dbhz = in.gnssSvs[i].cN0Dbhz;
512 info.elevationDegrees = in.gnssSvs[i].elevation;
513 info.azimuthDegrees = in.gnssSvs[i].azimuth;
514 info.svFlag = static_cast<uint8_t>(IGnssCallback::GnssSvFlags::NONE);
515 if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_EPHEMER_BIT)
516 info.svFlag |= IGnssCallback::GnssSvFlags::HAS_EPHEMERIS_DATA;
517 if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_ALMANAC_BIT)
518 info.svFlag |= IGnssCallback::GnssSvFlags::HAS_ALMANAC_DATA;
519 if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_USED_IN_FIX_BIT)
520 info.svFlag |= IGnssCallback::GnssSvFlags::USED_IN_FIX;
521 }
522 }
523
524 } // namespace implementation
525 } // namespace V1_0
526 } // namespace gnss
527 } // namespace hardware
528 } // namespace android
529