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_NDDEBUG 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
39 namespace android {
40 namespace hardware {
41 namespace gnss {
42 namespace V1_0 {
43 namespace implementation {
44
45 static void convertGnssSvStatus(GnssSvNotification& in, IGnssCallback::GnssSvStatus& out);
46
GnssAPIClient(const sp<IGnssCallback> & gpsCb,const sp<IGnssNiCallback> & niCb)47 GnssAPIClient::GnssAPIClient(const sp<IGnssCallback>& gpsCb,
48 const sp<IGnssNiCallback>& niCb) :
49 LocationAPIClientBase(),
50 mGnssCbIface(nullptr),
51 mGnssNiCbIface(nullptr),
52 mLocationCapabilitiesMask(0),
53 mLocationCapabilitiesCached(false)
54 {
55 LOC_LOGD("%s]: (%p %p)", __FUNCTION__, &gpsCb, &niCb);
56
57 // set default LocationOptions.
58 memset(&mLocationOptions, 0, sizeof(LocationOptions));
59 mLocationOptions.size = sizeof(LocationOptions);
60 mLocationOptions.minInterval = 1000;
61 mLocationOptions.minDistance = 0;
62 mLocationOptions.mode = GNSS_SUPL_MODE_STANDALONE;
63
64 gnssUpdateCallbacks(gpsCb, niCb);
65 }
66
~GnssAPIClient()67 GnssAPIClient::~GnssAPIClient()
68 {
69 LOC_LOGD("%s]: ()", __FUNCTION__);
70 }
71
72 // for GpsInterface
gnssUpdateCallbacks(const sp<IGnssCallback> & gpsCb,const sp<IGnssNiCallback> & niCb)73 void GnssAPIClient::gnssUpdateCallbacks(const sp<IGnssCallback>& gpsCb,
74 const sp<IGnssNiCallback>& niCb)
75 {
76 LOC_LOGD("%s]: (%p %p)", __FUNCTION__, &gpsCb, &niCb);
77 mMutex.lock();
78 mGnssCbIface = gpsCb;
79 mGnssNiCbIface = niCb;
80 mMutex.unlock();
81 LocationCallbacks locationCallbacks;
82 locationCallbacks.size = sizeof(LocationCallbacks);
83
84 locationCallbacks.trackingCb = nullptr;
85 if (mGnssCbIface != nullptr) {
86 locationCallbacks.trackingCb = [this](Location location) {
87 onTrackingCb(location);
88 };
89 }
90
91 locationCallbacks.batchingCb = nullptr;
92 locationCallbacks.geofenceBreachCb = nullptr;
93 locationCallbacks.geofenceStatusCb = nullptr;
94 locationCallbacks.gnssLocationInfoCb = nullptr;
95
96 locationCallbacks.gnssNiCb = nullptr;
97 if (mGnssNiCbIface != nullptr) {
98 locationCallbacks.gnssNiCb = [this](uint32_t id, GnssNiNotification gnssNiNotification) {
99 onGnssNiCb(id, gnssNiNotification);
100 };
101 }
102
103 locationCallbacks.gnssSvCb = nullptr;
104 if (mGnssCbIface != nullptr) {
105 locationCallbacks.gnssSvCb = [this](GnssSvNotification gnssSvNotification) {
106 onGnssSvCb(gnssSvNotification);
107 };
108 }
109
110 locationCallbacks.gnssNmeaCb = nullptr;
111 if (mGnssCbIface != nullptr) {
112 locationCallbacks.gnssNmeaCb = [this](GnssNmeaNotification gnssNmeaNotification) {
113 onGnssNmeaCb(gnssNmeaNotification);
114 };
115 }
116
117 locationCallbacks.gnssMeasurementsCb = nullptr;
118
119 locAPISetCallbacks(locationCallbacks);
120 }
121
gnssStart()122 bool GnssAPIClient::gnssStart()
123 {
124 LOC_LOGD("%s]: ()", __FUNCTION__);
125 bool retVal = true;
126 locAPIStartTracking(mLocationOptions);
127 return retVal;
128 }
129
gnssStop()130 bool GnssAPIClient::gnssStop()
131 {
132 LOC_LOGD("%s]: ()", __FUNCTION__);
133 bool retVal = true;
134 locAPIStopTracking();
135 return retVal;
136 }
137
gnssDeleteAidingData(IGnss::GnssAidingData aidingDataFlags)138 void GnssAPIClient::gnssDeleteAidingData(IGnss::GnssAidingData aidingDataFlags)
139 {
140 LOC_LOGD("%s]: (%02hx)", __FUNCTION__, aidingDataFlags);
141 GnssAidingData data;
142 memset(&data, 0, sizeof (GnssAidingData));
143 data.sv.svTypeMask = GNSS_AIDING_DATA_SV_TYPE_GPS_BIT |
144 GNSS_AIDING_DATA_SV_TYPE_GLONASS_BIT |
145 GNSS_AIDING_DATA_SV_TYPE_QZSS_BIT |
146 GNSS_AIDING_DATA_SV_TYPE_BEIDOU_BIT |
147 GNSS_AIDING_DATA_SV_TYPE_GALILEO_BIT;
148
149 if (aidingDataFlags == IGnss::GnssAidingData::DELETE_ALL)
150 data.deleteAll = true;
151 else {
152 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_EPHEMERIS)
153 data.sv.svMask |= GNSS_AIDING_DATA_SV_EPHEMERIS_BIT;
154 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_ALMANAC)
155 data.sv.svMask |= GNSS_AIDING_DATA_SV_ALMANAC_BIT;
156 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_POSITION)
157 data.common.mask |= GNSS_AIDING_DATA_COMMON_POSITION_BIT;
158 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_TIME)
159 data.common.mask |= GNSS_AIDING_DATA_COMMON_TIME_BIT;
160 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_IONO)
161 data.sv.svMask |= GNSS_AIDING_DATA_SV_IONOSPHERE_BIT;
162 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_UTC)
163 data.common.mask |= GNSS_AIDING_DATA_COMMON_UTC_BIT;
164 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_HEALTH)
165 data.sv.svMask |= GNSS_AIDING_DATA_SV_HEALTH_BIT;
166 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_SVDIR)
167 data.sv.svMask |= GNSS_AIDING_DATA_SV_DIRECTION_BIT;
168 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_SVSTEER)
169 data.sv.svMask |= GNSS_AIDING_DATA_SV_STEER_BIT;
170 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_SADATA)
171 data.sv.svMask |= GNSS_AIDING_DATA_SV_SA_DATA_BIT;
172 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_RTI)
173 data.common.mask |= GNSS_AIDING_DATA_COMMON_RTI_BIT;
174 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_CELLDB_INFO)
175 data.common.mask |= GNSS_AIDING_DATA_COMMON_CELLDB_BIT;
176 }
177 locAPIGnssDeleteAidingData(data);
178 }
179
gnssSetPositionMode(IGnss::GnssPositionMode mode,IGnss::GnssPositionRecurrence recurrence,uint32_t minIntervalMs,uint32_t preferredAccuracyMeters,uint32_t preferredTimeMs)180 bool GnssAPIClient::gnssSetPositionMode(IGnss::GnssPositionMode mode,
181 IGnss::GnssPositionRecurrence recurrence, uint32_t minIntervalMs,
182 uint32_t preferredAccuracyMeters, uint32_t preferredTimeMs)
183 {
184 LOC_LOGD("%s]: (%d %d %d %d %d)", __FUNCTION__,
185 (int)mode, recurrence, minIntervalMs, preferredAccuracyMeters, preferredTimeMs);
186 bool retVal = true;
187 memset(&mLocationOptions, 0, sizeof(LocationOptions));
188 mLocationOptions.size = sizeof(LocationOptions);
189 mLocationOptions.minInterval = minIntervalMs;
190 mLocationOptions.minDistance = preferredAccuracyMeters;
191 if (mode == IGnss::GnssPositionMode::STANDALONE)
192 mLocationOptions.mode = GNSS_SUPL_MODE_STANDALONE;
193 else if (mode == IGnss::GnssPositionMode::MS_BASED)
194 mLocationOptions.mode = GNSS_SUPL_MODE_MSB;
195 else if (mode == IGnss::GnssPositionMode::MS_ASSISTED)
196 mLocationOptions.mode = GNSS_SUPL_MODE_MSA;
197 locAPIUpdateTrackingOptions(mLocationOptions);
198 return retVal;
199 }
200
201 // for GpsNiInterface
gnssNiRespond(int32_t notifId,IGnssNiCallback::GnssUserResponseType userResponse)202 void GnssAPIClient::gnssNiRespond(int32_t notifId,
203 IGnssNiCallback::GnssUserResponseType userResponse)
204 {
205 LOC_LOGD("%s]: (%d %d)", __FUNCTION__, notifId, static_cast<int>(userResponse));
206 GnssNiResponse data = GNSS_NI_RESPONSE_IGNORE;
207 if (userResponse == IGnssNiCallback::GnssUserResponseType::RESPONSE_ACCEPT)
208 data = GNSS_NI_RESPONSE_ACCEPT;
209 else if (userResponse == IGnssNiCallback::GnssUserResponseType::RESPONSE_DENY)
210 data = GNSS_NI_RESPONSE_DENY;
211 else if (userResponse == IGnssNiCallback::GnssUserResponseType::RESPONSE_NORESP)
212 data = GNSS_NI_RESPONSE_NO_RESPONSE;
213 locAPIGnssNiResponse(notifId, data);
214 }
215
216 // for GnssConfigurationInterface
gnssConfigurationUpdate(const GnssConfig & gnssConfig)217 void GnssAPIClient::gnssConfigurationUpdate(const GnssConfig& gnssConfig)
218 {
219 LOC_LOGD("%s]: (%02x)", __FUNCTION__, gnssConfig.flags);
220 locAPIGnssUpdateConfig(gnssConfig);
221 }
222
requestCapabilities()223 void GnssAPIClient::requestCapabilities() {
224 // only send capablities if it's already cached, otherwise the first time LocationAPI
225 // is initialized, capabilities will be sent by LocationAPI
226 if (mLocationCapabilitiesCached) {
227 onCapabilitiesCb(mLocationCapabilitiesMask);
228 }
229 }
230
231 // callbacks
onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)232 void GnssAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)
233 {
234 LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask);
235 mLocationCapabilitiesMask = capabilitiesMask;
236 mLocationCapabilitiesCached = true;
237
238 mMutex.lock();
239 auto gnssCbIface(mGnssCbIface);
240 mMutex.unlock();
241
242 if (gnssCbIface != nullptr) {
243 uint32_t data = 0;
244 if ((capabilitiesMask & LOCATION_CAPABILITIES_TIME_BASED_TRACKING_BIT) ||
245 (capabilitiesMask & LOCATION_CAPABILITIES_TIME_BASED_BATCHING_BIT) ||
246 (capabilitiesMask & LOCATION_CAPABILITIES_DISTANCE_BASED_TRACKING_BIT) ||
247 (capabilitiesMask & LOCATION_CAPABILITIES_DISTANCE_BASED_BATCHING_BIT))
248 data |= IGnssCallback::Capabilities::SCHEDULING;
249 if (capabilitiesMask & LOCATION_CAPABILITIES_GEOFENCE_BIT)
250 data |= IGnssCallback::Capabilities::GEOFENCING;
251 if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT)
252 data |= IGnssCallback::Capabilities::MEASUREMENTS;
253 if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MSB_BIT)
254 data |= IGnssCallback::Capabilities::MSB;
255 if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MSA_BIT)
256 data |= IGnssCallback::Capabilities::MSA;
257 auto r = gnssCbIface->gnssSetCapabilitesCb(data);
258 if (!r.isOk()) {
259 LOC_LOGE("%s] Error from gnssSetCapabilitesCb description=%s",
260 __func__, r.description().c_str());
261 }
262 }
263 if (gnssCbIface != nullptr) {
264 IGnssCallback::GnssSystemInfo gnssInfo;
265 gnssInfo.yearOfHw = 2015;
266 if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT) {
267 gnssInfo.yearOfHw = 2017;
268 }
269 LOC_LOGV("%s:%d] set_system_info_cb (%d)", __FUNCTION__, __LINE__, gnssInfo.yearOfHw);
270 auto r = gnssCbIface->gnssSetSystemInfoCb(gnssInfo);
271 if (!r.isOk()) {
272 LOC_LOGE("%s] Error from gnssSetSystemInfoCb description=%s",
273 __func__, r.description().c_str());
274 }
275 }
276 }
277
onTrackingCb(Location location)278 void GnssAPIClient::onTrackingCb(Location location)
279 {
280 LOC_LOGD("%s]: (flags: %02x)", __FUNCTION__, location.flags);
281 mMutex.lock();
282 auto gnssCbIface(mGnssCbIface);
283 mMutex.unlock();
284
285 if (gnssCbIface != nullptr) {
286 GnssLocation gnssLocation;
287 convertGnssLocation(location, gnssLocation);
288 auto r = gnssCbIface->gnssLocationCb(gnssLocation);
289 if (!r.isOk()) {
290 LOC_LOGE("%s] Error from gnssLocationCb description=%s",
291 __func__, r.description().c_str());
292 }
293 }
294 }
295
onGnssNiCb(uint32_t id,GnssNiNotification gnssNiNotification)296 void GnssAPIClient::onGnssNiCb(uint32_t id, GnssNiNotification gnssNiNotification)
297 {
298 LOC_LOGD("%s]: (id: %d)", __FUNCTION__, id);
299 mMutex.lock();
300 auto gnssNiCbIface(mGnssNiCbIface);
301 mMutex.unlock();
302
303 if (gnssNiCbIface == nullptr) {
304 LOC_LOGE("%s]: mGnssNiCbIface is nullptr", __FUNCTION__);
305 return;
306 }
307
308 IGnssNiCallback::GnssNiNotification notificationGnss = {};
309
310 notificationGnss.notificationId = id;
311
312 if (gnssNiNotification.type == GNSS_NI_TYPE_VOICE)
313 notificationGnss.niType = IGnssNiCallback::GnssNiType::VOICE;
314 else if (gnssNiNotification.type == GNSS_NI_TYPE_SUPL)
315 notificationGnss.niType = IGnssNiCallback::GnssNiType::UMTS_SUPL;
316 else if (gnssNiNotification.type == GNSS_NI_TYPE_CONTROL_PLANE)
317 notificationGnss.niType = IGnssNiCallback::GnssNiType::UMTS_CTRL_PLANE;
318 else if (gnssNiNotification.type == GNSS_NI_TYPE_EMERGENCY_SUPL)
319 notificationGnss.niType = IGnssNiCallback::GnssNiType::EMERGENCY_SUPL;
320
321 if (gnssNiNotification.options & GNSS_NI_OPTIONS_NOTIFICATION_BIT)
322 notificationGnss.notifyFlags |= IGnssNiCallback::GnssNiNotifyFlags::NEED_NOTIFY;
323 if (gnssNiNotification.options & GNSS_NI_OPTIONS_VERIFICATION_BIT)
324 notificationGnss.notifyFlags |= IGnssNiCallback::GnssNiNotifyFlags::NEED_VERIFY;
325 if (gnssNiNotification.options & GNSS_NI_OPTIONS_PRIVACY_OVERRIDE_BIT)
326 notificationGnss.notifyFlags |= IGnssNiCallback::GnssNiNotifyFlags::PRIVACY_OVERRIDE;
327
328 notificationGnss.timeoutSec = gnssNiNotification.timeout;
329
330 if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_ACCEPT)
331 notificationGnss.defaultResponse = IGnssNiCallback::GnssUserResponseType::RESPONSE_ACCEPT;
332 else if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_DENY)
333 notificationGnss.defaultResponse = IGnssNiCallback::GnssUserResponseType::RESPONSE_DENY;
334 else if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_NO_RESPONSE ||
335 gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_IGNORE)
336 notificationGnss.defaultResponse = IGnssNiCallback::GnssUserResponseType::RESPONSE_NORESP;
337
338 notificationGnss.requestorId = gnssNiNotification.requestor;
339
340 notificationGnss.notificationMessage = gnssNiNotification.message;
341
342 if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_NONE)
343 notificationGnss.requestorIdEncoding =
344 IGnssNiCallback::GnssNiEncodingType::ENC_NONE;
345 else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_GSM_DEFAULT)
346 notificationGnss.requestorIdEncoding =
347 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_GSM_DEFAULT;
348 else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_UTF8)
349 notificationGnss.requestorIdEncoding =
350 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UTF8;
351 else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_UCS2)
352 notificationGnss.requestorIdEncoding =
353 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UCS2;
354
355 if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_NONE)
356 notificationGnss.notificationIdEncoding =
357 IGnssNiCallback::GnssNiEncodingType::ENC_NONE;
358 else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_GSM_DEFAULT)
359 notificationGnss.notificationIdEncoding =
360 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_GSM_DEFAULT;
361 else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_UTF8)
362 notificationGnss.notificationIdEncoding =
363 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UTF8;
364 else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_UCS2)
365 notificationGnss.notificationIdEncoding =
366 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UCS2;
367
368 gnssNiCbIface->niNotifyCb(notificationGnss);
369 }
370
onGnssSvCb(GnssSvNotification gnssSvNotification)371 void GnssAPIClient::onGnssSvCb(GnssSvNotification gnssSvNotification)
372 {
373 LOC_LOGD("%s]: (count: %zu)", __FUNCTION__, gnssSvNotification.count);
374 mMutex.lock();
375 auto gnssCbIface(mGnssCbIface);
376 mMutex.unlock();
377
378 if (gnssCbIface != nullptr) {
379 IGnssCallback::GnssSvStatus svStatus;
380 convertGnssSvStatus(gnssSvNotification, svStatus);
381 auto r = gnssCbIface->gnssSvStatusCb(svStatus);
382 if (!r.isOk()) {
383 LOC_LOGE("%s] Error from gnssSvStatusCb description=%s",
384 __func__, r.description().c_str());
385 }
386 }
387 }
388
onGnssNmeaCb(GnssNmeaNotification gnssNmeaNotification)389 void GnssAPIClient::onGnssNmeaCb(GnssNmeaNotification gnssNmeaNotification)
390 {
391 mMutex.lock();
392 auto gnssCbIface(mGnssCbIface);
393 mMutex.unlock();
394
395 if (gnssCbIface != nullptr) {
396 android::hardware::hidl_string nmeaString;
397 nmeaString.setToExternal(gnssNmeaNotification.nmea, gnssNmeaNotification.length);
398 auto r = gnssCbIface->gnssNmeaCb(
399 static_cast<GnssUtcTime>(gnssNmeaNotification.timestamp), nmeaString);
400 if (!r.isOk()) {
401 LOC_LOGE("%s] Error from gnssNmeaCb nmea=%s length=%u description=%s", __func__,
402 gnssNmeaNotification.nmea, gnssNmeaNotification.length, r.description().c_str());
403 }
404 }
405 }
406
onStartTrackingCb(LocationError error)407 void GnssAPIClient::onStartTrackingCb(LocationError error)
408 {
409 LOC_LOGD("%s]: (%d)", __FUNCTION__, error);
410 mMutex.lock();
411 auto gnssCbIface(mGnssCbIface);
412 mMutex.unlock();
413
414 if (error == LOCATION_ERROR_SUCCESS && gnssCbIface != nullptr) {
415 auto r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_ON);
416 if (!r.isOk()) {
417 LOC_LOGE("%s] Error from gnssStatusCb ENGINE_ON description=%s",
418 __func__, r.description().c_str());
419 }
420 r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_BEGIN);
421 if (!r.isOk()) {
422 LOC_LOGE("%s] Error from gnssStatusCb SESSION_BEGIN description=%s",
423 __func__, r.description().c_str());
424 }
425 }
426 }
427
onStopTrackingCb(LocationError error)428 void GnssAPIClient::onStopTrackingCb(LocationError error)
429 {
430 LOC_LOGD("%s]: (%d)", __FUNCTION__, error);
431 mMutex.lock();
432 auto gnssCbIface(mGnssCbIface);
433 mMutex.unlock();
434
435 if (error == LOCATION_ERROR_SUCCESS && gnssCbIface != nullptr) {
436 auto r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_END);
437 if (!r.isOk()) {
438 LOC_LOGE("%s] Error from gnssStatusCb SESSION_END description=%s",
439 __func__, r.description().c_str());
440 }
441 r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_OFF);
442 if (!r.isOk()) {
443 LOC_LOGE("%s] Error from gnssStatusCb ENGINE_OFF description=%s",
444 __func__, r.description().c_str());
445 }
446 }
447 }
448
convertGnssSvStatus(GnssSvNotification & in,IGnssCallback::GnssSvStatus & out)449 static void convertGnssSvStatus(GnssSvNotification& in, IGnssCallback::GnssSvStatus& out)
450 {
451 memset(&out, 0, sizeof(IGnssCallback::GnssSvStatus));
452 out.numSvs = in.count;
453 if (out.numSvs > static_cast<uint32_t>(GnssMax::SVS_COUNT)) {
454 LOC_LOGW("%s]: Too many satellites %zd. Clamps to %d.",
455 __FUNCTION__, out.numSvs, GnssMax::SVS_COUNT);
456 out.numSvs = static_cast<uint32_t>(GnssMax::SVS_COUNT);
457 }
458 for (size_t i = 0; i < out.numSvs; i++) {
459 IGnssCallback::GnssSvInfo& info = out.gnssSvList[i];
460 info.svid = in.gnssSvs[i].svId;
461 convertGnssConstellationType(in.gnssSvs[i].type, info.constellation);
462 info.cN0Dbhz = in.gnssSvs[i].cN0Dbhz;
463 info.elevationDegrees = in.gnssSvs[i].elevation;
464 info.azimuthDegrees = in.gnssSvs[i].azimuth;
465 info.carrierFrequencyHz = in.gnssSvs[i].carrierFrequencyHz;
466 info.svFlag = static_cast<uint8_t>(IGnssCallback::GnssSvFlags::NONE);
467 if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_EPHEMER_BIT)
468 info.svFlag |= IGnssCallback::GnssSvFlags::HAS_EPHEMERIS_DATA;
469 if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_ALMANAC_BIT)
470 info.svFlag |= IGnssCallback::GnssSvFlags::HAS_ALMANAC_DATA;
471 if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_USED_IN_FIX_BIT)
472 info.svFlag |= IGnssCallback::GnssSvFlags::USED_IN_FIX;
473 if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_CARRIER_FREQUENCY_BIT)
474 info.svFlag |= IGnssCallback::GnssSvFlags::HAS_CARRIER_FREQUENCY;
475 }
476 }
477
478 } // namespace implementation
479 } // namespace V1_0
480 } // namespace gnss
481 } // namespace hardware
482 } // namespace android
483