• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Copyright (C) 2021 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 #include "block_connect_service.h"
16 #ifndef OHOS_ARCH_LITE
17 #include "wifi_config_center.h"
18 #include "wifi_system_timer.h"
19 #include "wifi_global_func.h"
20 #endif
21 
22 namespace OHOS {
23 namespace Wifi {
24 DEFINE_WIFILOG_LABEL("BlockConnectService");
25 constexpr int FREQUENT_DISCONNECT_COUNT = 5;
26 constexpr int64_t FREQUENT_DISCONNECT_TIME_INTERVAL_MAX = 10 * 60 * 1000 * 1000;
27 constexpr int64_t FREQUENT_DISCONNECT_TIME_INTERVAL_MID = 1 * 60 * 1000 * 1000;
28 constexpr int64_t FREQUENT_DISCONNECT_TIME_INTERVAL_MIN = 0.5 * 60 * 1000 * 1000;
29 #ifndef OHOS_ARCH_LITE
30 constexpr int64_t TIMEOUT_CLEAR_SET = 4 * 60 * 1000;
31 constexpr int32_t MIN_RSSI_LEVEL_3 = -75;
32 constexpr int32_t MIN_BSSID_COUNT = 2;
33 constexpr int32_t INVALID_RSSI = -200;
34 #endif
35 
GetInstance()36 BlockConnectService &BlockConnectService::GetInstance()
37 {
38     static BlockConnectService gStaBlockConnectService;
39     return gStaBlockConnectService;
40 }
41 
BlockConnectService()42 BlockConnectService::BlockConnectService()
43 {
44     // Initialize any necessary variables or data structures
45     blockConnectPolicies = {
46         {DisabledReason::DISABLED_ASSOCIATION_REJECTION,
47          DisablePolicy(5 * 60 * 1000 * 1000, 3, WifiDeviceConfigStatus::DISABLED)},
48         {DisabledReason::DISABLED_AUTHENTICATION_FAILURE,
49          DisablePolicy(5 * 60 * 1000 * 1000, 3, WifiDeviceConfigStatus::DISABLED)},
50         {DisabledReason::DISABLED_DHCP_FAILURE,
51          DisablePolicy(5 * 60 * 1000 * 1000, 5, WifiDeviceConfigStatus::DISABLED)},
52         {DisabledReason::DISABLED_NO_INTERNET_TEMPORARY,
53          DisablePolicy(5 * 60 * 1000 * 1000, 1, WifiDeviceConfigStatus::DISABLED)},
54         {DisabledReason::DISABLED_AUTHENTICATION_NO_CREDENTIALS,
55          DisablePolicy(-1, 3, WifiDeviceConfigStatus::PERMEMANTLY_DISABLED)},
56         {DisabledReason::DISABLED_NO_INTERNET_PERMANENT,
57          DisablePolicy(-1, 1, WifiDeviceConfigStatus::PERMEMANTLY_DISABLED)},
58         {DisabledReason::DISABLED_BY_WIFI_MANAGER,
59          DisablePolicy(-1, 1, WifiDeviceConfigStatus::PERMEMANTLY_DISABLED)},
60         {DisabledReason::DISABLED_BY_WRONG_PASSWORD,
61          DisablePolicy(-1, 1, WifiDeviceConfigStatus::PERMEMANTLY_DISABLED)},
62         {DisabledReason::DISABLED_AUTHENTICATION_NO_SUBSCRIPTION,
63          DisablePolicy(-1, 1, WifiDeviceConfigStatus::PERMEMANTLY_DISABLED)},
64         {DisabledReason::DISABLED_AUTHENTICATION_PRIVATE_EAP_ERROR,
65          DisablePolicy(-1, 1, WifiDeviceConfigStatus::PERMEMANTLY_DISABLED)},
66         {DisabledReason::DISABLED_MDM_RESTRICTED,
67          DisablePolicy(-1, 1, WifiDeviceConfigStatus::PERMEMANTLY_DISABLED)},
68         {DisabledReason::DISABLED_NETWORK_NOT_FOUND,
69          DisablePolicy(5 * 60 * 1000 * 1000, 2, WifiDeviceConfigStatus::DISABLED)},
70         {DisabledReason::DISABLED_CONSECUTIVE_FAILURES,
71          DisablePolicy(5 * 60 * 1000 * 1000, 1, WifiDeviceConfigStatus::DISABLED)},
72         {DisabledReason::DISABLED_BY_SYSTEM,
73          DisablePolicy(-1, 1, WifiDeviceConfigStatus::PERMEMANTLY_DISABLED)},
74         {DisabledReason::DISABLED_EAP_AKA_FAILURE,
75          DisablePolicy(-1, 1, WifiDeviceConfigStatus::PERMEMANTLY_DISABLED)},
76         {DisabledReason::DISABLED_DISASSOC_REASON,
77          DisablePolicy(5 * 60 * 1000 * 1000, 5, WifiDeviceConfigStatus::DISABLED)},
78     };
79 
80     validReasons = {
81         static_cast<int>(DisconnectDetailReason::UNSPECIFIED),
82         static_cast<int>(DisconnectDetailReason::PREV_AUTH_NOT_VALID),
83         static_cast<int>(DisconnectDetailReason::DISASSOC_DUE_TO_INACTIVITY),
84         static_cast<int>(DisconnectDetailReason::DISASSOC_AP_BUSY),
85         static_cast<int>(DisconnectDetailReason::DISASSOC_STA_HAS_LEFT),
86         static_cast<int>(DisconnectDetailReason::DISASSOC_IEEE_802_1X_AUTH_FAILED),
87         static_cast<int>(DisconnectDetailReason::DISASSOC_LOW_ACK)
88     };
89 
90     mLastConnectedApInfo = {"", -1, 0};
91 }
92 
93 // Destructor
~BlockConnectService()94 BlockConnectService::~BlockConnectService()
95 {
96     // Clean up any resources
97     blockConnectPolicies.clear();
98 }
99 
Exit()100 void BlockConnectService::Exit()
101 {
102     // Implement the logic to exit the service
103     // Clean up any resources
104     blockConnectPolicies.clear();
105     mLastConnectedApInfo = {"", -1, 0};
106 }
107 
108 // Method to check if auto connect is enabled for a given WifiDeviceConfig
ShouldAutoConnect(const WifiDeviceConfig & config)109 bool BlockConnectService::ShouldAutoConnect(const WifiDeviceConfig &config)
110 {
111     // Return true if auto connect is enabled, false otherwise
112     WIFI_LOGD("ENTER shouldAutoConnect %{public}d",
113         config.networkSelectionStatus.status == WifiDeviceConfigStatus::ENABLED);
114     return config.networkSelectionStatus.status == WifiDeviceConfigStatus::ENABLED;
115 }
116 
117 // Update the selection status of all saved networks and check if disabled networks have expired
UpdateAllNetworkSelectStatus()118 bool BlockConnectService::UpdateAllNetworkSelectStatus()
119 {
120     WIFI_LOGD("ENTER updateAllNetworkSelectStatus");
121     // Implement the logic to update the selection status of all saved networks
122     // and check if disabled networks have expired
123     // Return true if successful, false otherwise
124     int64_t timestamp = GetElapsedMicrosecondsSinceBoot();
125     std::vector<WifiDeviceConfig> results;
126     if (WifiSettings::GetInstance().GetDeviceConfig(results) != 0) {
127         WIFI_LOGE("Failed to get device config");
128         return false;
129     }
130     for (auto &config : results) {
131         WifiSettings::GetInstance().ClearNetworkCandidateScanResult(config.networkId);
132         if ((config.networkSelectionStatus.status == WifiDeviceConfigStatus::ENABLED) &&
133             (config.networkSelectionStatus.networkSelectionDisableReason == DisabledReason::DISABLED_NONE)) {
134             continue;
135         }
136         DisablePolicy policy = CalculateDisablePolicy(config.networkSelectionStatus.networkSelectionDisableReason);
137         if (policy.disableStatus == WifiDeviceConfigStatus::PERMEMANTLY_DISABLED) {
138             LogDisabledConfig(config);
139             continue;
140         }
141         if (policy.disableStatus == WifiDeviceConfigStatus::ENABLED ||
142             (config.networkSelectionStatus.networkDisableTimeStamp > 0 &&
143             timestamp - config.networkSelectionStatus.networkDisableTimeStamp >= policy.disableTime)) {
144             config.networkSelectionStatus.status = WifiDeviceConfigStatus::ENABLED;
145             config.networkSelectionStatus.networkSelectionDisableReason = DisabledReason::DISABLED_NONE;
146             config.networkSelectionStatus.networkDisableTimeStamp = -1;
147             config.networkSelectionStatus.networkDisableCount = 0;
148             WifiSettings::GetInstance().AddDeviceConfig(config);
149         }
150         LogDisabledConfig(config);
151     }
152     return true;
153 }
154 
155 // Enable the selection status of a target network
EnableNetworkSelectStatus(int targetNetworkId)156 bool BlockConnectService::EnableNetworkSelectStatus(int targetNetworkId)
157 {
158     WIFI_LOGD("ENTER EnableNetworkSelectStatus");
159     // Implement the logic to enable the selection status of a target network
160     // Return true if successful, false otherwise
161     WifiDeviceConfig targetNetwork;
162     if (WifiSettings::GetInstance().GetDeviceConfig(targetNetworkId, targetNetwork)) {
163         WIFI_LOGE("Failed to get device config %{public}d", targetNetworkId);
164         return false;
165     }
166     targetNetwork.networkSelectionStatus.status = WifiDeviceConfigStatus::ENABLED;
167     targetNetwork.networkSelectionStatus.networkSelectionDisableReason = DisabledReason::DISABLED_NONE;
168     targetNetwork.networkSelectionStatus.networkDisableTimeStamp = -1;
169     targetNetwork.networkSelectionStatus.networkDisableCount = 0;
170     WifiSettings::GetInstance().AddDeviceConfig(targetNetwork);
171     WIFI_LOGI("EnableNetworkSelectStatus %{public}d %{public}s enabled",
172         targetNetworkId, SsidAnonymize(targetNetwork.ssid).c_str());
173     return true;
174 }
175 
CalculateDisablePolicy(DisabledReason disableReason)176 DisablePolicy BlockConnectService::CalculateDisablePolicy(DisabledReason disableReason)
177 {
178     // Implement the logic to calculate the disable reason based on the disconnect reason
179     // Return the disable reason
180     std::map<DisabledReason, DisablePolicy>::iterator it = blockConnectPolicies.find(disableReason);
181     if (it == blockConnectPolicies.end()) {
182         return DisablePolicy(-1, 0, WifiDeviceConfigStatus::ENABLED);
183     }
184     return it->second;
185 }
186 
187 // Clear the blocklist information of a target network with reason for wpa_supplicant disconnection
UpdateNetworkSelectStatus(int targetNetworkId,DisabledReason disableReason,int wpaReason)188 bool BlockConnectService::UpdateNetworkSelectStatus(int targetNetworkId, DisabledReason disableReason, int wpaReason)
189 {
190     // Implement the logic to clear the blocklist information of a target network
191     // Return true if successful, false otherwise
192     WIFI_LOGD("ENTER updateNetworkSelectStatus");
193     if (disableReason == DisabledReason::DISABLED_DISASSOC_REASON) {
194         if (std::find(validReasons.begin(), validReasons.end(), wpaReason) == validReasons.end()) {
195             return false;
196         }
197     }
198     return UpdateNetworkSelectStatus(targetNetworkId, disableReason);
199 }
200 
201 #ifdef FEATURE_WIFI_MDM_RESTRICTED_SUPPORT
202 // set thie blocklist information for mdm restrictedlist
UpdateNetworkSelectStatusForMdmRestrictedList()203 bool BlockConnectService::UpdateNetworkSelectStatusForMdmRestrictedList()
204 {
205     WIFI_LOGD("ENTER UpdateNetworkSelectStatusForMdmRestrictedList");
206     std::vector<WifiDeviceConfig> results;
207     int64_t timestamp = GetElapsedMicrosecondsSinceBoot();
208     if (WifiSettings::GetInstance().GetMdmRestrictedBlockDeviceConfig(results) != 0) {
209         WIFI_LOGE("Failed to get device config");
210         return false;
211     }
212     for (auto &config : results) {
213         DisablePolicy disablePolicy = CalculateDisablePolicy(DisabledReason::DISABLED_MDM_RESTRICTED);
214         if (disablePolicy.disableStatus == WifiDeviceConfigStatus::ENABLED) {
215             config.networkSelectionStatus.status = WifiDeviceConfigStatus::DISABLED;
216             config.networkSelectionStatus.networkSelectionDisableReason = DisabledReason::DISABLED_MDM_RESTRICTED;
217             config.networkSelectionStatus.networkDisableTimeStamp = timestamp;
218             config.networkSelectionStatus.networkDisableCount = 1;
219             WifiSettings::GetInstance().AddDeviceConfig(config);
220             continue;
221         }
222         if (config.networkSelectionStatus.networkSelectionDisableReason != DisabledReason::DISABLED_MDM_RESTRICTED) {
223             config.networkSelectionStatus.networkDisableCount = 1;
224             config.networkSelectionStatus.networkSelectionDisableReason = DisabledReason::DISABLED_MDM_RESTRICTED;
225         }
226         config.networkSelectionStatus.networkDisableTimeStamp = timestamp;
227         WifiSettings::GetInstance().AddDeviceConfig(config);
228     }
229     return true;
230 }
231 
232 // Clear mdmRestrictedList from block connect
ClearBlockConnectForMdmRestrictedList()233 bool BlockConnectService::ClearBlockConnectForMdmRestrictedList()
234 {
235     WIFI_LOGD("ENTER ClearBlockConnectForMdmRestrictedList");
236     std::vector<WifiDeviceConfig> results;
237     if (WifiSettings::GetInstance().GetMdmRestrictedBlockDeviceConfig(results) != 0) {
238         WIFI_LOGE("Failed to get device config");
239         return false;
240     }
241     for (auto &config : results) {
242         if (config.networkSelectionStatus.status == WifiDeviceConfigStatus::ENABLED) {
243             continue;
244         }
245         if (config.networkSelectionStatus.networkSelectionDisableReason == DisabledReason::DISABLED_MDM_RESTRICTED) {
246             config.networkSelectionStatus.status = WifiDeviceConfigStatus::ENABLED;
247             config.networkSelectionStatus.networkSelectionDisableReason = DisabledReason::DISABLED_NONE;
248             config.networkSelectionStatus.networkDisableTimeStamp = -1;
249             config.networkSelectionStatus.networkDisableCount = 0;
250             WifiSettings::GetInstance().AddDeviceConfig(config);
251         }
252     }
253     return true;
254 }
255 #endif
256 
257 // Clear the blocklist information of a target network
UpdateNetworkSelectStatus(int targetNetworkId,DisabledReason disableReason)258 bool BlockConnectService::UpdateNetworkSelectStatus(int targetNetworkId, DisabledReason disableReason)
259 {
260     // Implement the logic to clear the blocklist information of a target network
261     // Return true if successful, false otherwise
262     WIFI_LOGD("ENTER updateNetworkSelectStatus");
263     WifiDeviceConfig targetNetwork;
264     int64_t timestamp = GetElapsedMicrosecondsSinceBoot();
265     if (WifiSettings::GetInstance().GetDeviceConfig(targetNetworkId, targetNetwork)) {
266         WIFI_LOGE("Failed to get device config %{public}d", targetNetworkId);
267         return false;
268     }
269     DisablePolicy disablePolicy = CalculateDisablePolicy(disableReason);
270     if (disablePolicy.disableStatus == WifiDeviceConfigStatus::ENABLED) {
271         targetNetwork.networkSelectionStatus.status = WifiDeviceConfigStatus::ENABLED;
272         targetNetwork.networkSelectionStatus.networkSelectionDisableReason = disableReason;
273         targetNetwork.networkSelectionStatus.networkDisableTimeStamp = -1;
274         targetNetwork.networkSelectionStatus.networkDisableCount = 0;
275         return true;
276     }
277     if (targetNetwork.networkSelectionStatus.networkSelectionDisableReason == disableReason) {
278         targetNetwork.networkSelectionStatus.networkDisableCount++;
279     } else {
280         targetNetwork.networkSelectionStatus.networkDisableCount = 1;
281         targetNetwork.networkSelectionStatus.networkSelectionDisableReason = disableReason;
282     }
283 
284     if (targetNetwork.networkSelectionStatus.networkDisableCount >= disablePolicy.disableCount) {
285         targetNetwork.networkSelectionStatus.status = disablePolicy.disableStatus;
286         targetNetwork.networkSelectionStatus.networkSelectionDisableReason = disableReason;
287     }
288     targetNetwork.networkSelectionStatus.networkDisableTimeStamp = timestamp;
289     WifiSettings::GetInstance().AddDeviceConfig(targetNetwork);
290     WIFI_LOGI("updateNetworkSelectStatus networkId %{public}d %{public}s %{public}d",
291         targetNetworkId, SsidAnonymize(targetNetwork.ssid).c_str(), disableReason);
292     return true;
293 }
294 
295 // Check if the given BSSID has frequent disconnects with the last connected network
IsFrequentDisconnect(std::string bssid,int wpaReason,int locallyGenerated)296 bool BlockConnectService::IsFrequentDisconnect(std::string bssid, int wpaReason, int locallyGenerated)
297 {
298     // Implement the logic to check if the given BSSID has frequent disconnects
299     // with the last connected network
300     // Return true if frequent disconnects, false otherwise
301     int64_t timestamp = GetElapsedMicrosecondsSinceBoot();
302     int64_t time_duration = timestamp - mLastConnectedApInfo.lastDisconnectTimestamp;
303     WIFI_LOGD("ENTER isFrequentDisconnect %{public}" PRId64"  %{public}s", time_duration, MacAnonymize(bssid).c_str());
304     WIFI_LOGD("mLastConnectedApInfo alreadyConnectedCount %{public}d", mLastConnectedApInfo.alreadyConnectedCount);
305     mLastConnectedApInfo.lastDisconnectTimestamp = timestamp;
306     if (mLastConnectedApInfo.bssid != bssid) {
307         mLastConnectedApInfo.bssid = bssid;
308         mLastConnectedApInfo.alreadyConnectedCount = 1;
309         return false;
310     }
311 
312     if (time_duration > FREQUENT_DISCONNECT_TIME_INTERVAL_MAX) {
313         mLastConnectedApInfo.bssid = bssid;
314         mLastConnectedApInfo.alreadyConnectedCount = 1;
315         return false;
316     }
317     if (wpaReason == static_cast<int>(DisconnectDetailReason::DEAUTH_STA_IS_LEFING) ||
318         wpaReason == static_cast<int>(DisconnectDetailReason::DISASSOC_STA_HAS_LEFT)) {
319         if (time_duration < FREQUENT_DISCONNECT_TIME_INTERVAL_MIN && !locallyGenerated) {
320             WIFI_LOGD("isFrequentDisconnect case min %{public}s %{public}d  duration %{public}" PRId64,
321                 MacAnonymize(bssid).c_str(), wpaReason, time_duration);
322             mLastConnectedApInfo.alreadyConnectedCount++;
323         }
324     } else if (time_duration < FREQUENT_DISCONNECT_TIME_INTERVAL_MID) {
325         WIFI_LOGD("isFrequentDisconnect case mid %{public}s %{public}d duration %{public}" PRId64,
326             MacAnonymize(bssid).c_str(), wpaReason, time_duration);
327         mLastConnectedApInfo.alreadyConnectedCount++;
328     }
329     if (mLastConnectedApInfo.alreadyConnectedCount >= FREQUENT_DISCONNECT_COUNT) {
330         WIFI_LOGI("isFrequentDisconnect %{public}s %{public}d count %{public}d",
331             MacAnonymize(bssid).c_str(), wpaReason, mLastConnectedApInfo.alreadyConnectedCount);
332         mLastConnectedApInfo.alreadyConnectedCount = 1;
333         return true;
334     }
335     return false;
336 }
337 
338 // Check if the given targetNetworkId is blocked due to wrong password
IsWrongPassword(int targetNetworkId)339 bool BlockConnectService::IsWrongPassword(int targetNetworkId)
340 {
341     // Implement the logic to check if the given targetNetworkId is blocked due to wrong password
342     // Return true if blocked due to wrong password, false otherwise
343     WifiDeviceConfig targetNetwork;
344     if (WifiSettings::GetInstance().GetDeviceConfig(targetNetworkId, targetNetwork)) {
345         WIFI_LOGE("Failed to get device config %{public}d", targetNetworkId);
346         return false;
347     }
348 
349     if (targetNetwork.numAssociation == 0) {
350         return true;
351     }
352     return false;
353 }
354 
EnableAllNetworksByEnteringSettings(std::vector<DisabledReason> enableReasons)355 void BlockConnectService::EnableAllNetworksByEnteringSettings(std::vector<DisabledReason> enableReasons)
356 {
357     WIFI_LOGI("ENTER EnableAllNetworksByEnteringSettings");
358     std::vector<WifiDeviceConfig> results;
359     if (WifiSettings::GetInstance().GetDeviceConfig(results) != 0) {
360         WIFI_LOGE("Failed to get device config");
361         return;
362     }
363     for (auto &config : results) {
364         if (config.networkSelectionStatus.status == WifiDeviceConfigStatus::ENABLED) {
365             continue;
366         }
367         if (std::find(enableReasons.begin(), enableReasons.end(),
368             config.networkSelectionStatus.networkSelectionDisableReason) != enableReasons.end()) {
369             config.networkSelectionStatus.status = WifiDeviceConfigStatus::ENABLED;
370             config.networkSelectionStatus.networkSelectionDisableReason = DisabledReason::DISABLED_NONE;
371             config.networkSelectionStatus.networkDisableTimeStamp = -1;
372             config.networkSelectionStatus.networkDisableCount = 0;
373             WifiSettings::GetInstance().AddDeviceConfig(config);
374         }
375     }
376 }
377 
OnReceiveSettingsEnterEvent(bool isEnter)378 void BlockConnectService::OnReceiveSettingsEnterEvent(bool isEnter)
379 {
380     WIFI_LOGI("ENTER OnReceiveSettingsEnterEvent %{public}d", static_cast<int>(isEnter));
381     if (isEnter) {
382         std::vector<DisabledReason> enableReasons = {
383             DisabledReason::DISABLED_AUTHENTICATION_FAILURE,
384             DisabledReason::DISABLED_ASSOCIATION_REJECTION,
385             DisabledReason::DISABLED_DHCP_FAILURE,
386             DisabledReason::DISABLED_CONSECUTIVE_FAILURES,
387         };
388         EnableAllNetworksByEnteringSettings(enableReasons);
389 #ifndef OHOS_ARCH_LITE
390         ReleaseUnusableBssidSet();
391 #endif
392     }
393 }
394 
LogDisabledConfig(const WifiDeviceConfig & config)395 void BlockConnectService::LogDisabledConfig(const WifiDeviceConfig &config)
396 {
397     if (config.networkSelectionStatus.status == WifiDeviceConfigStatus::ENABLED) {
398         WIFI_LOGD("%{public}s config is ENABLED", SsidAnonymize(config.ssid).c_str());
399         return;
400     }
401     if (config.networkSelectionStatus.status == WifiDeviceConfigStatus::DISABLED) {
402         WIFI_LOGI("%{public}s config is DISABLED due to reason: %{public}d",
403             SsidAnonymize(config.ssid).c_str(), config.networkSelectionStatus.networkSelectionDisableReason);
404         return;
405     }
406     if (config.networkSelectionStatus.status == WifiDeviceConfigStatus::PERMEMANTLY_DISABLED) {
407         WIFI_LOGI("%{public}s  networkId :%{public}d config is PERMEMANTLY DISABLED due to reason: %{public}d",
408             SsidAnonymize(config.ssid).c_str(), config.networkId,
409             config.networkSelectionStatus.networkSelectionDisableReason);
410         return;
411     }
412 }
413 
414 #ifndef OHOS_ARCH_LITE
DealStaStopped(int instId)415 void BlockConnectService::DealStaStopped(int instId)
416 {
417     if (instId != 0) {
418         WIFI_LOGD("sta stopped, but instId is %{public}d", instId);
419         return;
420     }
421     if (WifiConfigCenter::GetInstance().GetScreenState() == MODE_STATE_OPEN) {
422         ReleaseUnusableBssidSet();
423     }
424 }
425 
NotifyWifiConnFailedInfo(int targetNetworkId,std::string bssid,DisabledReason disableReason)426 void BlockConnectService::NotifyWifiConnFailedInfo(int targetNetworkId, std::string bssid, DisabledReason disableReason)
427 {
428     WifiDeviceConfig targetNetwork;
429     if (WifiSettings::GetInstance().GetDeviceConfig(targetNetworkId, targetNetwork)) {
430         WIFI_LOGE("Failed to get device config %{public}d", targetNetworkId);
431         return;
432     }
433 
434     if (disableReason == DisabledReason::DISABLED_ASSOCIATION_REJECTION
435         || disableReason == DisabledReason::DISABLED_AUTHENTICATION_FAILURE) {
436         std::lock_guard<std::mutex> lock(bssidMutex_);
437         if (targetNetwork.ssid != curUnusableSsid_ ||
438             !WifiSettings::GetInstance().InKeyMgmtBitset(targetNetwork, curUnusableKeyMgmt_)) {
439             autoJoinUnusableBssidSet_.clear();
440         }
441         if (!bssid.empty()) {
442             WIFI_LOGI("NotifyWifiConnFailedInfo, add %{public}s as unusableBssidSet, reason:%{public}d",
443                 MacAnonymize(bssid).c_str(), static_cast<int32_t>(disableReason));
444             autoJoinUnusableBssidSet_.insert(bssid);
445             curUnusableSsid_ = targetNetwork.ssid;
446             curUnusableKeyMgmt_ = targetNetwork.keyMgmt;
447         }
448     }
449     if (disableReason == DisabledReason::DISABLED_DHCP_FAILURE) {
450         std::lock_guard<std::mutex> lock(dhcpFailMutex_);
451         IpInfo lastDhcpResults;
452         WifiConfigCenter::GetInstance().GetIpInfo(lastDhcpResults);
453         std::vector<WifiScanInfo> scanResults;
454         WifiConfigCenter::GetInstance().GetWifiScanConfig()->GetScanInfoList(scanResults);
455         int32_t rssi = INVALID_RSSI;
456         for (auto scanInfo : scanResults) {
457             if (scanInfo.bssid == bssid) {
458                 rssi = scanInfo.rssi;
459             }
460         }
461         int32_t bssidCnt = GetBssidCounter(targetNetwork, scanResults);
462         if (!bssid.empty() && rssi >= MIN_RSSI_LEVEL_3 && bssidCnt >= MIN_BSSID_COUNT
463             && lastDhcpResults.ipAddress == 0) {
464             WIFI_LOGI("NotifyWifiConnFailedInfo, add %{public}s as dhcpFailBssidSet, reason:%{public}d",
465                 MacAnonymize(bssid).c_str(), static_cast<int32_t>(disableReason));
466             dhcpFailBssids_.insert(bssid);
467         }
468     }
469 }
470 
ReleaseUnusableBssidSet()471 void BlockConnectService::ReleaseUnusableBssidSet()
472 {
473     StopClearSetTimer();
474     std::lock_guard<std::mutex> lock(bssidMutex_);
475     autoJoinUnusableBssidSet_.clear();
476     curUnusableSsid_ = "";
477     curUnusableKeyMgmt_ = "";
478 }
479 
ReleaseDhcpFailBssidSet()480 void BlockConnectService::ReleaseDhcpFailBssidSet()
481 {
482     std::lock_guard<std::mutex> lock(dhcpFailMutex_);
483     dhcpFailBssids_.clear();
484 }
485 
IsBssidMatchUnusableSet(std::string bssid)486 bool BlockConnectService::IsBssidMatchUnusableSet(std::string bssid)
487 {
488     {
489         std::lock_guard<std::mutex> lock(bssidMutex_);
490         for (auto curBssid : autoJoinUnusableBssidSet_) {
491             if (bssid == curBssid) {
492                 WIFI_LOGI("current bssid %{public}s match unusable bssid set.", MacAnonymize(bssid).c_str());
493                 return true;
494             }
495         }
496     }
497     {
498         std::lock_guard<std::mutex> lock(dhcpFailMutex_);
499         for (auto dhcpBssid : dhcpFailBssids_) {
500             if (bssid == dhcpBssid) {
501                 WIFI_LOGI("current bssid %{public}s match dhcp fail bssid set.", MacAnonymize(bssid).c_str());
502                 return true;
503             }
504         }
505     }
506     return false;
507 }
508 
StartClearSetTimer()509 void BlockConnectService::StartClearSetTimer()
510 {
511     WIFI_LOGD("%{public}s, enter", __FUNCTION__);
512     std::lock_guard<std::mutex> lock(clearSetTimerMutex_);
513     if (clearSetTimerId_ != 0) {
514         WIFI_LOGI("%{public}s, clearSetTimerId_ is not zero", __FUNCTION__);
515         return;
516     }
517     std::shared_ptr<WifiSysTimer> clearSetTimer =
518         std::make_shared<WifiSysTimer>(false, 0, true, false);
519     std::function<void()> callback = [this]() { this->ClearSetTimerCallback(); };
520     clearSetTimer->SetCallbackInfo(callback);
521     clearSetTimerId_ = MiscServices::TimeServiceClient::GetInstance()->CreateTimer(clearSetTimer);
522     int64_t currentTime = MiscServices::TimeServiceClient::GetInstance()->GetBootTimeMs();
523     MiscServices::TimeServiceClient::GetInstance()->StartTimer(clearSetTimerId_, currentTime + TIMEOUT_CLEAR_SET);
524     WIFI_LOGI("%{public}s, succuss", __FUNCTION__);
525 }
526 
StopClearSetTimer()527 void BlockConnectService::StopClearSetTimer()
528 {
529     WIFI_LOGI("enter %{public}s, ", __FUNCTION__);
530     std::lock_guard<std::mutex> lock(clearSetTimerMutex_);
531     if (clearSetTimerId_ == 0) {
532         WIFI_LOGE("%{public}s, clearSetTimerId_ is zero", __FUNCTION__);
533         return;
534     } else {
535         MiscServices::TimeServiceClient::GetInstance()->StopTimer(clearSetTimerId_);
536         MiscServices::TimeServiceClient::GetInstance()->DestroyTimer(clearSetTimerId_);
537         clearSetTimerId_ = 0;
538         return;
539     }
540 }
541 
ClearSetTimerCallback()542 void BlockConnectService::ClearSetTimerCallback()
543 {
544     std::lock_guard<std::mutex> lock(bssidMutex_);
545     autoJoinUnusableBssidSet_.clear();
546     curUnusableSsid_ = "";
547     curUnusableKeyMgmt_ = "";
548 }
549 #endif
550 }
551 }