1 /* Copyright (c) 2017, The Linux Foundation. All rights reserved. 2 * 3 * Redistribution and use in source and binary forms, with or without 4 * modification, are permitted provided that the following conditions are 5 * met: 6 * * Redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer. 8 * * Redistributions in binary form must reproduce the above 9 * copyright notice, this list of conditions and the following 10 * disclaimer in the documentation and/or other materials provided 11 * with the distribution. 12 * * Neither the name of The Linux Foundation, nor the names of its 13 * contributors may be used to endorse or promote products derived 14 * from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 */ 29 30 #define LOG_NDDEBUG 0 31 #define LOG_TAG "LocSvc_GnssAPIClient" 32 33 #include <log_util.h> 34 #include <loc_cfg.h> 35 36 #include "LocationUtil.h" 37 #include "GnssAPIClient.h" 38 39 namespace android { 40 namespace hardware { 41 namespace gnss { 42 namespace V1_0 { 43 namespace implementation { 44 45 static void convertGnssSvStatus(GnssSvNotification& in, IGnssCallback::GnssSvStatus& out); 46 47 GnssAPIClient::GnssAPIClient(const sp<IGnssCallback>& gpsCb, 48 const sp<IGnssNiCallback>& niCb) : 49 LocationAPIClientBase(), 50 mGnssCbIface(nullptr), 51 mGnssNiCbIface(nullptr), 52 mLocationCapabilitiesMask(0) 53 { 54 LOC_LOGD("%s]: (%p %p)", __FUNCTION__, &gpsCb, &niCb); 55 56 // set default LocationOptions. 57 memset(&mLocationOptions, 0, sizeof(LocationOptions)); 58 mLocationOptions.size = sizeof(LocationOptions); 59 mLocationOptions.minInterval = 1000; 60 mLocationOptions.minDistance = 0; 61 mLocationOptions.mode = GNSS_SUPL_MODE_STANDALONE; 62 63 gnssUpdateCallbacks(gpsCb, niCb); 64 } 65 66 GnssAPIClient::~GnssAPIClient() 67 { 68 LOC_LOGD("%s]: ()", __FUNCTION__); 69 } 70 71 // for GpsInterface 72 void GnssAPIClient::gnssUpdateCallbacks(const sp<IGnssCallback>& gpsCb, 73 const sp<IGnssNiCallback>& niCb) 74 { 75 LOC_LOGD("%s]: (%p %p)", __FUNCTION__, &gpsCb, &niCb); 76 77 mGnssCbIface = gpsCb; 78 mGnssNiCbIface = niCb; 79 80 LocationCallbacks locationCallbacks; 81 locationCallbacks.size = sizeof(LocationCallbacks); 82 83 locationCallbacks.trackingCb = nullptr; 84 if (mGnssCbIface != nullptr) { 85 locationCallbacks.trackingCb = [this](Location location) { 86 onTrackingCb(location); 87 }; 88 } 89 90 locationCallbacks.batchingCb = nullptr; 91 locationCallbacks.geofenceBreachCb = nullptr; 92 locationCallbacks.geofenceStatusCb = nullptr; 93 locationCallbacks.gnssLocationInfoCb = nullptr; 94 95 locationCallbacks.gnssNiCb = nullptr; 96 if (mGnssNiCbIface != nullptr) { 97 locationCallbacks.gnssNiCb = [this](uint32_t id, GnssNiNotification gnssNiNotification) { 98 onGnssNiCb(id, gnssNiNotification); 99 }; 100 } 101 102 locationCallbacks.gnssSvCb = nullptr; 103 if (mGnssCbIface != nullptr) { 104 locationCallbacks.gnssSvCb = [this](GnssSvNotification gnssSvNotification) { 105 onGnssSvCb(gnssSvNotification); 106 }; 107 } 108 109 locationCallbacks.gnssNmeaCb = nullptr; 110 if (mGnssCbIface != nullptr) { 111 locationCallbacks.gnssNmeaCb = [this](GnssNmeaNotification gnssNmeaNotification) { 112 onGnssNmeaCb(gnssNmeaNotification); 113 }; 114 } 115 116 locationCallbacks.gnssMeasurementsCb = nullptr; 117 118 locAPISetCallbacks(locationCallbacks); 119 } 120 121 bool GnssAPIClient::gnssStart() 122 { 123 LOC_LOGD("%s]: ()", __FUNCTION__); 124 bool retVal = true; 125 locAPIStartTracking(mLocationOptions); 126 return retVal; 127 } 128 129 bool GnssAPIClient::gnssStop() 130 { 131 LOC_LOGD("%s]: ()", __FUNCTION__); 132 bool retVal = true; 133 locAPIStopTracking(); 134 return retVal; 135 } 136 137 void GnssAPIClient::gnssDeleteAidingData(IGnss::GnssAidingData aidingDataFlags) 138 { 139 LOC_LOGD("%s]: (%02hx)", __FUNCTION__, aidingDataFlags); 140 GnssAidingData data; 141 memset(&data, 0, sizeof (GnssAidingData)); 142 data.sv.svTypeMask = GNSS_AIDING_DATA_SV_TYPE_GPS | 143 GNSS_AIDING_DATA_SV_TYPE_GLONASS | 144 GNSS_AIDING_DATA_SV_TYPE_QZSS | 145 GNSS_AIDING_DATA_SV_TYPE_BEIDOU | 146 GNSS_AIDING_DATA_SV_TYPE_GALILEO; 147 148 if (aidingDataFlags == IGnss::GnssAidingData::DELETE_ALL) 149 data.deleteAll = true; 150 else { 151 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_EPHEMERIS) 152 data.sv.svMask |= GNSS_AIDING_DATA_SV_EPHEMERIS; 153 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_ALMANAC) 154 data.sv.svMask |= GNSS_AIDING_DATA_SV_ALMANAC; 155 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_POSITION) 156 data.common.mask |= GNSS_AIDING_DATA_COMMON_POSITION; 157 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_TIME) 158 data.common.mask |= GNSS_AIDING_DATA_COMMON_TIME; 159 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_IONO) 160 data.sv.svMask |= GNSS_AIDING_DATA_SV_IONOSPHERE; 161 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_UTC) 162 data.common.mask |= GNSS_AIDING_DATA_COMMON_UTC; 163 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_HEALTH) 164 data.sv.svMask |= GNSS_AIDING_DATA_SV_HEALTH; 165 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_SVDIR) 166 data.sv.svMask |= GNSS_AIDING_DATA_SV_DIRECTION; 167 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_SVSTEER) 168 data.sv.svMask |= GNSS_AIDING_DATA_SV_STEER; 169 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_SADATA) 170 data.sv.svMask |= GNSS_AIDING_DATA_SV_SA_DATA; 171 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_RTI) 172 data.common.mask |= GNSS_AIDING_DATA_COMMON_RTI; 173 if (aidingDataFlags & IGnss::GnssAidingData::DELETE_CELLDB_INFO) 174 data.common.mask |= GNSS_AIDING_DATA_COMMON_CELLDB; 175 } 176 locAPIGnssDeleteAidingData(data); 177 } 178 179 bool GnssAPIClient::gnssSetPositionMode(IGnss::GnssPositionMode mode, 180 IGnss::GnssPositionRecurrence recurrence, uint32_t minIntervalMs, 181 uint32_t preferredAccuracyMeters, uint32_t preferredTimeMs) 182 { 183 LOC_LOGD("%s]: (%d %d %d %d %d)", __FUNCTION__, 184 (int)mode, recurrence, minIntervalMs, preferredAccuracyMeters, preferredTimeMs); 185 bool retVal = true; 186 memset(&mLocationOptions, 0, sizeof(LocationOptions)); 187 mLocationOptions.size = sizeof(LocationOptions); 188 mLocationOptions.minInterval = minIntervalMs; 189 mLocationOptions.minDistance = preferredAccuracyMeters; 190 if (mode == IGnss::GnssPositionMode::STANDALONE) 191 mLocationOptions.mode = GNSS_SUPL_MODE_STANDALONE; 192 else if (mode == IGnss::GnssPositionMode::MS_BASED) 193 mLocationOptions.mode = GNSS_SUPL_MODE_MSB; 194 else if (mode == IGnss::GnssPositionMode::MS_ASSISTED) 195 mLocationOptions.mode = GNSS_SUPL_MODE_MSA; 196 return retVal; 197 } 198 199 // for GpsNiInterface 200 void GnssAPIClient::gnssNiRespond(int32_t notifId, 201 IGnssNiCallback::GnssUserResponseType userResponse) 202 { 203 LOC_LOGD("%s]: (%d %d)", __FUNCTION__, notifId, static_cast<int>(userResponse)); 204 GnssNiResponse data = GNSS_NI_RESPONSE_IGNORE; 205 if (userResponse == IGnssNiCallback::GnssUserResponseType::RESPONSE_ACCEPT) 206 data = GNSS_NI_RESPONSE_ACCEPT; 207 else if (userResponse == IGnssNiCallback::GnssUserResponseType::RESPONSE_DENY) 208 data = GNSS_NI_RESPONSE_DENY; 209 else if (userResponse == IGnssNiCallback::GnssUserResponseType::RESPONSE_NORESP) 210 data = GNSS_NI_RESPONSE_NO_RESPONSE; 211 locAPIGnssNiResponse(notifId, data); 212 } 213 214 // for GnssConfigurationInterface 215 void GnssAPIClient::gnssConfigurationUpdate(const GnssConfig& gnssConfig) 216 { 217 LOC_LOGD("%s]: (%02x)", __FUNCTION__, gnssConfig.flags); 218 locAPIGnssUpdateConfig(gnssConfig); 219 } 220 221 // callbacks 222 void GnssAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask) 223 { 224 LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask); 225 mLocationCapabilitiesMask = capabilitiesMask; 226 if (mGnssCbIface != nullptr) { 227 uint32_t data = 0; 228 if ((capabilitiesMask & LOCATION_CAPABILITIES_TIME_BASED_TRACKING_BIT) || 229 (capabilitiesMask & LOCATION_CAPABILITIES_TIME_BASED_BATCHING_BIT) || 230 (capabilitiesMask & LOCATION_CAPABILITIES_DISTANCE_BASED_TRACKING_BIT) || 231 (capabilitiesMask & LOCATION_CAPABILITIES_DISTANCE_BASED_BATCHING_BIT)) 232 data |= IGnssCallback::Capabilities::SCHEDULING; 233 if (capabilitiesMask & LOCATION_CAPABILITIES_GEOFENCE_BIT) 234 data |= IGnssCallback::Capabilities::GEOFENCING; 235 if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT) 236 data |= IGnssCallback::Capabilities::MEASUREMENTS; 237 if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MSB_BIT) 238 data |= IGnssCallback::Capabilities::MSB; 239 if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MSA_BIT) 240 data |= IGnssCallback::Capabilities::MSA; 241 mGnssCbIface->gnssSetCapabilitesCb(data); 242 } 243 if (mGnssCbIface != nullptr) { 244 IGnssCallback::GnssSystemInfo gnssInfo; 245 gnssInfo.yearOfHw = 2015; 246 if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT) { 247 gnssInfo.yearOfHw = 2017; 248 } 249 LOC_LOGV("%s:%d] set_system_info_cb (%d)", __FUNCTION__, __LINE__, gnssInfo.yearOfHw); 250 mGnssCbIface->gnssSetSystemInfoCb(gnssInfo); 251 } 252 } 253 254 void GnssAPIClient::onTrackingCb(Location location) 255 { 256 LOC_LOGD("%s]: (flags: %02x)", __FUNCTION__, location.flags); 257 if (mGnssCbIface != nullptr) { 258 GnssLocation gnssLocation; 259 convertGnssLocation(location, gnssLocation); 260 mGnssCbIface->gnssLocationCb(gnssLocation); 261 } 262 } 263 264 void GnssAPIClient::onGnssNiCb(uint32_t id, GnssNiNotification gnssNiNotification) 265 { 266 LOC_LOGD("%s]: (id: %d)", __FUNCTION__, id); 267 268 if (mGnssNiCbIface == nullptr) { 269 LOC_LOGE("%s]: mGnssNiCbIface is nullptr", __FUNCTION__); 270 return; 271 } 272 273 IGnssNiCallback::GnssNiNotification notificationGnss; 274 275 notificationGnss.notificationId = id; 276 277 if (gnssNiNotification.type == GNSS_NI_TYPE_VOICE) 278 notificationGnss.niType = IGnssNiCallback::GnssNiType::VOICE; 279 else if (gnssNiNotification.type == GNSS_NI_TYPE_SUPL) 280 notificationGnss.niType = IGnssNiCallback::GnssNiType::UMTS_SUPL; 281 else if (gnssNiNotification.type == GNSS_NI_TYPE_CONTROL_PLANE) 282 notificationGnss.niType = IGnssNiCallback::GnssNiType::UMTS_CTRL_PLANE; 283 // GNSS_NI_TYPE_EMERGENCY_SUPL not supported 284 285 if (gnssNiNotification.options == GNSS_NI_OPTIONS_NOTIFICATION) 286 notificationGnss.notifyFlags = 287 static_cast<uint32_t>(IGnssNiCallback::GnssNiNotifyFlags::NEED_NOTIFY); 288 else if (gnssNiNotification.options == GNSS_NI_OPTIONS_VERIFICATION) 289 notificationGnss.notifyFlags = 290 static_cast<uint32_t>(IGnssNiCallback::GnssNiNotifyFlags::NEED_VERIFY); 291 else if (gnssNiNotification.options == GNSS_NI_OPTIONS_PRIVACY_OVERRIDE) 292 notificationGnss.notifyFlags = 293 static_cast<uint32_t>(IGnssNiCallback::GnssNiNotifyFlags::PRIVACY_OVERRIDE); 294 295 notificationGnss.timeoutSec = gnssNiNotification.timeout; 296 297 if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_ACCEPT) 298 notificationGnss.defaultResponse = IGnssNiCallback::GnssUserResponseType::RESPONSE_ACCEPT; 299 else if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_DENY) 300 notificationGnss.defaultResponse = IGnssNiCallback::GnssUserResponseType::RESPONSE_DENY; 301 else if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_NO_RESPONSE || 302 gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_IGNORE) 303 notificationGnss.defaultResponse = IGnssNiCallback::GnssUserResponseType::RESPONSE_NORESP; 304 305 notificationGnss.requestorId = gnssNiNotification.requestor; 306 307 notificationGnss.notificationMessage = gnssNiNotification.message; 308 309 if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_NONE) 310 notificationGnss.requestorIdEncoding = 311 IGnssNiCallback::GnssNiEncodingType::ENC_NONE; 312 else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_GSM_DEFAULT) 313 notificationGnss.requestorIdEncoding = 314 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_GSM_DEFAULT; 315 else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_UTF8) 316 notificationGnss.requestorIdEncoding = 317 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UTF8; 318 else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_UCS2) 319 notificationGnss.requestorIdEncoding = 320 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UCS2; 321 322 if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_NONE) 323 notificationGnss.notificationIdEncoding = 324 IGnssNiCallback::GnssNiEncodingType::ENC_NONE; 325 else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_GSM_DEFAULT) 326 notificationGnss.notificationIdEncoding = 327 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_GSM_DEFAULT; 328 else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_UTF8) 329 notificationGnss.notificationIdEncoding = 330 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UTF8; 331 else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_UCS2) 332 notificationGnss.notificationIdEncoding = 333 IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UCS2; 334 335 mGnssNiCbIface->niNotifyCb(notificationGnss); 336 } 337 338 void GnssAPIClient::onGnssSvCb(GnssSvNotification gnssSvNotification) 339 { 340 LOC_LOGD("%s]: (count: %zu)", __FUNCTION__, gnssSvNotification.count); 341 if (mGnssCbIface != nullptr) { 342 IGnssCallback::GnssSvStatus svStatus; 343 convertGnssSvStatus(gnssSvNotification, svStatus); 344 mGnssCbIface->gnssSvStatusCb(svStatus); 345 } 346 } 347 348 void GnssAPIClient::onGnssNmeaCb(GnssNmeaNotification gnssNmeaNotification) 349 { 350 if (mGnssCbIface != nullptr) { 351 android::hardware::hidl_string nmeaString; 352 nmeaString.setToExternal(gnssNmeaNotification.nmea, gnssNmeaNotification.length); 353 mGnssCbIface->gnssNmeaCb(static_cast<GnssUtcTime>(gnssNmeaNotification.timestamp), 354 nmeaString); 355 } 356 } 357 358 void GnssAPIClient::onStartTrackingCb(LocationError error) 359 { 360 LOC_LOGD("%s]: (%d)", __FUNCTION__, error); 361 if (error == LOCATION_ERROR_SUCCESS && mGnssCbIface != nullptr) { 362 mGnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_ON); 363 mGnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_BEGIN); 364 } 365 } 366 367 void GnssAPIClient::onStopTrackingCb(LocationError error) 368 { 369 LOC_LOGD("%s]: (%d)", __FUNCTION__, error); 370 if (error == LOCATION_ERROR_SUCCESS && mGnssCbIface != nullptr) { 371 mGnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_END); 372 mGnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_ON); 373 } 374 } 375 376 static void convertGnssSvStatus(GnssSvNotification& in, IGnssCallback::GnssSvStatus& out) 377 { 378 memset(&out, 0, sizeof(IGnssCallback::GnssSvStatus)); 379 out.numSvs = in.count; 380 if (out.numSvs > static_cast<uint32_t>(GnssMax::SVS_COUNT)) { 381 LOC_LOGW("%s]: Too many satellites %zd. Clamps to %d.", 382 __FUNCTION__, out.numSvs, GnssMax::SVS_COUNT); 383 out.numSvs = static_cast<uint32_t>(GnssMax::SVS_COUNT); 384 } 385 for (size_t i = 0; i < out.numSvs; i++) { 386 IGnssCallback::GnssSvInfo& info = out.gnssSvList[i]; 387 info.svid = in.gnssSvs[i].svId; 388 convertGnssConstellationType(in.gnssSvs[i].type, info.constellation); 389 info.cN0Dbhz = in.gnssSvs[i].cN0Dbhz; 390 info.elevationDegrees = in.gnssSvs[i].elevation; 391 info.azimuthDegrees = in.gnssSvs[i].azimuth; 392 info.svFlag = static_cast<uint8_t>(IGnssCallback::GnssSvFlags::NONE); 393 if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_EPHEMER_BIT) 394 info.svFlag |= IGnssCallback::GnssSvFlags::HAS_EPHEMERIS_DATA; 395 if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_ALMANAC_BIT) 396 info.svFlag |= IGnssCallback::GnssSvFlags::HAS_ALMANAC_DATA; 397 if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_USED_IN_FIX_BIT) 398 info.svFlag |= IGnssCallback::GnssSvFlags::USED_IN_FIX; 399 } 400 } 401 402 } // namespace implementation 403 } // namespace V1_0 404 } // namespace gnss 405 } // namespace hardware 406 } // namespace android 407