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