1 /*
2  * Copyright (C) 2021-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "network_selection_utils.h"
17 #include "network_status_history_manager.h"
18 #include "wifi_common_util.h"
19 #include "wifi_config_center.h"
20 #include "wifi_p2p_msg.h"
21 #include "wifi_logger.h"
22 #ifdef FEATURE_ITNETWORK_PREFERRED_SUPPORT
23 #include "parameter.h"
24 #endif
25 
26 namespace OHOS::Wifi::NetworkSelection {
27 namespace {
28 constexpr int32_t SCAN_5GHZ_BAND = 2;
29 }
30 
31 DEFINE_WIFILOG_LABEL("NetworkSelectionUtils")
32 
IsOpenNetwork(const NetworkCandidate & networkCandidate)33 bool NetworkSelectionUtils::IsOpenNetwork(const NetworkCandidate &networkCandidate)
34 {
35     return networkCandidate.wifiDeviceConfig.keyMgmt == KEY_MGMT_NONE;
36 };
37 
IsOpenAndMaybePortal(const NetworkCandidate & networkCandidate)38 bool NetworkSelectionUtils::IsOpenAndMaybePortal(const NetworkCandidate &networkCandidate)
39 {
40     auto &wifiDeviceConfig = networkCandidate.wifiDeviceConfig;
41     return IsOpenNetwork(networkCandidate) && !wifiDeviceConfig.noInternetAccess
42         && NetworkStatusHistoryManager::IsEmptyNetworkStatusHistory(wifiDeviceConfig.networkStatusHistory);
43 }
44 
IsScanResultForOweNetwork(const NetworkCandidate & networkCandidate)45 bool NetworkSelectionUtils::IsScanResultForOweNetwork(const NetworkCandidate &networkCandidate)
46 {
47     return networkCandidate.interScanInfo.capabilities.find("OWE") != std::string::npos;
48 }
49 
IsBlackListNetwork(const NetworkCandidate & networkCandidate)50 bool NetworkSelectionUtils::IsBlackListNetwork(const NetworkCandidate &networkCandidate)
51 {
52     constexpr int maxRetryCount = 3;
53     return networkCandidate.wifiDeviceConfig.connFailedCount >= maxRetryCount;
54 }
55 
GetNetworkCandidatesInfo(const std::vector<NetworkCandidate * > & networkCandidates)56 std::string NetworkSelectionUtils::GetNetworkCandidatesInfo(const std::vector<NetworkCandidate*> &networkCandidates)
57 {
58     std::stringstream networkCandidatesInfo;
59     networkCandidatesInfo << "[";
60     for (std::size_t i = 0; i < networkCandidates.size(); i++) {
61         if (networkCandidates.at(i)->wifiDeviceConfig.networkId == INVALID_NETWORK_ID) {
62             continue;
63         }
64         networkCandidatesInfo << "\"" << networkCandidates.at(i)->ToString() << "\"";
65         if (i < networkCandidates.size() - 1) {
66             networkCandidatesInfo << ", ";
67         }
68     }
69     networkCandidatesInfo << "]";
70     return networkCandidatesInfo.str();
71 }
72 
GetScoreResultsInfo(const std::vector<ScoreResult> & scoreResults)73 std::string NetworkSelectionUtils::GetScoreResultsInfo(const std::vector<ScoreResult> &scoreResults)
74 {
75     std::stringstream scoreMsg;
76     scoreMsg << "[ ";
77     for (std::size_t i = 0; i < scoreResults.size(); i++) {
78         scoreMsg << scoreResults.at(i).ToString();
79         if (i < scoreResults.size() - 1) {
80             scoreMsg << ", ";
81         }
82     }
83     scoreMsg << " ]";
84     return scoreMsg.str();
85 }
86 
IsConfigOpenType(const NetworkCandidate & networkCandidate)87 bool NetworkSelectionUtils::IsConfigOpenType(const NetworkCandidate &networkCandidate)
88 {
89     return !(IsOpenNetwork(networkCandidate) || NetworkSelectionUtils::IsScanResultForOweNetwork(networkCandidate)) &&
90         !HasWepKeys(networkCandidate.wifiDeviceConfig);
91 }
92 
HasWepKeys(const WifiDeviceConfig & wifiConfig)93 bool NetworkSelectionUtils::HasWepKeys(const WifiDeviceConfig &wifiConfig)
94 {
95     for (int32_t i = 0; i < WEPKEYS_SIZE; i++) {
96         if (!wifiConfig.wepKeys[i].empty()) {
97             return true;
98         }
99     }
100     return false;
101 }
102 
IsEnterprise(const NetworkCandidate & networkCandidate)103 bool NetworkSelectionUtils::IsEnterprise(const NetworkCandidate &networkCandidate)
104 {
105     auto &keyMgmt = networkCandidate.wifiDeviceConfig.keyMgmt;
106     bool isEnterpriseSecurityType = (keyMgmt == KEY_MGMT_EAP) || (keyMgmt == KEY_MGMT_SUITE_B_192) ||
107         (keyMgmt == KEY_MGMT_WAPI_CERT);
108     auto &eap = networkCandidate.wifiDeviceConfig.wifiEapConfig.eap;
109     return isEnterpriseSecurityType && (eap != EAP_METHOD_NONE);
110 }
111 
IsConfigOpenOrEapType(const NetworkCandidate & networkCandidate)112 bool NetworkSelectionUtils::IsConfigOpenOrEapType(const NetworkCandidate &networkCandidate)
113 {
114     return IsConfigOpenType(networkCandidate) || IsEnterprise(networkCandidate);
115 }
116 
IsSameFreqAsP2p(const NetworkCandidate & networkCandidate)117 bool NetworkSelectionUtils::IsSameFreqAsP2p(const NetworkCandidate &networkCandidate)
118 {
119     WifiP2pGroupInfo group = WifiConfigCenter::GetInstance().GetCurrentP2pGroupInfo();
120     auto &interScanInfo = networkCandidate.interScanInfo;
121     int32_t p2pFrequency = group.GetFrequency();
122     if (interScanInfo.band == SCAN_5GHZ_BAND && p2pFrequency == interScanInfo.frequency) {
123         return true;
124     } else {
125         WIFI_LOGI("IsSameFreqAsP2p, p2p frequency:%{public}d and scanInfo frequency:%{public}d are not same",
126             p2pFrequency, interScanInfo.frequency);
127     }
128     return false;
129 }
130 
131 #ifdef FEATURE_ITNETWORK_PREFERRED_SUPPORT
CheckDeviceTypeByVendorCountry()132 bool NetworkSelectionUtils::CheckDeviceTypeByVendorCountry()
133 {
134     constexpr const char* VENDOR_COUNTRY_KEY = "const.cust.custPath";
135     constexpr const char* VENDOR_COUNTRY_DEFAULT = "";
136     constexpr const int32_t SYS_PARAMETER_SIZE = 256;
137     constexpr const int32_t SYSTEM_PARAMETER_ERROR_CODE = 0;
138     char param[SYS_PARAMETER_SIZE] = { 0 };
139     int errorCode = GetParameter(VENDOR_COUNTRY_KEY, VENDOR_COUNTRY_DEFAULT, param, SYS_PARAMETER_SIZE);
140     if (errorCode <= SYSTEM_PARAMETER_ERROR_CODE) {
141         WIFI_LOGE("get vendor country fail, errorCode: %{public}d", errorCode);
142         return false;
143     }
144 
145     WIFI_LOGI("vendor country: %{public}s, errorCode: %{public}d.", param, errorCode);
146     auto iter = std::string(param).find("hwit");
147     return iter != std::string::npos;
148 }
149 #endif
150 }
151