• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <iostream>
17 #include "wifi_scorer_impl.h"
18 #include "wifi_config_center.h"
19 #include "network_status_history_manager.h"
20 #include "external_wifi_common_builder_manager.h"
21 #include "wifi_logger.h"
22 
23 namespace OHOS::Wifi::NetworkSelection {
24 DEFINE_WIFILOG_LABEL("WifiScorerImpl")
25 namespace {
26 constexpr int SUFFICIENT_RSSI_5G = -70;
27 constexpr int SUFFICIENT_RSSI_2G = -73;
28 constexpr int RSSI_SCORE_OFFSET = 85;
29 constexpr int RSSI_SCORE_SLOPE_IS_4 = 4;
30 constexpr int TOP_TIME_BASE_SCORE = 1000000;
31 constexpr int BOTTOM_TIME_BASE_SCORE = -1000000;
32 constexpr int MAX_RECENT_SELECTION_SECONDS = 8 * 60 * 60;
33 constexpr int MIN_5G_FREQUENCY = 5160;
34 constexpr int MAX_5G_FREQUENCY = 5865;
35 constexpr int WIFI_5G_BAND_SCORE = 50;
36 constexpr int WIFI_2G_BAND_SCORE = 20;
37 constexpr int SECURITY_BONUS_SCORE = 5;
38 constexpr int RSSI_LEVEL_FOUR_SCORE = 80;
39 constexpr int RSSI_LEVEL_THREE_SCORE = 60;
40 constexpr int RSSI_LEVEL_TWO_SCORE = 20;
41 constexpr int WIFI_DEFAULT_SCORE = -1;
42 constexpr int RSSI_LEVEL_TWO_SCORE_5G = 40;
43 constexpr int RSSI_LEVEL_TWO_SCORE_2G = 20;
44 constexpr int SIGNAL_LEVEL_TWO = 2;
45 constexpr int SIGNAL_LEVEL_THREE = 3;
46 constexpr int SIGNAL_LEVEL_FOUR = 4;
47 constexpr int MIN_RSSI = -128;
48 constexpr int INTERNET_ACCESS_AWARD = 2;
49 constexpr int EMPTY_NETWORK_STATUS_HISTORY_AWARD = 1;
50 constexpr int MAX_HISTORY_NETWORK_STATUS_NUM = 10;
51 constexpr int HISTORY_NETWORK_STATUS_WEIGHTED_SCORE[MAX_HISTORY_NETWORK_STATUS_NUM] = {
52     81920, 40960, 20480, 10240, 5120, 2560, 1280, 640, 320, 160};
53 }
RssiScorer()54 RssiScorer::RssiScorer() : SimpleWifiScorer("rssiScorer") {}
55 
Score(NetworkCandidate & networkCandidate)56 double RssiScorer::Score(NetworkCandidate &networkCandidate)
57 {
58     if (networkCandidate.interScanInfo.rssi < MIN_RSSI) {
59         return MIN_RSSI;
60     } else if (networkCandidate.interScanInfo.rssi > 0) {
61         return 0;
62     }
63     return networkCandidate.interScanInfo.rssi;
64 }
65 
LastHaveInternetTimeScorer()66 LastHaveInternetTimeScorer::LastHaveInternetTimeScorer() : SimpleWifiScorer("lastHaveInternetTimeScorer") {}
67 
Score(NetworkCandidate & networkCandidate)68 double LastHaveInternetTimeScorer::Score(NetworkCandidate &networkCandidate)
69 {
70     if (networkCandidate.wifiDeviceConfig.lastHasInternetTime > 0) {
71         return static_cast<double>(networkCandidate.wifiDeviceConfig.lastHasInternetTime);
72     }
73     return 0;
74 }
75 
NetworkStatusHistoryScorer()76 NetworkStatusHistoryScorer::NetworkStatusHistoryScorer() : SimpleWifiScorer("networkStatusHistoryScorer") {}
77 
Score(NetworkCandidate & networkCandidate)78 double NetworkStatusHistoryScorer::Score(NetworkCandidate &networkCandidate)
79 {
80     auto networkStatusHistory = networkCandidate.wifiDeviceConfig.networkStatusHistory;
81     if (NetworkStatusHistoryManager::IsInternetAccessByHistory(networkStatusHistory)) {
82         return INTERNET_ACCESS_AWARD;
83     } else if (NetworkStatusHistoryManager::IsEmptyNetworkStatusHistory(networkStatusHistory)) {
84         return EMPTY_NETWORK_STATUS_HISTORY_AWARD;
85     }
86     return 0;
87 }
88 
GetRssiBaseScore(NetworkCandidate & networkCandidate)89 double ThroughputScorer::GetRssiBaseScore(NetworkCandidate &networkCandidate)
90 {
91     int rssi = networkCandidate.interScanInfo.rssi;
92     if (networkCandidate.interScanInfo.band == static_cast<int>(BandType::BAND_2GHZ)) {
93         rssi = rssi > SUFFICIENT_RSSI_2G ? SUFFICIENT_RSSI_2G : rssi;
94     } else {
95         rssi = rssi > SUFFICIENT_RSSI_5G ? SUFFICIENT_RSSI_5G : rssi;
96     }
97     return (rssi + RSSI_SCORE_OFFSET) * RSSI_SCORE_SLOPE_IS_4;
98 }
99 
GetSavedNetworkAward(NetworkCandidate & networkCandidate)100 double ThroughputScorer::GetSavedNetworkAward(NetworkCandidate &networkCandidate)
101 {
102     return networkCandidate.wifiDeviceConfig.isEphemeral ? 0 : SAVED_NETWORK_AWARD_SCORE;
103 }
104 
IsRecentUserSelected(NetworkCandidate & networkCandidate) const105 bool ThroughputScorer::IsRecentUserSelected(NetworkCandidate &networkCandidate) const
106 {
107     auto userLastSelectedNetworkId = WifiConfigCenter::GetInstance().GetUserLastSelectedNetworkId();
108     if (userLastSelectedNetworkId != INVALID_NETWORK_ID
109         && userLastSelectedNetworkId == networkCandidate.wifiDeviceConfig.networkId) {
110         time_t userLastSelectedNetworkTimeVal = WifiConfigCenter::GetInstance().GetUserLastSelectedNetworkTimeVal();
111         auto now = time(nullptr);
112         if (now < 0) {
113             WIFI_LOGW("time return invalid!\n.");
114             return false;
115         }
116         return (now - userLastSelectedNetworkTimeVal) < MAX_RECENT_SELECTION_SECONDS;
117     }
118     return false;
119 }
120 
IsSecurityNetwork(NetworkCandidate & networkCandidate) const121 bool ThroughputScorer::IsSecurityNetwork(NetworkCandidate &networkCandidate) const
122 {
123     return networkCandidate.wifiDeviceConfig.keyMgmt == KEY_MGMT_WEP
124         || networkCandidate.wifiDeviceConfig.keyMgmt == KEY_MGMT_WPA_PSK
125         || networkCandidate.wifiDeviceConfig.keyMgmt == KEY_MGMT_SAE
126         || networkCandidate.wifiDeviceConfig.keyMgmt == KEY_MGMT_EAP;
127 }
128 
DoScore(NetworkCandidate & networkCandidate,ScoreResult & scoreResult)129 void ThroughputScorer::DoScore(NetworkCandidate &networkCandidate, ScoreResult &scoreResult)
130 {
131     scoreResult.scorerName = "ThroughputScorer";
132     double rssiBaseScore = GetRssiBaseScore(networkCandidate);
133     double savedNetworkAward = GetSavedNetworkAward(networkCandidate);
134     scoreResult.score = rssiBaseScore + savedNetworkAward;
135     if (IsSecurityNetwork(networkCandidate)) {
136         scoreResult.score += SECURITY_AWARD_SCORE;
137     }
138 
139     // It is suggestion network that the network priority be very low.
140     if (networkCandidate.wifiDeviceConfig.uid != -1 &&
141         networkCandidate.wifiDeviceConfig.isShared == 0) {
142         scoreResult.score += BOTTOM_TIME_BASE_SCORE;
143         return;
144     }
145 
146     if (IsRecentUserSelected(networkCandidate)) {
147         scoreResult.score = TOP_TIME_BASE_SCORE + rssiBaseScore + savedNetworkAward;
148         return;
149     }
150 }
151 
SecurityBonusScorer()152 SecurityBonusScorer::SecurityBonusScorer() : SimpleWifiScorer("securityScore") {}
153 
IsHigherSecurityTypeFromScanResult(const InterScanInfo & interScanInfo)154 bool SecurityBonusScorer::IsHigherSecurityTypeFromScanResult(const InterScanInfo &interScanInfo)
155 {
156     return IsEncryptionSae(interScanInfo) || IsEncryptionPskSaeTransition(interScanInfo)
157         || IsEncryptionOwe(interScanInfo) || IsEncryptionOweTransition(interScanInfo)
158         || IsWpa3EnterpriseOnlyNetwork(interScanInfo) || IsWpa3EnterpriseTransitionNetwork(interScanInfo);
159 }
160 
IsEncryptionSae(const InterScanInfo & interScanInfo)161 bool SecurityBonusScorer::IsEncryptionSae(const InterScanInfo &interScanInfo)
162 {
163     return ExistSecurityType(interScanInfo, "SAE");
164 }
165 
IsEncryptionPskSaeTransition(const InterScanInfo & interScanInfo)166 bool SecurityBonusScorer::IsEncryptionPskSaeTransition(const InterScanInfo &interScanInfo)
167 {
168     return ExistSecurityType(interScanInfo, "PSK") && ExistSecurityType(interScanInfo, "SAE");
169 }
170 
IsEncryptionOwe(const InterScanInfo & interScanInfo)171 bool SecurityBonusScorer::IsEncryptionOwe(const InterScanInfo &interScanInfo)
172 {
173     return ExistSecurityType(interScanInfo, "OWE");
174 }
175 
IsEncryptionOweTransition(const InterScanInfo & interScanInfo)176 bool SecurityBonusScorer::IsEncryptionOweTransition(const InterScanInfo &interScanInfo)
177 {
178     return ExistSecurityType(interScanInfo, "OWE_TRANSITION");
179 }
180 
IsWpa3EnterpriseOnlyNetwork(const InterScanInfo & interScanInfo)181 bool SecurityBonusScorer::IsWpa3EnterpriseOnlyNetwork(const InterScanInfo &interScanInfo)
182 {
183     return ExistSecurityType(interScanInfo, "EAP/SHA256") && !ExistSecurityType(interScanInfo, "EAP/SHA1")
184         && ExistSecurityType(interScanInfo, "RSN") && !ExistSecurityType(interScanInfo, "WEP")
185         && !ExistSecurityType(interScanInfo, "TKIP")
186         && (ExistSecurityType(interScanInfo, "[MFPR]") || ExistSecurityType(interScanInfo, "[PMFR]"))
187         && (ExistSecurityType(interScanInfo, "[MFPC]") || ExistSecurityType(interScanInfo, "[PMFC]"));
188 }
189 
IsWpa3EnterpriseTransitionNetwork(const InterScanInfo & interScanInfo)190 bool SecurityBonusScorer::IsWpa3EnterpriseTransitionNetwork(const InterScanInfo &interScanInfo)
191 {
192     return ExistSecurityType(interScanInfo, "EAP/SHA1") && ExistSecurityType(interScanInfo, "EAP/SHA256")
193         && ExistSecurityType(interScanInfo, "RSN") && !ExistSecurityType(interScanInfo, "WEP")
194         && !ExistSecurityType(interScanInfo, "TKIP")
195         && !(ExistSecurityType(interScanInfo, "[MFPR]") || ExistSecurityType(interScanInfo, "[PMFR]"))
196         && (ExistSecurityType(interScanInfo, "[MFPC]") || ExistSecurityType(interScanInfo, "[PMFC]"));
197 }
198 
ExistSecurityType(const InterScanInfo & interScanInfo,const std::string & securityType)199 bool SecurityBonusScorer::ExistSecurityType(const InterScanInfo &interScanInfo, const std::string &securityType)
200 {
201     return interScanInfo.capabilities.find(securityType) != std::string::npos;
202 }
203 
Score(NetworkCandidate & networkCandidate)204 double SecurityBonusScorer::Score(NetworkCandidate &networkCandidate)
205 {
206     return IsHigherSecurityTypeFromScanResult(networkCandidate.interScanInfo) ? SECURITY_BONUS_SCORE : 0;
207 }
208 
RssiLevelBonusScorer()209 RssiLevelBonusScorer::RssiLevelBonusScorer() : SimpleWifiScorer("rssiLevelScore") {}
210 
Score(NetworkCandidate & networkCandidate)211 double RssiLevelBonusScorer::Score(NetworkCandidate &networkCandidate)
212 {
213     auto &scanInfo = networkCandidate.interScanInfo;
214     int frequency = networkCandidate.interScanInfo.frequency;
215     int currentSignalLevel = WifiSettings::GetInstance().GetSignalLevel(scanInfo.rssi, scanInfo.band);
216     if (currentSignalLevel == SIGNAL_LEVEL_FOUR) {
217         return RSSI_LEVEL_FOUR_SCORE;
218     }
219     if (currentSignalLevel == SIGNAL_LEVEL_THREE) {
220         return RSSI_LEVEL_THREE_SCORE;
221     }
222     if (currentSignalLevel == SIGNAL_LEVEL_TWO) {
223         if (frequency >= MIN_5G_FREQUENCY && frequency <= MAX_5G_FREQUENCY) {
224             return RSSI_LEVEL_TWO_SCORE_5G;
225         } else {
226             return RSSI_LEVEL_TWO_SCORE_2G;
227         }
228     }
229     return 0;
230 }
231 
SignalLevelScorer()232 SignalLevelScorer::SignalLevelScorer() : SimpleWifiScorer("SignalLevelScorer") {}
233 
Score(NetworkCandidate & networkCandidate)234 double SignalLevelScorer::Score(NetworkCandidate &networkCandidate)
235 {
236     auto &scanInfo = networkCandidate.interScanInfo;
237     int signalLevel = WifiSettings::GetInstance().GetSignalLevel(scanInfo.rssi, scanInfo.band);
238     int32_t levelScore = 0;
239     switch (signalLevel) {
240         case SIGNAL_LEVEL_FOUR:
241             levelScore = RSSI_LEVEL_FOUR_SCORE;
242             break;
243         case SIGNAL_LEVEL_THREE:
244             levelScore = RSSI_LEVEL_THREE_SCORE;
245             break;
246         case SIGNAL_LEVEL_TWO:
247             levelScore = RSSI_LEVEL_TWO_SCORE;
248             break;
249         default:
250             levelScore = WIFI_DEFAULT_SCORE;
251             break;
252     }
253 
254     return levelScore;
255 }
256 
Network5gBonusScorer()257 Network5gBonusScorer::Network5gBonusScorer() : SimpleWifiScorer("5gBonusScore") {}
258 
Score(NetworkCandidate & networkCandidate)259 double Network5gBonusScorer::Score(NetworkCandidate &networkCandidate)
260 {
261     int frequency = networkCandidate.interScanInfo.frequency;
262     return frequency >= MIN_5G_FREQUENCY && frequency <= MAX_5G_FREQUENCY ? WIFI_5G_BAND_SCORE : WIFI_2G_BAND_SCORE;
263 }
264 
SavedNetworkScorer(const std::string & scorerName)265 SavedNetworkScorer::SavedNetworkScorer(const std::string &scorerName) : CompositeWifiScorer(scorerName)
266 {
267     AddScorer(std::make_shared<RssiLevelBonusScorer>());
268     AddScorer(std::make_shared<SecurityBonusScorer>());
269     AddScorer(std::make_shared<Network5gBonusScorer>());
270     ExternalWifiCommonBuildManager::GetInstance().BuildScore(
271         TagType::HAS_INTERNET_NETWORK_SELECTOR_SCORE_WIFI_CATEGORY_TAG, *this);
272 }
273 
NoInternetNetworkStatusHistoryScorer()274 NoInternetNetworkStatusHistoryScorer::NoInternetNetworkStatusHistoryScorer()
275     : SimpleWifiScorer("NoInternetNetworkStatusHistoryScorer") {}
276 
Score(NetworkCandidate & networkCandidate)277 double NoInternetNetworkStatusHistoryScorer::Score(NetworkCandidate &networkCandidate)
278 {
279     double score = 0;
280     std::vector<int> vNetworkStatusHistory{};
281     vNetworkStatusHistory = NetworkStatusHistoryManager::GetCurrentNetworkStatusHistory2Array(
282         networkCandidate.wifiDeviceConfig.networkStatusHistory);
283 
284     int nSize = (int)vNetworkStatusHistory.size();
285     for (int i = 0; i < nSize; i++) {
286         if (i >= MAX_HISTORY_NETWORK_STATUS_NUM) {
287             break;
288         }
289         score += HISTORY_NETWORK_STATUS_WEIGHTED_SCORE[i] * vNetworkStatusHistory[i];
290     }
291     return score;
292 }
293 
ApQualityScorer(const std::string & scorerName)294 ApQualityScorer::ApQualityScorer(const std::string &scorerName) : CompositeWifiScorer(scorerName)
295 {
296     AddScorer(std::make_shared<SignalLevelScorer>());
297     AddScorer(std::make_shared<Network5gBonusScorer>());
298     ExternalWifiCommonBuildManager::GetInstance().BuildScore(
299         TagType::HAS_INTERNET_NETWORK_SELECTOR_SCORE_WIFI_CATEGORY_TAG, *this);
300     AddScorer(std::make_shared<SecurityBonusScorer>());
301 }
302 }
303