/* * Copyright (c) 2021-2024 Huawei Device Co., Ltd. * 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. */ #include #include #include "broadcast_manager.h" #include "net_manager_constants.h" #include "net_mgr_log_wrapper.h" #include "net_supplier.h" namespace OHOS { namespace NetManagerStandard { namespace { constexpr int32_t REG_OK = 0; constexpr const char *SIMID_IDENT_PREFIX = "simId"; } static std::atomic g_nextNetSupplierId = 0x03EB; NetSupplier::NetSupplier(NetBearType bearerType, const std::string &netSupplierIdent, const std::set &netCaps) : netSupplierType_(bearerType), netSupplierIdent_(netSupplierIdent), netCaps_(netCaps), supplierId_(g_nextNetSupplierId++) { netAllCapabilities_.netCaps_ = netCaps; netAllCapabilities_.bearerTypes_.insert(bearerType); ResetNetSupplier(); InitNetScore(); } sptr NetSupplier::GetSupplierCallback() { return netController_; } void NetSupplier::RegisterSupplierCallback(const sptr &callback) { netController_ = callback; } void NetSupplier::InitNetScore() { int32_t netScore = 0; auto iter = netTypeScore_.find(netSupplierType_); if (iter == netTypeScore_.end()) { NETMGR_LOG_E("Can not find net bearer type[%{public}d] for this net service", netSupplierType_); return; } NETMGR_LOG_D("Net type[%{public}d],default score[%{public}d]", static_cast(iter->first), static_cast(iter->second)); netScore = static_cast(iter->second); netScore_ = netScore; NETMGR_LOG_D("netScore_ = %{public}d", netScore_); } /** * Reset all attributes that may change in the supplier, such as detection progress and network quality. */ void NetSupplier::ResetNetSupplier() { // Reset network quality. netQuality_ = QUALITY_NORMAL_STATE; // Reset network detection progress. isFirstTimeDetectionDone = false; //Reset User Selection isAcceptUnvaliad = false; // Reset network capabilities for checking connectivity finished flag. netCaps_.InsertNetCap(NET_CAPABILITY_CHECKING_CONNECTIVITY); netAllCapabilities_.netCaps_.insert(NET_CAPABILITY_CHECKING_CONNECTIVITY); NETMGR_LOG_I("Reset net supplier %{public}u", supplierId_); } bool NetSupplier::operator==(const NetSupplier &netSupplier) const { return supplierId_ == netSupplier.supplierId_ && netSupplierType_ == netSupplier.netSupplierType_ && netSupplierIdent_ == netSupplier.netSupplierIdent_ && netCaps_ == netSupplier.netCaps_; } void NetSupplier::UpdateNetSupplierInfo(const NetSupplierInfo &netSupplierInfo) { NETMGR_LOG_D("Update net supplier[%{public}d, %{public}s], netSupplierInfo[%{public}s]", supplierId_, netSupplierIdent_.c_str(), netSupplierInfo_.ToString("").c_str()); bool oldAvailable = netSupplierInfo_.isAvailable_; netSupplierInfo_ = netSupplierInfo; netAllCapabilities_.linkUpBandwidthKbps_ = netSupplierInfo_.linkUpBandwidthKbps_; netAllCapabilities_.linkDownBandwidthKbps_ = netSupplierInfo_.linkDownBandwidthKbps_; if (!netSupplierInfo_.ident_.empty()) { netSupplierIdent_ = netSupplierInfo_.ident_; } if (oldAvailable == netSupplierInfo_.isAvailable_) { NETMGR_LOG_W("Same supplier available status:[%{public}d]", oldAvailable); return; } if (network_ == nullptr) { NETMGR_LOG_E("network_ is nullptr!"); return; } network_->UpdateBasicNetwork(netSupplierInfo_.isAvailable_); if (!netSupplierInfo_.isAvailable_) { UpdateNetConnState(NET_CONN_STATE_DISCONNECTED); } } int32_t NetSupplier::UpdateNetLinkInfo(NetLinkInfo &netLinkInfo) { if (network_ == nullptr) { NETMGR_LOG_E("network_ is nullptr!"); return NET_CONN_ERR_INVALID_NETWORK; } if (GetNetSupplierIdent().substr(0, strlen(SIMID_IDENT_PREFIX)) == SIMID_IDENT_PREFIX) { netLinkInfo.ident_ = GetNetSupplierIdent().substr(strlen(SIMID_IDENT_PREFIX)); } NETMGR_LOG_D("Update netlink info: netLinkInfo[%{public}s]", netLinkInfo.ToString(" ").c_str()); if (!network_->UpdateNetLinkInfo(netLinkInfo)) { return NET_CONN_ERR_SERVICE_UPDATE_NET_LINK_INFO_FAIL; } UpdateNetConnState(NET_CONN_STATE_CONNECTED); return NETMANAGER_SUCCESS; } NetBearType NetSupplier::GetNetSupplierType() const { return netSupplierType_; } std::string NetSupplier::GetNetSupplierIdent() const { return netSupplierIdent_; } bool NetSupplier::CompareNetCaps(const std::set caps) const { if (caps.empty()) { return true; } return netCaps_.HasNetCaps(caps); } bool NetSupplier::HasNetCap(NetCap cap) const { return netCaps_.HasNetCap(cap); } bool NetSupplier::HasNetCaps(const std::set &caps) const { return netCaps_.HasNetCaps(caps); } const NetCaps &NetSupplier::GetNetCaps() const { return netCaps_; } NetAllCapabilities NetSupplier::GetNetCapabilities() const { return netAllCapabilities_; } void NetSupplier::SetNetwork(const std::shared_ptr &network) { network_ = network; if (network_ != nullptr) { netHandle_ = std::make_unique(network_->GetNetId()).release(); } } std::shared_ptr NetSupplier::GetNetwork() const { return network_; } int32_t NetSupplier::GetNetId() const { if (network_ == nullptr) { return INVALID_NET_ID; } return network_->GetNetId(); } sptr NetSupplier::GetNetHandle() const { return netHandle_; } void NetSupplier::GetHttpProxy(HttpProxy &httpProxy) { if (network_ == nullptr) { NETMGR_LOG_E("network_ is nullptr."); return; } httpProxy = network_->GetHttpProxy(); } uint32_t NetSupplier::GetSupplierId() const { return supplierId_; } bool NetSupplier::GetRoaming() const { return netSupplierInfo_.isRoaming_; } int8_t NetSupplier::GetStrength() const { return netSupplierInfo_.strength_; } uint16_t NetSupplier::GetFrequency() const { return netSupplierInfo_.frequency_; } int32_t NetSupplier::GetSupplierUid() const { return netSupplierInfo_.uid_; } bool NetSupplier::IsAvailable() const { return netSupplierInfo_.isAvailable_; } bool NetSupplier::SupplierConnection(const std::set &netCaps, const NetRequest &netRequest) { NETMGR_LOG_D("Supplier[%{public}d, %{public}s] request connect, available=%{public}d", supplierId_, netSupplierIdent_.c_str(), netSupplierInfo_.isAvailable_); if (netSupplierInfo_.isAvailable_ && (netRequest.ident.empty()) && netSupplierIdent_.substr(0, strlen(SIMID_IDENT_PREFIX)) != SIMID_IDENT_PREFIX) { NETMGR_LOG_D("The supplier is currently available, there is no need to repeat the request for connection."); return true; } UpdateNetConnState(NET_CONN_STATE_IDLE); if (netController_ == nullptr) { NETMGR_LOG_E("netController_ is nullptr"); return false; } NETMGR_LOG_D("execute RequestNetwork"); int32_t errCode = netController_->RequestNetwork(netSupplierIdent_, netCaps, netRequest); NETMGR_LOG_D("RequestNetwork errCode[%{public}d]", errCode); if (errCode != REG_OK) { NETMGR_LOG_E("RequestNetwork fail"); return false; } return true; } void NetSupplier::SetRestrictBackground(bool restrictBackground) { restrictBackground_ = restrictBackground; } bool NetSupplier::GetRestrictBackground() const { return restrictBackground_; } bool NetSupplier::SupplierDisconnection(const std::set &netCaps) { NETMGR_LOG_D("Supplier[%{public}d, %{public}s] request disconnect, available=%{public}d", supplierId_, netSupplierIdent_.c_str(), netSupplierInfo_.isAvailable_); if (!netSupplierInfo_.isAvailable_ && netSupplierIdent_.substr(0, strlen(SIMID_IDENT_PREFIX)) != SIMID_IDENT_PREFIX) { NETMGR_LOG_D("The supplier is currently unavailable, there is no need to repeat the request to disconnect."); return true; } if (netController_ == nullptr) { NETMGR_LOG_E("netController_ is nullptr"); return false; } NETMGR_LOG_D("execute ReleaseNetwork, supplierId[%{public}d]", supplierId_); int32_t errCode = netController_->ReleaseNetwork(netSupplierIdent_, netCaps); NETMGR_LOG_D("ReleaseNetwork retCode[%{public}d]", errCode); if (errCode != REG_OK) { NETMGR_LOG_E("ReleaseNetwork fail"); return false; } return true; } void NetSupplier::UpdateNetConnState(NetConnState netConnState) { if (network_) { network_->UpdateNetConnState(netConnState); } } bool NetSupplier::IsConnecting() const { if (network_) { return network_->IsConnecting(); } return false; } bool NetSupplier::IsConnected() const { if (network_) { return network_->IsConnected(); } return false; } bool NetSupplier::RequestToConnect(uint32_t reqId, const NetRequest &netrequest) { if (requestList_.find(reqId) == requestList_.end()) { requestList_.insert(reqId); } return SupplierConnection(netCaps_.ToSet(), netrequest); } int32_t NetSupplier::SelectAsBestNetwork(uint32_t reqId) { NETMGR_LOG_I("Request[%{public}d] select [%{public}d, %{public}s] as best network", reqId, supplierId_, netSupplierIdent_.c_str()); if (requestList_.find(reqId) == requestList_.end()) { requestList_.insert(reqId); } if (bestReqList_.find(reqId) == bestReqList_.end()) { bestReqList_.insert(reqId); } return NETMANAGER_SUCCESS; } void NetSupplier::ReceiveBestScore(uint32_t reqId, int32_t bestScore, uint32_t supplierId) { NETMGR_LOG_D("Supplier[%{public}d, %{public}s] receive best score, bestSupplierId[%{public}d]", supplierId_, netSupplierIdent_.c_str(), supplierId); if (supplierId == supplierId_) { NETMGR_LOG_D("Same net supplier, no need to disconnect."); return; } if (requestList_.empty()) { SupplierDisconnection(netCaps_.ToSet()); return; } if (requestList_.find(reqId) == requestList_.end()) { NETMGR_LOG_W("Can not find request[%{public}d]", reqId); return; } if (netScore_ >= bestScore) { NETMGR_LOG_D("High priority network, no need to disconnect"); return; } requestList_.erase(reqId); NETMGR_LOG_D("Supplier[%{public}d, %{public}s] remaining request list size[%{public}zd]", supplierId_, netSupplierIdent_.c_str(), requestList_.size()); if (requestList_.empty()) { SupplierDisconnection(netCaps_.ToSet()); } bestReqList_.erase(reqId); } int32_t NetSupplier::CancelRequest(uint32_t reqId) { auto iter = requestList_.find(reqId); if (iter == requestList_.end()) { return NET_CONN_ERR_SERVICE_NO_REQUEST; } NETMGR_LOG_I("CancelRequest reqId:%{public}u", reqId); requestList_.erase(reqId); if (requestList_.empty()) { SupplierDisconnection(netCaps_.ToSet()); } bestReqList_.erase(reqId); return NETMANAGER_SUCCESS; } void NetSupplier::RemoveBestRequest(uint32_t reqId) { auto iter = bestReqList_.find(reqId); if (iter == bestReqList_.end()) { return; } bestReqList_.erase(reqId); NETMGR_LOG_I("RemoveBestRequest supplierId=[%{public}d], reqId=[%{public}u]", supplierId_, reqId); } std::set &NetSupplier::GetBestRequestList() { return bestReqList_; } void NetSupplier::SetNetValid(NetDetectionStatus netState) { NETMGR_LOG_I("Enter SetNetValid. supplier[%{public}d, %{public}s], ifValid[%{public}d]", supplierId_, netSupplierIdent_.c_str(), netState); if (netState == VERIFICATION_STATE) { if (!HasNetCap(NET_CAPABILITY_VALIDATED)) { netCaps_.InsertNetCap(NET_CAPABILITY_VALIDATED); netAllCapabilities_.netCaps_.insert(NET_CAPABILITY_VALIDATED); NETMGR_LOG_I("NetSupplier inserted cap:NET_CAPABILITY_VALIDATED"); } if (HasNetCap(NET_CAPABILITY_PORTAL)) { netCaps_.RemoveNetCap(NET_CAPABILITY_PORTAL); netAllCapabilities_.netCaps_.erase(NET_CAPABILITY_PORTAL); NETMGR_LOG_I("NetSupplier remove cap:NET_CAPABILITY_PORTAL"); } } else if (netState == CAPTIVE_PORTAL_STATE) { if (!HasNetCap(NET_CAPABILITY_PORTAL)) { netCaps_.InsertNetCap(NET_CAPABILITY_PORTAL); netAllCapabilities_.netCaps_.insert(NET_CAPABILITY_PORTAL); NETMGR_LOG_I("NetSupplier inserted cap:NET_CAPABILITY_PORTAL"); } if (HasNetCap(NET_CAPABILITY_VALIDATED)) { netCaps_.RemoveNetCap(NET_CAPABILITY_VALIDATED); netAllCapabilities_.netCaps_.erase(NET_CAPABILITY_VALIDATED); NETMGR_LOG_I("NetSupplier remove cap:NET_CAPABILITY_VALIDATED"); } } else if (netState == QUALITY_POOR_STATE) { netQuality_ = QUALITY_POOR_STATE; } else if (netState == QUALITY_GOOD_STATE) { netQuality_ = QUALITY_GOOD_STATE; } else if (netState == ACCEPT_UNVALIDATED) { netQuality_ = ACCEPT_UNVALIDATED; isAcceptUnvaliad = true; } else { if (HasNetCap(NET_CAPABILITY_VALIDATED)) { netCaps_.RemoveNetCap(NET_CAPABILITY_VALIDATED); netAllCapabilities_.netCaps_.erase(NET_CAPABILITY_VALIDATED); NETMGR_LOG_I("NetSupplier remove cap:NET_CAPABILITY_VALIDATED"); } if (HasNetCap(NET_CAPABILITY_PORTAL)) { netCaps_.RemoveNetCap(NET_CAPABILITY_PORTAL); netAllCapabilities_.netCaps_.erase(NET_CAPABILITY_PORTAL); NETMGR_LOG_I("NetSupplier remove cap:NET_CAPABILITY_PORTAL"); } } } bool NetSupplier::IsNetValidated() const { return HasNetCap(NET_CAPABILITY_VALIDATED); } /** * This method returns the score of the current network supplier. * * It is used to prioritize network suppliers so that higher priority producers can activate when lower * priority networks are available. * * @return the score of the current network supplier. */ int32_t NetSupplier::GetNetScore() const { return netScore_; } /** * This method returns the real score of current network supplier. * * This method subtracts the score depending on different conditions, or returns netScore_ if the conditions are not * met. * It is used to compare the priorities of different networks. * * @return the real score of current network supplier. */ int32_t NetSupplier::GetRealScore() { // Notice: the order is important here: // 1.If the user chooses to use this network, return MAX_SCORE if (isAcceptUnvaliad) { return static_cast(NetManagerStandard::NetTypeScoreValue::MAX_SCORE); } // 2. If network detection is not complete in the first time, subtract NET_VALID_SCORE. if (IsInFirstTimeDetecting()) { return netScore_ - NET_VALID_SCORE; } // 3. If network is not validated, subtract NET_VALID_SCORE. if (!IsNetValidated()) { return netScore_ - NET_VALID_SCORE; } // 4. Deduct DIFF_SCORE_BETWEEN_GOOD_POOR for poor network quality (reported by the supplier). if (IsNetQualityPoor()) { return netScore_ - DIFF_SCORE_BETWEEN_GOOD_POOR; } return netScore_; } void NetSupplier::SetDefault() { NETMGR_LOG_I("set default supplier[%{public}d].", supplierId_); if (network_) { network_->SetDefaultNetWork(); } } void NetSupplier::ClearDefault() { NETMGR_LOG_I("clear default supplier[%{public}d].", supplierId_); if (network_) { network_->ClearDefaultNetWorkNetId(); } } void NetSupplier::UpdateGlobalHttpProxy(const HttpProxy &httpProxy) { NETMGR_LOG_I("supplierId[%{public}d] update global httpProxy.", supplierId_); if (network_) { network_->UpdateGlobalHttpProxy(httpProxy); } } std::string NetSupplier::TechToType(NetSlotTech techType) { switch (techType) { case NetSlotTech::SLOT_TYPE_GSM: return "2G"; case NetSlotTech::SLOT_TYPE_LTE: case NetSlotTech::SLOT_TYPE_LTE_CA: return "4G"; default: return "3G"; } } void NetSupplier::SetSupplierType(int32_t type) { NETMGR_LOG_I("supplierId[%{public}d] update type[%{public}d].", supplierId_, type); type_ = TechToType(static_cast(type)); } std::string NetSupplier::GetSupplierType() { return type_; } bool NetSupplier::ResumeNetworkInfo() { if (network_ == nullptr) { NETMGR_LOG_E("network_ is nullptr!"); return false; } return network_->ResumeNetworkInfo(); } bool NetSupplier::IsNetQualityPoor() { return netQuality_ == QUALITY_POOR_STATE; } void NetSupplier::SetDetectionDone() { if (!isFirstTimeDetectionDone) { isFirstTimeDetectionDone = true; } if (HasNetCap(NET_CAPABILITY_CHECKING_CONNECTIVITY)) { netCaps_.RemoveNetCap(NET_CAPABILITY_CHECKING_CONNECTIVITY); netAllCapabilities_.netCaps_.erase(NET_CAPABILITY_CHECKING_CONNECTIVITY); NETMGR_LOG_I("supplier %{public}u detection done, remove NET_CAPABILITY_CHECKING_CONNECTIVITY", supplierId_); } } bool NetSupplier::IsInFirstTimeDetecting() const { return !isFirstTimeDetectionDone; } } // namespace NetManagerStandard } // namespace OHOS