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 }