1 /* 2 * Copyright (c) 2017, The Linux Foundation. All rights reserved. 3 * Not a Contribution 4 */ 5 /* 6 * Copyright (C) 2016 The Android Open Source Project 7 * 8 * Licensed under the Apache License, Version 2.0 (the "License"); 9 * you may not use this file except in compliance with the License. 10 * You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 */ 20 21 #define LOG_TAG "LocSvc_GnssInterface" 22 23 #include <log_util.h> 24 #include <dlfcn.h> 25 #include "Gnss.h" 26 typedef void* (getLocationInterface)(); 27 28 namespace android { 29 namespace hardware { 30 namespace gnss { 31 namespace V1_0 { 32 namespace implementation { 33 34 void Gnss::GnssDeathRecipient::serviceDied(uint64_t cookie, const wp<IBase>& who) { 35 LOC_LOGE("%s] service died. cookie: %llu, who: %p", 36 __FUNCTION__, static_cast<unsigned long long>(cookie), &who); 37 if (mGnss != nullptr) { 38 mGnss->stop(); 39 mGnss->cleanup(); 40 } 41 } 42 43 Gnss::Gnss() { 44 ENTRY_LOG_CALLFLOW(); 45 // clear pending GnssConfig 46 memset(&mPendingConfig, 0, sizeof(GnssConfig)); 47 48 mGnssDeathRecipient = new GnssDeathRecipient(this); 49 } 50 51 Gnss::~Gnss() { 52 ENTRY_LOG_CALLFLOW(); 53 if (mApi != nullptr) { 54 delete mApi; 55 mApi = nullptr; 56 } 57 } 58 59 GnssAPIClient* Gnss::getApi() { 60 if (mApi == nullptr && (mGnssCbIface != nullptr || mGnssNiCbIface != nullptr)) { 61 mApi = new GnssAPIClient(mGnssCbIface, mGnssNiCbIface); 62 if (mApi == nullptr) { 63 LOC_LOGE("%s] faild to create GnssAPIClient", __FUNCTION__); 64 return mApi; 65 } 66 67 if (mPendingConfig.size == sizeof(GnssConfig)) { 68 // we have pending GnssConfig 69 mApi->gnssConfigurationUpdate(mPendingConfig); 70 // clear size to invalid mPendingConfig 71 mPendingConfig.size = 0; 72 if (mPendingConfig.assistanceServer.hostName != nullptr) { 73 free((void*)mPendingConfig.assistanceServer.hostName); 74 } 75 } 76 } 77 if (mApi == nullptr) { 78 LOC_LOGW("%s] GnssAPIClient is not ready", __FUNCTION__); 79 } 80 return mApi; 81 } 82 83 GnssInterface* Gnss::getGnssInterface() { 84 static bool getGnssInterfaceFailed = false; 85 if (nullptr == mGnssInterface && !getGnssInterfaceFailed) { 86 LOC_LOGD("%s]: loading libgnss.so::getGnssInterface ...", __func__); 87 getLocationInterface* getter = NULL; 88 const char *error = NULL; 89 dlerror(); 90 void *handle = dlopen("libgnss.so", RTLD_NOW); 91 if (NULL == handle || (error = dlerror()) != NULL) { 92 LOC_LOGW("dlopen for libgnss.so failed, error = %s", error); 93 } else { 94 getter = (getLocationInterface*)dlsym(handle, "getGnssInterface"); 95 if ((error = dlerror()) != NULL) { 96 LOC_LOGW("dlsym for libgnss.so::getGnssInterface failed, error = %s", error); 97 getter = NULL; 98 } 99 } 100 101 if (NULL == getter) { 102 getGnssInterfaceFailed = true; 103 } else { 104 mGnssInterface = (GnssInterface*)(*getter)(); 105 } 106 } 107 return mGnssInterface; 108 } 109 110 Return<bool> Gnss::setCallback(const sp<IGnssCallback>& callback) { 111 ENTRY_LOG_CALLFLOW(); 112 if (mGnssCbIface != nullptr) { 113 mGnssCbIface->unlinkToDeath(mGnssDeathRecipient); 114 } 115 mGnssCbIface = callback; 116 if (mGnssCbIface != nullptr) { 117 mGnssCbIface->linkToDeath(mGnssDeathRecipient, 0 /*cookie*/); 118 } 119 120 GnssAPIClient* api = getApi(); 121 if (api != nullptr) { 122 api->gnssUpdateCallbacks(mGnssCbIface, mGnssNiCbIface); 123 api->locAPIEnable(LOCATION_TECHNOLOGY_TYPE_GNSS); 124 api->requestCapabilities(); 125 } 126 return true; 127 } 128 129 Return<bool> Gnss::setGnssNiCb(const sp<IGnssNiCallback>& callback) { 130 ENTRY_LOG_CALLFLOW(); 131 mGnssNiCbIface = callback; 132 GnssAPIClient* api = getApi(); 133 if (api != nullptr) { 134 api->gnssUpdateCallbacks(mGnssCbIface, mGnssNiCbIface); 135 } 136 return true; 137 } 138 139 Return<bool> Gnss::updateConfiguration(GnssConfig& gnssConfig) { 140 ENTRY_LOG_CALLFLOW(); 141 GnssAPIClient* api = getApi(); 142 if (api) { 143 api->locAPIGnssUpdateConfig(gnssConfig); 144 } else if (gnssConfig.flags != 0) { 145 // api is not ready yet, update mPendingConfig with gnssConfig 146 mPendingConfig.size = sizeof(GnssConfig); 147 148 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT) { 149 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT; 150 mPendingConfig.gpsLock = gnssConfig.gpsLock; 151 } 152 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT) { 153 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT; 154 mPendingConfig.suplVersion = gnssConfig.suplVersion; 155 } 156 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT) { 157 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT; 158 mPendingConfig.assistanceServer.size = sizeof(GnssConfigSetAssistanceServer); 159 mPendingConfig.assistanceServer.type = gnssConfig.assistanceServer.type; 160 if (mPendingConfig.assistanceServer.hostName != nullptr) { 161 free((void*)mPendingConfig.assistanceServer.hostName); 162 mPendingConfig.assistanceServer.hostName = 163 strdup(gnssConfig.assistanceServer.hostName); 164 } 165 mPendingConfig.assistanceServer.port = gnssConfig.assistanceServer.port; 166 } 167 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT) { 168 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT; 169 mPendingConfig.lppProfile = gnssConfig.lppProfile; 170 } 171 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT) { 172 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT; 173 mPendingConfig.lppeControlPlaneMask = gnssConfig.lppeControlPlaneMask; 174 } 175 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT) { 176 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT; 177 mPendingConfig.lppeUserPlaneMask = gnssConfig.lppeUserPlaneMask; 178 } 179 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT) { 180 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT; 181 mPendingConfig.aGlonassPositionProtocolMask = gnssConfig.aGlonassPositionProtocolMask; 182 } 183 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT) { 184 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT; 185 mPendingConfig.emergencyPdnForEmergencySupl = gnssConfig.emergencyPdnForEmergencySupl; 186 } 187 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT) { 188 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT; 189 mPendingConfig.suplEmergencyServices = gnssConfig.suplEmergencyServices; 190 } 191 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_MODE_BIT) { 192 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_MODE_BIT; 193 mPendingConfig.suplModeMask = gnssConfig.suplModeMask; 194 } 195 } 196 return true; 197 } 198 199 Return<bool> Gnss::start() { 200 ENTRY_LOG_CALLFLOW(); 201 bool retVal = false; 202 GnssAPIClient* api = getApi(); 203 if (api) { 204 retVal = api->gnssStart(); 205 } 206 return retVal; 207 } 208 209 Return<bool> Gnss::stop() { 210 ENTRY_LOG_CALLFLOW(); 211 bool retVal = false; 212 GnssAPIClient* api = getApi(); 213 if (api) { 214 retVal = api->gnssStop(); 215 } 216 return retVal; 217 } 218 219 Return<void> Gnss::cleanup() { 220 ENTRY_LOG_CALLFLOW(); 221 222 if (mApi != nullptr) { 223 mApi->locAPIDisable(); 224 } 225 226 return Void(); 227 } 228 229 Return<bool> Gnss::injectLocation(double latitudeDegrees, 230 double longitudeDegrees, 231 float accuracyMeters) { 232 ENTRY_LOG_CALLFLOW(); 233 GnssInterface* gnssInterface = getGnssInterface(); 234 if (nullptr != gnssInterface) { 235 gnssInterface->injectLocation(latitudeDegrees, longitudeDegrees, accuracyMeters); 236 return true; 237 } else { 238 return false; 239 } 240 } 241 242 Return<bool> Gnss::injectTime(int64_t timeMs, int64_t timeReferenceMs, 243 int32_t uncertaintyMs) { 244 ENTRY_LOG_CALLFLOW(); 245 GnssInterface* gnssInterface = getGnssInterface(); 246 if (nullptr != gnssInterface) { 247 gnssInterface->injectTime(timeMs, timeReferenceMs, uncertaintyMs); 248 return true; 249 } else { 250 return false; 251 } 252 } 253 254 Return<void> Gnss::deleteAidingData(IGnss::GnssAidingData aidingDataFlags) { 255 ENTRY_LOG_CALLFLOW(); 256 GnssAPIClient* api = getApi(); 257 if (api) { 258 api->gnssDeleteAidingData(aidingDataFlags); 259 } 260 return Void(); 261 } 262 263 Return<bool> Gnss::setPositionMode(IGnss::GnssPositionMode mode, 264 IGnss::GnssPositionRecurrence recurrence, 265 uint32_t minIntervalMs, 266 uint32_t preferredAccuracyMeters, 267 uint32_t preferredTimeMs) { 268 ENTRY_LOG_CALLFLOW(); 269 bool retVal = false; 270 GnssAPIClient* api = getApi(); 271 if (api) { 272 retVal = api->gnssSetPositionMode(mode, recurrence, minIntervalMs, 273 preferredAccuracyMeters, preferredTimeMs); 274 } 275 return retVal; 276 } 277 278 Return<sp<IAGnss>> Gnss::getExtensionAGnss() { 279 ENTRY_LOG_CALLFLOW(); 280 mAGnssIface = new AGnss(this); 281 return mAGnssIface; 282 } 283 284 Return<sp<IGnssNi>> Gnss::getExtensionGnssNi() { 285 ENTRY_LOG_CALLFLOW(); 286 mGnssNi = new GnssNi(this); 287 return mGnssNi; 288 } 289 290 Return<sp<IGnssMeasurement>> Gnss::getExtensionGnssMeasurement() { 291 ENTRY_LOG_CALLFLOW(); 292 mGnssMeasurement = new GnssMeasurement(); 293 return mGnssMeasurement; 294 } 295 296 Return<sp<IGnssConfiguration>> Gnss::getExtensionGnssConfiguration() { 297 ENTRY_LOG_CALLFLOW(); 298 mGnssConfig = new GnssConfiguration(this); 299 return mGnssConfig; 300 } 301 302 Return<sp<IGnssGeofencing>> Gnss::getExtensionGnssGeofencing() { 303 ENTRY_LOG_CALLFLOW(); 304 mGnssGeofencingIface = new GnssGeofencing(); 305 return mGnssGeofencingIface; 306 } 307 308 Return<sp<IGnssBatching>> Gnss::getExtensionGnssBatching() { 309 mGnssBatching = new GnssBatching(); 310 return mGnssBatching; 311 } 312 313 Return<sp<IGnssDebug>> Gnss::getExtensionGnssDebug() { 314 ENTRY_LOG_CALLFLOW(); 315 mGnssDebug = new GnssDebug(this); 316 return mGnssDebug; 317 } 318 319 Return<sp<IAGnssRil>> Gnss::getExtensionAGnssRil() { 320 mGnssRil = new AGnssRil(this); 321 return mGnssRil; 322 } 323 324 IGnss* HIDL_FETCH_IGnss(const char* hal) { 325 ENTRY_LOG_CALLFLOW(); 326 IGnss* iface = nullptr; 327 iface = new Gnss(); 328 if (iface == nullptr) { 329 LOC_LOGE("%s]: failed to get %s", __FUNCTION__, hal); 330 } 331 return iface; 332 } 333 334 } // namespace implementation 335 } // namespace V1_0 336 } // namespace gnss 337 } // namespace hardware 338 } // namespace android 339