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" 26typedef void* (getLocationInterface)(); 27 28namespace android { 29namespace hardware { 30namespace gnss { 31namespace V1_0 { 32namespace implementation { 33 34void 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 43Gnss::Gnss() { 44 ENTRY_LOG_CALLFLOW(); 45 // clear pending GnssConfig 46 memset(&mPendingConfig, 0, sizeof(GnssConfig)); 47 48 mGnssDeathRecipient = new GnssDeathRecipient(this); 49} 50 51Gnss::~Gnss() { 52 ENTRY_LOG_CALLFLOW(); 53 if (mApi != nullptr) { 54 delete mApi; 55 mApi = nullptr; 56 } 57} 58 59GnssAPIClient* 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 83GnssInterface* 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; 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 110Return<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 } 125 return true; 126} 127 128Return<bool> Gnss::setGnssNiCb(const sp<IGnssNiCallback>& callback) { 129 ENTRY_LOG_CALLFLOW(); 130 mGnssNiCbIface = callback; 131 GnssAPIClient* api = getApi(); 132 if (api != nullptr) { 133 api->gnssUpdateCallbacks(mGnssCbIface, mGnssNiCbIface); 134 } 135 return true; 136} 137 138Return<bool> Gnss::updateConfiguration(GnssConfig& gnssConfig) { 139 ENTRY_LOG_CALLFLOW(); 140 GnssAPIClient* api = getApi(); 141 if (api) { 142 api->locAPIGnssUpdateConfig(gnssConfig); 143 } else if (gnssConfig.flags != 0) { 144 // api is not ready yet, update mPendingConfig with gnssConfig 145 mPendingConfig.size = sizeof(GnssConfig); 146 147 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT) { 148 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT; 149 mPendingConfig.gpsLock = gnssConfig.gpsLock; 150 } 151 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT) { 152 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT; 153 mPendingConfig.suplVersion = gnssConfig.suplVersion; 154 } 155 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT) { 156 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT; 157 mPendingConfig.assistanceServer.size = sizeof(GnssConfigSetAssistanceServer); 158 mPendingConfig.assistanceServer.type = gnssConfig.assistanceServer.type; 159 if (mPendingConfig.assistanceServer.hostName != nullptr) { 160 free((void*)mPendingConfig.assistanceServer.hostName); 161 mPendingConfig.assistanceServer.hostName = 162 strdup(gnssConfig.assistanceServer.hostName); 163 } 164 mPendingConfig.assistanceServer.port = gnssConfig.assistanceServer.port; 165 } 166 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT) { 167 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT; 168 mPendingConfig.lppProfile = gnssConfig.lppProfile; 169 } 170 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT) { 171 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT; 172 mPendingConfig.lppeControlPlaneMask = gnssConfig.lppeControlPlaneMask; 173 } 174 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT) { 175 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT; 176 mPendingConfig.lppeUserPlaneMask = gnssConfig.lppeUserPlaneMask; 177 } 178 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT) { 179 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT; 180 mPendingConfig.aGlonassPositionProtocolMask = gnssConfig.aGlonassPositionProtocolMask; 181 } 182 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT) { 183 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT; 184 mPendingConfig.emergencyPdnForEmergencySupl = gnssConfig.emergencyPdnForEmergencySupl; 185 } 186 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT) { 187 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT; 188 mPendingConfig.suplEmergencyServices = gnssConfig.suplEmergencyServices; 189 } 190 if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_MODE_BIT) { 191 mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_MODE_BIT; 192 mPendingConfig.suplModeMask = gnssConfig.suplModeMask; 193 } 194 } 195 return true; 196} 197 198Return<bool> Gnss::start() { 199 ENTRY_LOG_CALLFLOW(); 200 bool retVal = false; 201 GnssAPIClient* api = getApi(); 202 if (api) { 203 retVal = api->gnssStart(); 204 } 205 return retVal; 206} 207 208Return<bool> Gnss::stop() { 209 ENTRY_LOG_CALLFLOW(); 210 bool retVal = false; 211 GnssAPIClient* api = getApi(); 212 if (api) { 213 retVal = api->gnssStop(); 214 } 215 return retVal; 216} 217 218Return<void> Gnss::cleanup() { 219 ENTRY_LOG_CALLFLOW(); 220 221 if (mApi != nullptr) { 222 mApi->locAPIDisable(); 223 } 224 225 return Void(); 226} 227 228Return<bool> Gnss::injectLocation(double latitudeDegrees, 229 double longitudeDegrees, 230 float accuracyMeters) { 231 ENTRY_LOG_CALLFLOW(); 232 GnssInterface* gnssInterface = getGnssInterface(); 233 if (nullptr != gnssInterface) { 234 gnssInterface->injectLocation(latitudeDegrees, longitudeDegrees, accuracyMeters); 235 return true; 236 } else { 237 return false; 238 } 239} 240 241Return<bool> Gnss::injectTime(int64_t timeMs, int64_t timeReferenceMs, 242 int32_t uncertaintyMs) { 243 ENTRY_LOG_CALLFLOW(); 244 GnssInterface* gnssInterface = getGnssInterface(); 245 if (nullptr != gnssInterface) { 246 gnssInterface->injectTime(timeMs, timeReferenceMs, uncertaintyMs); 247 return true; 248 } else { 249 return false; 250 } 251} 252 253Return<void> Gnss::deleteAidingData(IGnss::GnssAidingData aidingDataFlags) { 254 ENTRY_LOG_CALLFLOW(); 255 GnssAPIClient* api = getApi(); 256 if (api) { 257 api->gnssDeleteAidingData(aidingDataFlags); 258 } 259 return Void(); 260} 261 262Return<bool> Gnss::setPositionMode(IGnss::GnssPositionMode mode, 263 IGnss::GnssPositionRecurrence recurrence, 264 uint32_t minIntervalMs, 265 uint32_t preferredAccuracyMeters, 266 uint32_t preferredTimeMs) { 267 ENTRY_LOG_CALLFLOW(); 268 bool retVal = false; 269 GnssAPIClient* api = getApi(); 270 if (api) { 271 retVal = api->gnssSetPositionMode(mode, recurrence, minIntervalMs, 272 preferredAccuracyMeters, preferredTimeMs); 273 } 274 return retVal; 275} 276 277Return<sp<IAGnss>> Gnss::getExtensionAGnss() { 278 ENTRY_LOG_CALLFLOW(); 279 mAGnssIface = new AGnss(this); 280 return mAGnssIface; 281} 282 283Return<sp<IGnssNi>> Gnss::getExtensionGnssNi() { 284 ENTRY_LOG_CALLFLOW(); 285 mGnssNi = new GnssNi(this); 286 return mGnssNi; 287} 288 289Return<sp<IGnssMeasurement>> Gnss::getExtensionGnssMeasurement() { 290 ENTRY_LOG_CALLFLOW(); 291 mGnssMeasurement = new GnssMeasurement(); 292 return mGnssMeasurement; 293} 294 295Return<sp<IGnssConfiguration>> Gnss::getExtensionGnssConfiguration() { 296 ENTRY_LOG_CALLFLOW(); 297 mGnssConfig = new GnssConfiguration(this); 298 return mGnssConfig; 299} 300 301Return<sp<IGnssGeofencing>> Gnss::getExtensionGnssGeofencing() { 302 ENTRY_LOG_CALLFLOW(); 303 mGnssGeofencingIface = new GnssGeofencing(); 304 return mGnssGeofencingIface; 305} 306 307Return<sp<IGnssBatching>> Gnss::getExtensionGnssBatching() { 308 mGnssBatching = new GnssBatching(); 309 return mGnssBatching; 310} 311 312IGnss* HIDL_FETCH_IGnss(const char* hal) { 313 ENTRY_LOG_CALLFLOW(); 314 IGnss* iface = nullptr; 315 iface = new Gnss(); 316 if (iface == nullptr) { 317 LOC_LOGE("%s]: failed to get %s", __FUNCTION__, hal); 318 } 319 return iface; 320} 321 322} // namespace implementation 323} // namespace V1_0 324} // namespace gnss 325} // namespace hardware 326} // namespace android 327