/* * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. * Not a Contribution */ /* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2_0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2_0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "LocSvc_GnssConfigurationInterface" #include #include "Gnss.h" #include "GnssConfiguration.h" #include "ContextBase.h" #include namespace android { namespace hardware { namespace gnss { namespace V2_1 { namespace implementation { using ::android::hardware::gnss::V2_0::GnssConstellationType; using namespace loc_core; GnssConfiguration::GnssConfiguration(Gnss* gnss) : mGnss(gnss) { } // Methods from ::android::hardware::gps::V1_0::IGnssConfiguration follow. Return GnssConfiguration::setSuplEs(bool enabled __unused) { // deprecated function. Must return false to pass VTS return false; } Return GnssConfiguration::setSuplVersion(uint32_t version) { if (mGnss == nullptr) { LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__); return false; } GnssConfig config; memset(&config, 0, sizeof(GnssConfig)); config.size = sizeof(GnssConfig); config.flags = GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT; switch (version) { case 0x00020004: config.suplVersion = GNSS_CONFIG_SUPL_VERSION_2_0_4; break; case 0x00020002: config.suplVersion = GNSS_CONFIG_SUPL_VERSION_2_0_2; break; case 0x00020000: config.suplVersion = GNSS_CONFIG_SUPL_VERSION_2_0_0; break; case 0x00010000: config.suplVersion = GNSS_CONFIG_SUPL_VERSION_1_0_0; break; default: LOC_LOGE("%s]: invalid version: 0x%x.", __FUNCTION__, version); return false; } return mGnss->updateConfiguration(config); } Return GnssConfiguration::setSuplMode(uint8_t mode) { if (mGnss == nullptr) { LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__); return false; } GnssConfig config; memset(&config, 0, sizeof(GnssConfig)); config.size = sizeof(GnssConfig); config.flags = GNSS_CONFIG_FLAGS_SUPL_MODE_BIT; switch (mode) { case 0: config.suplModeMask = 0; // STANDALONE ONLY break; case 1: config.suplModeMask = GNSS_CONFIG_SUPL_MODE_MSB_BIT; break; case 2: config.suplModeMask = GNSS_CONFIG_SUPL_MODE_MSA_BIT; break; case 3: config.suplModeMask = GNSS_CONFIG_SUPL_MODE_MSB_BIT | GNSS_CONFIG_SUPL_MODE_MSA_BIT; break; default: LOC_LOGE("%s]: invalid mode: %d.", __FUNCTION__, mode); return false; } return mGnss->updateConfiguration(config); } Return GnssConfiguration::setLppProfile(uint8_t lppProfileMask) { if (mGnss == nullptr) { LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__); return false; } GnssConfig config = {}; config.size = sizeof(GnssConfig); config.flags = GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT; config.lppProfileMask = GNSS_CONFIG_LPP_PROFILE_RRLP_ON_LTE; //default if (lppProfileMask & (1<<0)) { config.lppProfileMask |= GNSS_CONFIG_LPP_PROFILE_USER_PLANE_BIT; } if (lppProfileMask & (1<<1)) { config.lppProfileMask |= GNSS_CONFIG_LPP_PROFILE_CONTROL_PLANE_BIT; } if (lppProfileMask & (1<<2)) { config.lppProfileMask |= GNSS_CONFIG_LPP_PROFILE_USER_PLANE_OVER_NR5G_SA_BIT; } if (lppProfileMask & (1<<3)) { config.lppProfileMask |= GNSS_CONFIG_LPP_PROFILE_CONTROL_PLANE_OVER_NR5G_SA_BIT; } return mGnss->updateConfiguration(config); } Return GnssConfiguration::setGlonassPositioningProtocol(uint8_t protocol) { if (mGnss == nullptr) { LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__); return false; } GnssConfig config; memset(&config, 0, sizeof(GnssConfig)); config.size = sizeof(GnssConfig); config.flags = GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT; if (protocol & (1<<0)) { config.aGlonassPositionProtocolMask |= GNSS_CONFIG_RRC_CONTROL_PLANE_BIT; } if (protocol & (1<<1)) { config.aGlonassPositionProtocolMask |= GNSS_CONFIG_RRLP_USER_PLANE_BIT; } if (protocol & (1<<2)) { config.aGlonassPositionProtocolMask |= GNSS_CONFIG_LLP_USER_PLANE_BIT; } if (protocol & (1<<3)) { config.aGlonassPositionProtocolMask |= GNSS_CONFIG_LLP_CONTROL_PLANE_BIT; } return mGnss->updateConfiguration(config); } Return GnssConfiguration::setGpsLock(uint8_t lock) { if (mGnss == nullptr) { LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__); return false; } GnssConfig config = {}; config.size = sizeof(GnssConfig); config.flags = GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT; switch (lock) { case 0: config.gpsLock = GNSS_CONFIG_GPS_LOCK_NONE; break; case 1: config.gpsLock = GNSS_CONFIG_GPS_LOCK_MO; break; case 2: config.gpsLock = GNSS_CONFIG_GPS_LOCK_NI; break; case 3: config.gpsLock = GNSS_CONFIG_GPS_LOCK_MO_AND_NI; break; default: LOC_LOGE("%s]: invalid lock: %d.", __FUNCTION__, lock); return false; } mGnss->updateConfiguration(config); // Must return false to pass VTS return false; } Return GnssConfiguration::setEmergencySuplPdn(bool enabled) { if (mGnss == nullptr) { LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__); return false; } GnssConfig config; memset(&config, 0, sizeof(GnssConfig)); config.size = sizeof(GnssConfig); config.flags = GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT; config.emergencyPdnForEmergencySupl = (enabled ? GNSS_CONFIG_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_YES : GNSS_CONFIG_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_NO); return mGnss->updateConfiguration(config); } // Methods from ::android::hardware::gnss::V1_1::IGnssConfiguration follow. Return GnssConfiguration::setBlacklist( const hidl_vec& blacklist) { ENTRY_LOG_CALLFLOW(); if (nullptr == mGnss) { LOC_LOGe("mGnss is null"); return false; } // blValid is true if blacklist is empty, i.e. clearing the BL; // if blacklist is not empty, blValid is initialied to false, and later // updated in the for loop to become true only if there is at least // one {constellation, svid} in the list that is valid. bool blValid = (0 == blacklist.size()); GnssConfig config; memset(&config, 0, sizeof(GnssConfig)); config.size = sizeof(GnssConfig); config.flags = GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT; config.blacklistedSvIds.clear(); GnssSvIdSource source = {}; for (int idx = 0; idx < (int)blacklist.size(); idx++) { // Set blValid true if any one source is valid blValid = setBlacklistedSource(source, (GnssConstellationType)blacklist[idx].constellation, blacklist[idx].svid) || blValid; config.blacklistedSvIds.push_back(source); } // Update configuration only if blValid is true // i.e. only if atleast one source is valid for blacklisting return (blValid && mGnss->updateConfiguration(config)); } bool GnssConfiguration::setBlacklistedSource( GnssSvIdSource& copyToSource, const GnssConstellationType& constellation, const int16_t svid) { bool retVal = true; uint16_t svIdOffset = 0; copyToSource.size = sizeof(GnssSvIdSource); copyToSource.svId = svid; switch(constellation) { case GnssConstellationType::GPS: copyToSource.constellation = GNSS_SV_TYPE_GPS; LOC_LOGe("GPS SVs can't be blacklisted."); retVal = false; break; case GnssConstellationType::SBAS: copyToSource.constellation = GNSS_SV_TYPE_SBAS; LOC_LOGe("SBAS SVs can't be blacklisted."); retVal = false; break; case GnssConstellationType::GLONASS: copyToSource.constellation = GNSS_SV_TYPE_GLONASS; svIdOffset = GNSS_SV_CONFIG_GLO_INITIAL_SV_ID - 1; break; case GnssConstellationType::QZSS: copyToSource.constellation = GNSS_SV_TYPE_QZSS; svIdOffset = 0; break; case GnssConstellationType::BEIDOU: copyToSource.constellation = GNSS_SV_TYPE_BEIDOU; svIdOffset = GNSS_SV_CONFIG_BDS_INITIAL_SV_ID - 1; break; case GnssConstellationType::GALILEO: copyToSource.constellation = GNSS_SV_TYPE_GALILEO; svIdOffset = GNSS_SV_CONFIG_GAL_INITIAL_SV_ID - 1; break; case GnssConstellationType::IRNSS: copyToSource.constellation = GNSS_SV_TYPE_NAVIC; svIdOffset = 0; break; default: copyToSource.constellation = GNSS_SV_TYPE_UNKNOWN; LOC_LOGe("Invalid constellation %hhu", constellation); retVal = false; break; } if (copyToSource.svId > 0 && svIdOffset > 0) { copyToSource.svId += svIdOffset; } return retVal; } bool GnssConfiguration::setBlacklistedSource( GnssSvIdSource& copyToSource, const GnssConfiguration::BlacklistedSource& copyFromSource) { bool retVal = true; uint16_t svIdOffset = 0; copyToSource.size = sizeof(GnssSvIdSource); copyToSource.svId = copyFromSource.svid; switch(copyFromSource.constellation) { case GnssConstellationType::GPS: copyToSource.constellation = GNSS_SV_TYPE_GPS; LOC_LOGe("GPS SVs can't be blacklisted."); retVal = false; break; case GnssConstellationType::SBAS: copyToSource.constellation = GNSS_SV_TYPE_SBAS; LOC_LOGe("SBAS SVs can't be blacklisted."); retVal = false; break; case GnssConstellationType::GLONASS: copyToSource.constellation = GNSS_SV_TYPE_GLONASS; svIdOffset = GNSS_SV_CONFIG_GLO_INITIAL_SV_ID - 1; break; case GnssConstellationType::QZSS: copyToSource.constellation = GNSS_SV_TYPE_QZSS; svIdOffset = GNSS_SV_CONFIG_QZSS_INITIAL_SV_ID - 1; break; case GnssConstellationType::BEIDOU: copyToSource.constellation = GNSS_SV_TYPE_BEIDOU; svIdOffset = GNSS_SV_CONFIG_BDS_INITIAL_SV_ID - 1; break; case GnssConstellationType::GALILEO: copyToSource.constellation = GNSS_SV_TYPE_GALILEO; svIdOffset = GNSS_SV_CONFIG_GAL_INITIAL_SV_ID - 1; break; case GnssConstellationType::IRNSS: copyToSource.constellation = GNSS_SV_TYPE_NAVIC; svIdOffset = GNSS_SV_CONFIG_NAVIC_INITIAL_SV_ID - 1; break; default: copyToSource.constellation = GNSS_SV_TYPE_UNKNOWN; LOC_LOGe("Invalid constellation %hhu", copyFromSource.constellation); retVal = false; break; } if (copyToSource.svId > 0 && svIdOffset > 0) { copyToSource.svId += svIdOffset; } return retVal; } // Methods from ::android::hardware::gnss::V2_0::IGnssConfiguration follow. Return GnssConfiguration::setEsExtensionSec(uint32_t emergencyExtensionSeconds) { ENTRY_LOG_CALLFLOW(); if (mGnss == nullptr) { LOC_LOGe("mGnss is nullptr"); return false; } GnssConfig config; memset(&config, 0, sizeof(GnssConfig)); config.size = sizeof(GnssConfig); config.flags = GNSS_CONFIG_FLAGS_EMERGENCY_EXTENSION_SECONDS_BIT; config.emergencyExtensionSeconds = emergencyExtensionSeconds; return mGnss->updateConfiguration(config); } // Methods from ::android::hardware::gnss::V2_1::IGnssConfiguration follow. Return GnssConfiguration::setBlacklist_2_1( const hidl_vec& blacklist) { ENTRY_LOG_CALLFLOW(); if (nullptr == mGnss) { LOC_LOGe("mGnss is null"); return false; } // blValid is true if blacklist is empty, i.e. clearing the BL; // if blacklist is not empty, blValid is initialied to false, and later // updated in the for loop to become true only if there is at least // one {constellation, svid} in the list that is valid. bool blValid = (0 == blacklist.size()); GnssConfig config; memset(&config, 0, sizeof(GnssConfig)); config.size = sizeof(GnssConfig); config.flags = GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT; config.blacklistedSvIds.clear(); GnssSvIdSource source = {}; for (int idx = 0; idx < (int)blacklist.size(); idx++) { // Set blValid true if any one source is valid blValid = setBlacklistedSource(source, blacklist[idx]) || blValid; config.blacklistedSvIds.push_back(source); } // Update configuration only if blValid is true // i.e. only if atleast one source is valid for blacklisting return (blValid && mGnss->updateConfiguration(config)); } } // namespace implementation } // namespace V2_1 } // namespace gnss } // namespace hardware } // namespace android