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