1 /* Copyright (c) 2017-2020, 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 #define SINGLE_SHOT_MIN_TRACKING_INTERVAL_MSEC (590 * 60 * 60 * 1000) // 590 hours
33
34 #include <inttypes.h>
35 #include <log_util.h>
36 #include <loc_cfg.h>
37
38 #include "LocationUtil.h"
39 #include "GnssAPIClient.h"
40 #include <LocContext.h>
41
42 namespace android {
43 namespace hardware {
44 namespace gnss {
45 namespace V2_1 {
46 namespace implementation {
47
48 using ::android::hardware::gnss::V2_1::IGnss;
49 using ::android::hardware::gnss::V2_1::IGnssCallback;
50 using ::android::hardware::gnss::V1_0::IGnssNiCallback;
51 using ::android::hardware::gnss::V2_0::GnssLocation;
52
53 static void convertGnssSvStatus(GnssSvNotification& in, V1_0::IGnssCallback::GnssSvStatus& out);
54 static void convertGnssSvStatus(GnssSvNotification& in,
55 hidl_vec<V2_0::IGnssCallback::GnssSvInfo>& out);
56 static void convertGnssSvStatus(GnssSvNotification& in,
57 hidl_vec<V2_1::IGnssCallback::GnssSvInfo>& out);
58
GnssAPIClient(const sp<V1_0::IGnssCallback> & gpsCb,const sp<V1_0::IGnssNiCallback> & niCb)59 GnssAPIClient::GnssAPIClient(const sp<V1_0::IGnssCallback>& gpsCb,
60 const sp<V1_0::IGnssNiCallback>& niCb) :
61 LocationAPIClientBase(),
62 mGnssCbIface(nullptr),
63 mGnssNiCbIface(nullptr),
64 mControlClient(new LocationAPIControlClient()),
65 mLocationCapabilitiesMask(0),
66 mLocationCapabilitiesCached(false),
67 mTracking(false),
68 mGnssCbIface_2_0(nullptr)
69 {
70 LOC_LOGD("%s]: (%p %p)", __FUNCTION__, &gpsCb, &niCb);
71
72 initLocationOptions();
73 gnssUpdateCallbacks(gpsCb, niCb);
74 }
75
GnssAPIClient(const sp<V2_0::IGnssCallback> & gpsCb)76 GnssAPIClient::GnssAPIClient(const sp<V2_0::IGnssCallback>& gpsCb) :
77 LocationAPIClientBase(),
78 mGnssCbIface(nullptr),
79 mGnssNiCbIface(nullptr),
80 mControlClient(new LocationAPIControlClient()),
81 mLocationCapabilitiesMask(0),
82 mLocationCapabilitiesCached(false),
83 mTracking(false),
84 mGnssCbIface_2_0(nullptr)
85 {
86 LOC_LOGD("%s]: (%p)", __FUNCTION__, &gpsCb);
87
88 initLocationOptions();
89 gnssUpdateCallbacks_2_0(gpsCb);
90 }
91
GnssAPIClient(const sp<V2_1::IGnssCallback> & gpsCb)92 GnssAPIClient::GnssAPIClient(const sp<V2_1::IGnssCallback>& gpsCb) :
93 LocationAPIClientBase(),
94 mGnssCbIface(nullptr),
95 mGnssNiCbIface(nullptr),
96 mControlClient(new LocationAPIControlClient()),
97 mLocationCapabilitiesMask(0),
98 mLocationCapabilitiesCached(false),
99 mTracking(false),
100 mGnssCbIface_2_1(nullptr)
101 {
102 LOC_LOGD("%s]: (%p)", __FUNCTION__, &gpsCb);
103
104 initLocationOptions();
105 gnssUpdateCallbacks_2_1(gpsCb);
106 }
107
~GnssAPIClient()108 GnssAPIClient::~GnssAPIClient()
109 {
110 LOC_LOGD("%s]: ()", __FUNCTION__);
111 if (mControlClient) {
112 delete mControlClient;
113 mControlClient = nullptr;
114 }
115 }
116
initLocationOptions()117 void GnssAPIClient::initLocationOptions()
118 {
119 // set default LocationOptions.
120 memset(&mTrackingOptions, 0, sizeof(TrackingOptions));
121 mTrackingOptions.size = sizeof(TrackingOptions);
122 mTrackingOptions.minInterval = 1000;
123 mTrackingOptions.minDistance = 0;
124 mTrackingOptions.mode = GNSS_SUPL_MODE_STANDALONE;
125 }
126
setCallbacks()127 void GnssAPIClient::setCallbacks()
128 {
129 LocationCallbacks locationCallbacks;
130 memset(&locationCallbacks, 0, sizeof(LocationCallbacks));
131 locationCallbacks.size = sizeof(LocationCallbacks);
132
133 locationCallbacks.trackingCb = nullptr;
134 locationCallbacks.trackingCb = [this](Location location) {
135 onTrackingCb(location);
136 };
137
138 locationCallbacks.batchingCb = nullptr;
139 locationCallbacks.geofenceBreachCb = nullptr;
140 locationCallbacks.geofenceStatusCb = nullptr;
141 locationCallbacks.gnssLocationInfoCb = nullptr;
142 locationCallbacks.gnssNiCb = nullptr;
143 if (mGnssNiCbIface != nullptr) {
144 loc_core::ContextBase* context =
145 loc_core::LocContext::getLocContext(loc_core::LocContext::mLocationHalName);
146 if (!context->hasAgpsExtendedCapabilities()) {
147 LOC_LOGD("Registering NI CB");
148 locationCallbacks.gnssNiCb = [this](uint32_t id, GnssNiNotification gnssNiNotify) {
149 onGnssNiCb(id, gnssNiNotify);
150 };
151 }
152 }
153
154 locationCallbacks.gnssSvCb = nullptr;
155 locationCallbacks.gnssSvCb = [this](GnssSvNotification gnssSvNotification) {
156 onGnssSvCb(gnssSvNotification);
157 };
158
159 locationCallbacks.gnssNmeaCb = nullptr;
160 locationCallbacks.gnssNmeaCb = [this](GnssNmeaNotification gnssNmeaNotification) {
161 onGnssNmeaCb(gnssNmeaNotification);
162 };
163
164 locationCallbacks.gnssMeasurementsCb = nullptr;
165
166 locAPISetCallbacks(locationCallbacks);
167 }
168
169 // for GpsInterface
gnssUpdateCallbacks(const sp<V1_0::IGnssCallback> & gpsCb,const sp<IGnssNiCallback> & niCb)170 void GnssAPIClient::gnssUpdateCallbacks(const sp<V1_0::IGnssCallback>& gpsCb,
171 const sp<IGnssNiCallback>& niCb)
172 {
173 LOC_LOGD("%s]: (%p %p)", __FUNCTION__, &gpsCb, &niCb);
174
175 mMutex.lock();
176 mGnssCbIface = gpsCb;
177 mGnssNiCbIface = niCb;
178 mMutex.unlock();
179
180 if (mGnssCbIface != nullptr || mGnssNiCbIface != nullptr) {
181 setCallbacks();
182 }
183 }
184
gnssUpdateCallbacks_2_0(const sp<V2_0::IGnssCallback> & gpsCb)185 void GnssAPIClient::gnssUpdateCallbacks_2_0(const sp<V2_0::IGnssCallback>& gpsCb)
186 {
187 LOC_LOGD("%s]: (%p)", __FUNCTION__, &gpsCb);
188
189 mMutex.lock();
190 mGnssCbIface_2_0 = gpsCb;
191 mMutex.unlock();
192
193 if (mGnssCbIface_2_0 != nullptr) {
194 setCallbacks();
195 }
196 }
197
gnssUpdateCallbacks_2_1(const sp<V2_1::IGnssCallback> & gpsCb)198 void GnssAPIClient::gnssUpdateCallbacks_2_1(const sp<V2_1::IGnssCallback>& gpsCb)
199 {
200 LOC_LOGD("%s]: (%p)", __FUNCTION__, &gpsCb);
201
202 mMutex.lock();
203 mGnssCbIface_2_1 = gpsCb;
204 mMutex.unlock();
205
206 if (mGnssCbIface_2_1 != nullptr) {
207 setCallbacks();
208 }
209 }
210
gnssStart()211 bool GnssAPIClient::gnssStart()
212 {
213 LOC_LOGD("%s]: ()", __FUNCTION__);
214
215 mMutex.lock();
216 mTracking = true;
217 mMutex.unlock();
218
219 bool retVal = true;
220 locAPIStartTracking(mTrackingOptions);
221 return retVal;
222 }
223
gnssStop()224 bool GnssAPIClient::gnssStop()
225 {
226 LOC_LOGD("%s]: ()", __FUNCTION__);
227
228 mMutex.lock();
229 mTracking = false;
230 mMutex.unlock();
231
232 bool retVal = true;
233 locAPIStopTracking();
234 return retVal;
235 }
236
gnssSetPositionMode(IGnss::GnssPositionMode mode,IGnss::GnssPositionRecurrence recurrence,uint32_t minIntervalMs,uint32_t preferredAccuracyMeters,uint32_t preferredTimeMs,GnssPowerMode powerMode,uint32_t timeBetweenMeasurement)237 bool GnssAPIClient::gnssSetPositionMode(IGnss::GnssPositionMode mode,
238 IGnss::GnssPositionRecurrence recurrence, uint32_t minIntervalMs,
239 uint32_t preferredAccuracyMeters, uint32_t preferredTimeMs,
240 GnssPowerMode powerMode, uint32_t timeBetweenMeasurement)
241 {
242 LOC_LOGD("%s]: (%d %d %d %d %d %d %d)", __FUNCTION__,
243 (int)mode, recurrence, minIntervalMs, preferredAccuracyMeters,
244 preferredTimeMs, (int)powerMode, timeBetweenMeasurement);
245 bool retVal = true;
246 memset(&mTrackingOptions, 0, sizeof(TrackingOptions));
247 mTrackingOptions.size = sizeof(TrackingOptions);
248 mTrackingOptions.minInterval = minIntervalMs;
249 if (IGnss::GnssPositionMode::MS_ASSISTED == mode ||
250 IGnss::GnssPositionRecurrence::RECURRENCE_SINGLE == recurrence) {
251 // We set a very large interval to simulate SINGLE mode. Once we report a fix,
252 // the caller should take the responsibility to stop the session.
253 // For MSA, we always treat it as SINGLE mode.
254 mTrackingOptions.minInterval = SINGLE_SHOT_MIN_TRACKING_INTERVAL_MSEC;
255 }
256 if (mode == IGnss::GnssPositionMode::STANDALONE)
257 mTrackingOptions.mode = GNSS_SUPL_MODE_STANDALONE;
258 else if (mode == IGnss::GnssPositionMode::MS_BASED)
259 mTrackingOptions.mode = GNSS_SUPL_MODE_MSB;
260 else if (mode == IGnss::GnssPositionMode::MS_ASSISTED)
261 mTrackingOptions.mode = GNSS_SUPL_MODE_MSA;
262 else {
263 LOC_LOGD("%s]: invalid GnssPositionMode: %d", __FUNCTION__, (int)mode);
264 retVal = false;
265 }
266 if (GNSS_POWER_MODE_INVALID != powerMode) {
267 mTrackingOptions.powerMode = powerMode;
268 mTrackingOptions.tbm = timeBetweenMeasurement;
269 }
270 locAPIUpdateTrackingOptions(mTrackingOptions);
271 return retVal;
272 }
273
274 // for GpsNiInterface
gnssNiRespond(int32_t notifId,IGnssNiCallback::GnssUserResponseType userResponse)275 void GnssAPIClient::gnssNiRespond(int32_t notifId,
276 IGnssNiCallback::GnssUserResponseType userResponse)
277 {
278 LOC_LOGD("%s]: (%d %d)", __FUNCTION__, notifId, static_cast<int>(userResponse));
279 GnssNiResponse data;
280 switch (userResponse) {
281 case IGnssNiCallback::GnssUserResponseType::RESPONSE_ACCEPT:
282 data = GNSS_NI_RESPONSE_ACCEPT;
283 break;
284 case IGnssNiCallback::GnssUserResponseType::RESPONSE_DENY:
285 data = GNSS_NI_RESPONSE_DENY;
286 break;
287 case IGnssNiCallback::GnssUserResponseType::RESPONSE_NORESP:
288 data = GNSS_NI_RESPONSE_NO_RESPONSE;
289 break;
290 default:
291 data = GNSS_NI_RESPONSE_IGNORE;
292 break;
293 }
294
295 locAPIGnssNiResponse(notifId, data);
296 }
297
298 // these apis using LocationAPIControlClient
gnssDeleteAidingData(IGnss::GnssAidingData aidingDataFlags)299 void GnssAPIClient::gnssDeleteAidingData(IGnss::GnssAidingData aidingDataFlags)
300 {
301 LOC_LOGD("%s]: (%02hx)", __FUNCTION__, aidingDataFlags);
302 if (mControlClient == nullptr) {
303 return;
304 }
305 GnssAidingData data;
306 memset(&data, 0, sizeof (GnssAidingData));
307 data.sv.svTypeMask = GNSS_AIDING_DATA_SV_TYPE_GPS_BIT |
308 GNSS_AIDING_DATA_SV_TYPE_GLONASS_BIT |
309 GNSS_AIDING_DATA_SV_TYPE_QZSS_BIT |
310 GNSS_AIDING_DATA_SV_TYPE_BEIDOU_BIT |
311 GNSS_AIDING_DATA_SV_TYPE_GALILEO_BIT |
312 GNSS_AIDING_DATA_SV_TYPE_NAVIC_BIT;
313 data.posEngineMask = STANDARD_POSITIONING_ENGINE;
314
315 if (aidingDataFlags == IGnss::GnssAidingData::DELETE_ALL)
316 data.deleteAll = true;
317 else {
318 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_EPHEMERIS)
319 data.sv.svMask |= GNSS_AIDING_DATA_SV_EPHEMERIS_BIT;
320 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_ALMANAC)
321 data.sv.svMask |= GNSS_AIDING_DATA_SV_ALMANAC_BIT;
322 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_POSITION)
323 data.common.mask |= GNSS_AIDING_DATA_COMMON_POSITION_BIT;
324 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_TIME)
325 data.common.mask |= GNSS_AIDING_DATA_COMMON_TIME_BIT;
326 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_IONO)
327 data.sv.svMask |= GNSS_AIDING_DATA_SV_IONOSPHERE_BIT;
328 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_UTC)
329 data.common.mask |= GNSS_AIDING_DATA_COMMON_UTC_BIT;
330 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_HEALTH)
331 data.sv.svMask |= GNSS_AIDING_DATA_SV_HEALTH_BIT;
332 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_SVDIR)
333 data.sv.svMask |= GNSS_AIDING_DATA_SV_DIRECTION_BIT;
334 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_SVSTEER)
335 data.sv.svMask |= GNSS_AIDING_DATA_SV_STEER_BIT;
336 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_SADATA)
337 data.sv.svMask |= GNSS_AIDING_DATA_SV_SA_DATA_BIT;
338 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_RTI)
339 data.common.mask |= GNSS_AIDING_DATA_COMMON_RTI_BIT;
340 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_CELLDB_INFO)
341 data.common.mask |= GNSS_AIDING_DATA_COMMON_CELLDB_BIT;
342 }
343 mControlClient->locAPIGnssDeleteAidingData(data);
344 }
345
gnssEnable(LocationTechnologyType techType)346 void GnssAPIClient::gnssEnable(LocationTechnologyType techType)
347 {
348 LOC_LOGD("%s]: (%0d)", __FUNCTION__, techType);
349 if (mControlClient == nullptr) {
350 return;
351 }
352 mControlClient->locAPIEnable(techType);
353 }
354
gnssDisable()355 void GnssAPIClient::gnssDisable()
356 {
357 LOC_LOGD("%s]: ()", __FUNCTION__);
358 if (mControlClient == nullptr) {
359 return;
360 }
361 mControlClient->locAPIDisable();
362 }
363
gnssConfigurationUpdate(const GnssConfig & gnssConfig)364 void GnssAPIClient::gnssConfigurationUpdate(const GnssConfig& gnssConfig)
365 {
366 LOC_LOGD("%s]: (%02x)", __FUNCTION__, gnssConfig.flags);
367 if (mControlClient == nullptr) {
368 return;
369 }
370 mControlClient->locAPIGnssUpdateConfig(gnssConfig);
371 }
372
requestCapabilities()373 void GnssAPIClient::requestCapabilities() {
374 // only send capablities if it's already cached, otherwise the first time LocationAPI
375 // is initialized, capabilities will be sent by LocationAPI
376 if (mLocationCapabilitiesCached) {
377 onCapabilitiesCb(mLocationCapabilitiesMask);
378 }
379 }
380
381 // callbacks
onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)382 void GnssAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)
383 {
384 LOC_LOGD("%s]: (%" PRIu64 ")", __FUNCTION__, capabilitiesMask);
385 mLocationCapabilitiesMask = capabilitiesMask;
386 mLocationCapabilitiesCached = true;
387
388 mMutex.lock();
389 auto gnssCbIface(mGnssCbIface);
390 auto gnssCbIface_2_0(mGnssCbIface_2_0);
391 auto gnssCbIface_2_1(mGnssCbIface_2_1);
392 mMutex.unlock();
393
394 if (gnssCbIface_2_1 != nullptr ||gnssCbIface_2_0 != nullptr || gnssCbIface != nullptr) {
395
396 uint32_t antennaInfoVectorSize = 0;
397 uint32_t data = 0;
398 loc_param_s_type ant_info_vector_table[] =
399 {
400 { "ANTENNA_INFO_VECTOR_SIZE", &antennaInfoVectorSize, NULL, 'n' }
401 };
402 UTIL_READ_CONF(LOC_PATH_ANT_CORR, ant_info_vector_table);
403
404 if (0 != antennaInfoVectorSize) {
405 data |= V2_1::IGnssCallback::Capabilities::ANTENNA_INFO;
406 }
407
408 if ((capabilitiesMask & LOCATION_CAPABILITIES_TIME_BASED_TRACKING_BIT) ||
409 (capabilitiesMask & LOCATION_CAPABILITIES_TIME_BASED_BATCHING_BIT) ||
410 (capabilitiesMask & LOCATION_CAPABILITIES_DISTANCE_BASED_TRACKING_BIT) ||
411 (capabilitiesMask & LOCATION_CAPABILITIES_DISTANCE_BASED_BATCHING_BIT))
412 data |= IGnssCallback::Capabilities::SCHEDULING;
413 if (capabilitiesMask & LOCATION_CAPABILITIES_GEOFENCE_BIT)
414 data |= V1_0::IGnssCallback::Capabilities::GEOFENCING;
415 if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT)
416 data |= V1_0::IGnssCallback::Capabilities::MEASUREMENTS;
417 if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MSB_BIT)
418 data |= IGnssCallback::Capabilities::MSB;
419 if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MSA_BIT)
420 data |= IGnssCallback::Capabilities::MSA;
421 if (capabilitiesMask & LOCATION_CAPABILITIES_AGPM_BIT)
422 data |= IGnssCallback::Capabilities::LOW_POWER_MODE;
423 if (capabilitiesMask & LOCATION_CAPABILITIES_CONSTELLATION_ENABLEMENT_BIT)
424 data |= IGnssCallback::Capabilities::SATELLITE_BLACKLIST;
425 if (capabilitiesMask & LOCATION_CAPABILITIES_MEASUREMENTS_CORRECTION_BIT)
426 data |= V2_0::IGnssCallback::Capabilities::MEASUREMENT_CORRECTIONS;
427
428 IGnssCallback::GnssSystemInfo gnssInfo = { .yearOfHw = 2015 };
429
430 if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT) {
431 gnssInfo.yearOfHw++; // 2016
432 if (capabilitiesMask & LOCATION_CAPABILITIES_DEBUG_NMEA_BIT) {
433 gnssInfo.yearOfHw++; // 2017
434 if (capabilitiesMask & LOCATION_CAPABILITIES_CONSTELLATION_ENABLEMENT_BIT ||
435 capabilitiesMask & LOCATION_CAPABILITIES_AGPM_BIT) {
436 gnssInfo.yearOfHw++; // 2018
437 if (capabilitiesMask & LOCATION_CAPABILITIES_PRIVACY_BIT) {
438 gnssInfo.yearOfHw++; // 2019
439 if (capabilitiesMask & LOCATION_CAPABILITIES_MEASUREMENTS_CORRECTION_BIT) {
440 gnssInfo.yearOfHw++; // 2020
441 }
442 }
443 }
444 }
445 }
446 LOC_LOGV("%s:%d] set_system_info_cb (%d)", __FUNCTION__, __LINE__, gnssInfo.yearOfHw);
447
448 if (gnssCbIface_2_1 != nullptr) {
449 auto r = gnssCbIface_2_1->gnssSetCapabilitiesCb_2_1(data);
450 if (!r.isOk()) {
451 LOC_LOGE("%s] Error from gnssSetCapabilitiesCb_2_1 description=%s",
452 __func__, r.description().c_str());
453 }
454 r = gnssCbIface_2_1->gnssSetSystemInfoCb(gnssInfo);
455 if (!r.isOk()) {
456 LOC_LOGE("%s] Error from gnssSetSystemInfoCb description=%s",
457 __func__, r.description().c_str());
458 }
459 } else if (gnssCbIface_2_0 != nullptr) {
460 auto r = gnssCbIface_2_0->gnssSetCapabilitiesCb_2_0(data);
461 if (!r.isOk()) {
462 LOC_LOGE("%s] Error from gnssSetCapabilitiesCb_2_0 description=%s",
463 __func__, r.description().c_str());
464 }
465 r = gnssCbIface_2_0->gnssSetSystemInfoCb(gnssInfo);
466 if (!r.isOk()) {
467 LOC_LOGE("%s] Error from gnssSetSystemInfoCb description=%s",
468 __func__, r.description().c_str());
469 }
470 } else if (gnssCbIface != nullptr) {
471 auto r = gnssCbIface->gnssSetCapabilitesCb(data);
472 if (!r.isOk()) {
473 LOC_LOGE("%s] Error from gnssSetCapabilitesCb description=%s",
474 __func__, r.description().c_str());
475 }
476 r = gnssCbIface->gnssSetSystemInfoCb(gnssInfo);
477 if (!r.isOk()) {
478 LOC_LOGE("%s] Error from gnssSetSystemInfoCb description=%s",
479 __func__, r.description().c_str());
480 }
481 }
482
483 }
484
485 }
486
onTrackingCb(Location location)487 void GnssAPIClient::onTrackingCb(Location location)
488 {
489 mMutex.lock();
490 auto gnssCbIface(mGnssCbIface);
491 auto gnssCbIface_2_0(mGnssCbIface_2_0);
492 auto gnssCbIface_2_1(mGnssCbIface_2_1);
493 bool isTracking = mTracking;
494 mMutex.unlock();
495
496 LOC_LOGD("%s]: (flags: %02x isTracking: %d)", __FUNCTION__, location.flags, isTracking);
497
498 if (!isTracking) {
499 return;
500 }
501
502 if (gnssCbIface_2_1 != nullptr) {
503 V2_0::GnssLocation gnssLocation;
504 convertGnssLocation(location, gnssLocation);
505 auto r = gnssCbIface_2_1->gnssLocationCb_2_0(gnssLocation);
506 if (!r.isOk()) {
507 LOC_LOGE("%s] Error from gnssLocationCb_2_0 description=%s",
508 __func__, r.description().c_str());
509 }
510 } else if (gnssCbIface_2_0 != nullptr) {
511 V2_0::GnssLocation gnssLocation;
512 convertGnssLocation(location, gnssLocation);
513 auto r = gnssCbIface_2_0->gnssLocationCb_2_0(gnssLocation);
514 if (!r.isOk()) {
515 LOC_LOGE("%s] Error from gnssLocationCb_2_0 description=%s",
516 __func__, r.description().c_str());
517 }
518 } else if (gnssCbIface != nullptr) {
519 V1_0::GnssLocation gnssLocation;
520 convertGnssLocation(location, gnssLocation);
521 auto r = gnssCbIface->gnssLocationCb(gnssLocation);
522 if (!r.isOk()) {
523 LOC_LOGE("%s] Error from gnssLocationCb description=%s",
524 __func__, r.description().c_str());
525 }
526 } else {
527 LOC_LOGW("%s] No GNSS Interface ready for gnssLocationCb ", __FUNCTION__);
528 }
529
530 }
531
onGnssNiCb(uint32_t id,GnssNiNotification gnssNiNotification)532 void GnssAPIClient::onGnssNiCb(uint32_t id, GnssNiNotification gnssNiNotification)
533 {
534 LOC_LOGD("%s]: (id: %d)", __FUNCTION__, id);
535 mMutex.lock();
536 auto gnssNiCbIface(mGnssNiCbIface);
537 mMutex.unlock();
538
539 if (gnssNiCbIface == nullptr) {
540 LOC_LOGE("%s]: mGnssNiCbIface is nullptr", __FUNCTION__);
541 return;
542 }
543
544 IGnssNiCallback::GnssNiNotification notificationGnss = {};
545
546 notificationGnss.notificationId = id;
547
548 if (gnssNiNotification.type == GNSS_NI_TYPE_VOICE)
549 notificationGnss.niType = IGnssNiCallback::GnssNiType::VOICE;
550 else if (gnssNiNotification.type == GNSS_NI_TYPE_SUPL)
551 notificationGnss.niType = IGnssNiCallback::GnssNiType::UMTS_SUPL;
552 else if (gnssNiNotification.type == GNSS_NI_TYPE_CONTROL_PLANE)
553 notificationGnss.niType = IGnssNiCallback::GnssNiType::UMTS_CTRL_PLANE;
554 else if (gnssNiNotification.type == GNSS_NI_TYPE_EMERGENCY_SUPL)
555 notificationGnss.niType = IGnssNiCallback::GnssNiType::EMERGENCY_SUPL;
556
557 if (gnssNiNotification.options & GNSS_NI_OPTIONS_NOTIFICATION_BIT)
558 notificationGnss.notifyFlags |= IGnssNiCallback::GnssNiNotifyFlags::NEED_NOTIFY;
559 if (gnssNiNotification.options & GNSS_NI_OPTIONS_VERIFICATION_BIT)
560 notificationGnss.notifyFlags |= IGnssNiCallback::GnssNiNotifyFlags::NEED_VERIFY;
561 if (gnssNiNotification.options & GNSS_NI_OPTIONS_PRIVACY_OVERRIDE_BIT)
562 notificationGnss.notifyFlags |= IGnssNiCallback::GnssNiNotifyFlags::PRIVACY_OVERRIDE;
563
564 notificationGnss.timeoutSec = gnssNiNotification.timeout;
565
566 if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_ACCEPT)
567 notificationGnss.defaultResponse = IGnssNiCallback::GnssUserResponseType::RESPONSE_ACCEPT;
568 else if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_DENY)
569 notificationGnss.defaultResponse = IGnssNiCallback::GnssUserResponseType::RESPONSE_DENY;
570 else if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_NO_RESPONSE ||
571 gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_IGNORE)
572 notificationGnss.defaultResponse = IGnssNiCallback::GnssUserResponseType::RESPONSE_NORESP;
573
574 notificationGnss.requestorId = gnssNiNotification.requestor;
575
576 notificationGnss.notificationMessage = gnssNiNotification.message;
577
578 if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_NONE)
579 notificationGnss.requestorIdEncoding =
580 IGnssNiCallback::GnssNiEncodingType::ENC_NONE;
581 else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_GSM_DEFAULT)
582 notificationGnss.requestorIdEncoding =
583 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_GSM_DEFAULT;
584 else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_UTF8)
585 notificationGnss.requestorIdEncoding =
586 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UTF8;
587 else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_UCS2)
588 notificationGnss.requestorIdEncoding =
589 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UCS2;
590
591 if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_NONE)
592 notificationGnss.notificationIdEncoding =
593 IGnssNiCallback::GnssNiEncodingType::ENC_NONE;
594 else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_GSM_DEFAULT)
595 notificationGnss.notificationIdEncoding =
596 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_GSM_DEFAULT;
597 else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_UTF8)
598 notificationGnss.notificationIdEncoding =
599 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UTF8;
600 else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_UCS2)
601 notificationGnss.notificationIdEncoding =
602 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UCS2;
603
604 gnssNiCbIface->niNotifyCb(notificationGnss);
605 }
606
onGnssSvCb(GnssSvNotification gnssSvNotification)607 void GnssAPIClient::onGnssSvCb(GnssSvNotification gnssSvNotification)
608 {
609 LOC_LOGD("%s]: (count: %u)", __FUNCTION__, gnssSvNotification.count);
610 mMutex.lock();
611 auto gnssCbIface(mGnssCbIface);
612 auto gnssCbIface_2_0(mGnssCbIface_2_0);
613 auto gnssCbIface_2_1(mGnssCbIface_2_1);
614 mMutex.unlock();
615
616 if (gnssCbIface_2_1 != nullptr) {
617 hidl_vec<V2_1::IGnssCallback::GnssSvInfo> svInfoList;
618 convertGnssSvStatus(gnssSvNotification, svInfoList);
619 auto r = gnssCbIface_2_1->gnssSvStatusCb_2_1(svInfoList);
620 if (!r.isOk()) {
621 LOC_LOGE("%s] Error from gnssSvStatusCb_2_1 description=%s",
622 __func__, r.description().c_str());
623 }
624 } else if (gnssCbIface_2_0 != nullptr) {
625 hidl_vec<V2_0::IGnssCallback::GnssSvInfo> svInfoList;
626 convertGnssSvStatus(gnssSvNotification, svInfoList);
627 auto r = gnssCbIface_2_0->gnssSvStatusCb_2_0(svInfoList);
628 if (!r.isOk()) {
629 LOC_LOGE("%s] Error from gnssSvStatusCb_2_0 description=%s",
630 __func__, r.description().c_str());
631 }
632 } else if (gnssCbIface != nullptr) {
633 V1_0::IGnssCallback::GnssSvStatus svStatus;
634 convertGnssSvStatus(gnssSvNotification, svStatus);
635 auto r = gnssCbIface->gnssSvStatusCb(svStatus);
636 if (!r.isOk()) {
637 LOC_LOGE("%s] Error from gnssSvStatusCb description=%s",
638 __func__, r.description().c_str());
639 }
640 }
641 }
642
onGnssNmeaCb(GnssNmeaNotification gnssNmeaNotification)643 void GnssAPIClient::onGnssNmeaCb(GnssNmeaNotification gnssNmeaNotification)
644 {
645 mMutex.lock();
646 auto gnssCbIface(mGnssCbIface);
647 auto gnssCbIface_2_0(mGnssCbIface_2_0);
648 auto gnssCbIface_2_1(mGnssCbIface_2_1);
649 mMutex.unlock();
650
651 if (gnssCbIface != nullptr || gnssCbIface_2_0 != nullptr || gnssCbIface_2_1 != nullptr) {
652 const std::string s(gnssNmeaNotification.nmea);
653 std::stringstream ss(s);
654 std::string each;
655 while(std::getline(ss, each, '\n')) {
656 each += '\n';
657 android::hardware::hidl_string nmeaString;
658 nmeaString.setToExternal(each.c_str(), each.length());
659 if (gnssCbIface_2_1 != nullptr) {
660 auto r = gnssCbIface_2_1->gnssNmeaCb(
661 static_cast<V1_0::GnssUtcTime>(gnssNmeaNotification.timestamp), nmeaString);
662 if (!r.isOk()) {
663 LOC_LOGE("%s] Error from gnssCbIface_2_1 nmea=%s length=%u description=%s",
664 __func__, gnssNmeaNotification.nmea, gnssNmeaNotification.length,
665 r.description().c_str());
666 }
667 } else if (gnssCbIface_2_0 != nullptr) {
668 auto r = gnssCbIface_2_0->gnssNmeaCb(
669 static_cast<V1_0::GnssUtcTime>(gnssNmeaNotification.timestamp), nmeaString);
670 if (!r.isOk()) {
671 LOC_LOGE("%s] Error from gnssCbIface_2_0 nmea=%s length=%u description=%s",
672 __func__, gnssNmeaNotification.nmea, gnssNmeaNotification.length,
673 r.description().c_str());
674 }
675 } else if (gnssCbIface != nullptr) {
676 auto r = gnssCbIface->gnssNmeaCb(
677 static_cast<V1_0::GnssUtcTime>(gnssNmeaNotification.timestamp), nmeaString);
678 if (!r.isOk()) {
679 LOC_LOGE("%s] Error from gnssNmeaCb nmea=%s length=%u description=%s",
680 __func__, gnssNmeaNotification.nmea, gnssNmeaNotification.length,
681 r.description().c_str());
682 }
683 }
684 }
685 }
686 }
687
onStartTrackingCb(LocationError error)688 void GnssAPIClient::onStartTrackingCb(LocationError error)
689 {
690 LOC_LOGD("%s]: (%d)", __FUNCTION__, error);
691 mMutex.lock();
692 auto gnssCbIface(mGnssCbIface);
693 auto gnssCbIface_2_0(mGnssCbIface_2_0);
694 auto gnssCbIface_2_1(mGnssCbIface_2_1);
695 mMutex.unlock();
696
697 if (error == LOCATION_ERROR_SUCCESS) {
698 if (gnssCbIface_2_1 != nullptr) {
699 auto r = gnssCbIface_2_1->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_ON);
700 if (!r.isOk()) {
701 LOC_LOGE("%s] Error from gnssStatusCb 2_0 ENGINE_ON description=%s",
702 __func__, r.description().c_str());
703 }
704 r = gnssCbIface_2_1->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_BEGIN);
705 if (!r.isOk()) {
706 LOC_LOGE("%s] Error from gnssStatusCb 2_0 SESSION_BEGIN description=%s",
707 __func__, r.description().c_str());
708 }
709 } else if (gnssCbIface_2_0 != nullptr) {
710 auto r = gnssCbIface_2_0->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_ON);
711 if (!r.isOk()) {
712 LOC_LOGE("%s] Error from gnssStatusCb 2_0 ENGINE_ON description=%s",
713 __func__, r.description().c_str());
714 }
715 r = gnssCbIface_2_0->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_BEGIN);
716 if (!r.isOk()) {
717 LOC_LOGE("%s] Error from gnssStatusCb 2_0 SESSION_BEGIN description=%s",
718 __func__, r.description().c_str());
719 }
720 } else if (gnssCbIface != nullptr) {
721 auto r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_ON);
722 if (!r.isOk()) {
723 LOC_LOGE("%s] Error from gnssStatusCb ENGINE_ON description=%s",
724 __func__, r.description().c_str());
725 }
726 r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_BEGIN);
727 if (!r.isOk()) {
728 LOC_LOGE("%s] Error from gnssStatusCb SESSION_BEGIN description=%s",
729 __func__, r.description().c_str());
730 }
731 }
732 }
733 }
734
onStopTrackingCb(LocationError error)735 void GnssAPIClient::onStopTrackingCb(LocationError error)
736 {
737 LOC_LOGD("%s]: (%d)", __FUNCTION__, error);
738 mMutex.lock();
739 auto gnssCbIface(mGnssCbIface);
740 auto gnssCbIface_2_0(mGnssCbIface_2_0);
741 auto gnssCbIface_2_1(mGnssCbIface_2_1);
742 mMutex.unlock();
743
744 if (error == LOCATION_ERROR_SUCCESS) {
745 if (gnssCbIface_2_1 != nullptr) {
746 auto r = gnssCbIface_2_1->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_END);
747 if (!r.isOk()) {
748 LOC_LOGE("%s] Error from gnssStatusCb 2_0 SESSION_END description=%s",
749 __func__, r.description().c_str());
750 }
751 r = gnssCbIface_2_1->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_OFF);
752 if (!r.isOk()) {
753 LOC_LOGE("%s] Error from gnssStatusCb 2_0 ENGINE_OFF description=%s",
754 __func__, r.description().c_str());
755 }
756 } else if (gnssCbIface_2_0 != nullptr) {
757 auto r = gnssCbIface_2_0->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_END);
758 if (!r.isOk()) {
759 LOC_LOGE("%s] Error from gnssStatusCb 2_0 SESSION_END description=%s",
760 __func__, r.description().c_str());
761 }
762 r = gnssCbIface_2_0->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_OFF);
763 if (!r.isOk()) {
764 LOC_LOGE("%s] Error from gnssStatusCb 2_0 ENGINE_OFF description=%s",
765 __func__, r.description().c_str());
766 }
767
768 } else if (gnssCbIface != nullptr) {
769 auto r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_END);
770 if (!r.isOk()) {
771 LOC_LOGE("%s] Error from gnssStatusCb SESSION_END description=%s",
772 __func__, r.description().c_str());
773 }
774 r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_OFF);
775 if (!r.isOk()) {
776 LOC_LOGE("%s] Error from gnssStatusCb ENGINE_OFF description=%s",
777 __func__, r.description().c_str());
778 }
779 }
780 }
781 }
782
convertGnssSvStatus(GnssSvNotification & in,V1_0::IGnssCallback::GnssSvStatus & out)783 static void convertGnssSvStatus(GnssSvNotification& in, V1_0::IGnssCallback::GnssSvStatus& out)
784 {
785 memset(&out, 0, sizeof(IGnssCallback::GnssSvStatus));
786 out.numSvs = in.count;
787 if (out.numSvs > static_cast<uint32_t>(V1_0::GnssMax::SVS_COUNT)) {
788 LOC_LOGW("%s]: Too many satellites %u. Clamps to %d.",
789 __FUNCTION__, out.numSvs, V1_0::GnssMax::SVS_COUNT);
790 out.numSvs = static_cast<uint32_t>(V1_0::GnssMax::SVS_COUNT);
791 }
792 for (size_t i = 0; i < out.numSvs; i++) {
793 convertGnssSvid(in.gnssSvs[i], out.gnssSvList[i].svid);
794 convertGnssConstellationType(in.gnssSvs[i].type, out.gnssSvList[i].constellation);
795 out.gnssSvList[i].cN0Dbhz = in.gnssSvs[i].cN0Dbhz;
796 out.gnssSvList[i].elevationDegrees = in.gnssSvs[i].elevation;
797 out.gnssSvList[i].azimuthDegrees = in.gnssSvs[i].azimuth;
798 out.gnssSvList[i].carrierFrequencyHz = in.gnssSvs[i].carrierFrequencyHz;
799 out.gnssSvList[i].svFlag = static_cast<uint8_t>(IGnssCallback::GnssSvFlags::NONE);
800 if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_EPHEMER_BIT)
801 out.gnssSvList[i].svFlag |= IGnssCallback::GnssSvFlags::HAS_EPHEMERIS_DATA;
802 if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_ALMANAC_BIT)
803 out.gnssSvList[i].svFlag |= IGnssCallback::GnssSvFlags::HAS_ALMANAC_DATA;
804 if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_USED_IN_FIX_BIT)
805 out.gnssSvList[i].svFlag |= IGnssCallback::GnssSvFlags::USED_IN_FIX;
806 if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_CARRIER_FREQUENCY_BIT)
807 out.gnssSvList[i].svFlag |= IGnssCallback::GnssSvFlags::HAS_CARRIER_FREQUENCY;
808 }
809 }
810
convertGnssSvStatus(GnssSvNotification & in,hidl_vec<V2_0::IGnssCallback::GnssSvInfo> & out)811 static void convertGnssSvStatus(GnssSvNotification& in,
812 hidl_vec<V2_0::IGnssCallback::GnssSvInfo>& out)
813 {
814 out.resize(in.count);
815 for (size_t i = 0; i < in.count; i++) {
816 convertGnssSvid(in.gnssSvs[i], out[i].v1_0.svid);
817 out[i].v1_0.cN0Dbhz = in.gnssSvs[i].cN0Dbhz;
818 out[i].v1_0.elevationDegrees = in.gnssSvs[i].elevation;
819 out[i].v1_0.azimuthDegrees = in.gnssSvs[i].azimuth;
820 out[i].v1_0.carrierFrequencyHz = in.gnssSvs[i].carrierFrequencyHz;
821 out[i].v1_0.svFlag = static_cast<uint8_t>(IGnssCallback::GnssSvFlags::NONE);
822 if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_EPHEMER_BIT)
823 out[i].v1_0.svFlag |= IGnssCallback::GnssSvFlags::HAS_EPHEMERIS_DATA;
824 if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_ALMANAC_BIT)
825 out[i].v1_0.svFlag |= IGnssCallback::GnssSvFlags::HAS_ALMANAC_DATA;
826 if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_USED_IN_FIX_BIT)
827 out[i].v1_0.svFlag |= IGnssCallback::GnssSvFlags::USED_IN_FIX;
828 if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_CARRIER_FREQUENCY_BIT)
829 out[i].v1_0.svFlag |= IGnssCallback::GnssSvFlags::HAS_CARRIER_FREQUENCY;
830
831 convertGnssConstellationType(in.gnssSvs[i].type, out[i].constellation);
832 }
833 }
834
convertGnssSvStatus(GnssSvNotification & in,hidl_vec<V2_1::IGnssCallback::GnssSvInfo> & out)835 static void convertGnssSvStatus(GnssSvNotification& in,
836 hidl_vec<V2_1::IGnssCallback::GnssSvInfo>& out)
837 {
838 out.resize(in.count);
839 for (size_t i = 0; i < in.count; i++) {
840 convertGnssSvid(in.gnssSvs[i], out[i].v2_0.v1_0.svid);
841 out[i].v2_0.v1_0.cN0Dbhz = in.gnssSvs[i].cN0Dbhz;
842 out[i].v2_0.v1_0.elevationDegrees = in.gnssSvs[i].elevation;
843 out[i].v2_0.v1_0.azimuthDegrees = in.gnssSvs[i].azimuth;
844 out[i].v2_0.v1_0.carrierFrequencyHz = in.gnssSvs[i].carrierFrequencyHz;
845 out[i].v2_0.v1_0.svFlag = static_cast<uint8_t>(IGnssCallback::GnssSvFlags::NONE);
846 if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_EPHEMER_BIT)
847 out[i].v2_0.v1_0.svFlag |= IGnssCallback::GnssSvFlags::HAS_EPHEMERIS_DATA;
848 if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_ALMANAC_BIT)
849 out[i].v2_0.v1_0.svFlag |= IGnssCallback::GnssSvFlags::HAS_ALMANAC_DATA;
850 if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_USED_IN_FIX_BIT)
851 out[i].v2_0.v1_0.svFlag |= IGnssCallback::GnssSvFlags::USED_IN_FIX;
852 if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_CARRIER_FREQUENCY_BIT)
853 out[i].v2_0.v1_0.svFlag |= IGnssCallback::GnssSvFlags::HAS_CARRIER_FREQUENCY;
854
855 convertGnssConstellationType(in.gnssSvs[i].type, out[i].v2_0.constellation);
856 out[i].basebandCN0DbHz = in.gnssSvs[i].basebandCarrierToNoiseDbHz;
857 }
858 }
859
860 } // namespace implementation
861 } // namespace V2_1
862 } // namespace gnss
863 } // namespace hardware
864 } // namespace android
865