• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023-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 "self_cure_state_machine.h"
17 #include <vector>
18 #include <string>
19 #include "wifi_cmd_client.h"
20 #include "wifi_logger.h"
21 #include "mac_address.h"
22 #include "multi_gateway.h"
23 #include "wifi_manager.h"
24 #include "wifi_sta_hal_interface.h"
25 #include "network_status_history_manager.h"
26 #include "wifi_hisysevent.h"
27 #include "wifi_config_center.h"
28 #include "wifi_app_state_aware.h"
29 #include "ip_qos_monitor.h"
30 #include "wifi_net_agent.h"
31 #include "wifi_internal_event_dispatcher.h"
32 #include "wifi_net_agent.h"
33 #include "parameter.h"
34 #include "wifi_common_event_helper.h"
35 #include "wifi_country_code_manager.h"
36 #include "self_cure_utils.h"
37 #include "wifi_global_func.h"
38 
39 namespace OHOS {
40 namespace Wifi {
41 const std::string CLASS_NAME = "WifiSelfCure";
42 
43 DEFINE_WIFILOG_LABEL("SelfCureStateMachine");
44 
45 const uint32_t CONNECT_NETWORK_RETRY = 1;
46 const uint32_t WIFI_SINGLE_ITEM_BYTE_LEN = 8;
47 const uint32_t WIFI_SINGLE_MAC_LEN = 6;
48 const uint32_t WIFI_MAX_BLA_LIST_NUM = 16;
49 const uint32_t DHCP_OFFER_COUNT = 2;
50 const std::string INIT_SELFCURE_HISTORY = "0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0";
51 const std::string COUNTRY_CODE_CN = "460";
52 
SelfCureStateMachine(int instId)53 SelfCureStateMachine::SelfCureStateMachine(int instId)
54     : StateMachine("SelfCureStateMachine"),
55       pDefaultState_(nullptr),
56       pConnectedMonitorState_(nullptr),
57       pDisconnectedMonitorState_(nullptr),
58       pConnectionSelfCureState_(nullptr),
59       pInternetSelfCureState_(nullptr),
60       pWifi6SelfCureState_(nullptr),
61       pNoInternetState_(nullptr),
62       instId_(instId)
63 {
64     mNetWorkDetect_ = sptr<NetStateObserver>(new NetStateObserver());
65 }
66 
~SelfCureStateMachine()67 SelfCureStateMachine::~SelfCureStateMachine()
68 {
69     WIFI_LOGI("~SelfCureStateMachine");
70     StopHandlerThread();
71     ParsePointer(pDefaultState_);
72     ParsePointer(pConnectedMonitorState_);
73     ParsePointer(pDisconnectedMonitorState_);
74     ParsePointer(pConnectionSelfCureState_);
75     ParsePointer(pInternetSelfCureState_);
76     ParsePointer(pWifi6SelfCureState_);
77     ParsePointer(pNoInternetState_);
78 }
79 
BuildStateTree()80 void SelfCureStateMachine::BuildStateTree()
81 {
82     StatePlus(pDefaultState_, nullptr);
83     StatePlus(pConnectedMonitorState_, pDefaultState_);
84     StatePlus(pDisconnectedMonitorState_, pDefaultState_);
85     StatePlus(pConnectionSelfCureState_, pDefaultState_);
86     StatePlus(pInternetSelfCureState_, pDefaultState_);
87     StatePlus(pWifi6SelfCureState_, pDefaultState_);
88     StatePlus(pNoInternetState_, pDefaultState_);
89 }
90 
InitSelfCureStates()91 ErrCode SelfCureStateMachine::InitSelfCureStates()
92 {
93     WIFI_LOGI("Enter InitSelfCureStates\n");
94     int tmpErrNumber;
95     pDefaultState_ = new (std::nothrow)DefaultState(this);
96     tmpErrNumber = JudgmentEmpty(pDefaultState_);
97     pConnectedMonitorState_ = new (std::nothrow)ConnectedMonitorState(this);
98     tmpErrNumber += JudgmentEmpty(pConnectedMonitorState_);
99     pDisconnectedMonitorState_ = new (std::nothrow)DisconnectedMonitorState(this);
100     tmpErrNumber += JudgmentEmpty(pDisconnectedMonitorState_);
101     pConnectionSelfCureState_ = new (std::nothrow)ConnectionSelfCureState(this);
102     tmpErrNumber += JudgmentEmpty(pConnectionSelfCureState_);
103     pInternetSelfCureState_ = new (std::nothrow)InternetSelfCureState(this);
104     tmpErrNumber += JudgmentEmpty(pInternetSelfCureState_);
105     pWifi6SelfCureState_ = new (std::nothrow)Wifi6SelfCureState(this);
106     tmpErrNumber += JudgmentEmpty(pWifi6SelfCureState_);
107     pNoInternetState_ = new (std::nothrow)NoInternetState(this);
108     tmpErrNumber += JudgmentEmpty(pNoInternetState_);
109     if (tmpErrNumber != 0) {
110         WIFI_LOGE("InitSelfCureStates some one state is null\n");
111         return WIFI_OPT_FAILED;
112     }
113     return WIFI_OPT_SUCCESS;
114 }
115 
Initialize()116 ErrCode SelfCureStateMachine::Initialize()
117 {
118     if (!InitialStateMachine("SelfCureStateMachine")) {
119         WIFI_LOGE("Initial StateMachine failed.\n");
120         return WIFI_OPT_FAILED;
121     }
122     if (InitSelfCureStates() == WIFI_OPT_FAILED) {
123         return WIFI_OPT_FAILED;
124     }
125     BuildStateTree();
126     SetFirstState(pDisconnectedMonitorState_);
127     StartStateMachine();
128     return WIFI_OPT_SUCCESS;
129 }
130 
131 /* --------------------------- state machine default state ------------------------------ */
DefaultState(SelfCureStateMachine * selfCureStateMachine)132 SelfCureStateMachine::DefaultState::DefaultState(SelfCureStateMachine *selfCureStateMachine)
133     : State("DefaultState"),
134       pSelfCureStateMachine_(selfCureStateMachine)
135 {
136     WIFI_LOGD("DefaultState construct success.");
137 }
138 
~DefaultState()139 SelfCureStateMachine::DefaultState::~DefaultState() {}
140 
GoInState()141 void SelfCureStateMachine::DefaultState::GoInState()
142 {
143     pSelfCureStateMachine_->UpdateSelfcureState(WIFI_CURE_RESET_LEVEL_IDLE, false);
144     WIFI_LOGI("DefaultState GoInState function.");
145 }
146 
GoOutState()147 void SelfCureStateMachine::DefaultState::GoOutState()
148 {
149     WIFI_LOGI("DefaultState GoOutState function.");
150 }
151 
ExecuteStateMsg(InternalMessagePtr msg)152 bool SelfCureStateMachine::DefaultState::ExecuteStateMsg(InternalMessagePtr msg)
153 {
154     if (msg == nullptr) {
155         return false;
156     }
157     WIFI_LOGD("DefaultState-msgCode=%{public}d is received.\n", msg->GetMessageName());
158     bool ret = NOT_EXECUTED;
159     switch (msg->GetMessageName()) {
160         case WIFI_CURE_CMD_FORCE_STOP_SELF_CURE:
161             pSelfCureStateMachine_->ForceStopSelfCure();
162             break;
163         case WIFI_CURE_DHCP_OFFER_PKT_RCV: {
164             IpInfo info;
165             msg->GetMessageObj(info);
166             HandleDhcpOfferPacketRcv(info);
167             ret = EXECUTED;
168             break;
169         }
170         case WIFI_CURE_CMD_P2P_ENHANCE_STATE_CHANGED: {
171             int state = msg->GetParam1();
172             HandleP2pEnhanceStateChange(state);
173             ret = EXECUTED;
174             break;
175         }
176         case WIFI_CURE_RESET_OFF_TIMEOUT:
177         case WIFI_CURE_RESET_ON_TIMEOUT:
178         case WIFI_CURE_REASSOC_TIMEOUT:
179         case WIFI_CURE_CONNECT_TIMEOUT:
180         case WIFI_CURE_DISCONNECT_TIMEOUT:
181             pSelfCureStateMachine_->HandleSelfCureException(SCE_WIFI_STATUS_FAIL);
182             ret = EXECUTED;
183             break;
184         case WIFI_CURE_CMD_STOP_SELF_CURE: {
185             int status = msg->GetParam1();
186             pSelfCureStateMachine_->HandleSceStopSelfCure(status);
187             ret = EXECUTED;
188             break;
189         }
190         default:
191             WIFI_LOGD("DefaultState-msgCode=%{public}d not handled.\n", msg->GetMessageName());
192             break;
193     }
194     return ret;
195 }
196 
HandleDhcpOfferPacketRcv(const IpInfo & info)197 void SelfCureStateMachine::DefaultState::HandleDhcpOfferPacketRcv(const IpInfo &info)
198 {
199     IEnhanceService *pEnhanceService = WifiServiceManager::GetInstance().GetEnhanceServiceInst();
200     if (pEnhanceService == nullptr) {
201         WIFI_LOGE("HandleDhcpOfferPacketRcv get pEnhanceService service failed!");
202         return;
203     }
204     uint32_t retSize = 0;
205     pEnhanceService->DealDhcpOfferResult(OperationCmd::DHCP_OFFER_ADD, info, retSize);
206     WIFI_LOGI("dhcpOfferPackets size: %{public}u", retSize);
207 }
208 
HandleP2pEnhanceStateChange(int state)209 void SelfCureStateMachine::DefaultState::HandleP2pEnhanceStateChange(int state)
210 {
211     pSelfCureStateMachine_->isP2pEnhanceConnected_ = (state == 1) ? true : false;
212     if ((!pSelfCureStateMachine_->isP2pEnhanceConnected_) &&
213        (pSelfCureStateMachine_->GetCurStateName() == pSelfCureStateMachine_->pInternetSelfCureState_->GetStateName())) {
214         pSelfCureStateMachine_->SendMessage(WIFI_CURE_CMD_P2P_DISCONNECTED_EVENT);
215     }
216 }
217 /* --------------------------- state machine connected monitor state ------------------------------ */
ConnectedMonitorState(SelfCureStateMachine * selfCureStateMachine)218 SelfCureStateMachine::ConnectedMonitorState::ConnectedMonitorState(SelfCureStateMachine *selfCureStateMachine)
219     : State("ConnectedMonitorState"),
220       pSelfCureStateMachine_(selfCureStateMachine)
221 {
222     InitSelfCureCmsHandleMap();
223     WIFI_LOGD("ConnectedMonitorState construct success.");
224 }
225 
~ConnectedMonitorState()226 SelfCureStateMachine::ConnectedMonitorState::~ConnectedMonitorState() {}
227 
GoInState()228 void SelfCureStateMachine::ConnectedMonitorState::GoInState()
229 {
230     WIFI_LOGI("ConnectedMonitorState GoInState function.");
231     if (!pSelfCureStateMachine_->IsSuppOnCompletedState()) {
232         WIFI_LOGI("%{public}s: Wifi connection not completed", __FUNCTION__);
233         pSelfCureStateMachine_->MessageExecutedLater(
234             WIFI_CURE_NOTIFY_NETWORK_CONNECTED_RCVD, SELF_CURE_MONITOR_DELAYED_MS);
235     }
236     pSelfCureStateMachine_->UpdateSelfcureState(WIFI_CURE_RESET_LEVEL_IDLE, false);
237     pSelfCureStateMachine_->StopTimer(WIFI_CURE_NOTIFY_NETWORK_CONNECTED_RCVD);
238     IpQosMonitor::GetInstance().StartMonitor();
239     WifiLinkedInfo linkedInfo;
240     WifiConfigCenter::GetInstance().GetLinkedInfo(linkedInfo);
241     lastConnectedBssid_ = linkedInfo.bssid;
242     pSelfCureStateMachine_->arpDetectionFailedCnt_ = 0;
243     isHasInternetRecently_ = false;
244     isPortalUnthenEver_ = false;
245     pSelfCureStateMachine_->isInternetUnknown_ = false;
246     isUserSetStaticIpConfig_ = false;
247     isIpv4DnsEnabled_ = true;
248     isWifiSwitchAllowed_ = false;
249     isMobileHotspot_ = linkedInfo.isDataRestricted == 1 ? true : false;
250     pSelfCureStateMachine_->connectNetworkRetryCnt_ = 0;
251     WifiConfigCenter::GetInstance().SetLastNetworkId(linkedInfo.networkId);
252     WifiConfigCenter::GetInstance().SetWifiSelfcureReset(false);
253     pSelfCureStateMachine_->SetIsReassocWithFactoryMacAddress(0);
254     lastSignalLevel_ = WifiSettings::GetInstance().GetSignalLevel(linkedInfo.rssi, linkedInfo.band,
255         pSelfCureStateMachine_->instId_);
256     lastDnsFailedCnt_ = 0;
257     SelfCureUtils::GetInstance().ClearDnsFailedCounter();
258     if (!SetupSelfCureMonitor()) {
259         WIFI_LOGI("ConnectedMonitorState, config is null when connected broadcast received, delay to setup again.");
260         pSelfCureStateMachine_->MessageExecutedLater(WIFI_CURE_CMD_RESETUP_SELF_CURE_MONITOR,
261                                                      SELF_CURE_MONITOR_DELAYED_MS);
262     }
263     pSelfCureStateMachine_->MessageExecutedLater(WIFI_CURE_CMD_PERIODIC_ARP_DETECTED,
264                                                  FAST_ARP_DETECTED_MS);
265     pSelfCureStateMachine_->MessageExecutedLater(CMD_INTERNET_STATUS_DETECT_INTERVAL,
266                                                  INTERNET_STATUS_DETECT_INTERVAL_MS);
267 }
268 
GoOutState()269 void SelfCureStateMachine::ConnectedMonitorState::GoOutState()
270 {
271     WIFI_LOGI("ConnectedMonitorState GoOutState function.");
272 }
273 
ExecuteStateMsg(InternalMessagePtr msg)274 bool SelfCureStateMachine::ConnectedMonitorState::ExecuteStateMsg(InternalMessagePtr msg)
275 {
276     if (msg == nullptr) {
277         return false;
278     }
279     WIFI_LOGD("ConnectedMonitorState-msgCode=%{public}d is received.\n", msg->GetMessageName());
280     auto iter = selfCureCmsHandleFuncMap_.find(msg->GetMessageName());
281     if (iter != selfCureCmsHandleFuncMap_.end()) {
282         (iter->second)(msg);
283         return EXECUTED;
284     }
285     return NOT_EXECUTED;
286 }
287 
InitSelfCureCmsHandleMap()288 int SelfCureStateMachine::ConnectedMonitorState::InitSelfCureCmsHandleMap()
289 {
290     selfCureCmsHandleFuncMap_[WIFI_CURE_CMD_RESETUP_SELF_CURE_MONITOR] = [this](InternalMessagePtr msg) {
291         this->HandleResetupSelfCure(msg);
292     };
293     selfCureCmsHandleFuncMap_[WIFI_CURE_CMD_PERIODIC_ARP_DETECTED] = [this](InternalMessagePtr msg) {
294         this->HandlePeriodicArpDetection(msg);
295     };
296     selfCureCmsHandleFuncMap_[WIFI_CURE_CMD_ARP_FAILED_DETECTED] = [this](InternalMessagePtr msg) {
297         this->HandleArpDetectionFailed(msg);
298     };
299     selfCureCmsHandleFuncMap_[WIFI_CURE_CMD_INVALID_IP_CONFIRM] = [this](InternalMessagePtr msg) {
300         this->HandleInvalidIp(msg);
301     };
302     selfCureCmsHandleFuncMap_[WIFI_CURE_NOTIFY_NETWORK_CONNECTED_RCVD] = [this](InternalMessagePtr msg) {
303         this->HandleNetworkConnect(msg);
304     };
305     selfCureCmsHandleFuncMap_[WIFI_CURE_NOTIFY_NETWORK_DISCONNECTED_RCVD] = [this](InternalMessagePtr msg) {
306         this->HandleNetworkDisconnect(msg);
307     };
308     selfCureCmsHandleFuncMap_[WIFI_CURE_NOTIFY_RSSI_LEVEL_CHANGED_EVENT] = [this](InternalMessagePtr msg) {
309         this->HandleRssiLevelChange(msg);
310     };
311     selfCureCmsHandleFuncMap_[WIFI_CURE_CMD_INTERNET_FAILURE_DETECTED] = [this](InternalMessagePtr msg) {
312         this->HandleInternetFailedDetected(msg);
313     };
314     selfCureCmsHandleFuncMap_[CMD_INTERNET_STATUS_DETECT_INTERVAL] = [this](InternalMessagePtr msg) {
315         this->HandleTcpQualityQuery(msg);
316     };
317     selfCureCmsHandleFuncMap_[WIFI_CURE_CMD_GATEWAY_CHANGED_DETECT] = [this](InternalMessagePtr msg) {
318         this->HandleGatewayChanged(msg);
319     };
320     selfCureCmsHandleFuncMap_[WIFI_CURE_CMD_DNS_FAILED_MONITOR] = [this](InternalMessagePtr msg) {
321         this->HandleDnsFailedMonitor(msg);
322     };
323     return WIFI_OPT_SUCCESS;
324 }
325 
TransitionToSelfCureState(int reason)326 void SelfCureStateMachine::ConnectedMonitorState::TransitionToSelfCureState(int reason)
327 {
328     if (isMobileHotspot_ || pSelfCureStateMachine_->IsCustNetworkSelfCure()) {
329         WIFI_LOGW("transitionToSelfCureState, don't support SCE, do nothing");
330         return;
331     }
332     WIFI_LOGI("transitionToSelfCureState, reason is : %{public}d.", reason);
333     IpInfo wifiIpInfo;
334     WifiConfigCenter::GetInstance().GetIpInfo(wifiIpInfo, pSelfCureStateMachine_->instId_);
335     IpV6Info wifiIpv6Info;
336     WifiConfigCenter::GetInstance().GetIpv6Info(wifiIpv6Info, pSelfCureStateMachine_->instId_);
337     isIpv4DnsEnabled_ = wifiIpInfo.primaryDns != 0 || wifiIpInfo.secondDns != 0;
338     isGatewayInvalid_ = wifiIpInfo.gateway == 0 && wifiIpv6Info.gateway == "";
339     if (!isIpv4DnsEnabled_ || isGatewayInvalid_) {
340         WIFI_LOGI("transitionToSelfCureState, don't support SCE, do nothing or isIpv4DnsEnabled_ = %{public}d.",
341                   isIpv4DnsEnabled_);
342         return;
343     }
344     pSelfCureStateMachine_->MessageExecutedLater(WIFI_CURE_CMD_INTERNET_FAILED_SELF_CURE, reason, SELF_CURE_DELAYED_MS);
345     pSelfCureStateMachine_->SwitchState(pSelfCureStateMachine_->pInternetSelfCureState_);
346 }
347 
HandleResetupSelfCure(InternalMessagePtr msg)348 void SelfCureStateMachine::ConnectedMonitorState::HandleResetupSelfCure(InternalMessagePtr msg)
349 {
350     WIFI_LOGD("enter HandleResetupSelfCure.");
351     if (msg == nullptr) {
352         WIFI_LOGE("msg is nullptr.");
353         return;
354     }
355     SetupSelfCureMonitor();
356 }
357 
HandlePeriodicArpDetection(InternalMessagePtr msg)358 void SelfCureStateMachine::ConnectedMonitorState::HandlePeriodicArpDetection(InternalMessagePtr msg)
359 {
360     WIFI_LOGD("enter HandlePeriodicArpDetection.");
361     if (msg == nullptr) {
362         WIFI_LOGE("msg is nullptr.");
363         return;
364     }
365     pSelfCureStateMachine_->PeriodicArpDetection();
366 }
367 
HandleNetworkConnect(InternalMessagePtr msg)368 void SelfCureStateMachine::ConnectedMonitorState::HandleNetworkConnect(InternalMessagePtr msg)
369 {
370     WIFI_LOGD("enter HandleNetworkConnect.");
371     if (msg == nullptr) {
372         WIFI_LOGE("msg is nullptr.");
373         return;
374     }
375     GoInState();
376 }
377 
HandleNetworkDisconnect(InternalMessagePtr msg)378 void SelfCureStateMachine::ConnectedMonitorState::HandleNetworkDisconnect(InternalMessagePtr msg)
379 {
380     WIFI_LOGD("enter HandleNetworkDisconnect.");
381     if (msg == nullptr) {
382         WIFI_LOGE("msg is nullptr.");
383         return;
384     }
385     pSelfCureStateMachine_->StopTimer(WIFI_CURE_CMD_GATEWAY_CHANGED_DETECT);
386     pSelfCureStateMachine_->StopTimer(WIFI_CURE_CMD_RESETUP_SELF_CURE_MONITOR);
387     pSelfCureStateMachine_->SwitchState(pSelfCureStateMachine_->pDisconnectedMonitorState_);
388 }
389 
HandleRssiLevelChange(InternalMessagePtr msg)390 void SelfCureStateMachine::ConnectedMonitorState::HandleRssiLevelChange(InternalMessagePtr msg)
391 {
392     WIFI_LOGD("enter HandleRssiLevelChange.");
393     if (msg == nullptr) {
394         WIFI_LOGE("msg is nullptr.");
395         return;
396     }
397     lastSignalLevel_ = pSelfCureStateMachine_->GetCurSignalLevel();
398 }
399 
HandleArpDetectionFailed(InternalMessagePtr msg)400 void SelfCureStateMachine::ConnectedMonitorState::HandleArpDetectionFailed(InternalMessagePtr msg)
401 {
402     WIFI_LOGD("enter HandleArpDetectionFailed.");
403     if (pSelfCureStateMachine_->ShouldTransToWifi6SelfCure(msg, lastConnectedBssid_)) {
404         return;
405     }
406     if (pSelfCureStateMachine_->IsHttpReachable()) {
407         WIFI_LOGI("Http Reachable.");
408         return;
409     }
410     pSelfCureStateMachine_->selfCureReason_ = WIFI_CURE_INTERNET_FAILED_TYPE_TCP;
411     TransitionToSelfCureState(WIFI_CURE_INTERNET_FAILED_TYPE_TCP);
412 }
413 
SetupSelfCureMonitor()414 bool SelfCureStateMachine::ConnectedMonitorState::SetupSelfCureMonitor()
415 {
416     WifiDeviceConfig config;
417     if (pSelfCureStateMachine_->GetCurrentWifiDeviceConfig(config) == WIFI_OPT_SUCCESS) {
418         configAuthType_ = pSelfCureStateMachine_->GetAuthType();
419         AssignIpMethod ipAssignment;
420         pSelfCureStateMachine_->GetIpAssignment(ipAssignment);
421         isUserSetStaticIpConfig_ = ipAssignment == AssignIpMethod::STATIC;
422         pSelfCureStateMachine_->isInternetUnknown_ = NetworkStatusHistoryManager::IsEmptyNetworkStatusHistory(
423             pSelfCureStateMachine_->GetNetworkStatusHistory());
424         isHasInternetRecently_ = NetworkStatusHistoryManager::IsInternetAccessByHistory(
425             pSelfCureStateMachine_->GetNetworkStatusHistory());
426         isPortalUnthenEver_ = NetworkStatusHistoryManager::IsPortalByHistory(
427             pSelfCureStateMachine_->GetNetworkStatusHistory());
428         WIFI_LOGI("SetupSelfCureMonitor, isInternetUnknown_: %{public}d," \
429             " isHasInternetRecently_: %{public}d, isPortalUnthenEver_: %{public}d",
430             pSelfCureStateMachine_->isInternetUnknown_, isHasInternetRecently_, isPortalUnthenEver_);
431         if (!isMobileHotspot_) {
432             if (IsGatewayChanged()) {
433                 WIFI_LOGI("current gateway is different with history gateway that has internet.");
434                 pSelfCureStateMachine_->MessageExecutedLater(WIFI_CURE_CMD_GATEWAY_CHANGED_DETECT,
435                     GATEWAY_CHANGED_DETECT_DELAYED_MS);
436                 return true;
437             }
438         }
439         /** setup dns failed monitor when connected (the router's dns server maybe disabled). */
440         if ((!isMobileHotspot_) && (!pSelfCureStateMachine_->isStaticIpCureSuccess_) && isHasInternetRecently_) {
441             pSelfCureStateMachine_->MessageExecutedLater(WIFI_CURE_CMD_DNS_FAILED_MONITOR, INTERNET_DETECT_INTERVAL_MS);
442         }
443         return true;
444     }
445     return false;
446 }
447 
IsGatewayChanged()448 bool SelfCureStateMachine::ConnectedMonitorState::IsGatewayChanged()
449 {
450     IEnhanceService *pEnhanceService = WifiServiceManager::GetInstance().GetEnhanceServiceInst();
451     if (pEnhanceService == nullptr) {
452         WIFI_LOGE("IsGatewayChanged get pEnhanceService service failed!");
453         return false;
454     }
455     bool isChanged = false;
456     pEnhanceService->IsGatewayChanged(isChanged);
457     WIFI_LOGI("IsGatewayChanged, isChanged: %{public}d", isChanged);
458     return isChanged;
459 }
460 
RequestReassocWithFactoryMac()461 void SelfCureStateMachine::ConnectedMonitorState::RequestReassocWithFactoryMac()
462 {
463     pSelfCureStateMachine_->useWithRandMacAddress_ = FAC_MAC_REASSOC;
464     pSelfCureStateMachine_->selfCureReason_ = WIFI_CURE_INTERNET_FAILED_RAND_MAC;
465     TransitionToSelfCureState(WIFI_CURE_INTERNET_FAILED_RAND_MAC);
466 }
467 
HandleInvalidIp(InternalMessagePtr msg)468 void SelfCureStateMachine::ConnectedMonitorState::HandleInvalidIp(InternalMessagePtr msg)
469 {
470     if (pSelfCureStateMachine_->IsHttpReachable()) {
471         pSelfCureStateMachine_->noTcpRxCounter_ = 0;
472     } else {
473         int selfCureType = pSelfCureStateMachine_->IsMultiDhcpOffer() ?
474                             WIFI_CURE_INTERNET_FAILED_TYPE_GATEWAY :
475                             WIFI_CURE_INTERNET_FAILED_INVALID_IP;
476         pSelfCureStateMachine_->selfCureReason_ = selfCureType;
477         TransitionToSelfCureState(selfCureType);
478     }
479 }
480 
HandleDnsFailedMonitor(InternalMessagePtr msg)481 void SelfCureStateMachine::ConnectedMonitorState::HandleDnsFailedMonitor(InternalMessagePtr msg)
482 {
483     if (lastSignalLevel_ <= SIGNAL_LEVEL_1) {
484         WIFI_LOGI("HandleDnsFailedMonitor, lastSignalLevel_ <= 1, next peroid.");
485         lastDnsFailedCnt_ = SelfCureUtils::GetInstance().GetCurrentDnsFailedCounter();
486         pSelfCureStateMachine_->MessageExecutedLater(WIFI_CURE_CMD_DNS_FAILED_MONITOR, INTERNET_DETECT_INTERVAL_MS);
487         return;
488     }
489     int32_t currentDnsFailedCnt = 0;
490     currentDnsFailedCnt = SelfCureUtils::GetInstance().GetCurrentDnsFailedCounter();
491     int32_t deltaFailedDns = (currentDnsFailedCnt - lastDnsFailedCnt_);
492     WIFI_LOGI("HandleDnsFailedMonitor, deltaFailedDns is %{public}d", deltaFailedDns);
493     lastDnsFailedCnt_ = currentDnsFailedCnt;
494     if (deltaFailedDns >= DNS_FAILED_CNT) {
495         if (pSelfCureStateMachine_->IsHttpReachable()) {
496             WIFI_LOGI("HandleDnsFailedMonitor, HTTP detection succeeded.");
497             return;
498         }
499         pSelfCureStateMachine_->selfCureReason_ = WIFI_CURE_INTERNET_FAILED_TYPE_DNS;
500         TransitionToSelfCureState(WIFI_CURE_INTERNET_FAILED_TYPE_DNS);
501     }
502 }
503 
IsNeedSelfCure()504 bool SelfCureStateMachine::ConnectedMonitorState::IsNeedSelfCure()
505 {
506     if (pSelfCureStateMachine_->GetCurrentRssi() < MIN_VAL_LEVEL_3) {
507         return false;
508     }
509     if (pSelfCureStateMachine_->IsCustNetworkSelfCure() || pSelfCureStateMachine_->isInternetFailureDetected_) {
510         WIFI_LOGI("do not need selfcure, %{public}d", pSelfCureStateMachine_->isInternetFailureDetected_);
511         return false;
512     }
513 
514     if (!pSelfCureStateMachine_->IsSuppOnCompletedState()) {
515         WIFI_LOGI("%{public}s: Wifi connection not completed", __FUNCTION__);
516         return false;
517     }
518     pSelfCureStateMachine_->isInternetFailureDetected_ = true;
519     return true;
520 }
521 
HandleInternetFailedDetected(InternalMessagePtr msg)522 void SelfCureStateMachine::ConnectedMonitorState::HandleInternetFailedDetected(InternalMessagePtr msg)
523 {
524     if (msg == nullptr) {
525         WIFI_LOGE("%{public}s msg is null", __func__);
526         return;
527     }
528     if (!IsNeedSelfCure()) {
529         pSelfCureStateMachine_->isSelfcureDone_ = true;
530         return;
531     }
532     WIFI_LOGI("HandleInternetFailedDetected, wifi has no internet when connected.");
533     if (isMobileHotspot_ && !pSelfCureStateMachine_->IsWifi6Network(lastConnectedBssid_)) {
534         WIFI_LOGI("don't support selfcure, do nothing, isMobileHotspot_ = %{public}d", isMobileHotspot_);
535         return;
536     }
537     if (pSelfCureStateMachine_->ShouldTransToWifi6SelfCure(msg, lastConnectedBssid_)) {
538         WIFI_LOGI("%{public}s: TransToWifi6SelfCure", __FUNCTION__);
539         return;
540     }
541 
542     if ((msg != nullptr) && (!pSelfCureStateMachine_->isInternetUnknown_)) {
543         pSelfCureStateMachine_->isInternetUnknown_ = msg->GetParam1() == 1;
544     }
545     if (pSelfCureStateMachine_->IsNeedWifiReassocUseDeviceMac()) {
546         RequestReassocWithFactoryMac();
547         return;
548     }
549     // has no internet in history but not first connect, no need self cure
550     bool forceNoHttpCheck = static_cast<bool>(msg->GetParam2());
551     int64_t lastHasInetTime = static_cast<int64_t>(pSelfCureStateMachine_->GetLastHasInternetTime());
552     if (lastHasInetTime <= 0 || lastHasInetTime < pSelfCureStateMachine_->connectedTime_) {
553         forceNoHttpCheck = true;
554     }
555 
556     if (!pSelfCureStateMachine_->isStaticIpCureSuccess_ && forceNoHttpCheck) {
557         if (isHasInternetRecently_ || isPortalUnthenEver_ || pSelfCureStateMachine_->isInternetUnknown_) {
558             pSelfCureStateMachine_->selfCureReason_ = WIFI_CURE_INTERNET_FAILED_TYPE_DNS;
559             TransitionToSelfCureState(WIFI_CURE_INTERNET_FAILED_TYPE_DNS);
560         } else {
561             pSelfCureStateMachine_->SwitchState(pSelfCureStateMachine_->pNoInternetState_);
562             WIFI_LOGI("Handle network disable, there is not a expectant condition!.");
563         }
564         return;
565     }
566     HandleInternetFailedDetectedInner();
567 }
568 
HandleInternetFailedDetectedInner()569 void SelfCureStateMachine::ConnectedMonitorState::HandleInternetFailedDetectedInner()
570 {
571     if (pSelfCureStateMachine_->IsHttpReachable()) {
572         WIFI_LOGI("http is reachable, no need self cure");
573         pSelfCureStateMachine_->noTcpRxCounter_ = 0;
574         pSelfCureStateMachine_->isInternetFailureDetected_ = false;
575         return;
576     } else {
577         int32_t currentDnsFailedCnt = SelfCureUtils::GetInstance().GetCurrentDnsFailedCounter();
578         int32_t deltaFailedDns = (currentDnsFailedCnt - lastDnsFailedCnt_);
579         lastDnsFailedCnt_ = currentDnsFailedCnt;
580         pSelfCureStateMachine_->selfCureReason_ = deltaFailedDns >= DNS_FAILED_CNT ?
581             WIFI_CURE_INTERNET_FAILED_TYPE_DNS : WIFI_CURE_INTERNET_FAILED_TYPE_TCP;
582     }
583     WIFI_LOGI("HandleInternetFailedDetected, http unreachable, transition to SelfCureState,"
584         "selfCureReason_: %{public}d", pSelfCureStateMachine_->selfCureReason_);
585     TransitionToSelfCureState(pSelfCureStateMachine_->selfCureReason_);
586 }
587 
HandleTcpQualityQuery(InternalMessagePtr msg)588 void SelfCureStateMachine::ConnectedMonitorState::HandleTcpQualityQuery(InternalMessagePtr msg)
589 {
590     if (msg == nullptr) {
591         WIFI_LOGE("msg is nullptr.");
592         return;
593     }
594     pSelfCureStateMachine_->StopTimer(CMD_INTERNET_STATUS_DETECT_INTERVAL);
595     if (WifiConfigCenter::GetInstance().GetScreenState() != MODE_STATE_CLOSE) {
596         IpQosMonitor::GetInstance().QueryPackets();
597     }
598     pSelfCureStateMachine_->MessageExecutedLater(CMD_INTERNET_STATUS_DETECT_INTERVAL,
599         INTERNET_STATUS_DETECT_INTERVAL_MS);
600 }
601 
HandleGatewayChanged(InternalMessagePtr msg)602 void SelfCureStateMachine::ConnectedMonitorState::HandleGatewayChanged(InternalMessagePtr msg)
603 {
604     WIFI_LOGI("enter HandleGatewayChanged");
605     if (msg == nullptr) {
606         WIFI_LOGE("msg is nullptr.");
607         return;
608     }
609     if (pSelfCureStateMachine_->IsMultiDhcpOffer() ||
610         (isHasInternetRecently_ && pSelfCureStateMachine_->IsEncryptedAuthType(configAuthType_))) {
611         if (pSelfCureStateMachine_->IsHttpReachable()) {
612             return;
613         }
614         TransitionToSelfCureState(WIFI_CURE_INTERNET_FAILED_TYPE_GATEWAY);
615     }
616 }
617 
618 /* --------------------------- state machine disconnect monitor state ------------------------------ */
DisconnectedMonitorState(SelfCureStateMachine * selfCureStateMachine)619 SelfCureStateMachine::DisconnectedMonitorState::DisconnectedMonitorState(SelfCureStateMachine *selfCureStateMachine)
620     : State("DisconnectedMonitorState"),
621       pSelfCureStateMachine_(selfCureStateMachine)
622 {
623     WIFI_LOGD("DisconnectedMonitorState construct success.");
624 }
625 
~DisconnectedMonitorState()626 SelfCureStateMachine::DisconnectedMonitorState::~DisconnectedMonitorState() {}
627 
GoInState()628 void SelfCureStateMachine::DisconnectedMonitorState::GoInState()
629 {
630     WIFI_LOGI("DisconnectedMonitorState GoInState function.");
631     isSetStaticIpConfig_ = false;
632     pSelfCureStateMachine_->isStaticIpCureSuccess_ = false;
633     pSelfCureStateMachine_->isWifi6ArpSuccess_ = false;
634     pSelfCureStateMachine_->isHasTestWifi6Reassoc_ = false;
635     pSelfCureStateMachine_->noAutoConnCounter_ = 0;
636     pSelfCureStateMachine_->noAutoConnReason_ = -1;
637     pSelfCureStateMachine_->connectedTime_ = 0;
638     pSelfCureStateMachine_->isInternetFailureDetected_ = false;
639     pSelfCureStateMachine_->isSelfcureDone_ = false;
640     pSelfCureStateMachine_->UpdateSelfcureState(WIFI_CURE_RESET_LEVEL_IDLE, false);
641     pSelfCureStateMachine_->ClearDhcpOffer();
642     pSelfCureStateMachine_->HandleWifiBlackListUpdateMsg();
643 }
644 
GoOutState()645 void SelfCureStateMachine::DisconnectedMonitorState::GoOutState()
646 {
647     WIFI_LOGI("DisconnectedMonitorState GoOutState function.");
648 }
649 
ExecuteStateMsg(InternalMessagePtr msg)650 bool SelfCureStateMachine::DisconnectedMonitorState::ExecuteStateMsg(InternalMessagePtr msg)
651 {
652     if (msg == nullptr) {
653         return false;
654     }
655     WIFI_LOGD("DisconnectedMonitorState-msgCode=%{public}d is received.\n", msg->GetMessageName());
656     bool ret = NOT_EXECUTED;
657     switch (msg->GetMessageName()) {
658         case WIFI_CURE_NOTIFY_NETWORK_CONNECTED_RCVD:
659             ret = EXECUTED;
660             pSelfCureStateMachine_->HandleNetworkConnected();
661             pSelfCureStateMachine_->CheckConflictIpForSoftAp();
662             break;
663         case WIFI_CURE_CMD_WIFI7_DISCONNECT_COUNT:
664             ret = EXECUTED;
665             HandleNetworkConnectFailCount(msg);
666             break;
667         case WIFI_CURE_CMD_WIFI7_MLD_BACKOFF:
668             ret = EXECUTED;
669             HandleWifi7MldBackoff(msg);
670             break;
671         case WIFI_CURE_CMD_WIFI7_NON_MLD_BACKOFF:
672             ret = EXECUTED;
673             HandleWifi7WithoutMldBackoff(msg);
674             break;
675         case WIFI_CURE_CMD_WIFI7_BACKOFF_RECOVER:
676             ret = EXECUTED;
677             HandleWifi7BlacklistRecover(msg);
678             break;
679         default:
680             WIFI_LOGD("DisconnectedMonitorState-msgCode=%{public}d not handled.\n", msg->GetMessageName());
681             break;
682     }
683     return ret;
684 }
685 
HandleWifi7BlacklistRecover(InternalMessagePtr msg)686 void SelfCureStateMachine::DisconnectedMonitorState::HandleWifi7BlacklistRecover(InternalMessagePtr msg)
687 {
688     if (msg == nullptr) {
689         WIFI_LOGE("%{public}s: msg is nullptr.", __FUNCTION__);
690         return;
691     }
692     WifiLinkedInfo info;
693     msg->GetMessageObj(info);
694     if (info.bssid.empty()) {
695         WIFI_LOGE("%{public}s: lastconnect bssid is empty.", __FUNCTION__);
696         return;
697     }
698     WIFI_LOGI("remove %{public}s from wifi7 blalist.", MacAnonymize(info.bssid).c_str());
699     WifiConfigCenter::GetInstance().RemoveWifiCategoryBlackListCache(EVENT_BE_BLA_LIST, info.bssid);
700     pSelfCureStateMachine_->SendBlaListToDriver(EVENT_BE_BLA_LIST);
701 }
702 
HandleWifi7WithoutMldBackoff(InternalMessagePtr msg)703 void SelfCureStateMachine::DisconnectedMonitorState::HandleWifi7WithoutMldBackoff(InternalMessagePtr msg)
704 {
705     if (msg == nullptr) {
706         WIFI_LOGE("%{public}s: msg is nullptr.", __FUNCTION__);
707         return;
708     }
709     WifiLinkedInfo info;
710     msg->GetMessageObj(info);
711     if (info.bssid.empty()) {
712         WIFI_LOGE("%{public}s: lastconnect bssid is empty.", __FUNCTION__);
713         return;
714     }
715     WifiCategoryBlackListInfo wifi7BlackListInfo(ACTION_TYPE_WIFI7, GetCurrentTimeMilliSeconds());
716     WifiConfigCenter::GetInstance().InsertWifiCategoryBlackListCache(EVENT_BE_BLA_LIST, info.bssid, wifi7BlackListInfo);
717     WIFI_LOGI("add %{public}s to wifi7 blalist.", MacAnonymize(info.bssid).c_str());
718     pSelfCureStateMachine_->SendBlaListToDriver(EVENT_BE_BLA_LIST);
719 
720     WifiCategoryConnectFailInfo wifi7ConnectFailInfo(ACTION_TYPE_RECOVER_FAIL,
721         0, GetCurrentTimeMilliSeconds());
722     WifiConfigCenter::GetInstance().UpdateWifiConnectFailListCache(EVENT_BE_BLA_LIST, info.bssid, wifi7ConnectFailInfo);
723 }
724 
HandleWifi7MldBackoff(InternalMessagePtr msg)725 void SelfCureStateMachine::DisconnectedMonitorState::HandleWifi7MldBackoff(InternalMessagePtr msg)
726 {
727     if (msg == nullptr) {
728         WIFI_LOGE("%{public}s: msg is nullptr.", __FUNCTION__);
729         return;
730     }
731     WifiLinkedInfo info;
732     msg->GetMessageObj(info);
733     if (info.bssid.empty()) {
734         WIFI_LOGE("%{public}s: lastconnect bssid is empty.", __FUNCTION__);
735         return;
736     }
737     WifiCategoryBlackListInfo wifi7BlackListInfo(ACTION_TYPE_MLD, GetCurrentTimeMilliSeconds());
738     WifiConfigCenter::GetInstance().InsertWifiCategoryBlackListCache(EVENT_BE_BLA_LIST, info.bssid, wifi7BlackListInfo);
739     WIFI_LOGI("add %{public}s to wifi7 blalist.", MacAnonymize(info.bssid).c_str());
740     pSelfCureStateMachine_->SendBlaListToDriver(EVENT_BE_BLA_LIST);
741 
742     WifiCategoryConnectFailInfo wifi7ConnectFailInfo(ACTION_TYPE_WIFI7, 0,
743                                                     GetCurrentTimeMilliSeconds());
744     WifiConfigCenter::GetInstance().UpdateWifiConnectFailListCache(EVENT_BE_BLA_LIST, info.bssid, wifi7ConnectFailInfo);
745 }
746 
HandleNetworkConnectFailCount(InternalMessagePtr msg)747 void SelfCureStateMachine::DisconnectedMonitorState::HandleNetworkConnectFailCount(InternalMessagePtr msg)
748 {
749     if (msg == nullptr) {
750         WIFI_LOGE("%{public}s: msg is nullptr.", __FUNCTION__);
751         return;
752     }
753     WifiLinkedInfo info;
754     msg->GetMessageObj(info);
755     if (info.bssid.empty()) {
756         WIFI_LOGE("%{public}s: lastconnect bssid is empty.", __FUNCTION__);
757         return;
758     }
759     pSelfCureStateMachine_->AgeOutWifiConnectFailList();
760     int actionType = ACTION_TYPE_MLD;
761     std::map<std::string, WifiCategoryConnectFailInfo> connectFailCache;
762     WifiConfigCenter::GetInstance().GetWifiConnectFailListCache(connectFailCache);
763     WIFI_LOGI("add %{public}s to wifi7 connect fail list.", MacAnonymize(info.bssid).c_str());
764     if (connectFailCache.find(info.bssid) != connectFailCache.end()) {
765         actionType = connectFailCache[info.bssid].actionType;
766     }
767     WifiCategoryConnectFailInfo wifi7ConnectFailInfo(actionType, 1, GetCurrentTimeMilliSeconds());
768     WifiConfigCenter::GetInstance().UpdateWifiConnectFailListCache(EVENT_BE_BLA_LIST, info.bssid, wifi7ConnectFailInfo);
769     pSelfCureStateMachine_->ShouldTransToWifi7SelfCure(info);
770 }
771 
772 /* --------------------------- state machine connection self cure state ------------------------------ */
ConnectionSelfCureState(SelfCureStateMachine * selfCureStateMachine)773 SelfCureStateMachine::ConnectionSelfCureState::ConnectionSelfCureState(SelfCureStateMachine *selfCureStateMachine)
774     : State("ConnectionSelfCureState"),
775       pSelfCureStateMachine_(selfCureStateMachine)
776 {
777     WIFI_LOGD("ConnectionSelfCureState construct success.");
778 }
779 
~ConnectionSelfCureState()780 SelfCureStateMachine::ConnectionSelfCureState::~ConnectionSelfCureState() {}
781 
GoInState()782 void SelfCureStateMachine::ConnectionSelfCureState::GoInState()
783 {
784     WIFI_LOGI("ConnectionSelfCureState GoInState function.");
785 }
786 
GoOutState()787 void SelfCureStateMachine::ConnectionSelfCureState::GoOutState()
788 {
789     WIFI_LOGI("ConnectionSelfCureState GoOutState function.");
790 }
791 
ExecuteStateMsg(InternalMessagePtr msg)792 bool SelfCureStateMachine::ConnectionSelfCureState::ExecuteStateMsg(InternalMessagePtr msg)
793 {
794     if (msg == nullptr) {
795         return false;
796     }
797     WIFI_LOGD("ConnectionSelfCureState-msgCode=%{public}d is received.\n", msg->GetMessageName());
798     bool ret = NOT_EXECUTED;
799     switch (msg->GetMessageName()) {
800         case 0: {
801             ret = EXECUTED;
802             pSelfCureStateMachine_->GetAuthType();
803             break;
804         }
805         default:
806             WIFI_LOGD("ConnectionSelfCureState-msgCode=%{public}d not handled.\n", msg->GetMessageName());
807             break;
808     }
809     return ret;
810 }
811 
812 /* --------------------------- state machine internet self cure state ------------------------------ */
InternetSelfCureState(SelfCureStateMachine * selfCureStateMachine)813 SelfCureStateMachine::InternetSelfCureState::InternetSelfCureState(SelfCureStateMachine *selfCureStateMachine)
814     : State("InternetSelfCureState"),
815       pSelfCureStateMachine_(selfCureStateMachine)
816 {
817     InitSelfCureIssHandleMap();
818     WIFI_LOGD("InternetSelfCureState construct success.");
819 }
820 
~InternetSelfCureState()821 SelfCureStateMachine::InternetSelfCureState::~InternetSelfCureState() {}
822 
GoInState()823 void SelfCureStateMachine::InternetSelfCureState::GoInState()
824 {
825     WIFI_LOGI("InternetSelfCureState GoInState function.");
826     currentRssi_ = CURRENT_RSSI_INIT;
827     currentAbnormalType_ = -1;
828     currentSelfCureLevel_ = WIFI_CURE_RESET_LEVEL_IDLE;
829     isHasInternetRecently_ = false;
830     isPortalUnthenEver_ = false;
831     isUserSetStaticIpConfig_ = false;
832     testedSelfCureLevel_.clear();
833     isFinalSelfCureUsed_ = false;
834     isDelayedReassocSelfCure_ = false;
835     isDelayedRandMacReassocSelfCure_ = false;
836     isDelayedResetSelfCure_ = false;
837     isSetStaticIp4InvalidIp_ = false;
838     unConflictedIp_ = "";
839     renewDhcpCount_ = 0;
840     lastMultiGwSelfFailedType_ = -1;
841     isUsedMultiGwSelfcure_ = false;
842     pSelfCureStateMachine_->selfCureWifiLastState_ = WifiState::UNKNOWN;
843     pSelfCureStateMachine_->selfCureL2State_ = SelfCureState::SCE_WIFI_INVALID_STATE;
844     WifiConfigCenter::GetInstance().SetWifiSelfcureReset(false);
845 
846     WifiLinkedInfo linkedInfo;
847     WifiConfigCenter::GetInstance().GetLinkedInfo(linkedInfo);
848     currentRssi_ = linkedInfo.rssi;
849     currentBssid_ = linkedInfo.bssid;
850     pSelfCureStateMachine_->MessageExecutedLater(WIFI_CURE_CMD_PERIODIC_ARP_DETECTED, DEFAULT_ARP_DETECTED_MS);
851     SelfCureUtils::GetInstance().String2InternetSelfCureHistoryInfo(pSelfCureStateMachine_->GetSelfCureHistoryInfo(),
852                                                                     selfCureHistoryInfo_);
853     isHasInternetRecently_ = NetworkStatusHistoryManager::IsInternetAccessByHistory(
854         pSelfCureStateMachine_->GetNetworkStatusHistory());
855     isPortalUnthenEver_ = NetworkStatusHistoryManager::IsPortalByHistory(
856         pSelfCureStateMachine_->GetNetworkStatusHistory());
857     AssignIpMethod ipAssignment;
858     pSelfCureStateMachine_->GetIpAssignment(ipAssignment);
859     isUserSetStaticIpConfig_ = ipAssignment == AssignIpMethod::STATIC;
860     lastHasInetTime_ = pSelfCureStateMachine_->GetLastHasInternetTime();
861     configAuthType_ = pSelfCureStateMachine_->GetAuthType();
862     WIFI_LOGI("isHasInternetRecently_: %{public}d, isPortalUnthenEver_: %{public}d, selfCureHistoryInfo_: %{public}s",
863         isHasInternetRecently_, isPortalUnthenEver_, pSelfCureStateMachine_->GetSelfCureHistoryInfo().c_str());
864     InitCurrentGateway();
865 }
866 
GoOutState()867 void SelfCureStateMachine::InternetSelfCureState::GoOutState()
868 {
869     WIFI_LOGI("InternetSelfCureState GoOutState function.");
870     pSelfCureStateMachine_->UpdateSelfcureState(currentSelfCureLevel_, false);
871     pSelfCureStateMachine_->ResetSelfCureParam();
872 }
873 
ExecuteStateMsg(InternalMessagePtr msg)874 bool SelfCureStateMachine::InternetSelfCureState::ExecuteStateMsg(InternalMessagePtr msg)
875 {
876     if (msg == nullptr) {
877         return false;
878     }
879     WIFI_LOGD("InternetSelfCureState-msgCode = %{public}d is received.\n", msg->GetMessageName());
880     auto iter = selfCureIssHandleFuncMap_.find(msg->GetMessageName());
881     if (iter != selfCureIssHandleFuncMap_.end()) {
882         (iter->second)(msg);
883         return EXECUTED;
884     }
885     return NOT_EXECUTED;
886 }
887 
InitSelfCureIssHandleMap()888 int SelfCureStateMachine::InternetSelfCureState::InitSelfCureIssHandleMap()
889 {
890     selfCureIssHandleFuncMap_[WIFI_CURE_CMD_INTERNET_FAILED_SELF_CURE] = [this](InternalMessagePtr msg) {
891         this->HandleInternetFailedSelfCure(msg);
892     };
893     selfCureIssHandleFuncMap_[WIFI_CURE_CMD_SELF_CURE_WIFI_LINK] = [this](InternalMessagePtr msg) {
894         this->HandleSelfCureWifiLink(msg);
895     };
896     selfCureIssHandleFuncMap_[WIFI_CURE_NOTIFY_NETWORK_DISCONNECTED_RCVD] = [this](InternalMessagePtr msg) {
897         this->HandleNetworkDisconnected(msg);
898     };
899     selfCureIssHandleFuncMap_[WIFI_CURE_CMD_INTERNET_RECOVERY_CONFIRM] = [this](InternalMessagePtr msg) {
900         this->HandleInternetRecoveryConfirm(msg);
901     };
902     selfCureIssHandleFuncMap_[WIFI_CURE_NOTIFY_RSSI_LEVEL_CHANGED_EVENT] = [this](InternalMessagePtr msg) {
903         this->HandleRssiChangedEvent(msg);
904     };
905     selfCureIssHandleFuncMap_[WIFI_CURE_CMD_P2P_DISCONNECTED_EVENT] = [this](InternalMessagePtr msg) {
906         this->HandleP2pDisconnected(msg);
907     };
908     selfCureIssHandleFuncMap_[WIFI_CURE_CMD_PERIODIC_ARP_DETECTED] = [this](InternalMessagePtr msg) {
909         this->HandlePeriodicArpDetecte(msg);
910     };
911     selfCureIssHandleFuncMap_[WIFI_CURE_CMD_ARP_FAILED_DETECTED] = [this](InternalMessagePtr msg) {
912         this->HandleArpFailedDetected(msg);
913     };
914     selfCureIssHandleFuncMap_[WIFI_CURE_CMD_HTTP_REACHABLE_RCV] = [this](InternalMessagePtr msg) {
915         this->HandleHttpReachableRecv(msg);
916     };
917     selfCureIssHandleFuncMap_[WIFI_CURE_CMD_MULTI_GATEWAY] = [this](InternalMessagePtr msg) {
918         this->SelfcureForMultiGateway(msg);
919     };
920     selfCureIssHandleFuncMap_[WIFI_CURE_CMD_SELF_CURE_FAILED] = [this](InternalMessagePtr msg) {
921         this->HandleSelfCureResultFailed(msg);
922     };
923     return WIFI_OPT_SUCCESS;
924 }
925 
HandleInternetFailedSelfCure(InternalMessagePtr msg)926 void SelfCureStateMachine::InternetSelfCureState::HandleInternetFailedSelfCure(InternalMessagePtr msg)
927 {
928     WIFI_LOGD("enter HandleInternetFailedSelfCure.");
929     if (msg == nullptr) {
930         WIFI_LOGE("msg is nullptr.");
931         return;
932     }
933     if (!pSelfCureStateMachine_->IsSuppOnCompletedState()) {
934         pSelfCureStateMachine_->SwitchState(pSelfCureStateMachine_->pDisconnectedMonitorState_);
935         return;
936     }
937     SelectSelfCureByFailedReason(msg->GetParam1());
938 }
939 
HandleSelfCureWifiLink(InternalMessagePtr msg)940 void SelfCureStateMachine::InternetSelfCureState::HandleSelfCureWifiLink(InternalMessagePtr msg)
941 {
942     WIFI_LOGD("enter HandleSelfCureWifiLink.");
943     if (msg == nullptr) {
944         WIFI_LOGE("msg is nullptr.");
945         return;
946     }
947     if (!pSelfCureStateMachine_->IsSuppOnCompletedState()) {
948         pSelfCureStateMachine_->SwitchState(pSelfCureStateMachine_->pDisconnectedMonitorState_);
949         return;
950     }
951     currentSelfCureLevel_ = msg->GetParam1();
952     SelfCureWifiLink(msg->GetParam1());
953 }
954 
HandleNetworkDisconnected(InternalMessagePtr msg)955 void SelfCureStateMachine::InternetSelfCureState::HandleNetworkDisconnected(InternalMessagePtr msg)
956 {
957     WIFI_LOGD("enter HandleNetworkDisconnected.");
958     if (msg == nullptr) {
959         WIFI_LOGE("msg is nullptr.");
960         return;
961     }
962     pSelfCureStateMachine_->StopTimer(WIFI_CURE_CMD_INTERNET_RECOVERY_CONFIRM);
963     pSelfCureStateMachine_->SwitchState(pSelfCureStateMachine_->pDisconnectedMonitorState_);
964 }
965 
HandleInternetRecoveryConfirm(InternalMessagePtr msg)966 void SelfCureStateMachine::InternetSelfCureState::HandleInternetRecoveryConfirm(InternalMessagePtr msg)
967 {
968     SelfCureUtils::GetInstance().UpdateSelfCureConnectHistoryInfo(selfCureHistoryInfo_, currentSelfCureLevel_, true);
969     bool success = ConfirmInternetSelfCure(currentSelfCureLevel_);
970     if (success) {
971         pSelfCureStateMachine_->isInternetFailureDetected_ = false;
972         currentSelfCureLevel_ = WIFI_CURE_RESET_LEVEL_IDLE;
973         isHasInternetRecently_ = true;
974     }
975 }
976 
HandleRssiChangedEvent(InternalMessagePtr msg)977 void SelfCureStateMachine::InternetSelfCureState::HandleRssiChangedEvent(InternalMessagePtr msg)
978 {
979     WIFI_LOGD("enter HandleRssiChangedEvent.");
980     if (msg == nullptr) {
981         WIFI_LOGE("msg is nullptr.");
982         return;
983     }
984     currentRssi_ = msg->GetParam1();
985     HandleRssiChanged();
986 }
987 
HandleP2pDisconnected(InternalMessagePtr msg)988 void SelfCureStateMachine::InternetSelfCureState::HandleP2pDisconnected(InternalMessagePtr msg)
989 {
990     WIFI_LOGD("enter HandleP2pDisconnected.");
991     if (msg == nullptr) {
992         WIFI_LOGE("msg is nullptr.");
993         return;
994     }
995     HandleRssiChanged();
996 }
997 
HandlePeriodicArpDetecte(InternalMessagePtr msg)998 void SelfCureStateMachine::InternetSelfCureState::HandlePeriodicArpDetecte(InternalMessagePtr msg)
999 {
1000     WIFI_LOGD("enter HandlePeriodicArpDetecte.");
1001     if (msg == nullptr) {
1002         WIFI_LOGE("msg is nullptr.");
1003         return;
1004     }
1005     pSelfCureStateMachine_->PeriodicArpDetection();
1006 }
1007 
HandleHttpReachableRecv(InternalMessagePtr msg)1008 void SelfCureStateMachine::InternetSelfCureState::HandleHttpReachableRecv(InternalMessagePtr msg)
1009 {
1010     WIFI_LOGD("enter HandleHttpReachableRecv.");
1011     if (msg == nullptr) {
1012         WIFI_LOGE("msg is nullptr.");
1013         return;
1014     }
1015     pSelfCureStateMachine_->SetSelfCureHistoryInfo(INIT_SELFCURE_HISTORY);
1016     pSelfCureStateMachine_->SwitchState(pSelfCureStateMachine_->pConnectedMonitorState_);
1017 }
1018 
HandleArpFailedDetected(InternalMessagePtr msg)1019 void SelfCureStateMachine::InternetSelfCureState::HandleArpFailedDetected(InternalMessagePtr msg)
1020 {
1021     WIFI_LOGD("enter HandleArpFailedDetected.");
1022     if (pSelfCureStateMachine_->ShouldTransToWifi6SelfCure(msg, currentBssid_)) {
1023         return;
1024     }
1025     if (pSelfCureStateMachine_->isSelfCureOnGoing_) {
1026         return;
1027     }
1028     if (!pSelfCureStateMachine_->IsHttpReachable()) {
1029         pSelfCureStateMachine_->SendMessage(WIFI_CURE_CMD_SELF_CURE_WIFI_LINK, WIFI_CURE_RESET_LEVEL_MIDDLE_REASSOC);
1030     }
1031 }
1032 
SelectSelfCureByFailedReason(int internetFailedType)1033 void SelfCureStateMachine::InternetSelfCureState::SelectSelfCureByFailedReason(int internetFailedType)
1034 {
1035     WIFI_LOGI("SelectSelfCureByFailedReason, internetFailedType = %{public}d, isUserSetStaticIpConfig_ = %{public}d",
1036               internetFailedType, isUserSetStaticIpConfig_);
1037 
1038     if (IsNeedMultiGatewaySelfcure()) {
1039         WIFI_LOGI("start multi gateway selfcure");
1040         lastMultiGwSelfFailedType_ = internetFailedType;
1041         pSelfCureStateMachine_->SendMessage(WIFI_CURE_CMD_MULTI_GATEWAY);
1042         return;
1043     }
1044 
1045     if (isUserSetStaticIpConfig_ && ((internetFailedType == WIFI_CURE_INTERNET_FAILED_TYPE_DNS) ||
1046                                      (internetFailedType == WIFI_CURE_INTERNET_FAILED_TYPE_GATEWAY))) {
1047         HandleInternetFailedAndUserSetStaticIp(internetFailedType);
1048         return;
1049     }
1050     int requestSelfCureLevel = SelectBestSelfCureSolution(internetFailedType);
1051     if (requestSelfCureLevel != WIFI_CURE_RESET_LEVEL_IDLE) {
1052         currentAbnormalType_ = internetFailedType;
1053         pSelfCureStateMachine_->SendMessage(WIFI_CURE_CMD_SELF_CURE_WIFI_LINK, requestSelfCureLevel);
1054         return;
1055     }
1056     if (SelfCureUtils::GetInstance().SelfCureAcceptable(selfCureHistoryInfo_, WIFI_CURE_RESET_LEVEL_HIGH_RESET)) {
1057         WIFI_LOGI("SelectSelfCureByFailedReason, use wifi reset to cure this failed type = %{public}d",
1058                   internetFailedType);
1059         currentAbnormalType_ = internetFailedType;
1060         pSelfCureStateMachine_->SendMessage(WIFI_CURE_CMD_SELF_CURE_WIFI_LINK, WIFI_CURE_RESET_LEVEL_HIGH_RESET);
1061         return;
1062     }
1063     WIFI_LOGI("SelectSelfCureByFailedReason, no usable self cure for this failed type = %{public}d",
1064               internetFailedType);
1065     HandleHttpUnreachableFinally();
1066 }
1067 
SelectBestSelfCureSolution(int internetFailedType)1068 int SelfCureStateMachine::InternetSelfCureState::SelectBestSelfCureSolution(int internetFailedType)
1069 {
1070     int bestSelfCureLevel = WIFI_CURE_RESET_LEVEL_IDLE;
1071     bool multipleDhcpServer = pSelfCureStateMachine_->IsMultiDhcpOffer();
1072     bool noInternetWhenConnected =
1073         (lastHasInetTime_ <= 0 || lastHasInetTime_ < pSelfCureStateMachine_->connectedTime_);
1074     WIFI_LOGD("SelectBestSelfCureSolution, multipleDhcpServer = %{public}d, noInternetWhenConnected = %{public}d",
1075               multipleDhcpServer, noInternetWhenConnected);
1076 
1077     if ((multipleDhcpServer) && (noInternetWhenConnected) && (GetNextTestDhcpResults().ipAddress != 0) &&
1078         (SelfCureUtils::GetInstance().SelfCureAcceptable(selfCureHistoryInfo_,
1079                                                          WIFI_CURE_RESET_LEVEL_LOW_3_STATIC_IP)) &&
1080         ((internetFailedType == WIFI_CURE_INTERNET_FAILED_TYPE_DNS) ||
1081         (internetFailedType == WIFI_CURE_INTERNET_FAILED_TYPE_TCP))) {
1082         bestSelfCureLevel = WIFI_CURE_RESET_LEVEL_LOW_3_STATIC_IP;
1083         isConfigStaticIp4MultiDhcpServer_ = true;
1084     } else if ((internetFailedType == WIFI_CURE_INTERNET_FAILED_TYPE_GATEWAY) &&
1085                 (multipleDhcpServer) && (GetNextTestDhcpResults().ipAddress != 0) &&
1086                 (SelfCureUtils::GetInstance().SelfCureAcceptable(selfCureHistoryInfo_,
1087                 WIFI_CURE_RESET_LEVEL_LOW_3_STATIC_IP))) {
1088         bestSelfCureLevel = WIFI_CURE_RESET_LEVEL_LOW_3_STATIC_IP;
1089         isConfigStaticIp4MultiDhcpServer_ = true;
1090     } else if ((internetFailedType == WIFI_CURE_INTERNET_FAILED_TYPE_GATEWAY) &&
1091                 pSelfCureStateMachine_->IsEncryptedAuthType(configAuthType_) &&
1092                 (SelfCureUtils::GetInstance().SelfCureAcceptable(selfCureHistoryInfo_,
1093                 WIFI_CURE_RESET_LEVEL_LOW_3_STATIC_IP))) {
1094         bestSelfCureLevel = WIFI_CURE_RESET_LEVEL_LOW_3_STATIC_IP;
1095     } else {
1096         bestSelfCureLevel = SelectBestSelfCureSolutionExt(internetFailedType);
1097     }
1098     WIFI_LOGI("SelectBestSelfCureSolution, internetFailedType = %{public}d, bestSelfCureLevel = %{public}d",
1099               internetFailedType, bestSelfCureLevel);
1100     return bestSelfCureLevel;
1101 }
1102 
SelectBestSelfCureSolutionExt(int internetFailedType)1103 int SelfCureStateMachine::InternetSelfCureState::SelectBestSelfCureSolutionExt(int internetFailedType)
1104 {
1105     int bestSelfCureLevel = WIFI_CURE_RESET_LEVEL_IDLE;
1106     if (internetFailedType == WIFI_CURE_INTERNET_FAILED_INVALID_IP) {
1107         bestSelfCureLevel = WIFI_CURE_RESET_LEVEL_RECONNECT_4_INVALID_IP;
1108     } else if (internetFailedType == WIFI_CURE_INTERNET_FAILED_TYPE_DNS &&
1109                 SelfCureUtils::GetInstance().SelfCureAcceptable(
1110                     selfCureHistoryInfo_,
1111                     WIFI_CURE_RESET_LEVEL_HIGH_RESET)) {
1112         bestSelfCureLevel = WIFI_CURE_RESET_LEVEL_HIGH_RESET;
1113     } else if (internetFailedType == WIFI_CURE_INTERNET_FAILED_RAND_MAC &&
1114                 SelfCureUtils::GetInstance().SelfCureAcceptable(
1115                     selfCureHistoryInfo_,
1116                     WIFI_CURE_RESET_LEVEL_RAND_MAC_REASSOC)) {
1117         bestSelfCureLevel = WIFI_CURE_RESET_LEVEL_RAND_MAC_REASSOC;
1118     } else if (internetFailedType == WIFI_CURE_INTERNET_FAILED_TYPE_TCP &&
1119                 SelfCureUtils::GetInstance().SelfCureAcceptable(
1120                     selfCureHistoryInfo_,
1121                     WIFI_CURE_RESET_LEVEL_MIDDLE_REASSOC)) {
1122         bestSelfCureLevel = WIFI_CURE_RESET_LEVEL_MIDDLE_REASSOC;
1123     }
1124     return bestSelfCureLevel;
1125 }
1126 
SelfCureWifiLink(int requestCureLevel)1127 void SelfCureStateMachine::InternetSelfCureState::SelfCureWifiLink(int requestCureLevel)
1128 {
1129     WIFI_LOGI("SelfCureWifiLink, requestCureLevel = %{public}d, currentRssi_ = %{public}d",
1130         requestCureLevel, currentRssi_);
1131     if (requestCureLevel == WIFI_CURE_RESET_LEVEL_LOW_3_STATIC_IP) {
1132         SelfCureForStaticIp(requestCureLevel);
1133     } else if (requestCureLevel == WIFI_CURE_RESET_LEVEL_RECONNECT_4_INVALID_IP) {
1134         SelfCureForInvalidIp();
1135     } else if (requestCureLevel == WIFI_CURE_RESET_LEVEL_MIDDLE_REASSOC) {
1136         SelfCureForReassoc(requestCureLevel);
1137     } else if (requestCureLevel == WIFI_CURE_RESET_LEVEL_RAND_MAC_REASSOC) {
1138         SelfCureForRandMacReassoc(requestCureLevel);
1139     } else if (requestCureLevel == WIFI_CURE_RESET_LEVEL_HIGH_RESET) {
1140         SelfCureForReset(requestCureLevel);
1141     }
1142 }
1143 
SelfCureForInvalidIp()1144 void SelfCureStateMachine::InternetSelfCureState::SelfCureForInvalidIp()
1145 {
1146     WIFI_LOGI("begin to self cure for internet access: InvalidIp");
1147     IpInfo dhcpResults;
1148     pSelfCureStateMachine_->GetLegalIpConfiguration(dhcpResults);
1149     unConflictedIp_ = IpTools::ConvertIpv4Address(dhcpResults.ipAddress);
1150     if (selfCureForInvalidIpCnt_ < MAX_SELF_CURE_CNT_INVALID_IP) {
1151         IStaService *pStaService = WifiServiceManager::GetInstance().GetStaServiceInst(0);
1152         if (pStaService == nullptr) {
1153             WIFI_LOGE("Get pStaService failed!");
1154             return;
1155         }
1156         if (pStaService->Disconnect()!=WIFI_OPT_SUCCESS) {
1157             WIFI_LOGE("Disconnect failed.\n");
1158         }
1159         selfCureForInvalidIpCnt_++;
1160     }
1161 }
1162 
GetNextTestDhcpResults()1163 IpInfo SelfCureStateMachine::InternetSelfCureState::GetNextTestDhcpResults()
1164 {
1165     IpInfo ipInfo;
1166     IEnhanceService *pEnhanceService = WifiServiceManager::GetInstance().GetEnhanceServiceInst();
1167     if (pEnhanceService == nullptr) {
1168         WIFI_LOGE("GetNextTestDhcpResults get pEnhanceService service failed!");
1169         return ipInfo;
1170     }
1171     bool isMultiDhcpServer = true;
1172     bool startSelfcure = false;
1173     pEnhanceService->GetStaticIpConfig(isMultiDhcpServer, startSelfcure, ipInfo);
1174     return ipInfo;
1175 }
1176 
GetRecordDhcpResults()1177 IpInfo SelfCureStateMachine::InternetSelfCureState::GetRecordDhcpResults()
1178 {
1179     IpInfo ipInfo;
1180     IEnhanceService *pEnhanceService = WifiServiceManager::GetInstance().GetEnhanceServiceInst();
1181     if (pEnhanceService == nullptr) {
1182         WIFI_LOGE("GetRecordDhcpResults get pEnhanceService service failed!");
1183         return ipInfo;
1184     }
1185     bool isMultiDhcpServer = false;
1186     bool startSelfcure = false;
1187     pEnhanceService->GetStaticIpConfig(isMultiDhcpServer, startSelfcure, ipInfo);
1188     std::string gateway = IpTools::ConvertIpv4Address(ipInfo.gateway);
1189     if (!pSelfCureStateMachine_->DoSlowArpTest(gateway)) {
1190         pSelfCureStateMachine_->MessageExecutedLater(WIFI_CURE_CMD_INTERNET_RECOVERY_CONFIRM,
1191             DHCP_CONFIRM_DELAYED_MS);
1192         IpInfo dhcpResult;
1193         return dhcpResult;
1194     }
1195     return ipInfo;
1196 }
1197 
InitCurrentGateway()1198 void SelfCureStateMachine::InternetSelfCureState::InitCurrentGateway()
1199 {
1200     IpInfo ipInfo;
1201     WifiConfigCenter::GetInstance().GetIpInfo(ipInfo, pSelfCureStateMachine_->instId_);
1202     IEnhanceService *pEnhanceService = WifiServiceManager::GetInstance().GetEnhanceServiceInst();
1203     if (pEnhanceService == nullptr) {
1204         WIFI_LOGE("InitCurrentGateway get pEnhanceService service failed!");
1205         return;
1206     }
1207     uint32_t retSize = 0;
1208     pEnhanceService->DealDhcpOfferResult(OperationCmd::CURRENT_IP_INFO_SET, ipInfo, retSize);
1209 }
1210 
SelfCureForStaticIp(int requestCureLevel)1211 void SelfCureStateMachine::InternetSelfCureState::SelfCureForStaticIp(int requestCureLevel)
1212 {
1213     IpInfo dhcpResult;
1214     IEnhanceService *pEnhanceService = WifiServiceManager::GetInstance().GetEnhanceServiceInst();
1215     if (pEnhanceService == nullptr) {
1216         WIFI_LOGE("SelfCureForStaticIp get pEnhanceService service failed!");
1217         return;
1218     }
1219     bool isMultiDhcpServer = isConfigStaticIp4MultiDhcpServer_ ? true : false;
1220     bool startSelfcure = true;
1221     if (isMultiDhcpServer) {
1222         pEnhanceService->GetStaticIpConfig(isMultiDhcpServer, startSelfcure, dhcpResult);
1223     } else {
1224         dhcpResult = GetRecordDhcpResults();
1225     }
1226     if (dhcpResult.gateway == 0 || dhcpResult.ipAddress == 0) {
1227         WIFI_LOGE("%{public}s: dhcpResult is null", __FUNCTION__);
1228         return;
1229     }
1230     std::string gatewayKey = IpTools::ConvertIpv4Address(dhcpResult.gateway);
1231     WIFI_LOGI("begin to self cure for internet access: TRY_NEXT_DHCP_OFFER");
1232     pSelfCureStateMachine_->UpdateSelfcureState(WIFI_CURE_RESET_LEVEL_LOW_3_STATIC_IP, true);
1233     WriteWifiSelfcureHisysevent(static_cast<int>(WifiSelfcureType::GATEWAY_ABNORMAL));
1234     RequestUseStaticIpConfig(dhcpResult);
1235 }
1236 
RequestUseStaticIpConfig(IpInfo & dhcpResult)1237 void SelfCureStateMachine::InternetSelfCureState::RequestUseStaticIpConfig(IpInfo &dhcpResult)
1238 {
1239     WIFI_LOGI("enter %{public}s", __FUNCTION__);
1240     WifiLinkedInfo linkedInfo;
1241     WifiConfigCenter::GetInstance().GetLinkedInfo(linkedInfo, pSelfCureStateMachine_->instId_);
1242     if (linkedInfo.connState != ConnState::CONNECTED) {
1243         return;
1244     }
1245     IpV6Info wifiIpV6Info;
1246     WifiConfigCenter::GetInstance().GetIpv6Info(wifiIpV6Info, pSelfCureStateMachine_->instId_);
1247     WifiDeviceConfig config;
1248     WifiSettings::GetInstance().GetDeviceConfig(linkedInfo.networkId, config);
1249     WifiNetAgent::GetInstance().OnStaMachineUpdateNetLinkInfo(
1250         dhcpResult, wifiIpV6Info, config.wifiProxyconfig,
1251         pSelfCureStateMachine_->instId_);
1252     linkedInfo.ipAddress = dhcpResult.ipAddress;
1253     WifiConfigCenter::GetInstance().SaveIpInfo(dhcpResult);
1254     WifiConfigCenter::GetInstance().SaveLinkedInfo(linkedInfo, pSelfCureStateMachine_->instId_);
1255     WifiEventCallbackMsg cbMsg;
1256     cbMsg.msgCode = WIFI_CBK_MSG_CONNECTION_CHANGE;
1257     cbMsg.msgData = ConnState::CONNECTED;
1258     cbMsg.linkInfo = linkedInfo;
1259     cbMsg.id = pSelfCureStateMachine_->instId_;
1260     WifiInternalEventDispatcher::GetInstance().AddBroadCastMsg(cbMsg);
1261     pSelfCureStateMachine_->MessageExecutedLater(WIFI_CURE_CMD_INTERNET_RECOVERY_CONFIRM, HTTP_DETECT_TIMEOUT);
1262 }
1263 
SelfCureForReassoc(int requestCureLevel)1264 void SelfCureStateMachine::InternetSelfCureState::SelfCureForReassoc(int requestCureLevel)
1265 {
1266     if ((currentRssi_ < MIN_VAL_LEVEL_3) || pSelfCureStateMachine_->IfP2pConnected() ||
1267         pSelfCureStateMachine_->isP2pEnhanceConnected_) {
1268         WIFI_LOGI("delay reassoc selfcure");
1269         isDelayedReassocSelfCure_ = true;
1270         return;
1271     }
1272     WIFI_LOGI("begin to self cure for internet access: Reassoc");
1273     WriteWifiSelfcureHisysevent(static_cast<int>(WifiSelfcureType::TCP_RX_ABNORMAL));
1274     pSelfCureStateMachine_->UpdateSelfcureState(WIFI_CURE_RESET_LEVEL_MIDDLE_REASSOC, true);
1275     testedSelfCureLevel_.push_back(requestCureLevel);
1276     isDelayedReassocSelfCure_ = false;
1277     IStaService *pStaService = WifiServiceManager::GetInstance().GetStaServiceInst(0);
1278     if (pStaService == nullptr) {
1279         WIFI_LOGE("Get pStaService failed!");
1280         return;
1281     }
1282     if (pStaService->ReAssociate() != WIFI_OPT_SUCCESS) {
1283         WIFI_LOGE("ReAssociate failed.\n");
1284     }
1285     pSelfCureStateMachine_->SetSelfCureWifiTimeOut(SelfCureState::SCE_WIFI_REASSOC_STATE);
1286 }
1287 
IsNeedMultiGatewaySelfcure()1288 bool SelfCureStateMachine::InternetSelfCureState::IsNeedMultiGatewaySelfcure()
1289 {
1290     WIFI_LOGI("isUsedMultiGwSelfcure_ is %{public}d", isUsedMultiGwSelfcure_);
1291     if (isUsedMultiGwSelfcure_) {
1292         return false;
1293     }
1294     return pSelfCureStateMachine_->IfMultiGateway();
1295 }
1296 
SelfcureForMultiGateway(InternalMessagePtr msg)1297 void SelfCureStateMachine::InternetSelfCureState::SelfcureForMultiGateway(InternalMessagePtr msg)
1298 {
1299     WIFI_LOGI("begin to self cure for internet access: multi gateway");
1300     if (!pSelfCureStateMachine_->IsSuppOnCompletedState()) {
1301         WIFI_LOGW("it is not connect, no need selfcure");
1302         return;
1303     }
1304     isUsedMultiGwSelfcure_ = true;
1305     std::string ipAddr = MultiGateway::GetInstance().GetGatewayIp();
1306     std::string macString = "";
1307     MultiGateway::GetInstance().GetNextGatewayMac(macString);
1308     if (macString.empty() || ipAddr.empty()) {
1309         WIFI_LOGE("macString or ipAddr is nullptr");
1310         pSelfCureStateMachine_->UpdateSelfcureState(WIFI_CURE_RESET_LEVEL_MULTI_GATEWAY, false);
1311         if (lastMultiGwSelfFailedType_ != -1) {
1312             SelectSelfCureByFailedReason(lastMultiGwSelfFailedType_);
1313         }
1314         return;
1315     }
1316     std::string ifaceName = WifiConfigCenter::GetInstance().GetStaIfaceName();
1317     if (MultiGateway::GetInstance().SetStaticArp(ifaceName, ipAddr, macString) != 0) {
1318         WIFI_LOGE("SetStaticArp failed");
1319         if (lastMultiGwSelfFailedType_ != -1) {
1320             SelectSelfCureByFailedReason(lastMultiGwSelfFailedType_);
1321         }
1322         return;
1323     }
1324     WriteWifiSelfcureHisysevent(static_cast<int>(WifiSelfcureType::MULTI_GATEWAY_SELFCURE));
1325     pSelfCureStateMachine_->UpdateSelfcureState(WIFI_CURE_RESET_LEVEL_MULTI_GATEWAY, true);
1326     if (!pSelfCureStateMachine_->IsHttpReachable()) {
1327         MultiGateway::GetInstance().DelStaticArp(ifaceName, ipAddr);
1328         pSelfCureStateMachine_->SendMessage(WIFI_CURE_CMD_MULTI_GATEWAY);
1329     } else {
1330         WriteWifiSelfcureHisysevent(static_cast<int>(WifiSelfcureType::MULTI_GATEWAY_SELFCURE_SUCC));
1331         pSelfCureStateMachine_->SwitchState(pSelfCureStateMachine_->pConnectedMonitorState_);
1332     }
1333 }
1334 
HandleSelfCureResultFailed(InternalMessagePtr msg)1335 void SelfCureStateMachine::InternetSelfCureState::HandleSelfCureResultFailed(InternalMessagePtr msg)
1336 {
1337     SelfCureUtils::GetInstance().UpdateSelfCureConnectHistoryInfo(selfCureHistoryInfo_, currentSelfCureLevel_, false);
1338     pSelfCureStateMachine_->SwitchState(pSelfCureStateMachine_->pDisconnectedMonitorState_);
1339 }
1340 
SelfCureForRandMacReassoc(int requestCureLevel)1341 void SelfCureStateMachine::InternetSelfCureState::SelfCureForRandMacReassoc(int requestCureLevel)
1342 {
1343     if ((currentRssi_ < MIN_VAL_LEVEL_3) || pSelfCureStateMachine_->IfP2pConnected() ||
1344         pSelfCureStateMachine_->isP2pEnhanceConnected_) {
1345         isDelayedRandMacReassocSelfCure_ = true;
1346         WIFI_LOGW("delay randmac self cure");
1347         return;
1348     }
1349     WIFI_LOGI("begin to self cure for internet access: RandMacReassoc");
1350     pSelfCureStateMachine_->UpdateSelfcureState(WIFI_CURE_RESET_LEVEL_RAND_MAC_REASSOC, true);
1351     isDelayedRandMacReassocSelfCure_ = false;
1352     pSelfCureStateMachine_->useWithRandMacAddress_ = FAC_MAC_REASSOC;
1353     pSelfCureStateMachine_->SetIsReassocWithFactoryMacAddress(FAC_MAC_REASSOC);
1354     WifiLinkedInfo linkedInfo;
1355     WifiConfigCenter::GetInstance().GetLinkedInfo(linkedInfo);
1356     int networkId = linkedInfo.networkId;
1357     WifiConfigCenter::GetInstance().SetLastNetworkId(networkId);
1358     WriteWifiSelfcureHisysevent(static_cast<int>(WifiSelfcureType::RAND_MAC_REASSOC_SELFCURE));
1359     IStaService *pStaService = WifiServiceManager::GetInstance().GetStaServiceInst(0);
1360     if (pStaService == nullptr) {
1361         WIFI_LOGE("Get pStaService failed!");
1362         return;
1363     }
1364     pStaService->Disconnect();
1365     pSelfCureStateMachine_->SetSelfCureWifiTimeOut(SelfCureState::SCE_WIFI_DISCONNECT_STATE);
1366 }
1367 
SelfCureForReset(int requestCureLevel)1368 void SelfCureStateMachine::InternetSelfCureState::SelfCureForReset(int requestCureLevel)
1369 {
1370     WIFI_LOGI("enter SelfCureForReset, isInternetUnknown_: %{public}d, isHasInternetRecently_: %{public}d",
1371         pSelfCureStateMachine_->isInternetUnknown_, isHasInternetRecently_);
1372     if ((pSelfCureStateMachine_->isInternetUnknown_) || (!isHasInternetRecently_) ||
1373         (pSelfCureStateMachine_->IsSettingsPage())) {
1374         pSelfCureStateMachine_->SwitchState(pSelfCureStateMachine_->pNoInternetState_);
1375         return;
1376     }
1377 
1378     if ((currentRssi_ < MIN_VAL_LEVEL_3_5) || pSelfCureStateMachine_->IfP2pConnected() ||
1379         pSelfCureStateMachine_->isP2pEnhanceConnected_) {
1380         WIFI_LOGI("delay Reset self cure");
1381         isDelayedResetSelfCure_ = true;
1382         return;
1383     }
1384     WIFI_LOGI("begin to self cure for internet access: Reset");
1385 
1386     pSelfCureStateMachine_->SetSelfCureWifiTimeOut(SelfCureState::SCE_WIFI_OFF_STATE);
1387     WifiConfigCenter::GetInstance().SetWifiSelfcureResetEntered(true);
1388     pSelfCureStateMachine_->UpdateSelfcureState(WIFI_CURE_RESET_LEVEL_HIGH_RESET, true);
1389     pSelfCureStateMachine_->StopTimer(WIFI_CURE_CMD_SELF_CURE_WIFI_LINK);
1390     isDelayedResetSelfCure_ = false;
1391     testedSelfCureLevel_.push_back(requestCureLevel);
1392 
1393     WifiLinkedInfo wifiLinkedInfo;
1394     WifiConfigCenter::GetInstance().GetLinkedInfo(wifiLinkedInfo);
1395     WifiConfigCenter::GetInstance().SetLastNetworkId(wifiLinkedInfo.networkId);
1396     WifiConfigCenter::GetInstance().SetWifiSelfcureReset(true);
1397     if (WifiManager::GetInstance().GetWifiTogglerManager() == nullptr) {
1398         WIFI_LOGE("SelfCureForReset, GetWifiTogglerManager get failed");
1399         return;
1400     }
1401     auto &wifiControllerMachine = WifiManager::GetInstance().GetWifiTogglerManager()->GetControllerMachine();
1402     if (wifiControllerMachine == nullptr) {
1403         WIFI_LOGE("selfcureForReset, wifiControllerMachine get failed");
1404         return;
1405     }
1406     wifiControllerMachine->SelfcureResetWifi(pSelfCureStateMachine_->instId_);
1407 }
1408 
SelectedSelfCureAcceptable()1409 bool SelfCureStateMachine::InternetSelfCureState::SelectedSelfCureAcceptable()
1410 {
1411     if (currentAbnormalType_ == WIFI_CURE_INTERNET_FAILED_TYPE_DNS ||
1412         currentAbnormalType_ == WIFI_CURE_INTERNET_FAILED_TYPE_GATEWAY) {
1413         if (SelfCureUtils::GetInstance().SelfCureAcceptable(selfCureHistoryInfo_, WIFI_CURE_RESET_LEVEL_HIGH_RESET)) {
1414             WIFI_LOGD("HTTP unreachable, use dns replace to cure for dns failed.");
1415             pSelfCureStateMachine_->SendMessage(WIFI_CURE_CMD_SELF_CURE_WIFI_LINK,
1416                                                 WIFI_CURE_RESET_LEVEL_HIGH_RESET, 0);
1417             return true;
1418         }
1419     } else if (currentAbnormalType_ == WIFI_CURE_INTERNET_FAILED_TYPE_TCP) {
1420         if (SelfCureUtils::GetInstance().SelfCureAcceptable(selfCureHistoryInfo_,
1421             WIFI_CURE_RESET_LEVEL_MIDDLE_REASSOC)) {
1422             WIFI_LOGD("HTTP unreachable, use reassoc to cure for no rx pkt.");
1423             pSelfCureStateMachine_->SendMessage(WIFI_CURE_CMD_SELF_CURE_WIFI_LINK, WIFI_CURE_RESET_LEVEL_MIDDLE_REASSOC,
1424                                                 0);
1425             return true;
1426         }
1427     }
1428     return false;
1429 }
1430 
HandleInternetFailedAndUserSetStaticIp(int internetFailedType)1431 void SelfCureStateMachine::InternetSelfCureState::HandleInternetFailedAndUserSetStaticIp(int internetFailedType)
1432 {
1433     if (isHasInternetRecently_ &&
1434         SelfCureUtils::GetInstance().SelfCureAcceptable(selfCureHistoryInfo_, WIFI_CURE_RESET_LEVEL_HIGH_RESET)) {
1435         pSelfCureStateMachine_->SendMessage(WIFI_CURE_CMD_SELF_CURE_WIFI_LINK, WIFI_CURE_RESET_LEVEL_HIGH_RESET);
1436         return;
1437     }
1438     WIFI_LOGI("user set static ip config, ignore to update config for user.");
1439     if (!pSelfCureStateMachine_->isInternetUnknown_) {
1440         currentAbnormalType_ = WIFI_CURE_RESET_REJECTED_BY_STATIC_IP_ENABLED;
1441     }
1442 }
1443 
ConfirmInternetSelfCure(int currentCureLevel)1444 bool SelfCureStateMachine::InternetSelfCureState::ConfirmInternetSelfCure(int currentCureLevel)
1445 {
1446     WIFI_LOGI("ConfirmInternetSelfCure, cureLevel = %{public}d, finally = %{public}d",
1447         currentCureLevel, isFinalSelfCureUsed_);
1448     if (currentCureLevel == WIFI_CURE_RESET_LEVEL_IDLE) {
1449         return false;
1450     }
1451     if (pSelfCureStateMachine_->IsHttpReachable()) {
1452         HandleHttpReachableAfterSelfCure(currentCureLevel);
1453         pSelfCureStateMachine_->SwitchState(pSelfCureStateMachine_->pConnectedMonitorState_);
1454         return true;
1455     }
1456     HandleConfirmInternetSelfCureFailed(currentCureLevel);
1457     return false;
1458 }
1459 
HandleConfirmInternetSelfCureFailed(int currentCureLevel)1460 void SelfCureStateMachine::InternetSelfCureState::HandleConfirmInternetSelfCureFailed(int currentCureLevel)
1461 {
1462     if (currentCureLevel == WIFI_CURE_RESET_LEVEL_RAND_MAC_REASSOC) {
1463         HandleSelfCureFailedForRandMacReassoc();
1464         return;
1465     }
1466     SelfCureUtils::GetInstance().UpdateSelfCureHistoryInfo(selfCureHistoryInfo_, currentCureLevel, false);
1467     pSelfCureStateMachine_->SetSelfCureHistoryInfo(selfCureHistoryInfo_.GetSelfCureHistory());
1468     WIFI_LOGI("HTTP unreachable, self cure failed for %{public}d, selfCureHistoryInfo_ = %{public}s", currentCureLevel,
1469               pSelfCureStateMachine_->GetSelfCureHistoryInfo().c_str());
1470     pSelfCureStateMachine_->UpdateSelfcureState(currentCureLevel, false);
1471     if (isFinalSelfCureUsed_) {
1472         HandleHttpUnreachableFinally();
1473         return;
1474     }
1475     if (currentCureLevel == WIFI_CURE_RESET_LEVEL_MIDDLE_REASSOC &&
1476         pSelfCureStateMachine_->isHasTestWifi6Reassoc_ &&
1477         pSelfCureStateMachine_->IsNeedWifiReassocUseDeviceMac()) {
1478         pSelfCureStateMachine_->SendMessage(WIFI_CURE_CMD_INTERNET_FAILED_SELF_CURE,
1479                                             WIFI_CURE_INTERNET_FAILED_RAND_MAC);
1480         return;
1481     }
1482     if (currentCureLevel == WIFI_CURE_RESET_LEVEL_LOW_3_STATIC_IP) {
1483         if (GetNextTestDhcpResults().ipAddress != 0) {
1484             WIFI_LOGI("HTTP unreachable, and has next dhcp results, try next one.");
1485             pSelfCureStateMachine_->SendMessage(WIFI_CURE_CMD_SELF_CURE_WIFI_LINK,
1486                 WIFI_CURE_RESET_LEVEL_LOW_3_STATIC_IP, 0);
1487             return;
1488         }
1489         isConfigStaticIp4MultiDhcpServer_ = false;
1490         if (SelectedSelfCureAcceptable()) {
1491             return;
1492         }
1493     }
1494     if (!HasBeenTested(WIFI_CURE_RESET_LEVEL_HIGH_RESET) &&
1495         SelfCureUtils::GetInstance().SelfCureAcceptable(selfCureHistoryInfo_, WIFI_CURE_RESET_LEVEL_HIGH_RESET)) {
1496         pSelfCureStateMachine_->SendMessage(WIFI_CURE_CMD_INTERNET_FAILED_SELF_CURE, WIFI_CURE_RESET_LEVEL_HIGH_RESET);
1497     } else {
1498         HandleHttpUnreachableFinally();
1499     }
1500 }
1501 
HandleSelfCureFailedForRandMacReassoc()1502 void SelfCureStateMachine::InternetSelfCureState::HandleSelfCureFailedForRandMacReassoc()
1503 {
1504     WIFI_LOGI("enter %{public}s", __FUNCTION__);
1505     if (pSelfCureStateMachine_->useWithRandMacAddress_ == FAC_MAC_REASSOC &&
1506         pSelfCureStateMachine_->IsUseFactoryMac()) {
1507         WIFI_LOGI("HTTP unreachable, factory mac failed and use rand mac instead of");
1508         pSelfCureStateMachine_->useWithRandMacAddress_ = RAND_MAC_REASSOC;
1509         pSelfCureStateMachine_->SetIsReassocWithFactoryMacAddress(RAND_MAC_REASSOC);
1510         WifiLinkedInfo linkedInfo;
1511         WifiConfigCenter::GetInstance().GetLinkedInfo(linkedInfo);
1512         int networkId = linkedInfo.networkId;
1513         WifiConfigCenter::GetInstance().SetLastNetworkId(networkId);
1514         IStaService *pStaService = WifiServiceManager::GetInstance().GetStaServiceInst(0);
1515         if (pStaService == nullptr) {
1516             WIFI_LOGE("Get pStaService failed!");
1517             return;
1518         }
1519         pStaService->Disconnect();
1520         pSelfCureStateMachine_->SetSelfCureWifiTimeOut(SelfCureState::SCE_WIFI_DISCONNECT_STATE);
1521         return;
1522     }
1523     SelfCureUtils::GetInstance().UpdateSelfCureHistoryInfo(selfCureHistoryInfo_,
1524                                                            WIFI_CURE_RESET_LEVEL_RAND_MAC_REASSOC, false);
1525     WIFI_LOGI("HTTP unreachable, self cure failed for rand mac reassoc");
1526     pSelfCureStateMachine_->UpdateSelfcureState(WIFI_CURE_RESET_LEVEL_RAND_MAC_REASSOC, false);
1527     pSelfCureStateMachine_->useWithRandMacAddress_ = 0;
1528     pSelfCureStateMachine_->SetIsReassocWithFactoryMacAddress(0);
1529     pSelfCureStateMachine_->SendMessage(WIFI_CURE_CMD_INTERNET_FAILED_SELF_CURE, WIFI_CURE_INTERNET_FAILED_TYPE_DNS);
1530 }
1531 
HandleHttpReachableAfterSelfCure(int currentCureLevel)1532 void SelfCureStateMachine::InternetSelfCureState::HandleHttpReachableAfterSelfCure(int currentCureLevel)
1533 {
1534     WIFI_LOGI("HandleHttpReachableAfterSelfCure, currentCureLevel = %{public}d", currentCureLevel);
1535     SelfCureUtils::GetInstance().UpdateSelfCureHistoryInfo(selfCureHistoryInfo_, currentCureLevel, true);
1536     pSelfCureStateMachine_->UpdateSelfcureState(currentSelfCureLevel_, false);
1537     if (!isSetStaticIp4InvalidIp_ && currentCureLevel == WIFI_CURE_RESET_LEVEL_LOW_3_STATIC_IP) {
1538         currentAbnormalType_ = WIFI_CURE_INTERNET_FAILED_TYPE_GATEWAY;
1539         pSelfCureStateMachine_->RequestArpConflictTest();
1540         pSelfCureStateMachine_->isStaticIpCureSuccess_ = true;
1541     }
1542 
1543     if (currentCureLevel == WIFI_CURE_RESET_LEVEL_LOW_3_STATIC_IP) {
1544         WriteWifiSelfcureHisysevent(static_cast<int>(WifiSelfcureType::STATIC_IP_SELFCURE_SUCC));
1545     } else if (currentCureLevel == WIFI_CURE_RESET_LEVEL_MIDDLE_REASSOC) {
1546         WriteWifiSelfcureHisysevent(static_cast<int>(WifiSelfcureType::REASSOC_SELFCURE_SUCC));
1547     } else if (currentCureLevel == WIFI_CURE_RESET_LEVEL_HIGH_RESET) {
1548         WriteWifiSelfcureHisysevent(static_cast<int>(WifiSelfcureType::RESET_SELFCURE_SUCC));
1549     } else if (currentCureLevel == WIFI_CURE_RESET_LEVEL_RAND_MAC_REASSOC) {
1550         WriteWifiSelfcureHisysevent(static_cast<int>(WifiSelfcureType::RAND_MAC_REASSOC_SELFCURE_SUCC));
1551     }
1552 }
1553 
HandleHttpUnreachableFinally()1554 void SelfCureStateMachine::InternetSelfCureState::HandleHttpUnreachableFinally()
1555 {
1556     WIFI_LOGI("enter %{public}s", __FUNCTION__);
1557     pSelfCureStateMachine_->SwitchState(pSelfCureStateMachine_->pNoInternetState_);
1558 }
1559 
HasBeenTested(int cureLevel)1560 bool SelfCureStateMachine::InternetSelfCureState::HasBeenTested(int cureLevel)
1561 {
1562     for (int itemTestedSelfCureLevel : testedSelfCureLevel_) {
1563         if (itemTestedSelfCureLevel == cureLevel) {
1564             return true;
1565         }
1566     }
1567     return false;
1568 }
1569 
HandleRssiChanged()1570 void SelfCureStateMachine::InternetSelfCureState::HandleRssiChanged()
1571 {
1572     if (currentRssi_ < MIN_VAL_LEVEL_3_5 || pSelfCureStateMachine_->isP2pEnhanceConnected_ ||
1573         pSelfCureStateMachine_->isP2pConnected_) {
1574         WIFI_LOGW("no need deal rssi change");
1575         return;
1576     }
1577 
1578     if (isDelayedResetSelfCure_) {
1579         HandleDelayedResetSelfCure();
1580         return;
1581     }
1582     if (!pSelfCureStateMachine_->isSelfCureOnGoing_ &&
1583         (isDelayedReassocSelfCure_ || isDelayedRandMacReassocSelfCure_)) {
1584         if (!pSelfCureStateMachine_->IsHttpReachable()) {
1585             WIFI_LOGD("HandleRssiChanged, HTTP failed, delayedReassoc = %{public}s, delayedRandMacReassoc = %{public}s",
1586                       std::to_string(isDelayedReassocSelfCure_).c_str(),
1587                       std::to_string(isDelayedRandMacReassocSelfCure_).c_str());
1588             pSelfCureStateMachine_->StopTimer(WIFI_CURE_CMD_SELF_CURE_WIFI_LINK);
1589             if (isDelayedReassocSelfCure_) {
1590                 pSelfCureStateMachine_->SendMessage(WIFI_CURE_CMD_SELF_CURE_WIFI_LINK,
1591                                                     WIFI_CURE_RESET_LEVEL_MIDDLE_REASSOC, 0);
1592             } else if (isDelayedRandMacReassocSelfCure_) {
1593                 pSelfCureStateMachine_->SendMessage(WIFI_CURE_CMD_SELF_CURE_WIFI_LINK,
1594                                                     WIFI_CURE_RESET_LEVEL_RAND_MAC_REASSOC, 0);
1595             }
1596         } else {
1597             isDelayedReassocSelfCure_ = false;
1598             isDelayedResetSelfCure_ = false;
1599             isDelayedRandMacReassocSelfCure_ = false;
1600             pSelfCureStateMachine_->SwitchState(pSelfCureStateMachine_->pConnectedMonitorState_);
1601         }
1602     }
1603 }
1604 
HandleDelayedResetSelfCure()1605 void SelfCureStateMachine::InternetSelfCureState::HandleDelayedResetSelfCure()
1606 {
1607     if (!pSelfCureStateMachine_->IsHttpReachable()) {
1608         WIFI_LOGD("HandleDelayedResetSelfCure, HTTP failed, delayedReset = %{public}s",
1609                   std::to_string(isDelayedResetSelfCure_).c_str());
1610         pSelfCureStateMachine_->StopTimer(WIFI_CURE_CMD_SELF_CURE_WIFI_LINK);
1611         pSelfCureStateMachine_->SendMessageAtFrontOfQueue(WIFI_CURE_CMD_SELF_CURE_WIFI_LINK,
1612                                                           WIFI_CURE_RESET_LEVEL_HIGH_RESET);
1613     } else {
1614         isDelayedReassocSelfCure_ = false;
1615         isDelayedResetSelfCure_ = false;
1616         isDelayedRandMacReassocSelfCure_ = false;
1617         pSelfCureStateMachine_->SwitchState(pSelfCureStateMachine_->pConnectedMonitorState_);
1618     }
1619 }
1620 
1621 /* --------------------------- state machine wifi6 self cure state ------------------------------ */
Wifi6SelfCureState(SelfCureStateMachine * selfCureStateMachine)1622 SelfCureStateMachine::Wifi6SelfCureState::Wifi6SelfCureState(SelfCureStateMachine *selfCureStateMachine)
1623     : State("Wifi6SelfCureState"),
1624       pSelfCureStateMachine_(selfCureStateMachine)
1625 {
1626     WIFI_LOGD("Wifi6SelfCureState construct success.");
1627 }
1628 
~Wifi6SelfCureState()1629 SelfCureStateMachine::Wifi6SelfCureState::~Wifi6SelfCureState() {}
1630 
GoInState()1631 void SelfCureStateMachine::Wifi6SelfCureState::GoInState()
1632 {
1633     WIFI_LOGI("Wifi6SelfCureState GoInState function.");
1634     wifi6HtcArpDetectionFailedCnt_ = 0;
1635     wifi6ArpDetectionFailedCnt_ = 0;
1636     pSelfCureStateMachine_->UpdateSelfcureState(WIFI_CURE_RESET_LEVEL_WIFI6, true);
1637 }
1638 
GoOutState()1639 void SelfCureStateMachine::Wifi6SelfCureState::GoOutState()
1640 {
1641     WIFI_LOGI("Wifi6SelfCureState GoOutState function.");
1642     pSelfCureStateMachine_->UpdateSelfcureState(WIFI_CURE_RESET_LEVEL_WIFI6, false);
1643 }
1644 
ExecuteStateMsg(InternalMessagePtr msg)1645 bool SelfCureStateMachine::Wifi6SelfCureState::ExecuteStateMsg(InternalMessagePtr msg)
1646 {
1647     if (msg == nullptr) {
1648         return false;
1649     }
1650 
1651     WIFI_LOGD("Wifi6SelfCureState-msgCode=%{public}d is received.\n", msg->GetMessageName());
1652     bool ret = NOT_EXECUTED;
1653     switch (msg->GetMessageName()) {
1654         case WIFI_CURE_CMD_WIFI6_SELFCURE:
1655             ret = EXECUTED;
1656             internetValue_ = msg->GetParam1();
1657             isForceHttpCheck_ = msg->GetParam2();
1658             pSelfCureStateMachine_->SendMessage(WIFI_CURE_CMD_WIFI6_WITH_HTC_PERIODIC_ARP_DETECTED);
1659             break;
1660         case WIFI_CURE_CMD_WIFI6_BACKOFF_SELFCURE:
1661             ret = EXECUTED;
1662             internetValue_ = msg->GetParam1();
1663             isForceHttpCheck_ = msg->GetParam2();
1664             pSelfCureStateMachine_->SendMessage(WIFI_CURE_CMD_WIFI6_WITHOUT_HTC_PERIODIC_ARP_DETECTED);
1665             break;
1666         case WIFI_CURE_CMD_WIFI6_WITH_HTC_PERIODIC_ARP_DETECTED:
1667             ret = EXECUTED;
1668             PeriodicWifi6WithHtcArpDetect(msg);
1669             break;
1670         case WIFI_CURE_CMD_WIFI6_WITHOUT_HTC_PERIODIC_ARP_DETECTED:
1671             ret = EXECUTED;
1672             PeriodicWifi6WithoutHtcArpDetect(msg);
1673             break;
1674         case WIFI_CURE_CMD_WIFI6_WITH_HTC_ARP_FAILED_DETECTED:
1675             ret = EXECUTED;
1676             HandleWifi6WithHtcArpFail(msg);
1677             break;
1678         case WIFI_CURE_CMD_WIFI6_WITHOUT_HTC_ARP_FAILED_DETECTED:
1679             ret = EXECUTED;
1680             HandleWifi6WithoutHtcArpFail(msg);
1681             break;
1682         case WIFI_CURE_NOTIFY_NETWORK_DISCONNECTED_RCVD:
1683             ret = EXECUTED;
1684             pSelfCureStateMachine_->SwitchState(pSelfCureStateMachine_->pDisconnectedMonitorState_);
1685             break;
1686         default:
1687             WIFI_LOGD("Wifi6SelfCureState-msgCode=%{public}d not handled.\n", msg->GetMessageName());
1688             break;
1689     }
1690     return ret;
1691 }
1692 
PeriodicWifi6WithHtcArpDetect(InternalMessagePtr msg)1693 void SelfCureStateMachine::Wifi6SelfCureState::PeriodicWifi6WithHtcArpDetect(InternalMessagePtr msg)
1694 {
1695     if (msg == nullptr) {
1696         WIFI_LOGE("%{public}s msg is nullptr", __FUNCTION__);
1697         return;
1698     }
1699     if (!pSelfCureStateMachine_->CanArpReachable()) {
1700         wifi6HtcArpDetectionFailedCnt_++;
1701         WIFI_LOGI("wifi6 with htc arp detection failed, times : %{public}d", wifi6HtcArpDetectionFailedCnt_);
1702         if (wifi6HtcArpDetectionFailedCnt_ == ARP_DETECTED_FAILED_COUNT) {
1703             pSelfCureStateMachine_->SendMessage(WIFI_CURE_CMD_WIFI6_WITH_HTC_ARP_FAILED_DETECTED);
1704             return;
1705         } else if (wifi6HtcArpDetectionFailedCnt_ > 0 && wifi6HtcArpDetectionFailedCnt_ < ARP_DETECTED_FAILED_COUNT) {
1706             pSelfCureStateMachine_->MessageExecutedLater(WIFI_CURE_CMD_WIFI6_WITH_HTC_PERIODIC_ARP_DETECTED,
1707                 WIFI6_HTC_ARP_DETECTED_MS);
1708             return;
1709         }
1710     } else {
1711         WIFI_LOGI("wifi6 with htc arp detect success");
1712         wifi6HtcArpDetectionFailedCnt_ = 0;
1713         pSelfCureStateMachine_->isWifi6ArpSuccess_ = true;
1714         pSelfCureStateMachine_->isInternetFailureDetected_ = false;
1715         pSelfCureStateMachine_->MessageExecutedLater(WIFI_CURE_CMD_INTERNET_FAILURE_DETECTED, internetValue_,
1716             isForceHttpCheck_, 0);
1717         pSelfCureStateMachine_->SwitchState(pSelfCureStateMachine_->pConnectedMonitorState_);
1718         return;
1719     }
1720 }
1721 
PeriodicWifi6WithoutHtcArpDetect(InternalMessagePtr msg)1722 void SelfCureStateMachine::Wifi6SelfCureState::PeriodicWifi6WithoutHtcArpDetect(InternalMessagePtr msg)
1723 {
1724     if (msg == nullptr) {
1725         WIFI_LOGE("%{public}s msg is nullptr", __FUNCTION__);
1726         return;
1727     }
1728     if (!pSelfCureStateMachine_->CanArpReachable()) {
1729         wifi6ArpDetectionFailedCnt_++;
1730         WIFI_LOGI("wifi6 without htc arp detection failed, times : %{public}d", wifi6ArpDetectionFailedCnt_);
1731         if (wifi6ArpDetectionFailedCnt_ == ARP_DETECTED_FAILED_COUNT) {
1732             pSelfCureStateMachine_->SendMessage(WIFI_CURE_CMD_WIFI6_WITHOUT_HTC_ARP_FAILED_DETECTED);
1733             return;
1734         } else if (wifi6ArpDetectionFailedCnt_ > 0 && wifi6ArpDetectionFailedCnt_ < ARP_DETECTED_FAILED_COUNT) {
1735             pSelfCureStateMachine_->MessageExecutedLater(WIFI_CURE_CMD_WIFI6_WITHOUT_HTC_PERIODIC_ARP_DETECTED,
1736                 WIFI6_HTC_ARP_DETECTED_MS);
1737             return;
1738         }
1739     } else {
1740         WIFI_LOGI("wifi6 without htc arp detect success");
1741         wifi6ArpDetectionFailedCnt_ = 0;
1742         pSelfCureStateMachine_->isWifi6ArpSuccess_ = true;
1743         if (!pSelfCureStateMachine_->IsHttpReachable()) {
1744             pSelfCureStateMachine_->isInternetFailureDetected_ = false;
1745             pSelfCureStateMachine_->MessageExecutedLater(WIFI_CURE_CMD_INTERNET_FAILURE_DETECTED, internetValue_,
1746                 isForceHttpCheck_, SELF_CURE_DELAYED_MS);
1747         }
1748         pSelfCureStateMachine_->SwitchState(pSelfCureStateMachine_->pConnectedMonitorState_);
1749         return;
1750     }
1751 }
1752 
HandleWifi6WithHtcArpFail(InternalMessagePtr msg)1753 void SelfCureStateMachine::Wifi6SelfCureState::HandleWifi6WithHtcArpFail(InternalMessagePtr msg)
1754 {
1755     if (msg == nullptr) {
1756         WIFI_LOGE("%{public}s msg is nullptr", __FUNCTION__);
1757         return;
1758     }
1759     pSelfCureStateMachine_->isWifi6ArpSuccess_ = false;
1760     WifiCategoryBlackListInfo wifi6BlackListInfo(ACTION_TYPE_HTC, GetCurrentTimeMilliSeconds());
1761     std::string currentBssid = pSelfCureStateMachine_->GetCurrentBssid();
1762     if (currentBssid.empty()) {
1763         WIFI_LOGE("%{public}s currentBssid is empty", __FUNCTION__);
1764         Wifi6ReassocSelfcure();
1765         return;
1766     }
1767     WifiConfigCenter::GetInstance().InsertWifiCategoryBlackListCache(EVENT_AX_BLA_LIST,
1768         currentBssid, wifi6BlackListInfo);
1769     WIFI_LOGI("add %{public}s to HTC bla list", MacAnonymize(currentBssid).c_str());
1770     pSelfCureStateMachine_->SendBlaListToDriver(EVENT_AX_BLA_LIST);
1771     std::string param = "1";
1772     std::string ifName = "wlan0";
1773     if (WifiCmdClient::GetInstance().SendCmdToDriver(ifName, EVENT_AX_CLOSE_HTC, param) != 0) {
1774         WIFI_LOGE("%{public}s Ax Selfcure fail", __FUNCTION__);
1775         return;
1776     }
1777     pSelfCureStateMachine_->SendMessage(WIFI_CURE_CMD_WIFI6_WITHOUT_HTC_PERIODIC_ARP_DETECTED);
1778 }
1779 
HandleWifi6WithoutHtcArpFail(InternalMessagePtr msg)1780 void SelfCureStateMachine::Wifi6SelfCureState::HandleWifi6WithoutHtcArpFail(InternalMessagePtr msg)
1781 {
1782     if (msg == nullptr) {
1783         WIFI_LOGE("%{public}s msg is nullptr", __FUNCTION__);
1784         return;
1785     }
1786     WIFI_LOGI("wifi6 without htc arp detect failed");
1787     std::string currentBssid = pSelfCureStateMachine_->GetCurrentBssid();
1788     if (currentBssid.empty()) {
1789         WIFI_LOGE("%{public}s currentBssid is empty", __FUNCTION__);
1790         Wifi6ReassocSelfcure();
1791         return;
1792     }
1793     pSelfCureStateMachine_->isWifi6ArpSuccess_ = false;
1794     WifiCategoryBlackListInfo wifi6BlackListInfo(ACTION_TYPE_WIFI6, GetCurrentTimeMilliSeconds());
1795 
1796     WifiConfigCenter::GetInstance().InsertWifiCategoryBlackListCache(EVENT_AX_BLA_LIST,
1797         currentBssid, wifi6BlackListInfo);
1798 
1799     WIFI_LOGI("add %{public}s to wifi6 bla list", MacAnonymize(currentBssid).c_str());
1800     pSelfCureStateMachine_->SendBlaListToDriver(EVENT_AX_BLA_LIST);
1801     Wifi6ReassocSelfcure();
1802 }
1803 
Wifi6ReassocSelfcure()1804 void SelfCureStateMachine::Wifi6SelfCureState::Wifi6ReassocSelfcure()
1805 {
1806     WIFI_LOGI("begin to self cure for wifi6 reassoc");
1807     pSelfCureStateMachine_->isHasTestWifi6Reassoc_ = true;
1808     pSelfCureStateMachine_->MessageExecutedLater(WIFI_CURE_CMD_INTERNET_FAILED_SELF_CURE,
1809         WIFI_CURE_INTERNET_FAILED_TYPE_TCP, SELF_CURE_DELAYED_MS);
1810     pSelfCureStateMachine_->SwitchState(pSelfCureStateMachine_->pInternetSelfCureState_);
1811 }
1812 
1813 /* --------------------------- state machine noInternet state ------------------------------ */
NoInternetState(SelfCureStateMachine * selfCureStateMachine)1814 SelfCureStateMachine::NoInternetState::NoInternetState(SelfCureStateMachine *selfCureStateMachine)
1815     : State("NoInternetState"),
1816       pSelfCureStateMachine_(selfCureStateMachine)
1817 {
1818     WIFI_LOGD("NoInternetState construct success.");
1819 }
1820 
~NoInternetState()1821 SelfCureStateMachine::NoInternetState::~NoInternetState() {}
1822 
GoInState()1823 void SelfCureStateMachine::NoInternetState::GoInState()
1824 {
1825     WIFI_LOGI("NoInternetState GoInState function.");
1826     pSelfCureStateMachine_->isSelfcureDone_ = true;
1827     SelfCureUtils::GetInstance().ReportNoInternetChrEvent();
1828     pSelfCureStateMachine_->UpdateSelfcureState(WIFI_CURE_RESET_LEVEL_IDLE, false);
1829     pSelfCureStateMachine_->MessageExecutedLater(CMD_INTERNET_STATUS_DETECT_INTERVAL,
1830         NO_INTERNET_DETECT_INTERVAL_MS);
1831 }
1832 
GoOutState()1833 void SelfCureStateMachine::NoInternetState::GoOutState()
1834 {
1835     WIFI_LOGI("NoInternetState GoOutState function.");
1836 }
1837 
ExecuteStateMsg(InternalMessagePtr msg)1838 bool SelfCureStateMachine::NoInternetState::ExecuteStateMsg(InternalMessagePtr msg)
1839 {
1840     if (msg == nullptr) {
1841         return false;
1842     }
1843     WIFI_LOGD("NoInternetState-msgCode=%{public}d is received.\n", msg->GetMessageName());
1844     bool ret = NOT_EXECUTED;
1845     switch (msg->GetMessageName()) {
1846         case CMD_INTERNET_STATUS_DETECT_INTERVAL:
1847             ret = EXECUTED;
1848             pSelfCureStateMachine_->StopTimer(CMD_INTERNET_STATUS_DETECT_INTERVAL);
1849             if (WifiConfigCenter::GetInstance().GetScreenState() != MODE_STATE_CLOSE) {
1850                 IpQosMonitor::GetInstance().QueryPackets();
1851             }
1852             pSelfCureStateMachine_->MessageExecutedLater(CMD_INTERNET_STATUS_DETECT_INTERVAL,
1853                 NO_INTERNET_DETECT_INTERVAL_MS);
1854             break;
1855         case WIFI_CURE_CMD_HTTP_REACHABLE_RCV:
1856             ret = EXECUTED;
1857             pSelfCureStateMachine_->SetSelfCureHistoryInfo(INIT_SELFCURE_HISTORY);
1858             pSelfCureStateMachine_->SwitchState(pSelfCureStateMachine_->pConnectedMonitorState_);
1859             break;
1860         case WIFI_CURE_NOTIFY_NETWORK_DISCONNECTED_RCVD:
1861             ret = EXECUTED;
1862             pSelfCureStateMachine_->SwitchState(pSelfCureStateMachine_->pDisconnectedMonitorState_);
1863             break;
1864         case WIFI_CURE_CMD_PERIODIC_ARP_DETECTED:
1865             ret = EXECUTED;
1866             pSelfCureStateMachine_->PeriodicArpDetection();
1867             break;
1868         case WIFI_CURE_CMD_ARP_FAILED_DETECTED:
1869             ret = EXECUTED;
1870             HandleArpFailedDetected(msg);
1871             break;
1872         default:
1873             WIFI_LOGD("NoInternetState-msgCode=%{public}d not handled.\n", msg->GetMessageName());
1874             break;
1875     }
1876     return ret;
1877 }
1878 
HandleArpFailedDetected(InternalMessagePtr msg)1879 void SelfCureStateMachine::NoInternetState::HandleArpFailedDetected(InternalMessagePtr msg)
1880 {
1881     if (msg == nullptr) {
1882         WIFI_LOGW("HandleArpFailedDetected, msg is nullptr");
1883         return;
1884     }
1885     std::string currentBssid = pSelfCureStateMachine_->GetCurrentBssid();
1886     if (pSelfCureStateMachine_->ShouldTransToWifi6SelfCure(msg, currentBssid)) {
1887         return;
1888     }
1889 
1890     std::string selfCureHistory = pSelfCureStateMachine_->GetSelfCureHistoryInfo();
1891     WifiSelfCureHistoryInfo selfCureInfo;
1892     SelfCureUtils::GetInstance().String2InternetSelfCureHistoryInfo(selfCureHistory, selfCureInfo);
1893     if (SelfCureUtils::GetInstance().SelfCureAcceptable(selfCureInfo, WIFI_CURE_RESET_LEVEL_MIDDLE_REASSOC)) {
1894         WIFI_LOGI("arp failed, try to reassoc");
1895         pSelfCureStateMachine_->MessageExecutedLater(WIFI_CURE_CMD_SELF_CURE_WIFI_LINK,
1896             WIFI_CURE_RESET_LEVEL_MIDDLE_REASSOC, 0, SELF_CURE_DELAYED_MS);
1897         pSelfCureStateMachine_->SwitchState(pSelfCureStateMachine_->pInternetSelfCureState_);
1898     }
1899 }
1900 
SendBlaListToDriver(int blaListType)1901 void SelfCureStateMachine::SendBlaListToDriver(int blaListType)
1902 {
1903     AgeOutWifiCategoryBlack(blaListType);
1904     std::map<std::string, WifiCategoryBlackListInfo> wifiBlackListCache;
1905     WifiConfigCenter::GetInstance().GetWifiCategoryBlackListCache(blaListType, wifiBlackListCache);
1906     std::string param = BlackListToString(wifiBlackListCache);
1907     std::string ifName = "wlan0";
1908     if (WifiCmdClient::GetInstance().SendCmdToDriver(ifName, blaListType, param) != 0) {
1909         WIFI_LOGE("%{public}s set BlaList fail", __FUNCTION__);
1910         return;
1911     }
1912 }
1913 
BlackListToString(std::map<std::string,WifiCategoryBlackListInfo> & map)1914 std::string SelfCureStateMachine::BlackListToString(std::map<std::string, WifiCategoryBlackListInfo> &map)
1915 {
1916     std::string param;
1917     uint32_t idx = map.size() >= WIFI_MAX_BLA_LIST_NUM ? WIFI_MAX_BLA_LIST_NUM : map.size();
1918     param.push_back(idx);
1919     if (idx == 0u) {
1920         return param;
1921     }
1922     for (auto iter : map) {
1923         std::string singleParam = ParseWifiCategoryBlackListInfo(iter);
1924         if (singleParam.size() != WIFI_SINGLE_ITEM_BYTE_LEN) {
1925             continue;
1926         }
1927         param.append(singleParam);
1928         if (param.size() >= WIFI_MAX_BLA_LIST_NUM * WIFI_SINGLE_ITEM_BYTE_LEN + 1) {
1929             break;
1930         }
1931     }
1932     return param;
1933 }
1934 
ParseWifiCategoryBlackListInfo(std::pair<std::string,WifiCategoryBlackListInfo> iter)1935 std::string SelfCureStateMachine::ParseWifiCategoryBlackListInfo(std::pair<std::string, WifiCategoryBlackListInfo> iter)
1936 {
1937     std::string singleParam;
1938     std::string currBssid = iter.first;
1939     WIFI_LOGI("currBssid %{public}s", MacAnonymize(currBssid).c_str());
1940     for (uint32_t i = 0; i < WIFI_SINGLE_MAC_LEN; i++) {
1941         std::string::size_type npos = currBssid.find(":");
1942         if (npos != std::string::npos) {
1943             std::string value = currBssid.substr(0, npos);
1944             singleParam.push_back(static_cast<uint8_t>(CheckDataLegalHex(value)));
1945             currBssid = currBssid.substr(npos + 1);
1946         } else {
1947             if (currBssid.empty()) {
1948                 WIFI_LOGI("currBssid is empty");
1949                 break;
1950             }
1951             singleParam.push_back(static_cast<uint8_t>(CheckDataLegalHex(currBssid)));
1952         }
1953     }
1954     singleParam.push_back(static_cast<uint8_t>(iter.second.actionType));
1955     singleParam.push_back(0);
1956     return singleParam;
1957 }
1958 
AgeOutWifiCategoryBlack(int blaListType)1959 bool SelfCureStateMachine::AgeOutWifiCategoryBlack(int blaListType)
1960 {
1961     bool isUpdate = false;
1962     std::map<std::string, WifiCategoryBlackListInfo> blackListCache;
1963     WifiConfigCenter::GetInstance().GetWifiCategoryBlackListCache(blaListType, blackListCache);
1964     if (blackListCache.empty()) {
1965         return false;
1966     }
1967     if (blaListType != EVENT_AX_BLA_LIST && blaListType != EVENT_BE_BLA_LIST) {
1968         WIFI_LOGE("AgeOutWifiCategoryBlack wrong type.");
1969         return false;
1970     }
1971     for (auto iter = blackListCache.begin(); iter != blackListCache.end(); ++iter) {
1972         if (GetCurrentTimeMilliSeconds() - iter->second.updateTime >= WIFI_BLA_LIST_TIME_EXPIRED) {
1973             WifiConfigCenter::GetInstance().RemoveWifiCategoryBlackListCache(blaListType, iter->first);
1974             isUpdate = true;
1975             WIFI_LOGI("%{public}s blaListType:%{public}d remove bssid: %{public}s for ageOut", __FUNCTION__,
1976                 blaListType, MacAnonymize(iter->first).c_str());
1977         }
1978     }
1979     if (blackListCache.size() >= WIFI_MAX_BLA_LIST_NUM) {
1980         int64_t earliestTime = std::numeric_limits<int64_t>::max();
1981         std::string delBssid;
1982         for (auto iter = blackListCache.begin(); iter != blackListCache.end(); ++iter) {
1983             if (iter->second.updateTime < earliestTime) {
1984                 delBssid = iter->first;
1985                 earliestTime = iter->second.updateTime;
1986             }
1987         }
1988         WifiConfigCenter::GetInstance().RemoveWifiCategoryBlackListCache(blaListType, delBssid);
1989         isUpdate = true;
1990         WIFI_LOGI("%{public}s blaListType:%{public}d remove bssid: %{public}s for reach max size", __FUNCTION__,
1991             blaListType, MacAnonymize(delBssid).c_str());
1992     }
1993     return isUpdate;
1994 }
1995 
AgeOutWifiConnectFailList()1996 void SelfCureStateMachine::AgeOutWifiConnectFailList()
1997 {
1998     std::map<std::string, WifiCategoryConnectFailInfo> connectFailListCache;
1999     WifiConfigCenter::GetInstance().GetWifiConnectFailListCache(connectFailListCache);
2000     for (auto iter = connectFailListCache.begin(); iter != connectFailListCache.end(); ++iter) {
2001         if (GetCurrentTimeMilliSeconds() - iter->second.updateTime >= WIFI_CONNECT_FAIL_LIST_TIME_EXPIRED) {
2002             WifiConfigCenter::GetInstance().RemoveWifiConnectFailListCache(iter->first);
2003         }
2004     }
2005     if (connectFailListCache.size() >= WIFI_MAX_BLA_LIST_NUM) {
2006         int64_t earliestTime = std::numeric_limits<int64_t>::max();
2007         std::string delBssid;
2008         for (auto iter = connectFailListCache.begin(); iter != connectFailListCache.end(); ++iter) {
2009             if (iter->second.updateTime < earliestTime) {
2010                 delBssid = iter->first;
2011                 earliestTime = iter->second.updateTime;
2012             }
2013         }
2014         WifiConfigCenter::GetInstance().RemoveWifiConnectFailListCache(delBssid);
2015     }
2016 }
2017 
SetHttpMonitorStatus(bool isHttpReachable)2018 void SelfCureStateMachine::SetHttpMonitorStatus(bool isHttpReachable)
2019 {
2020     isHttpReachable_ = isHttpReachable;
2021     detectionCond_.notify_all();
2022 }
2023 
GetCurSignalLevel()2024 int SelfCureStateMachine::GetCurSignalLevel()
2025 {
2026     WifiLinkedInfo linkedInfo;
2027     WifiConfigCenter::GetInstance().GetLinkedInfo(linkedInfo);
2028     int signalLevel = WifiSettings::GetInstance().GetSignalLevel(linkedInfo.rssi, linkedInfo.band, instId_);
2029     WIFI_LOGD("GetCurSignalLevel, signalLevel : %{public}d", signalLevel);
2030     return signalLevel;
2031 }
2032 
IsHttpReachable()2033 bool SelfCureStateMachine::IsHttpReachable()
2034 {
2035     WIFI_LOGI("IsHttpReachable network detect start");
2036     if (mNetWorkDetect_ == nullptr) {
2037         WIFI_LOGI("mNetWorkDetect_");
2038         return isHttpReachable_;
2039     }
2040     mNetWorkDetect_->StartWifiDetection();
2041     std::unique_lock<std::mutex> locker(detectionMtx_);
2042     detectionCond_.wait_for(locker, std::chrono::milliseconds(HTTP_DETECT_TIMEOUT));
2043     WIFI_LOGI("IsHttpReachable network detect end, result is %{public}d", isHttpReachable_);
2044     return isHttpReachable_;
2045 }
2046 
GetLegalIpConfiguration(IpInfo & dhcpResults)2047 int SelfCureStateMachine::GetLegalIpConfiguration(IpInfo &dhcpResults)
2048 {
2049     WifiConfigCenter::GetInstance().GetIpInfo(dhcpResults);
2050     if ((dhcpResults.gateway != 0) && (dhcpResults.ipAddress != 0)) {
2051         std::string gateway = IpTools::ConvertIpv4Address(dhcpResults.gateway);
2052         std::string initialIpAddr = IpTools::ConvertIpv4Address(dhcpResults.ipAddress);
2053         int tryTimes = TRY_TIMES;
2054         int testCnt = 0;
2055         std::vector<std::string> conflictedIpAddr;
2056         std::string testIpAddr = initialIpAddr;
2057         /** find unconflicted ip */
2058         while (testCnt++ < tryTimes) {
2059             conflictedIpAddr.push_back(testIpAddr);
2060             testIpAddr = SelfCureUtils::GetInstance().GetNextIpAddr(gateway, initialIpAddr, conflictedIpAddr);
2061             if (DoSlowArpTest(testIpAddr)) {
2062                 WIFI_LOGI("GetLegalIpConfiguration, find a new unconflicted one.");
2063                 std::string newIpAddress = testIpAddr;
2064                 WIFI_LOGI("newIpAddress, newIpAddress = %{private}s", newIpAddress.c_str());
2065                 dhcpResults.ipAddress = IpTools::ConvertIpv4Address(newIpAddress);
2066                 return 0;
2067             }
2068         }
2069         /** there is no unconflicted ip, use 156 as static ip */
2070         uint32_t newIpAddr = STATIC_IP_ADDR;
2071         std::vector<uint32_t> oldIpAddr = SelfCureUtils::GetInstance().TransIpAddressToVec(
2072             IpTools::ConvertIpv4Address(dhcpResults.ipAddress));
2073         if (oldIpAddr.size() != IP_ADDR_SIZE) {
2074             return -1;
2075         }
2076         oldIpAddr[VEC_POS_3] = newIpAddr;
2077         std::string newIpAddress = SelfCureUtils::GetInstance().TransVecToIpAddress(oldIpAddr);
2078         dhcpResults.ipAddress = IpTools::ConvertIpv4Address(newIpAddress);
2079         return 0;
2080     }
2081     return -1;
2082 }
2083 
CanArpReachable()2084 bool SelfCureStateMachine::CanArpReachable()
2085 {
2086     ArpChecker arpChecker;
2087     std::string macAddress;
2088     WifiConfigCenter::GetInstance().GetMacAddress(macAddress, instId_);
2089     IpInfo ipInfo;
2090     WifiConfigCenter::GetInstance().GetIpInfo(ipInfo, instId_);
2091     std::string ipAddress = IpTools::ConvertIpv4Address(ipInfo.ipAddress);
2092     std::string ifName = WifiConfigCenter::GetInstance().GetStaIfaceName();
2093     if (ipInfo.gateway == 0) {
2094         WIFI_LOGE("gateway is null");
2095         return false;
2096     }
2097     std::string gateway = IpTools::ConvertIpv4Address(ipInfo.gateway);
2098     uint64_t arpRtt = 0;
2099     arpChecker.Start(ifName, macAddress, ipAddress, gateway);
2100     for (int i = 0; i < DEFAULT_SLOW_NUM_ARP_PINGS; i++) {
2101         if (arpChecker.DoArpCheck(MAX_ARP_DNS_CHECK_TIME, true, arpRtt)) {
2102             WriteArpInfoHiSysEvent(arpRtt, 0);
2103             return true;
2104         }
2105     }
2106     WriteArpInfoHiSysEvent(arpRtt, 1);
2107     return false;
2108 }
2109 
DoSlowArpTest(const std::string & testIpAddr)2110 bool SelfCureStateMachine::DoSlowArpTest(const std::string& testIpAddr)
2111 {
2112     ArpChecker arpChecker;
2113     std::string macAddress;
2114     WifiConfigCenter::GetInstance().GetMacAddress(macAddress, instId_);
2115     std::string ipAddress = testIpAddr;
2116     std::string ifName = WifiConfigCenter::GetInstance().GetStaIfaceName();
2117     IpInfo ipInfo;
2118     std::string gateway = IpTools::ConvertIpv4Address(ipInfo.gateway);
2119     arpChecker.Start(ifName, macAddress, ipAddress, gateway);
2120     for (int i = 0; i < DEFAULT_SLOW_NUM_ARP_PINGS; i++) {
2121         if (arpChecker.DoArpCheck(MAX_ARP_DNS_CHECK_TIME, false)) {
2122             return true;
2123         }
2124     }
2125     return false;
2126 }
2127 
DoArpTest(std::string & ipAddress,std::string & gateway)2128 bool SelfCureStateMachine::DoArpTest(std::string& ipAddress, std::string& gateway)
2129 {
2130     ArpChecker arpChecker;
2131     std::string macAddress;
2132     WifiConfigCenter::GetInstance().GetMacAddress(macAddress, instId_);
2133     std::string ifName = WifiConfigCenter::GetInstance().GetStaIfaceName();
2134     arpChecker.Start(ifName, macAddress, ipAddress, gateway);
2135     return arpChecker.DoArpCheck(MAX_ARP_DNS_CHECK_TIME, true);
2136 }
2137 
IsIpAddressInvalid()2138 bool SelfCureStateMachine::IsIpAddressInvalid()
2139 {
2140     IpInfo dhcpInfo;
2141     std::vector<uint32_t> currAddr;
2142     WifiConfigCenter::GetInstance().GetIpInfo(dhcpInfo);
2143     if (dhcpInfo.ipAddress != 0) {
2144         std::string addr = IpTools::ConvertIpv4Address(dhcpInfo.ipAddress);
2145         currAddr = SelfCureUtils::GetInstance().TransIpAddressToVec(addr);
2146         if ((currAddr.size() == IP_ADDR_SIZE)) {
2147             uint32_t intCurrAddr3 = (currAddr[VEC_POS_3] & 0xFF);
2148             uint32_t netmaskLenth =
2149                 static_cast<uint32_t>(IpTools::GetMaskLength(IpTools::ConvertIpv4Address(dhcpInfo.netmask)));
2150             bool ipEqualsGw = (dhcpInfo.ipAddress == dhcpInfo.gateway);
2151             bool invalidIp = (intCurrAddr3 == 0 || intCurrAddr3 == 1 || intCurrAddr3 == IP_ADDR_LIMIT);
2152             if ((ipEqualsGw) || ((netmaskLenth == NET_MASK_LENGTH) && (invalidIp))) {
2153                 WIFI_LOGI("current rcvd ip is invalid, maybe no internet access, need to comfirm and cure it.");
2154                 return true;
2155             }
2156         }
2157     }
2158     return false;
2159 }
2160 
IsUseFactoryMac()2161 bool SelfCureStateMachine::IsUseFactoryMac()
2162 {
2163     WIFI_LOGI("enter %{public}s", __FUNCTION__);
2164     WifiLinkedInfo wifiLinkedInfo;
2165     std::string currMacAddress;
2166     std::string realMacAddress;
2167     WifiConfigCenter::GetInstance().GetMacAddress(currMacAddress);
2168     WifiSettings::GetInstance().GetRealMacAddress(realMacAddress);
2169     if (!currMacAddress.empty() && !realMacAddress.empty() && currMacAddress == realMacAddress) {
2170         WIFI_LOGI("use factory mac address currently.");
2171         return true;
2172     }
2173     return false;
2174 }
2175 
IsNeedWifiReassocUseDeviceMac()2176 bool SelfCureStateMachine::IsNeedWifiReassocUseDeviceMac()
2177 {
2178     WIFI_LOGI("enter %{public}s", __FUNCTION__);
2179     WifiDeviceConfig config;
2180     if (GetCurrentWifiDeviceConfig(config) != WIFI_OPT_SUCCESS) {
2181         WIFI_LOGE("%{public}s: GetCurrentWifiDeviceConfig failed!", __FUNCTION__);
2182         return false;
2183     }
2184 #ifdef SUPPORT_LOCAL_RANDOM_MAC
2185     WIFI_LOGD("random MAC address is supported!");
2186     if (!CanArpReachable()) {
2187         WIFI_LOGI("arp is not reachable!");
2188         return false;
2189     }
2190     if (IsUseFactoryMac()) {
2191         WIFI_LOGI("use factory mac now!");
2192         return false;
2193     }
2194     std::vector<WifiScanInfo> scanResults;
2195     WifiConfigCenter::GetInstance().GetWifiScanConfig()->GetScanInfoList(scanResults);
2196     if (GetBssidCounter(config, scanResults) < MULTI_BSSID_NUM) {
2197         WIFI_LOGI("not multi bssid condition!");
2198         return false;
2199     }
2200     bool hasInternetEver = NetworkStatusHistoryManager::HasInternetEverByHistory(GetNetworkStatusHistory());
2201     bool isPortalNetwork = config.isPortal;
2202     if (hasInternetEver || isPortalNetwork) {
2203         WIFI_LOGI("hasinternet or portal network, don't to reassoc with factory mac!");
2204         return false;
2205     }
2206     WifiSelfCureHistoryInfo selfCureInfo;
2207     std::string internetSelfCureHistory = GetSelfCureHistoryInfo();
2208     SelfCureUtils::GetInstance().String2InternetSelfCureHistoryInfo(internetSelfCureHistory, selfCureInfo);
2209     if (selfCureInfo.randMacSelfCureConnectFailedCnt > SELF_CURE_RAND_MAC_CONNECT_FAIL_MAX_COUNT ||
2210         selfCureInfo.randMacSelfCureFailedCnt > SELF_CURE_RAND_MAC_MAX_COUNT) {
2211         WIFI_LOGI("has connect fail three times or randMac self cure fail 20 times!");
2212         return false;
2213     }
2214     auto now = std::chrono::system_clock::now();
2215     int64_t currentMs = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count();
2216     int64_t lastConnectFailMs = selfCureInfo.lastRandMacSelfCureConnectFailedCntTs;
2217     if ((currentMs - lastConnectFailMs) < RAND_MAC_FAIL_EXPIRATION_AGE_MILLIS) {
2218         WIFI_LOGI("Too close to the last connection failure time return");
2219         return false;
2220     }
2221     return true;
2222 #endif
2223     WIFI_LOGI("random MAC address is not supported!");
2224     return false;
2225 }
2226 
IsSuppOnCompletedState()2227 bool SelfCureStateMachine::IsSuppOnCompletedState()
2228 {
2229     WifiLinkedInfo linkedInfo;
2230     WifiConfigCenter::GetInstance().GetLinkedInfo(linkedInfo);
2231     if (linkedInfo.supplicantState == SupplicantState::COMPLETED) {
2232         return true;
2233     }
2234     return false;
2235 }
2236 
IfPeriodicArpDetection()2237 bool SelfCureStateMachine::IfPeriodicArpDetection()
2238 {
2239     int curSignalLevel = GetCurSignalLevel();
2240     int state = WifiConfigCenter::GetInstance().GetScreenState();
2241     WIFI_LOGD("IfPeriodicArpDetection, GetScreenState: %{public}d", state);
2242     return (curSignalLevel >= SIGNAL_LEVEL_2) && (!isSelfCureOnGoing_) && (IsSuppOnCompletedState()) &&
2243            (state == MODE_STATE_OPEN);
2244 }
2245 
PeriodicArpDetection()2246 void SelfCureStateMachine::PeriodicArpDetection()
2247 {
2248     StopTimer(WIFI_CURE_CMD_PERIODIC_ARP_DETECTED);
2249     if (!IfPeriodicArpDetection()) {
2250         WIFI_LOGD("PeriodicArpDetection, no need detection, just jump");
2251         MessageExecutedLater(WIFI_CURE_CMD_PERIODIC_ARP_DETECTED, DEFAULT_ARP_DETECTED_MS);
2252         return;
2253     }
2254     if (!CanArpReachable()) {
2255         arpDetectionFailedCnt_++;
2256         WIFI_LOGI("Periodic Arp Detection failed, times : %{public}d", arpDetectionFailedCnt_);
2257         if (arpDetectionFailedCnt_ == ARP_DETECTED_FAILED_COUNT) {
2258             SendMessage(WIFI_CURE_CMD_ARP_FAILED_DETECTED);
2259         } else if (arpDetectionFailedCnt_ > 0 && arpDetectionFailedCnt_ < ARP_DETECTED_FAILED_COUNT) {
2260             MessageExecutedLater(WIFI_CURE_CMD_PERIODIC_ARP_DETECTED, FAST_ARP_DETECTED_MS);
2261             return;
2262         }
2263     } else {
2264         WIFI_LOGI("Periodic Arp Detection success");
2265         arpDetectionFailedCnt_ = 0;
2266     }
2267     MessageExecutedLater(WIFI_CURE_CMD_PERIODIC_ARP_DETECTED, DEFAULT_ARP_DETECTED_MS);
2268 }
2269 
ShouldTransToWifi6SelfCure(InternalMessagePtr msg,std::string currConnectedBssid)2270 bool SelfCureStateMachine::ShouldTransToWifi6SelfCure(InternalMessagePtr msg, std::string currConnectedBssid)
2271 {
2272     WIFI_LOGI("enter ShouldTransToWifi6SelfCure");
2273     if (currConnectedBssid.empty() || msg== nullptr) {
2274         WIFI_LOGE("currConnectedBssid is empty or msg is nullptr");
2275         return false;
2276     }
2277     if (!IsWifi6Network(currConnectedBssid) || isWifi6ArpSuccess_ || GetCurrentRssi() < MIN_VAL_LEVEL_3) {
2278         return false;
2279     }
2280     int32_t arg = isInternetUnknown_ ? 1 : 0;
2281     std::map<std::string, WifiCategoryBlackListInfo> wifi6BlackListCache;
2282     WifiConfigCenter::GetInstance().GetWifiCategoryBlackListCache(EVENT_AX_BLA_LIST, wifi6BlackListCache);
2283     if (wifi6BlackListCache.find(currConnectedBssid) == wifi6BlackListCache.end()) {
2284         MessageExecutedLater(WIFI_CURE_CMD_WIFI6_SELFCURE, arg, msg->GetParam2(), SELF_CURE_DELAYED_MS);
2285         SwitchState(pWifi6SelfCureState_);
2286         return true;
2287     } else {
2288         auto iter = wifi6BlackListCache.find(currConnectedBssid);
2289         if (iter->second.actionType == 0) {
2290             MessageExecutedLater(WIFI_CURE_CMD_WIFI6_BACKOFF_SELFCURE, arg, msg->GetParam2(), SELF_CURE_DELAYED_MS);
2291             SwitchState(pWifi6SelfCureState_);
2292             return true;
2293         } else {
2294             WIFI_LOGI("don't need to do wifi6 selfcure");
2295         }
2296     }
2297     return false;
2298 }
2299 
GetWifi7SelfCureType(int connectFailTimes,WifiLinkedInfo & info)2300 int SelfCureStateMachine::GetWifi7SelfCureType(int connectFailTimes, WifiLinkedInfo &info)
2301 {
2302     std::vector<WifiScanInfo> scanResults;
2303     WifiConfigCenter::GetInstance().GetWifiScanConfig()->GetScanInfoList(scanResults);
2304     int scanRssi = GetScanRssi(info.bssid, scanResults);
2305     WifiCategory wifiCategory = WifiConfigCenter::GetInstance().GetWifiScanConfig()->GetWifiCategoryRecord(info.bssid);
2306     WIFI_LOGI("GetWifi7SelfCureType scanRssi %{public}d, wifiCategory: %{public}d, connectFailTimes: %{public}d",
2307         scanRssi, static_cast<int>(wifiCategory), connectFailTimes);
2308     if ((wifiCategory == WifiCategory::WIFI7 || wifiCategory == WifiCategory::WIFI7_PLUS)
2309         && connectFailTimes >= SELF_CURE_WIFI7_CONNECT_FAIL_MAX_COUNT && scanRssi >= MIN_VAL_LEVEL_3) {
2310         return WIFI7_SELFCURE_DISCONNECTED;
2311     }
2312     return WIFI7_NO_SELFCURE;
2313 }
2314 
ShouldTransToWifi7SelfCure(WifiLinkedInfo & info)2315 void SelfCureStateMachine::ShouldTransToWifi7SelfCure(WifiLinkedInfo &info)
2316 {
2317     WIFI_LOGI("enter ShouldTransToWifi7SelfCure");
2318     if (info.bssid.empty()) {
2319         return;
2320     }
2321     std::map<std::string, WifiCategoryConnectFailInfo> connectFailListCache;
2322     WifiConfigCenter::GetInstance().GetWifiConnectFailListCache(connectFailListCache);
2323     auto iterConnectFail = connectFailListCache.find(info.bssid);
2324     if (iterConnectFail == connectFailListCache.end()) {
2325         WIFI_LOGE("no bssid in connectFailListCache");
2326         return;
2327     }
2328     int wifi7SelfCureType = GetWifi7SelfCureType(iterConnectFail->second.connectFailTimes, info);
2329     if (wifi7SelfCureType == WIFI7_SELFCURE_DISCONNECTED) {
2330         std::map<std::string, WifiCategoryBlackListInfo> blackListCache;
2331         WifiConfigCenter::GetInstance().GetWifiCategoryBlackListCache(EVENT_BE_BLA_LIST, blackListCache);
2332         auto iterBlackList = blackListCache.find(info.bssid);
2333         if (iterBlackList == blackListCache.end()) {
2334             WIFI_LOGI("start wifi7 with mld backoff");
2335             SendMessage(WIFI_CURE_CMD_WIFI7_MLD_BACKOFF, info);
2336         } else if (iterBlackList->second.actionType == ACTION_TYPE_MLD) {
2337             WIFI_LOGI("start wifi7 without mld backoff");
2338             SendMessage(WIFI_CURE_CMD_WIFI7_NON_MLD_BACKOFF, info);
2339         } else if (iterBlackList->second.actionType == ACTION_TYPE_WIFI7
2340             && iterConnectFail->second.actionType == ACTION_TYPE_RECOVER_FAIL) {
2341             WIFI_LOGI("start wifi7 selfcure fail recover");
2342             SendMessage(WIFI_CURE_CMD_WIFI7_BACKOFF_RECOVER, info);
2343         }
2344     } else {
2345         WIFI_LOGD("don't need to do wifi7 selfcure");
2346     }
2347 }
2348 
HandleWifiBlackListUpdateMsg()2349 void SelfCureStateMachine::HandleWifiBlackListUpdateMsg()
2350 {
2351     if (AgeOutWifiCategoryBlack(EVENT_BE_BLA_LIST)) {
2352         SendBlaListToDriver(EVENT_BE_BLA_LIST);
2353     }
2354     if (AgeOutWifiCategoryBlack(EVENT_AX_BLA_LIST)) {
2355         SendBlaListToDriver(EVENT_AX_BLA_LIST);
2356     }
2357 }
2358 
GetScanRssi(std::string currentBssid,const std::vector<WifiScanInfo> scanResults)2359 int SelfCureStateMachine::GetScanRssi(std::string currentBssid, const std::vector<WifiScanInfo> scanResults)
2360 {
2361     for (WifiScanInfo nextResult : scanResults) {
2362         if (currentBssid == nextResult.bssid) {
2363             return nextResult.rssi;
2364         }
2365     }
2366     return CURRENT_RSSI_INIT;
2367 }
2368 
GetCurrentRssi()2369 int SelfCureStateMachine::GetCurrentRssi()
2370 {
2371     WifiLinkedInfo wifiLinkedInfo;
2372     if (WifiConfigCenter::GetInstance().GetLinkedInfo(wifiLinkedInfo) != 0) {
2373         WIFI_LOGE("Get current link info failed!");
2374     }
2375     int currentRssi_ = wifiLinkedInfo.rssi;
2376     return currentRssi_;
2377 }
2378 
GetCurrentBssid()2379 std::string SelfCureStateMachine::GetCurrentBssid()
2380 {
2381     WifiDeviceConfig config;
2382     if (GetCurrentWifiDeviceConfig(config) != WIFI_OPT_SUCCESS) {
2383         WIFI_LOGE("Get current bssid failed!");
2384         return "";
2385     }
2386     std::string currentBssid_ = config.bssid;
2387     return currentBssid_;
2388 }
2389 
IsWifi6Network(std::string currConnectedBssid)2390 bool SelfCureStateMachine::IsWifi6Network(std::string currConnectedBssid)
2391 {
2392     if (currConnectedBssid.empty()) {
2393         WIFI_LOGE("currConnectedBssid is empty");
2394         return false;
2395     }
2396     WifiLinkedInfo wifiLinkedInfo;
2397     if (WifiConfigCenter::GetInstance().GetLinkedInfo(wifiLinkedInfo) != 0) {
2398         WIFI_LOGE("Get current link info failed!");
2399     }
2400     if (wifiLinkedInfo.supportedWifiCategory == WifiCategory::WIFI6 ||
2401         wifiLinkedInfo.supportedWifiCategory == WifiCategory::WIFI6_PLUS) {
2402         WIFI_LOGI("current network is wifi6 network");
2403         return true;
2404     }
2405     std::map<std::string, WifiCategoryBlackListInfo> wifi7BlackListCache;
2406     WifiConfigCenter::GetInstance().GetWifiCategoryBlackListCache(EVENT_BE_BLA_LIST, wifi7BlackListCache);
2407     auto iter = wifi7BlackListCache.find(currConnectedBssid);
2408     if (iter != wifi7BlackListCache.end() &&
2409         iter->second.actionType == ACTION_TYPE_WIFI7 &&
2410         (wifiLinkedInfo.supportedWifiCategory == WifiCategory::WIFI7 ||
2411         wifiLinkedInfo.supportedWifiCategory == WifiCategory::WIFI7_PLUS)) {
2412         WIFI_LOGI("current network is wifi7 network but in wifi6 mode");
2413         return true;
2414     }
2415     return false;
2416 }
2417 
IfP2pConnected()2418 bool SelfCureStateMachine::IfP2pConnected()
2419 {
2420     WifiP2pLinkedInfo linkedInfo;
2421     WifiConfigCenter::GetInstance().GetP2pInfo(linkedInfo);
2422     WIFI_LOGI("P2p connection state : %{public}d", linkedInfo.GetConnectState());
2423     return linkedInfo.GetConnectState() == P2pConnectedState::P2P_CONNECTED;
2424 }
2425 
GetAuthType()2426 std::string SelfCureStateMachine::GetAuthType()
2427 {
2428     WifiDeviceConfig config;
2429     if (GetCurrentWifiDeviceConfig(config) != WIFI_OPT_SUCCESS) {
2430         WIFI_LOGE("GetAuthType failed!");
2431         return "";
2432     }
2433     std::string keyMgmt = config.keyMgmt;
2434     return keyMgmt;
2435 }
2436 
GetIpAssignment(AssignIpMethod & ipAssignment)2437 int SelfCureStateMachine::GetIpAssignment(AssignIpMethod &ipAssignment)
2438 {
2439     WifiDeviceConfig config;
2440     if (GetCurrentWifiDeviceConfig(config) != WIFI_OPT_SUCCESS) {
2441         WIFI_LOGE("GetIpAssignment failed!");
2442         return -1;
2443     }
2444     ipAssignment = config.wifiIpConfig.assignMethod;
2445     return 0;
2446 }
2447 
GetLastHasInternetTime()2448 time_t SelfCureStateMachine::GetLastHasInternetTime()
2449 {
2450     WifiDeviceConfig config;
2451     if (GetCurrentWifiDeviceConfig(config) != WIFI_OPT_SUCCESS) {
2452         WIFI_LOGE("GetLastHasInternetTime failed!");
2453         return -1;
2454     }
2455     time_t lastHasInternetTime = config.lastHasInternetTime;
2456     return lastHasInternetTime;
2457 }
2458 
GetNetworkStatusHistory()2459 uint32_t SelfCureStateMachine::GetNetworkStatusHistory()
2460 {
2461     WifiDeviceConfig config;
2462     if (GetCurrentWifiDeviceConfig(config) != WIFI_OPT_SUCCESS) {
2463         WIFI_LOGE("GetNetworkStatusHistory failed!");
2464         return 0;
2465     }
2466     uint32_t networkStatusHistory = config.networkStatusHistory;
2467     return networkStatusHistory;
2468 }
2469 
GetSelfCureHistoryInfo()2470 std::string SelfCureStateMachine::GetSelfCureHistoryInfo()
2471 {
2472     WifiDeviceConfig config;
2473     if (GetCurrentWifiDeviceConfig(config) != WIFI_OPT_SUCCESS) {
2474         WIFI_LOGE("GetSelfCureHistoryInfo failed!");
2475         return "";
2476     }
2477     std::string internetSelfCureHistory = config.internetSelfCureHistory;
2478     return internetSelfCureHistory;
2479 }
2480 
SetSelfCureHistoryInfo(const std::string selfCureHistory)2481 int SelfCureStateMachine::SetSelfCureHistoryInfo(const std::string selfCureHistory)
2482 {
2483     WIFI_LOGI("enter %{public}s", __FUNCTION__);
2484     if (selfCureHistory == "") {
2485         WIFI_LOGW("selfCureHistory is empty");
2486         return -1;
2487     }
2488     WifiDeviceConfig config;
2489     if (GetCurrentWifiDeviceConfig(config) != WIFI_OPT_SUCCESS) {
2490         WIFI_LOGE("SetSelfCureHistoryInfo failed!");
2491         return -1;
2492     }
2493     config.internetSelfCureHistory = selfCureHistory;
2494     WifiSettings::GetInstance().AddDeviceConfig(config);
2495     WifiSettings::GetInstance().SyncDeviceConfig();
2496     return 0;
2497 }
2498 
GetIsReassocWithFactoryMacAddress()2499 int SelfCureStateMachine::GetIsReassocWithFactoryMacAddress()
2500 {
2501     WifiDeviceConfig config;
2502     if (GetCurrentWifiDeviceConfig(config) != WIFI_OPT_SUCCESS) {
2503         WIFI_LOGE("GetIsReassocWithFactoryMacAddress failed!");
2504         return 0;
2505     }
2506     int isReassocWithFactoryMacAddress = config.isReassocSelfCureWithFactoryMacAddress;
2507     return isReassocWithFactoryMacAddress;
2508 }
2509 
IsCustNetworkSelfCure()2510 bool SelfCureStateMachine::IsCustNetworkSelfCure()
2511 {
2512     IEnhanceService *pEnhanceService = WifiServiceManager::GetInstance().GetEnhanceServiceInst();
2513     if (pEnhanceService == nullptr) {
2514         WIFI_LOGE("IsCustNetworkSelfCure get pEnhanceService service failed!");
2515         return false;
2516     }
2517     WifiDeviceConfig config;
2518     if (GetCurrentWifiDeviceConfig(config) != WIFI_OPT_SUCCESS) {
2519         return false;
2520     }
2521     if (pEnhanceService->IsItCustNetwork(config)) {
2522         WIFI_LOGD("selfcure is not triggered under currrent network.");
2523         return true;
2524     }
2525     return false;
2526 }
2527 
SetIsReassocWithFactoryMacAddress(int isReassocWithFactoryMacAddress)2528 int SelfCureStateMachine::SetIsReassocWithFactoryMacAddress(int isReassocWithFactoryMacAddress)
2529 {
2530     int networkId = WifiConfigCenter::GetInstance().GetLastNetworkId();
2531     WifiDeviceConfig config;
2532     if (WifiSettings::GetInstance().GetDeviceConfig(networkId, config) != 0) {
2533         WIFI_LOGE("SetIsReassocWithFactoryMacAddress Get device config failed!");
2534         return -1;
2535     }
2536     config.isReassocSelfCureWithFactoryMacAddress = isReassocWithFactoryMacAddress;
2537     WifiSettings::GetInstance().AddDeviceConfig(config);
2538     WifiSettings::GetInstance().SyncDeviceConfig();
2539     return 0;
2540 }
2541 
GetCurrentWifiDeviceConfig(WifiDeviceConfig & config)2542 ErrCode SelfCureStateMachine::GetCurrentWifiDeviceConfig(WifiDeviceConfig &config)
2543 {
2544     WifiLinkedInfo wifiLinkedInfo;
2545     if (WifiConfigCenter::GetInstance().GetLinkedInfo(wifiLinkedInfo) != 0) {
2546         WIFI_LOGE("Get current link info failed!");
2547         return WIFI_OPT_FAILED;
2548     }
2549     if (WifiSettings::GetInstance().GetDeviceConfig(wifiLinkedInfo.networkId, config) != 0) {
2550         WIFI_LOGE("Get device config failed!, netId is %{public}d", wifiLinkedInfo.networkId);
2551         return WIFI_OPT_FAILED;
2552     }
2553     return WIFI_OPT_SUCCESS;
2554 }
2555 
UpdateConnSelfCureFailedHistory()2556 bool SelfCureStateMachine::UpdateConnSelfCureFailedHistory()
2557 {
2558     return false;
2559 }
2560 
HandleNetworkConnected()2561 void SelfCureStateMachine::HandleNetworkConnected()
2562 {
2563     if (!UpdateConnSelfCureFailedHistory()) {
2564         WIFI_LOGD("Config is null for update, delay 2s to update again.");
2565         MessageExecutedLater(WIFI_CURE_CMD_UPDATE_CONN_SELF_CURE_HISTORY, SELF_CURE_MONITOR_DELAYED_MS);
2566     }
2567     noAutoConnCounter_ = 0;
2568     autoConnectFailedNetworksRssi_.clear();
2569     connectedTime_ = static_cast<int64_t>(time(nullptr));
2570     {
2571         std::lock_guard<std::mutex> lock(dhcpFailedBssidLock_);
2572         dhcpFailedBssids_.clear();
2573         dhcpFailedConfigKeys_.clear();
2574     }
2575     SwitchState(pConnectedMonitorState_);
2576 }
2577 
IsEncryptedAuthType(const std::string authType)2578 bool SelfCureStateMachine::IsEncryptedAuthType(const std::string authType)
2579 {
2580     if (authType == KEY_MGMT_WPA_PSK || authType == KEY_MGMT_WAPI_PSK || authType == KEY_MGMT_SAE) {
2581         return true;
2582     }
2583     return false;
2584 }
2585 
RecoverySoftAp()2586 void SelfCureStateMachine::RecoverySoftAp()
2587 {
2588     if (WifiManager::GetInstance().GetWifiTogglerManager() == nullptr) {
2589         WIFI_LOGI("GetWifiTogglerManager is nullptr!!");
2590         return;
2591     }
2592     WifiManager::GetInstance().GetWifiTogglerManager()->SoftapToggled(0, 0);
2593     WifiManager::GetInstance().GetWifiTogglerManager()->SoftapToggled(1, 0);
2594 }
2595 
IsSoftApSsidSameWithWifi(const HotspotConfig & curApConfig)2596 bool SelfCureStateMachine::IsSoftApSsidSameWithWifi(const HotspotConfig& curApConfig)
2597 {
2598     WifiLinkedInfo linkedInfo;
2599     WifiDeviceConfig config;
2600     WifiConfigCenter::GetInstance().GetLinkedInfo(linkedInfo);
2601     WifiSettings::GetInstance().GetDeviceConfig(linkedInfo.networkId, config);
2602     bool isSameSsid = (curApConfig.GetSsid() == linkedInfo.ssid);
2603     bool isSamePassword = (curApConfig.GetPreSharedKey() == config.preSharedKey);
2604     std::string().swap(config.preSharedKey);
2605     bool isSameSecurityType = ("WPA2-PSK" == config.keyMgmt || "WPA-PSK" == config.keyMgmt);
2606     if (isSameSsid && isSameSecurityType && !isSamePassword) {
2607         return true;
2608     }
2609     return false;
2610 }
2611 
CheckConflictIpForSoftAp()2612 void SelfCureStateMachine::CheckConflictIpForSoftAp()
2613 {
2614     IpInfo ipInfo;
2615     HotspotConfig curApConfig;
2616     WifiSettings::GetInstance().GetHotspotConfig(curApConfig, 0);
2617     WifiConfigCenter::GetInstance().GetIpInfo(ipInfo);
2618     WIFI_LOGI("CheckConflictIpForSoftAp enter!");
2619     if (!WifiConfigCenter::GetInstance().GetSoftapToggledState()) {
2620         WIFI_LOGI("softap not started, return!");
2621         return;
2622     }
2623     if (WifiManager::GetInstance().GetWifiTogglerManager() == nullptr) {
2624         WIFI_LOGI("GetWifiTogglerManager is nullptr!!");
2625         return;
2626     }
2627     if (IsSoftApSsidSameWithWifi(curApConfig)) {
2628         WIFI_LOGI("sta and sofap have same ssid and PSK, close softap!");
2629         WifiManager::GetInstance().GetWifiTogglerManager()->SoftapToggled(0, 0);
2630         return;
2631     }
2632     if (IpTools::ConvertIpv4Address(ipInfo.gateway) == curApConfig.GetIpAddress()) {
2633         WIFI_LOGI("sta and sofap gateway conflict, recovery softap!");
2634         RecoverySoftAp();
2635     }
2636 }
2637 
RequestArpConflictTest()2638 void SelfCureStateMachine::RequestArpConflictTest()
2639 {
2640     IpInfo ipInfo;
2641     WifiConfigCenter::GetInstance().GetIpInfo(ipInfo);
2642     std::string ipAddr = IpTools::ConvertIpv4Address(ipInfo.ipAddress);
2643     if (ipAddr != "" && DoSlowArpTest(ipAddr)) {
2644         WIFI_LOGI("RequestArpConflictTest, Upload static ip conflicted chr!");
2645     }
2646 }
2647 
HandleP2pConnChanged(const WifiP2pLinkedInfo & info)2648 void SelfCureStateMachine::HandleP2pConnChanged(const WifiP2pLinkedInfo &info)
2649 {
2650     if (info.GetConnectState() == P2pConnectedState::P2P_CONNECTED) {
2651         isP2pConnected_ = true;
2652         return;
2653     }
2654     isP2pConnected_ = false;
2655     if (GetCurStateName() == pInternetSelfCureState_->GetStateName()) {
2656         SendMessage(WIFI_CURE_CMD_P2P_DISCONNECTED_EVENT);
2657     }
2658 }
2659 
IsWifiSelfcureDone()2660 bool SelfCureStateMachine::IsWifiSelfcureDone()
2661 {
2662     if (IsSelfCureOnGoing()) {
2663         return false;
2664     }
2665     return isSelfcureDone_;
2666 }
2667 
IfMultiGateway()2668 bool SelfCureStateMachine::IfMultiGateway()
2669 {
2670     MultiGateway::GetInstance().GetGatewayAddr(instId_);
2671     int32_t gatewayCnt = MultiGateway::GetInstance().GetGatewayNum();
2672     WriteArpInfoHiSysEvent(0, 0, gatewayCnt);
2673     return MultiGateway::GetInstance().IsMultiGateway();
2674 }
2675 
IsSettingsPage()2676 bool SelfCureStateMachine::IsSettingsPage()
2677 {
2678     std::string page = WifiSettings::GetInstance().GetPackageName("SETTINGS");
2679     if (WifiAppStateAware::GetInstance().IsForegroundApp(page)) {
2680         WIFI_LOGI("settings page, do not allow reset self cure");
2681         return true;
2682     }
2683     return false;
2684 }
2685 
IsSelfCureOnGoing()2686 bool SelfCureStateMachine::IsSelfCureOnGoing()
2687 {
2688     return isSelfCureOnGoing_;
2689 }
2690 
IsSelfCureL2Connecting()2691 bool SelfCureStateMachine::IsSelfCureL2Connecting()
2692 {
2693     return selfCureL2State_ != SelfCureState::SCE_WIFI_INVALID_STATE;
2694 }
2695 
ForceStopSelfCure()2696 void SelfCureStateMachine::ForceStopSelfCure()
2697 {
2698     if (GetCurStateName() != pDisconnectedMonitorState_->GetStateName()) {
2699         WIFI_LOGI("stop selfcure");
2700         SwitchState(pDisconnectedMonitorState_);
2701     }
2702 }
2703 
StopSelfCureWifi(int32_t status)2704 void SelfCureStateMachine::StopSelfCureWifi(int32_t status)
2705 {
2706     SendMessage(WIFI_CURE_CMD_FORCE_STOP_SELF_CURE);
2707     if (selfCureL2State_ == SelfCureState::SCE_WIFI_INVALID_STATE) {
2708         return;
2709     }
2710     HandleSceStopSelfCure(status);
2711 }
2712 
IsMultiDhcpOffer()2713 bool SelfCureStateMachine::IsMultiDhcpOffer()
2714 {
2715     IEnhanceService *pEnhanceService = WifiServiceManager::GetInstance().GetEnhanceServiceInst();
2716     if (pEnhanceService == nullptr) {
2717         WIFI_LOGE("IsMultiDhcpOffer get pEnhanceService service failed!");
2718         return false;
2719     }
2720     uint32_t retSize = 0;
2721     IpInfo info;
2722     pEnhanceService->DealDhcpOfferResult(OperationCmd::DHCP_OFFER_SIZE_GET, info, retSize);
2723     return retSize >= DHCP_OFFER_COUNT;
2724 }
2725 
ClearDhcpOffer()2726 void SelfCureStateMachine::ClearDhcpOffer()
2727 {
2728     IEnhanceService *pEnhanceService = WifiServiceManager::GetInstance().GetEnhanceServiceInst();
2729     if (pEnhanceService == nullptr) {
2730         WIFI_LOGE("ClearDhcpOffer get pEnhanceService service failed!");
2731         return;
2732     }
2733     uint32_t retSize = 0;
2734     IpInfo info;
2735     pEnhanceService->DealDhcpOfferResult(OperationCmd::DHCP_OFFER_CLEAR, info, retSize);
2736 }
2737 
UpdateSelfcureState(int currentCureLevel,bool isSelfCureOnGoing)2738 void SelfCureStateMachine::UpdateSelfcureState(int currentCureLevel, bool isSelfCureOnGoing)
2739 {
2740     if (isSelfCureOnGoing_ == isSelfCureOnGoing && currentCureLevel != WIFI_CURE_RESET_LEVEL_HIGH_RESET_WIFI_ON) {
2741         WIFI_LOGW("selfCureOnGoing state is not change");
2742         return;
2743     }
2744     isSelfCureOnGoing_ = isSelfCureOnGoing;
2745     WIFI_LOGI("UpdateSelfcureState currentCureLevel: %{public}d, isSelfCureOnGoing: %{public}d",
2746         currentCureLevel, isSelfCureOnGoing);
2747     int32_t selfcureType = SelfCureUtils::GetInstance().GetSelfCureType(currentCureLevel);
2748     if (selfcureType == 0) {
2749         WIFI_LOGW("selfcureType is invalid");
2750         return;
2751     }
2752     int currentPid = static_cast<int>(getpid());
2753     WifiCommonEventHelper::PublishSelfcureStateChangedEvent(currentPid, selfcureType, isSelfCureOnGoing);
2754 }
2755 
CheckSelfCureWifiResult(int event)2756 bool SelfCureStateMachine::CheckSelfCureWifiResult(int event)
2757 {
2758     if (selfCureL2State_ == SelfCureState::SCE_WIFI_INVALID_STATE) {
2759         return false;
2760     }
2761     WifiState wifiState = static_cast<WifiState>(WifiConfigCenter::GetInstance().GetWifiState(instId_));
2762     if (wifiState == WifiState::DISABLING || wifiState == WifiState::DISABLED) {
2763         if (!WifiConfigCenter::GetInstance().GetWifiSelfcureReset()) {
2764             WIFI_LOGI("user may close wifi during reassoc or reconnect self-cure going");
2765             StopSelfCureDelay(SCE_WIFI_STATUS_ABORT, 0);
2766             return false;
2767         }
2768     }
2769     if ((selfCureWifiLastState_ > wifiState) && (selfCureL2State_ != SelfCureState::SCE_WIFI_OFF_STATE) &&
2770         (selfCureWifiLastState_ != WifiState::UNKNOWN)) {
2771         WIFI_LOGI("user may toggle wifi! stop selfcure, last State: %{public}d, current state: %{public}d",
2772             selfCureWifiLastState_, wifiState);
2773         StopSelfCureDelay(SCE_WIFI_STATUS_ABORT, 0);
2774         return false;
2775     }
2776     selfCureWifiLastState_ = wifiState;
2777     bool retValue = true;
2778     switch (selfCureL2State_) {
2779         case SelfCureState::SCE_WIFI_OFF_STATE:
2780             if (wifiState == WifiState::DISABLED) {
2781                 StopTimer(WIFI_CURE_RESET_OFF_TIMEOUT);
2782                 HandleSelfCureNormal();
2783             }
2784             break;
2785         case SelfCureState::SCE_WIFI_ON_STATE:
2786             if (wifiState == WifiState::ENABLED) {
2787                 StopTimer(WIFI_CURE_RESET_ON_TIMEOUT);
2788                 HandleSelfCureNormal();
2789             }
2790             break;
2791         case SelfCureState::SCE_WIFI_CONNECT_STATE:
2792             retValue = CheckSelfCureConnectState();
2793             break;
2794         case SelfCureState::SCE_WIFI_REASSOC_STATE:
2795             CheckSelfCureReassocState();
2796             break;
2797         case SelfCureState::SCE_WIFI_DISCONNECT_STATE:
2798             CheckSelfCureDisconnectState();
2799             break;
2800         default:
2801             retValue = false;
2802             break;
2803     }
2804     return retValue;
2805 }
2806 
CheckSelfCureConnectState()2807 bool SelfCureStateMachine::CheckSelfCureConnectState()
2808 {
2809     WifiLinkedInfo info;
2810     WifiConfigCenter::GetInstance().GetLinkedInfo(info);
2811     if (info.detailedState == DetailedState::DISCONNECTED) {
2812         HandleSelfCureException(SCE_WIFI_STATUS_FAIL);
2813         if (connectNetworkRetryCnt_ >= CONNECT_NETWORK_RETRY) {
2814             return false; // while reconnect fail, should not ignore sta connect event callback
2815         }
2816     }
2817     if (selfCureNetworkLastState_ == info.detailedState) {
2818         WIFI_LOGW("state not change, state is %{public}d", selfCureNetworkLastState_);
2819         return true;
2820     }
2821     selfCureNetworkLastState_ = info.detailedState;
2822     if (selfCureNetworkLastState_ == DetailedState::CONNECTED) {
2823         WIFI_LOGI("wifi connect > CMD_SCE_WIFI_CONNECT_TIMEOUT msg removed state = %{public}d",
2824             selfCureNetworkLastState_);
2825         HandleSelfCureNormal();
2826     }
2827     return true;
2828 }
2829 
CheckSelfCureReassocState()2830 void SelfCureStateMachine::CheckSelfCureReassocState()
2831 {
2832     WifiLinkedInfo info;
2833     WifiConfigCenter::GetInstance().GetLinkedInfo(info);
2834     if ((selfCureNetworkLastState_ == info.detailedState) &&
2835         (info.detailedState != DetailedState::CONNECTION_REJECT)) {
2836         WIFI_LOGW("state not change, state is %{public}d", selfCureNetworkLastState_);
2837         return;
2838     }
2839     selfCureNetworkLastState_ = info.detailedState;
2840     WIFI_LOGI("selfCureNetworkLastState_ is %{public}d", selfCureNetworkLastState_);
2841     if (selfCureNetworkLastState_ == DetailedState::CONNECTED) {
2842         WIFI_LOGI("wifi reassoc > CMD_SCE_WIFI_REASSOC_TIMEOUT msg removed state = %{public}d",
2843             selfCureNetworkLastState_);
2844         HandleSelfCureNormal();
2845     } else if ((selfCureNetworkLastState_ == DetailedState::DISCONNECTED) ||
2846         (selfCureNetworkLastState_ == DetailedState::CONNECTION_REJECT)) {
2847         WIFI_LOGI("wifi reassoc failed");
2848         StopTimer(WIFI_CURE_REASSOC_TIMEOUT);
2849         HandleSelfCureException(SCE_WIFI_STATUS_FAIL);
2850     }
2851 }
2852 
CheckSelfCureDisconnectState()2853 void SelfCureStateMachine::CheckSelfCureDisconnectState()
2854 {
2855     WifiLinkedInfo info;
2856     WifiConfigCenter::GetInstance().GetLinkedInfo(info);
2857     if (info.detailedState == DetailedState::DISCONNECTED) {
2858         StopTimer(WIFI_CURE_DISCONNECT_TIMEOUT);
2859         HandleSelfCureNormal();
2860     }
2861 }
2862 
HandleSelfCureNormal()2863 void SelfCureStateMachine::HandleSelfCureNormal()
2864 {
2865     switch (selfCureL2State_) {
2866         case SelfCureState::SCE_WIFI_OFF_STATE: {
2867             SetSelfCureWifiTimeOut(SCE_WIFI_ON_STATE);
2868             break;
2869         }
2870         case SelfCureState::SCE_WIFI_DISCONNECT_STATE:  // fall through
2871         case SelfCureState::SCE_WIFI_ON_STATE: {
2872             WIFI_LOGI("HandleSelfCureNormal wifi on OK or disconnect ok! -> wifi connect");
2873             if (selfCureL2State_ == SelfCureState::SCE_WIFI_ON_STATE) {
2874                 UpdateSelfcureState(WIFI_CURE_RESET_LEVEL_HIGH_RESET_WIFI_ON, true);
2875             }
2876             int networkId = WifiConfigCenter::GetInstance().GetLastNetworkId();
2877             IStaService *pStaService = WifiServiceManager::GetInstance().GetStaServiceInst(instId_);
2878             if (pStaService == nullptr) {
2879                 WIFI_LOGE("Get %{public}s service failed!", WIFI_SERVICE_STA);
2880                 return;
2881             }
2882             if (pStaService->ConnectToNetwork(networkId, NETWORK_SELECTED_BY_SELFCURE) != WIFI_OPT_SUCCESS) {
2883                 WIFI_LOGE("connect to network failed");
2884                 HandleSelfCureException(SCE_WIFI_STATUS_FAIL);
2885                 return;
2886             }
2887             SetSelfCureWifiTimeOut(SCE_WIFI_CONNECT_STATE);
2888             break;
2889         }
2890         case SelfCureState::SCE_WIFI_CONNECT_STATE:
2891         case SelfCureState::SCE_WIFI_REASSOC_STATE:
2892             WIFI_LOGI("HandleSelfCureNormal, wifi connect/reassoc/reconnect ok!");
2893             StopSelfCureDelay(SCE_WIFI_STATUS_SUCC, WIFI_CURE_CONN_SUCCESS_MS);
2894             break;
2895         default:
2896             WIFI_LOGE("HandleSelfCureNormal, unvalid selfCureL2State_");
2897             break;
2898     }
2899 }
2900 
HandleSelfCureException(int reasonCode)2901 void SelfCureStateMachine::HandleSelfCureException(int reasonCode)
2902 {
2903     switch (selfCureL2State_) {
2904         case SelfCureState::SCE_WIFI_OFF_STATE:
2905             WIFI_LOGI("HandleSelfCureException, wifi off fail! -> wifi off");
2906             StopSelfCureDelay(SCE_WIFI_STATUS_FAIL, 0);
2907             break;
2908         case SelfCureState::SCE_WIFI_ON_STATE:
2909             WIFI_LOGI("HandleSelfCureException, wifi on fail! -> wifi on");
2910             StopSelfCureDelay(SCE_WIFI_STATUS_FAIL, 0);
2911             break;
2912         case SelfCureState::SCE_WIFI_DISCONNECT_STATE:
2913             HandleSelfCureDisconnectException();
2914             break;
2915         case SelfCureState::SCE_WIFI_CONNECT_STATE:
2916         case SelfCureState::SCE_WIFI_REASSOC_STATE: {
2917             WIFI_LOGI("HandleSelfCureException, wifi connect/reassoc/reconnect fail! retry = %{public}d",
2918                 connectNetworkRetryCnt_);
2919             if (connectNetworkRetryCnt_ >= CONNECT_NETWORK_RETRY) {
2920                 HandleConnectFailed();
2921                 StopSelfCureDelay(SCE_WIFI_STATUS_FAIL, 0);
2922                 break;
2923             }
2924             connectNetworkRetryCnt_++;
2925             if ((selfCureL2State_ == SCE_WIFI_CONNECT_STATE) && (useWithRandMacAddress_ == FAC_MAC_REASSOC)) {
2926                 useWithRandMacAddress_ = RAND_MAC_REASSOC;
2927                 SetIsReassocWithFactoryMacAddress(RAND_MAC_REASSOC);
2928             }
2929             IStaService *pStaService = WifiServiceManager::GetInstance().GetStaServiceInst(instId_);
2930             if (pStaService == nullptr) {
2931                 WIFI_LOGE("pStaService get failed");
2932                 return;
2933             }
2934             pStaService->Disconnect();
2935             SetSelfCureWifiTimeOut(SCE_WIFI_DISCONNECT_STATE);
2936             break;
2937         }
2938         default:
2939             WIFI_LOGE("HandleSelfCureException, unvalid selfCureL2State_");
2940             break;
2941     }
2942 }
2943 
HandleSelfCureDisconnectException()2944 void SelfCureStateMachine::HandleSelfCureDisconnectException()
2945 {
2946     WIFI_LOGI("HandleSelfCureException, disconnect timeout! -> connect");
2947     int networkId = WifiConfigCenter::GetInstance().GetLastNetworkId();
2948     IStaService *pStaService = WifiServiceManager::GetInstance().GetStaServiceInst(instId_);
2949     if (pStaService == nullptr) {
2950         WIFI_LOGE("pStaService get failed");
2951         return;
2952     }
2953     if (pStaService->ConnectToNetwork(networkId, NETWORK_SELECTED_BY_SELFCURE) != WIFI_OPT_SUCCESS) {
2954         WIFI_LOGE("connect to network failed");
2955         StopSelfCureDelay(SCE_WIFI_STATUS_FAIL, 0);
2956         return;
2957     }
2958     SetSelfCureWifiTimeOut(SCE_WIFI_CONNECT_STATE);
2959 }
2960 
SetSelfCureWifiTimeOut(SelfCureState wifiSelfCureState)2961 void SelfCureStateMachine::SetSelfCureWifiTimeOut(SelfCureState wifiSelfCureState)
2962 {
2963     selfCureL2State_ = wifiSelfCureState;
2964     switch (selfCureL2State_) {
2965         case SelfCureState::SCE_WIFI_OFF_STATE:
2966             WIFI_LOGI("SetSelfCureWifiTimeOut send delay message CMD_SELFCURE_WIFI_OFF_TIMEOUT");
2967             MessageExecutedLater(WIFI_CURE_RESET_OFF_TIMEOUT, WIFI_CURE_OFF_TIMEOUT_MS);
2968             break;
2969         case SelfCureState::SCE_WIFI_ON_STATE:
2970             WIFI_LOGI("SetSelfCureWifiTimeOut send delay message CMD_SELFCURE_WIFI_ON_TIMEOUT");
2971             MessageExecutedLater(WIFI_CURE_RESET_ON_TIMEOUT, WIFI_CURE_ON_TIMEOUT_MS);
2972             break;
2973         case SelfCureState::SCE_WIFI_REASSOC_STATE:
2974             WIFI_LOGI("SetSelfCureWifiTimeOut send delay message CMD_SELFCURE_WIFI_REASSOC_TIMEOUT");
2975             selfCureNetworkLastState_ = DetailedState::DISCONNECTED;
2976             MessageExecutedLater(WIFI_CURE_REASSOC_TIMEOUT, WIFI_CURE_REASSOC_TIMEOUT_MS);
2977             break;
2978         case SelfCureState::SCE_WIFI_CONNECT_STATE: {
2979             WIFI_LOGI("SetSelfCureWifiTimeOut send delay message CMD_SELFCURE_WIFI_CONNECT_TIMEOUT");
2980             int32_t delayMs = WIFI_CURE_CONNECT_TIMEOUT_MS;
2981             if (WifiConfigCenter::GetInstance().GetScreenState() != MODE_STATE_OPEN) {
2982                 delayMs += WIFI_CURE_CONNECT_TIMEOUT_MS;
2983             }
2984             MessageExecutedLater(WIFI_CURE_CONNECT_TIMEOUT, delayMs);
2985             break;
2986         }
2987         case SelfCureState::SCE_WIFI_DISCONNECT_STATE:
2988             MessageExecutedLater(WIFI_CURE_DISCONNECT_TIMEOUT, WIFI_CURE_DISCONNECT_TIMEOUT_MS);
2989             break;
2990         default:
2991             WIFI_LOGW("SetSelfCureWifiTimeOut, unvalid selfcurestate");
2992             break;
2993     }
2994 }
2995 
StopSelfCureDelay(int status,int delay)2996 void SelfCureStateMachine::StopSelfCureDelay(int status, int delay)
2997 {
2998     if (delay == 0) {
2999         HandleSceStopSelfCure(status);
3000     } else {
3001         MessageExecutedLater(WIFI_CURE_CMD_STOP_SELF_CURE, status, 0, delay);
3002     }
3003 }
3004 
HandleSceStopSelfCure(int status)3005 void SelfCureStateMachine::HandleSceStopSelfCure(int status)
3006 {
3007     WIFI_LOGI("HandleSceStopSelfCure status %{public}d", status);
3008     ResetSelfCureParam();
3009     NotifySelfCureCompleted(status);
3010 }
3011 
NotifySelfCureCompleted(int status)3012 void SelfCureStateMachine::NotifySelfCureCompleted(int status)
3013 {
3014     if (status == SCE_WIFI_STATUS_SUCC) {
3015         MessageExecutedLater(WIFI_CURE_CMD_INTERNET_RECOVERY_CONFIRM, 0);
3016     } else if ((status == SCE_WIFI_STATUS_FAIL) || (status == SCE_WIFI_STATUS_ABORT) ||
3017         (status == SCE_WIFI_STATUS_LOST)) {
3018         MessageExecutedLater(WIFI_CURE_CMD_SELF_CURE_FAILED, 0);
3019     }
3020 }
3021 
ResetSelfCureParam()3022 void SelfCureStateMachine::ResetSelfCureParam()
3023 {
3024     selfCureNetworkLastState_ = DetailedState::IDLE;
3025     selfCureWifiLastState_ = WifiState::UNKNOWN;
3026     selfCureL2State_ = SelfCureState::SCE_WIFI_INVALID_STATE;
3027     connectNetworkRetryCnt_ = 0;
3028     WifiConfigCenter::GetInstance().SetWifiSelfcureReset(false);
3029     StopTimer(WIFI_CURE_RESET_OFF_TIMEOUT);
3030     StopTimer(WIFI_CURE_RESET_ON_TIMEOUT);
3031     StopTimer(WIFI_CURE_REASSOC_TIMEOUT);
3032     StopTimer(WIFI_CURE_CONNECT_TIMEOUT);
3033     StopTimer(WIFI_CURE_DISCONNECT_TIMEOUT);
3034 }
3035 
HandleConnectFailed()3036 void SelfCureStateMachine::HandleConnectFailed()
3037 {
3038     WIFI_LOGI("enter HandleConnectFailed");
3039     if (useWithRandMacAddress_ != 0 && isSelfCureOnGoing_) {
3040         useWithRandMacAddress_ = 0;
3041         WifiDeviceConfig config;
3042         int networkId = WifiConfigCenter::GetInstance().GetLastNetworkId();
3043         if (WifiSettings::GetInstance().GetDeviceConfig(networkId, config) != 0) {
3044             WIFI_LOGE("%{public}s: GetDeviceConfig failed!.", __FUNCTION__);
3045             return;
3046         }
3047         //Connect failed, updateSelfcureConnectHistoryInfo
3048         WifiSelfCureHistoryInfo selfCureHistoryInfo;
3049         std::string internetSelfCureHistory = config.internetSelfCureHistory;
3050         SelfCureUtils::GetInstance().String2InternetSelfCureHistoryInfo(internetSelfCureHistory, selfCureHistoryInfo);
3051         int requestCureLevel = WIFI_CURE_RESET_LEVEL_RAND_MAC_REASSOC;
3052         SelfCureUtils::GetInstance().UpdateSelfCureConnectHistoryInfo(selfCureHistoryInfo, requestCureLevel, false);
3053         config.internetSelfCureHistory = selfCureHistoryInfo.GetSelfCureHistory();
3054         config.isReassocSelfCureWithFactoryMacAddress = 0;
3055         config.wifiPrivacySetting = WifiPrivacyConfig::RANDOMMAC;
3056         WifiSettings::GetInstance().AddDeviceConfig(config);
3057         WifiSettings::GetInstance().SyncDeviceConfig();
3058     }
3059     IStaService *pStaService = WifiServiceManager::GetInstance().GetStaServiceInst(0);
3060     if (pStaService == nullptr) {
3061         WIFI_LOGE("Get pStaService failed");
3062         return;
3063     }
3064     pStaService->Disconnect();
3065 }
3066 } // namespace Wifi
3067 } // namespace OHOS