1 /*
2  * Copyright (C) 2024 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 "wifi_filter_impl.h"
17 #include "network_selection_utils.h"
18 #include "network_status_history_manager.h"
19 #include "wifi_config_center.h"
20 #include "wifi_logger.h"
21 #include "wifi_settings.h"
22 #include "network_black_list_manager.h"
23 #include "wifi_ap_msg.h"
24 #ifndef OHOS_ARCH_LITE
25 #include "wifi_app_state_aware.h"
26 #endif
27 namespace OHOS::Wifi::NetworkSelection {
28 DEFINE_WIFILOG_LABEL("WifiFilter")
29 namespace {
30 constexpr int RECHECK_DELAYED_SECONDS = 1 * 60 * 60;
31 constexpr int MIN_5GHZ_BAND_FREQUENCY = 5000;
32 constexpr int MIN_RSSI_VALUE_24G = -77;
33 constexpr int MIN_RSSI_VALUE_5G = -80;
34 constexpr int SIGNAL_LEVEL_TWO = 2;
35 constexpr int POOR_PORTAL_RECHECK_DELAYED_SECONDS = 2 * RECHECK_DELAYED_SECONDS;
36 constexpr int32_t MIN_SIGNAL_LEVEL_INTERVAL = 2;
37 constexpr int32_t SIGNAL_LEVEL_THREE = 3;
38 constexpr int32_t SIGNAL_LEVEL_FOUR = 4;
39 constexpr int32_t MIN_RSSI_INTERVAL = 8;
40 }
41 
HiddenWifiFilter()42 HiddenWifiFilter::HiddenWifiFilter() : SimpleWifiFilter("notHidden") {}
43 
~HiddenWifiFilter()44 HiddenWifiFilter::~HiddenWifiFilter()
45 {
46     if (!filteredNetworkCandidates.empty()) {
47         WIFI_LOGD("filteredNetworkCandidates in %{public}s: %{public}s",
48                   filterName.c_str(),
49                   NetworkSelectionUtils::GetNetworkCandidatesInfo(filteredNetworkCandidates).c_str());
50     }
51 }
52 
Filter(NetworkCandidate & networkCandidate)53 bool HiddenWifiFilter::Filter(NetworkCandidate &networkCandidate)
54 {
55     return !networkCandidate.interScanInfo.ssid.empty();
56 }
57 
58 
SignalStrengthWifiFilter()59 SignalStrengthWifiFilter::SignalStrengthWifiFilter(): SimpleWifiFilter("notSignalWooWeak") {}
60 
~SignalStrengthWifiFilter()61 SignalStrengthWifiFilter::~SignalStrengthWifiFilter()
62 {
63     if (!filteredNetworkCandidates.empty()) {
64         WIFI_LOGD("filteredNetworkCandidates in %{public}s: %{public}s",
65                   filterName.c_str(),
66                   NetworkSelectionUtils::GetNetworkCandidatesInfo(filteredNetworkCandidates).c_str());
67     }
68 }
69 
Filter(NetworkCandidate & networkCandidate)70 bool SignalStrengthWifiFilter::Filter(NetworkCandidate &networkCandidate)
71 {
72     auto &scanInfo = networkCandidate.interScanInfo;
73     auto rssiThreshold = scanInfo.frequency < MIN_5GHZ_BAND_FREQUENCY ? MIN_RSSI_VALUE_24G : MIN_RSSI_VALUE_5G;
74     return scanInfo.rssi >= rssiThreshold;
75 }
76 
SavedWifiFilter()77 SavedWifiFilter::SavedWifiFilter() : SimpleWifiFilter("savedWifiFilter") {}
78 
~SavedWifiFilter()79 SavedWifiFilter::~SavedWifiFilter()
80 {
81     if (!filteredNetworkCandidates.empty()) {
82         WIFI_LOGI("filteredNetworkCandidates in %{public}s: %{public}s",
83                   filterName.c_str(),
84                   NetworkSelectionUtils::GetNetworkCandidatesInfo(filteredNetworkCandidates).c_str());
85     }
86 }
87 
Filter(NetworkCandidate & networkCandidate)88 bool SavedWifiFilter::Filter(NetworkCandidate &networkCandidate)
89 {
90     return networkCandidate.wifiDeviceConfig.networkId != INVALID_NETWORK_ID;
91 }
92 
93 
EphemeralWifiFilter()94 EphemeralWifiFilter::EphemeralWifiFilter() : SimpleWifiFilter("notEphemeral") {}
95 
~EphemeralWifiFilter()96 EphemeralWifiFilter::~EphemeralWifiFilter()
97 {
98     if (!filteredNetworkCandidates.empty()) {
99         WIFI_LOGI("filteredNetworkCandidates in %{public}s: %{public}s",
100                   filterName.c_str(),
101                   NetworkSelectionUtils::GetNetworkCandidatesInfo(filteredNetworkCandidates).c_str());
102     }
103 }
104 
Filter(NetworkCandidate & networkCandidate)105 bool EphemeralWifiFilter::Filter(NetworkCandidate &networkCandidate)
106 {
107     return !networkCandidate.wifiDeviceConfig.isEphemeral;
108 }
109 
PassPointWifiFilter()110 PassPointWifiFilter::PassPointWifiFilter() : SimpleWifiFilter("notPassPoint") {}
111 
~PassPointWifiFilter()112 PassPointWifiFilter::~PassPointWifiFilter()
113 {
114     if (!filteredNetworkCandidates.empty()) {
115         WIFI_LOGI("filteredNetworkCandidates in %{public}s: %{public}s",
116                   filterName.c_str(),
117                   NetworkSelectionUtils::GetNetworkCandidatesInfo(filteredNetworkCandidates).c_str());
118     }
119 }
120 
Filter(NetworkCandidate & networkCandidate)121 bool PassPointWifiFilter::Filter(NetworkCandidate &networkCandidate)
122 {
123     return !networkCandidate.wifiDeviceConfig.isPasspoint;
124 }
125 
126 
DisableWifiFilter()127 DisableWifiFilter::DisableWifiFilter() : SimpleWifiFilter("enableWifi") {}
128 
~DisableWifiFilter()129 DisableWifiFilter::~DisableWifiFilter()
130 {
131     if (!filteredNetworkCandidates.empty()) {
132         WIFI_LOGI("filteredNetworkCandidates in %{public}s: %{public}s",
133                   filterName.c_str(),
134                   NetworkSelectionUtils::GetNetworkCandidatesInfo(filteredNetworkCandidates).c_str());
135     }
136 }
137 
Filter(NetworkCandidate & networkCandidate)138 bool DisableWifiFilter::Filter(NetworkCandidate &networkCandidate)
139 {
140     return networkCandidate.wifiDeviceConfig.networkSelectionStatus.status == WifiDeviceConfigStatus::ENABLED;
141 }
142 
MatchedUserSelectBssidWifiFilter()143 MatchedUserSelectBssidWifiFilter::MatchedUserSelectBssidWifiFilter() : SimpleWifiFilter("matchUserSelect") {}
144 
~MatchedUserSelectBssidWifiFilter()145 MatchedUserSelectBssidWifiFilter::~MatchedUserSelectBssidWifiFilter()
146 {
147     if (!filteredNetworkCandidates.empty()) {
148         WIFI_LOGI("filteredNetworkCandidates in %{public}s: %{public}s",
149                   filterName.c_str(),
150                   NetworkSelectionUtils::GetNetworkCandidatesInfo(filteredNetworkCandidates).c_str());
151     }
152 }
153 
Filter(NetworkCandidate & networkCandidate)154 bool MatchedUserSelectBssidWifiFilter::Filter(NetworkCandidate &networkCandidate)
155 {
156     if (networkCandidate.wifiDeviceConfig.userSelectBssid.empty()) {
157         return true;
158     }
159     return networkCandidate.interScanInfo.bssid == networkCandidate.wifiDeviceConfig.userSelectBssid;
160 }
161 
HasInternetWifiFilter()162 HasInternetWifiFilter::HasInternetWifiFilter() : SimpleWifiFilter("hasInternet") {}
163 
~HasInternetWifiFilter()164 HasInternetWifiFilter::~HasInternetWifiFilter()
165 {
166     if (!filteredNetworkCandidates.empty()) {
167         WIFI_LOGI("filteredNetworkCandidates in %{public}s: %{public}s",
168                   filterName.c_str(),
169                   NetworkSelectionUtils::GetNetworkCandidatesInfo(filteredNetworkCandidates).c_str());
170     }
171 }
172 
Filter(NetworkCandidate & networkCandidate)173 bool HasInternetWifiFilter::Filter(NetworkCandidate &networkCandidate)
174 {
175     auto &wifiDeviceConfig = networkCandidate.wifiDeviceConfig;
176     if (wifiDeviceConfig.noInternetAccess || wifiDeviceConfig.isPortal) {
177         return false;
178     }
179     if (NetworkStatusHistoryManager::IsInternetAccessByHistory(wifiDeviceConfig.networkStatusHistory)) {
180         return true;
181     }
182     if (NetworkSelectionUtils::IsOpenNetwork(networkCandidate)) {
183         return false;
184     }
185     return NetworkStatusHistoryManager::IsEmptyNetworkStatusHistory(wifiDeviceConfig.networkStatusHistory);
186 }
187 
RecoveryWifiFilter()188 RecoveryWifiFilter::RecoveryWifiFilter() : SimpleWifiFilter("recovery") {}
189 
~RecoveryWifiFilter()190 RecoveryWifiFilter::~RecoveryWifiFilter()
191 {
192     if (!filteredNetworkCandidates.empty()) {
193         WIFI_LOGI("filteredNetworkCandidates in %{public}s: %{public}s",
194                   filterName.c_str(),
195                   NetworkSelectionUtils::GetNetworkCandidatesInfo(filteredNetworkCandidates).c_str());
196     }
197 }
198 
Filter(NetworkCandidate & networkCandidate)199 bool RecoveryWifiFilter::Filter(NetworkCandidate &networkCandidate)
200 {
201     auto &wifiDeviceConfig = networkCandidate.wifiDeviceConfig;
202     if (NetworkStatusHistoryManager::IsEmptyNetworkStatusHistory(wifiDeviceConfig.networkStatusHistory)) {
203         InterScanInfo interScanInfo = networkCandidate.interScanInfo;
204         WIFI_LOGI("RecoveryWifiFilter, network history is 0, try reconnect, add candidate network, bssid=%{public}s",
205             MacAnonymize(interScanInfo.bssid).c_str());
206         return true;
207     }
208     return wifiDeviceConfig.noInternetAccess && !wifiDeviceConfig.isPortal &&
209         NetworkStatusHistoryManager::IsAllowRecoveryByHistory(wifiDeviceConfig.networkStatusHistory);
210 }
211 
PoorPortalWifiFilter()212 PoorPortalWifiFilter::PoorPortalWifiFilter() : SimpleWifiFilter("notPoorPortal") {}
213 
~PoorPortalWifiFilter()214 PoorPortalWifiFilter::~PoorPortalWifiFilter()
215 {
216     if (!filteredNetworkCandidates.empty()) {
217         WIFI_LOGI("filteredNetworkCandidates in %{public}s: %{public}s",
218                   filterName.c_str(),
219                   NetworkSelectionUtils::GetNetworkCandidatesInfo(filteredNetworkCandidates).c_str());
220     }
221 }
222 
Filter(NetworkCandidate & networkCandidate)223 bool PoorPortalWifiFilter::Filter(NetworkCandidate &networkCandidate)
224 {
225     auto &interScanInfo = networkCandidate.interScanInfo;
226     if (networkCandidate.wifiDeviceConfig.isPortal &&
227         networkCandidate.wifiDeviceConfig.noInternetAccess &&
228         !NetworkStatusHistoryManager::IsAllowRecoveryByHistory(
229             networkCandidate.wifiDeviceConfig.networkStatusHistory)) {
230         return false;
231     }
232     int currentSignalLevel = WifiSettings::GetInstance().GetSignalLevel(interScanInfo.rssi, interScanInfo.band);
233     if (currentSignalLevel > SIGNAL_LEVEL_TWO) {
234         return true;
235     }
236     if (currentSignalLevel < SIGNAL_LEVEL_TWO) {
237         return false;
238     }
239     auto lastHasInternetTime = networkCandidate.wifiDeviceConfig.lastHasInternetTime;
240     auto now = time(nullptr);
241     if (now < 0) {
242         WIFI_LOGW("time return invalid!\n.");
243         return false;
244     }
245     return (now - lastHasInternetTime) <= POOR_PORTAL_RECHECK_DELAYED_SECONDS;
246 }
247 
PortalWifiFilter()248 PortalWifiFilter::PortalWifiFilter() : SimpleWifiFilter("portalWifiFilter") {}
249 
~PortalWifiFilter()250 PortalWifiFilter::~PortalWifiFilter()
251 {
252     if (!filteredNetworkCandidates.empty()) {
253         WIFI_LOGI("filteredNetworkCandidates in %{public}s: %{public}s",
254                   filterName.c_str(),
255                   NetworkSelectionUtils::GetNetworkCandidatesInfo(filteredNetworkCandidates).c_str());
256     }
257 }
258 
Filter(NetworkCandidate & networkCandidate)259 bool PortalWifiFilter::Filter(NetworkCandidate &networkCandidate)
260 {
261     if (networkCandidate.wifiDeviceConfig.isPortal &&
262         networkCandidate.wifiDeviceConfig.noInternetAccess &&
263         !NetworkStatusHistoryManager::IsAllowRecoveryByHistory(
264             networkCandidate.wifiDeviceConfig.networkStatusHistory)) {
265         return false;
266     }
267     return networkCandidate.wifiDeviceConfig.isPortal;
268 }
269 
MaybePortalWifiFilter()270 MaybePortalWifiFilter::MaybePortalWifiFilter() : SimpleWifiFilter("maybePortal") {}
271 
~MaybePortalWifiFilter()272 MaybePortalWifiFilter::~MaybePortalWifiFilter()
273 {
274     if (!filteredNetworkCandidates.empty()) {
275         WIFI_LOGI("filteredNetworkCandidates in %{public}s: %{public}s",
276                   filterName.c_str(),
277                   NetworkSelectionUtils::GetNetworkCandidatesInfo(filteredNetworkCandidates).c_str());
278     }
279 }
280 
Filter(NetworkCandidate & networkCandidate)281 bool MaybePortalWifiFilter::Filter(NetworkCandidate &networkCandidate)
282 {
283     return !NetworkSelectionUtils::IsScanResultForOweNetwork(networkCandidate) &&
284         NetworkSelectionUtils::IsOpenAndMaybePortal(networkCandidate) &&
285         (!networkCandidate.wifiDeviceConfig.noInternetAccess ||
286         NetworkStatusHistoryManager::IsAllowRecoveryByHistory(
287             networkCandidate.wifiDeviceConfig.networkStatusHistory));
288 }
289 
290 
NoInternetWifiFilter()291 NoInternetWifiFilter::NoInternetWifiFilter() : SimpleWifiFilter("noInternet") {}
292 
~NoInternetWifiFilter()293 NoInternetWifiFilter::~NoInternetWifiFilter()
294 {
295     if (!filteredNetworkCandidates.empty()) {
296         WIFI_LOGI("filteredNetworkCandidates in %{public}s: %{public}s",
297                   filterName.c_str(),
298                   NetworkSelectionUtils::GetNetworkCandidatesInfo(filteredNetworkCandidates).c_str());
299     }
300 }
301 
Filter(NetworkCandidate & networkCandidate)302 bool NoInternetWifiFilter::Filter(NetworkCandidate &networkCandidate)
303 {
304     auto &wifiDeviceConfig = networkCandidate.wifiDeviceConfig;
305     return NetworkStatusHistoryManager::HasInternetEverByHistory(wifiDeviceConfig.networkStatusHistory);
306 }
307 
WeakAlgorithmWifiFilter()308 WeakAlgorithmWifiFilter::WeakAlgorithmWifiFilter() : SimpleWifiFilter("noWeakAlgorithm") {}
309 
~WeakAlgorithmWifiFilter()310 WeakAlgorithmWifiFilter::~WeakAlgorithmWifiFilter()
311 {
312     if (!filteredNetworkCandidates.empty()) {
313         WIFI_LOGI("filteredNetworkCandidates in %{public}s: %{public}s",
314                   filterName.c_str(),
315                   NetworkSelectionUtils::GetNetworkCandidatesInfo(filteredNetworkCandidates).c_str());
316     }
317 }
318 
Filter(NetworkCandidate & networkCandidate)319 bool WeakAlgorithmWifiFilter::Filter(NetworkCandidate &networkCandidate)
320 {
321     auto &scanInfo = networkCandidate.interScanInfo;
322     if (scanInfo.securityType == WifiSecurity::WEP) {
323         WIFI_LOGD("WeakAlgorithm: WEP AP(%{public}s) is ignored", networkCandidate.ToString().c_str());
324         return false;
325     } else if (scanInfo.securityType == WifiSecurity::OPEN) {
326         WIFI_LOGD("WeakAlgorithm: OPEN AP(%{public}s) is ignored", networkCandidate.ToString().c_str());
327         return false;
328     } else if (scanInfo.securityType == WifiSecurity::PSK
329         && scanInfo.capabilities.find("TKIP") != std::string::npos) {
330         if (scanInfo.capabilities.find("CCMP") != std::string::npos) {
331             return true;
332         }
333         WIFI_LOGD("WeakAlgorithm: WPA AP(%{public}s) is ignored", networkCandidate.ToString().c_str());
334         return false;
335     }
336     return true;
337 }
338 
NotCurrentNetworkFilter()339 NotCurrentNetworkFilter::NotCurrentNetworkFilter() : SimpleWifiFilter("NotCurrentNetwork") {}
340 
~NotCurrentNetworkFilter()341 NotCurrentNetworkFilter::~NotCurrentNetworkFilter()
342 {
343     if (!filteredNetworkCandidates.empty()) {
344         WIFI_LOGI("filteredNetworkCandidates in %{public}s: %{public}s",
345                   filterName.c_str(),
346                   NetworkSelectionUtils::GetNetworkCandidatesInfo(filteredNetworkCandidates).c_str());
347     }
348 }
349 
Filter(NetworkCandidate & networkCandidate)350 bool NotCurrentNetworkFilter::Filter(NetworkCandidate &networkCandidate)
351 {
352     WifiLinkedInfo linkedInfo;
353     WifiConfigCenter::GetInstance().GetLinkedInfo(linkedInfo);
354     if (networkCandidate.interScanInfo.bssid == linkedInfo.bssid) {
355         WIFI_LOGI("NotCurrentNetworkFilter, same bssid:%{public}s",
356             networkCandidate.ToString().c_str());
357         return false;
358     }
359 
360     if ((networkCandidate.interScanInfo.ssid == linkedInfo.ssid) &&
361         NetworkSelectionUtils::IsConfigOpenOrEapType(networkCandidate)) {
362         WIFI_LOGI("NotCurrentNetworkFilter, same ssid and open or eap type:%{public}s",
363             networkCandidate.ToString().c_str());
364         return false;
365     }
366     return true;
367 }
368 
SignalLevelFilter()369 SignalLevelFilter::SignalLevelFilter() : SimpleWifiFilter("SignalLevel") {}
370 
~SignalLevelFilter()371 SignalLevelFilter::~SignalLevelFilter()
372 {
373     if (!filteredNetworkCandidates.empty()) {
374         WIFI_LOGI("filteredNetworkCandidates in %{public}s: %{public}s",
375                   filterName.c_str(),
376                   NetworkSelectionUtils::GetNetworkCandidatesInfo(filteredNetworkCandidates).c_str());
377     }
378 }
379 
Filter(NetworkCandidate & networkCandidate)380 bool SignalLevelFilter::Filter(NetworkCandidate &networkCandidate)
381 {
382     auto &interScanInfo = networkCandidate.interScanInfo;
383     int32_t signalLevel = WifiSettings::GetInstance().GetSignalLevel(interScanInfo.rssi, interScanInfo.band);
384     return signalLevel > SIGNAL_LEVEL_TWO;
385 }
386 
ValidNetworkIdFilter()387 ValidNetworkIdFilter::ValidNetworkIdFilter() : SimpleWifiFilter("ValidNetworkId") {}
388 
~ValidNetworkIdFilter()389 ValidNetworkIdFilter::~ValidNetworkIdFilter()
390 {
391     if (!filteredNetworkCandidates.empty()) {
392         WIFI_LOGI("filteredNetworkCandidates in %{public}s: %{public}s",
393                   filterName.c_str(),
394                   NetworkSelectionUtils::GetNetworkCandidatesInfo(filteredNetworkCandidates).c_str());
395     }
396 }
397 
Filter(NetworkCandidate & networkCandidate)398 bool ValidNetworkIdFilter::Filter(NetworkCandidate &networkCandidate)
399 {
400     return networkCandidate.wifiDeviceConfig.networkId != INVALID_NETWORK_ID;
401 }
402 
NotNetworkBlackListFilter()403 NotNetworkBlackListFilter::NotNetworkBlackListFilter() : SimpleWifiFilter("NotNetworkBlackList") {}
404 
~NotNetworkBlackListFilter()405 NotNetworkBlackListFilter::~NotNetworkBlackListFilter()
406 {
407     if (!filteredNetworkCandidates.empty()) {
408         WIFI_LOGI("filteredNetworkCandidates in %{public}s: %{public}s",
409                   filterName.c_str(),
410                   NetworkSelectionUtils::GetNetworkCandidatesInfo(filteredNetworkCandidates).c_str());
411     }
412 }
413 
Filter(NetworkCandidate & networkCandidate)414 bool NotNetworkBlackListFilter::Filter(NetworkCandidate &networkCandidate)
415 {
416     if (NetworkBlockListManager::GetInstance().IsInAbnormalWifiBlocklist(networkCandidate.interScanInfo.bssid)) {
417         WIFI_LOGI("NotNetworkBlockListFilter, in abnormal wifi blocklist, skip candidate:%{public}s",
418             networkCandidate.ToString().c_str());
419         return false;
420     }
421 
422     WifiLinkedInfo linkedInfo;
423     WifiConfigCenter::GetInstance().GetLinkedInfo(linkedInfo);
424     int32_t curSignalLevel = WifiSettings::GetInstance().GetSignalLevel(linkedInfo.rssi, linkedInfo.band);
425     auto scanInfo = networkCandidate.interScanInfo;
426     int32_t targetSignalLevel = WifiSettings::GetInstance().GetSignalLevel(scanInfo.rssi, scanInfo.band);
427     if (NetworkBlockListManager::GetInstance().IsInWifiBlocklist(networkCandidate.interScanInfo.bssid) &&
428         (targetSignalLevel <= SIGNAL_LEVEL_THREE || targetSignalLevel - curSignalLevel < MIN_SIGNAL_LEVEL_INTERVAL)) {
429         WIFI_LOGI("NotNetworkBlackListFilter, in wifi blocklist, targetSignalLevel:%{public}d, "
430             "curSignalLevel:%{public}d, skip candidate:%{public}s",
431             targetSignalLevel, curSignalLevel, networkCandidate.ToString().c_str());
432         return false;
433     }
434     return true;
435 }
436 
NotP2pFreqAt5gFilter()437 NotP2pFreqAt5gFilter::NotP2pFreqAt5gFilter() : SimpleWifiFilter("NotP2pFreqAt5g") {}
438 
~NotP2pFreqAt5gFilter()439 NotP2pFreqAt5gFilter::~NotP2pFreqAt5gFilter()
440 {
441     if (!filteredNetworkCandidates.empty()) {
442         WIFI_LOGI("filteredNetworkCandidates in %{public}s: %{public}s",
443                   filterName.c_str(),
444                   NetworkSelectionUtils::GetNetworkCandidatesInfo(filteredNetworkCandidates).c_str());
445     }
446 }
447 
Filter(NetworkCandidate & networkCandidate)448 bool NotP2pFreqAt5gFilter::Filter(NetworkCandidate &networkCandidate)
449 {
450     if (networkCandidate.interScanInfo.band == static_cast<int>(BandType::BAND_2GHZ)) {
451         return true;
452     }
453 
454     Hid2dUpperScene softbusScene;
455     Hid2dUpperScene castScene;
456     Hid2dUpperScene miracastScene;
457     WifiP2pLinkedInfo linkedInfo;
458     WifiConfigCenter::GetInstance().GetHid2dUpperScene(SOFT_BUS_SERVICE_UID, softbusScene);
459     WifiConfigCenter::GetInstance().GetHid2dUpperScene(CAST_ENGINE_SERVICE_UID, castScene);
460     WifiConfigCenter::GetInstance().GetHid2dUpperScene(MIRACAST_SERVICE_UID, miracastScene);
461     WifiConfigCenter::GetInstance().GetP2pInfo(linkedInfo);
462     if (linkedInfo.GetConnectState() == P2pConnectedState::P2P_DISCONNECTED
463         && WifiConfigCenter::GetInstance().GetP2pEnhanceState() == 0) {
464         return true;
465     }
466     // scene bit 0-2 is valid, 0x01: video, 0x02: audio, 0x04: file,
467     // scene & 0x07 > 0 means one of them takes effect.
468     bool isCastScene = false;
469     if ((softbusScene.scene & 0x07) > 0 || (castScene.scene & 0x07) > 0 || (miracastScene.scene & 0x07) > 0){
470         isCastScene = true;
471     }
472 
473     if (!isCastScene) {
474         return true;
475     }
476 
477     return NetworkSelectionUtils::IsSameFreqAsP2p(networkCandidate);
478 }
479 
ValidConfigNetworkFilter()480 ValidConfigNetworkFilter::ValidConfigNetworkFilter() : SimpleWifiFilter("ValidConfigNetwork") {}
481 
~ValidConfigNetworkFilter()482 ValidConfigNetworkFilter::~ValidConfigNetworkFilter()
483 {
484     if (!filteredNetworkCandidates.empty()) {
485         WIFI_LOGI("filteredNetworkCandidates in %{public}s: %{public}s",
486                   filterName.c_str(),
487                   NetworkSelectionUtils::GetNetworkCandidatesInfo(filteredNetworkCandidates).c_str());
488     }
489 }
490 
Filter(NetworkCandidate & networkCandidate)491 bool ValidConfigNetworkFilter::Filter(NetworkCandidate &networkCandidate)
492 {
493     // no internet filtering
494     auto &wifiDeviceConfig = networkCandidate.wifiDeviceConfig;
495     if (wifiDeviceConfig.noInternetAccess) {
496         WIFI_LOGI("ValidConfigNetworkFilter, no internet access, skip candidate:%{public}s",
497             networkCandidate.ToString().c_str());
498         return false;
499     }
500 
501     // portal network filtering
502     if (networkCandidate.wifiDeviceConfig.isPortal) {
503         WIFI_LOGI("ValidConfigNetworkFilter, portal network, skip candidate:%{public}s",
504             networkCandidate.ToString().c_str());
505         return false;
506     }
507 
508     // disable network filtering
509     auto &networkSelectionStatus = networkCandidate.wifiDeviceConfig.networkSelectionStatus;
510     if (networkSelectionStatus.networkSelectionDisableReason != DisabledReason::DISABLED_NONE) {
511         WIFI_LOGI("ValidConfigNetworkFilter, disable network, skip candidate:%{public}s",
512             networkCandidate.ToString().c_str());
513         return false;
514     }
515 
516     // empty network status history
517     if (NetworkStatusHistoryManager::IsEmptyNetworkStatusHistory(wifiDeviceConfig.networkStatusHistory)) {
518         WIFI_LOGI("ValidConfigNetworkFilter, no network status history, skip candidate:%{public}s",
519             networkCandidate.ToString().c_str());
520         return false;
521     }
522 
523     // maybe portal network filtering
524     if (NetworkSelectionUtils::IsScanResultForOweNetwork(networkCandidate) &&
525         NetworkSelectionUtils::IsOpenAndMaybePortal(networkCandidate)) {
526         WIFI_LOGI("ValidConfigNetworkFilter, maybe portal network, skip candidate:%{public}s",
527             networkCandidate.ToString().c_str());
528         return false;
529     }
530 
531     return true;
532 }
533 
WifiSwitchThresholdFilter()534 WifiSwitchThresholdFilter::WifiSwitchThresholdFilter() : SimpleWifiFilter("WifiSwitchThreshold") {}
535 
~WifiSwitchThresholdFilter()536 WifiSwitchThresholdFilter::~WifiSwitchThresholdFilter()
537 {
538     if (!filteredNetworkCandidates.empty()) {
539         WIFI_LOGI("filteredNetworkCandidates in %{public}s: %{public}s",
540                   filterName.c_str(),
541                   NetworkSelectionUtils::GetNetworkCandidatesInfo(filteredNetworkCandidates).c_str());
542     }
543 }
544 
Filter(NetworkCandidate & networkCandidate)545 bool WifiSwitchThresholdFilter::Filter(NetworkCandidate &networkCandidate)
546 {
547     WifiLinkedInfo linkedInfo;
548     WifiConfigCenter::GetInstance().GetLinkedInfo(linkedInfo);
549     int32_t curSignalLevel = WifiSettings::GetInstance().GetSignalLevel(linkedInfo.rssi, linkedInfo.band);
550     auto &interScanInfo = networkCandidate.interScanInfo;
551     if (linkedInfo.band == static_cast<int>(BandType::BAND_5GHZ) && curSignalLevel == SIGNAL_LEVEL_THREE &&
552         interScanInfo.band == static_cast<int>(BandType::BAND_2GHZ)) {
553         WIFI_LOGI("WifiSwitchThresholdFilter, current network is 5G and level is three and target network is 2G, "
554             "skip candidate:%{public}s", networkCandidate.ToString().c_str());
555         return false;
556     }
557 
558     if (curSignalLevel == SIGNAL_LEVEL_FOUR || (interScanInfo.rssi - linkedInfo.rssi < MIN_RSSI_INTERVAL)) {
559         WIFI_LOGI("WifiSwitchThresholdFilter, curSignalLevel:%{public}d, scan info rssi:%{public}d,"
560             "cur rssi:%{public}d, skip candidate:%{public}s",
561             curSignalLevel, interScanInfo.rssi, linkedInfo.rssi, networkCandidate.ToString().c_str());
562         return false;
563     }
564 
565     return true;
566 }
567 }