• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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