• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021-2022 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 <cstdio>
17 #include <chrono>
18 #include <random>
19 #include "sta_state_machine.h"
20 #include "if_config.h"
21 #include "ip_tools.h"
22 #include "mac_address.h"
23 #include "sta_monitor.h"
24 #include "wifi_common_util.h"
25 #include "wifi_global_func.h"
26 #include "wifi_logger.h"
27 #include "wifi_protect_manager.h"
28 #include "wifi_sta_hal_interface.h"
29 #include "wifi_supplicant_hal_interface.h"
30 #include "wifi_hisysevent.h"
31 #include "wifi_config_center.h"
32 #include "wifi_hisysevent.h"
33 #include "block_connect_service.h"
34 #include "wifi_randommac_helper.h"
35 #include "define.h"
36 #include "wifi_code_convert.h"
37 #ifndef OHOS_ARCH_LITE
38 #include <dlfcn.h>
39 #include "securec.h"
40 #include "wifi_app_state_aware.h"
41 #include "wifi_net_observer.h"
42 #include "wifi_system_timer.h"
43 #ifdef WIFI_CONFIG_UPDATE
44 #include "wifi_config_update.h"
45 #endif
46 #ifdef WIFI_SECURITY_DETECT_ENABLE
47 #include "wifi_security_detect.h"
48 #endif
49 #include "wifi_notification_util.h"
50 #include "wifi_net_stats_manager.h"
51 #include "wifi_history_record_manager.h"
52 #endif // OHOS_ARCH_LITE
53 
54 #include "wifi_channel_helper.h"
55 #ifndef OHOS_WIFI_STA_TEST
56 #else
57 #include "mock_dhcp_service.h"
58 #endif
59 #include "sta_define.h"
60 #include "ip_qos_monitor.h"
61 #include "wifi_telephony_utils.h"
62 
63 namespace OHOS {
64 namespace Wifi {
65 namespace {
66 constexpr const char* WIFI_IS_CONNECT_FROM_USER = "persist.wifi.is_connect_from_user";
67 constexpr int MAX_CHLOAD = 800;
68 }
69 DEFINE_WIFILOG_LABEL("StaStateMachine");
70 #define ANY_BSSID "any"
71 #define PORTAL_ACTION "ohos.want.action.awc"
72 #define PORTAL_ENTITY "entity.browser.hbct"
73 #define PORTAL_CHECK_TIME (10 * 60)
74 #define PORTAL_AUTH_EXPIRED_CHECK_TIME (2)
75 #define PORTAL_MILLSECOND 1000
76 #define WPA3_BLACKMAP_MAX_NUM 20
77 #define WPA3_BLACKMAP_RSSI_THRESHOLD (-70)
78 #define WPA3_CONNECT_FAIL_COUNT_THRESHOLD 2
79 #define TRANSFORMATION_TO_MBPS 10
80 #define DEFAULT_NUM_ARP_PINGS 3
81 #define MAX_ARP_CHECK_TIME 300
82 #define NETWORK 1
83 #define NO_NETWORK 0
84 #define DISCONNECTED_NETWORK 2
85 #define CONNECTED_NETWORK 3
86 #define WPA_DEFAULT_NETWORKID 0
87 #define SELF_CURE_FAC_MAC_REASSOC 2
88 #define SELF_CURE_RAND_MAC_REASSOC 3
89 #define USER_CONNECT "1"
90 #define AUTO_CONNECT "0"
91 
92 #define CMD_BUFFER_SIZE 1024
93 #define GSM_AUTH_RAND_LEN 16
94 #define GSM_AUTH_CHALLENGE_SRES_LEN 4
95 #define GSM_AUTH_CHALLENGE_KC_LEN 8
96 
97 #define MAX_SRES_STR_LEN (2 * GSM_AUTH_CHALLENGE_SRES_LEN)
98 #define MAX_KC_STR_LEN (2 * GSM_AUTH_CHALLENGE_KC_LEN)
99 
100 #define UMTS_AUTH_TYPE_TAG 0xdb
101 #define UMTS_AUTS_TYPE_TAG 0xdc
102 
103 #define UMTS_AUTH_CHALLENGE_RESULT_INDEX 0
104 #define UMTS_AUTH_CHALLENGE_DATA_START_IDNEX 1
105 
106 #define UMTS_AUTH_CHALLENGE_RAND_LEN 16
107 #define UMTS_AUTH_CHALLENGE_AUTN_LEN 16
108 #define UMTS_AUTH_CHALLENGE_RES_LEN 8
109 #define UMTS_AUTH_CHALLENGE_CK_LEN 16
110 #define UMTS_AUTH_CHALLENGE_IK_LEN 16
111 #define UMTS_AUTH_CHALLENGE_AUTS_LEN 16
112 
113 #define UMTS_AUTH_REQUEST_CONTENT_LEN (UMTS_AUTH_CHALLENGE_RAND_LEN + UMTS_AUTH_CHALLENGE_AUTN_LEN + 2)
114 
115 // res[9] + ck[17] + ik[17] + unknown[9]
116 #define UMTS_AUTH_RESPONSE_CONENT_LEN 52
117 
118 #define MAX_RES_STR_LEN (2 * UMTS_AUTH_CHALLENGE_RES_LEN)
119 #define MAX_CK_STR_LEN (2 * UMTS_AUTH_CHALLENGE_CK_LEN)
120 #define MAX_IK_STR_LEN (2 * UMTS_AUTH_CHALLENGE_IK_LEN)
121 #define MAX_RAND_STR_LEN (2 * UMTS_AUTH_CHALLENGE_RAND_LEN)
122 #define MAX_AUTN_STR_LEN (2 * UMTS_AUTH_CHALLENGE_AUTN_LEN)
123 
124 constexpr int32_t MAX_NO_INTERNET_CNT = 3;
125 
126 const std::map<int, int> wpa3FailreasonMap {
127     {WLAN_STATUS_AUTH_TIMEOUT, WPA3_AUTH_TIMEOUT},
128     {MAC_AUTH_RSP2_TIMEOUT, WPA3_AUTH_TIMEOUT},
129     {MAC_AUTH_RSP4_TIMEOUT, WPA3_AUTH_TIMEOUT},
130     {MAC_ASSOC_RSP_TIMEOUT, WPA3_ASSOC_TIMEOUT}
131 };
132 
133 const std::map<int, int> portalEventValues = {
134     {PortalState::NOT_PORTAL, HISYS_EVENT_PROTAL_STATE_NOT_PORTAL},
135     {PortalState::UNAUTHED, HISYS_EVENT_PROTAL_STATE_PORTAL_UNVERIFIED},
136     {PortalState::AUTHED, HISYS_EVENT_PROTAL_STATE_PORTAL_VERIFIED},
137     {PortalState::EXPERIED, HISYS_EVENT_PROTAL_STATE_PORTAL_UNVERIFIED}
138 };
139 
StaStateMachine(int instId)140 StaStateMachine::StaStateMachine(int instId)
141     : StateMachine("StaStateMachine"),
142       targetNetworkId_(INVALID_NETWORK_ID),
143       lastSignalLevel_(INVALID_SIGNAL_LEVEL), targetRoamBssid(WPA_BSSID_ANY), currentTpType(IPTYPE_IPV4),
144       getIpSucNum(0), getIpFailNum(0), enableSignalPoll(true), isRoam(false),
145       lastTimestamp(0), autoPullBrowserFlag(true), portalState(PortalState::UNCHECKED), detectNum(0),
146       portalExpiredDetectCount(0), mIsWifiInternetCHRFlag(false), networkStatusHistoryInserted(false),
147       pDhcpResultNotify(nullptr), pClosedState(nullptr), pInitState(nullptr),
148       pLinkState(nullptr), pSeparatedState(nullptr), pApLinkingState(nullptr),
149       pApLinkedState(nullptr), pGetIpState(nullptr),
150       pLinkedState(nullptr), pApRoamingState(nullptr), mLastConnectNetId(INVALID_NETWORK_ID),
151       mConnectFailedCnt(0)
152 {
153     m_instId = instId;
154 }
155 
~StaStateMachine()156 StaStateMachine::~StaStateMachine()
157 {
158     WIFI_LOGI("~StaStateMachine");
159     StopHandlerThread();
160     ParsePointer(pClosedState);
161     ParsePointer(pInitState);
162     ParsePointer(pLinkState);
163     ParsePointer(pSeparatedState);
164     ParsePointer(pApLinkingState);
165     ParsePointer(pApLinkedState);
166     ParsePointer(pGetIpState);
167     ParsePointer(pLinkedState);
168     ParsePointer(pApRoamingState);
169     ParsePointer(pDhcpResultNotify);
170 #ifndef OHOS_ARCH_LITE
171 #ifdef WIFI_DATA_REPORT_ENABLE
172     ParsePointer(wifiDataReportService_);
173 #endif
174 #endif
175     {
176         std::unique_lock<std::shared_mutex> lock(m_staCallbackMutex);
177         m_staCallback.clear();
178     }
179 }
180 
181 /* ---------------------------Initialization functions------------------------------ */
InitStaStateMachine()182 ErrCode StaStateMachine::InitStaStateMachine()
183 {
184     WIFI_LOGI("Enter InitStateMachine m_instId = %{public}d", m_instId);
185     if (!InitialStateMachine("StaStateMachine")) {
186         WIFI_LOGE("Initial StateMachine failed m_instId = %{public}d", m_instId);
187         return WIFI_OPT_FAILED;
188     }
189 
190     if (InitStaStates() == WIFI_OPT_FAILED) {
191         return WIFI_OPT_FAILED;
192     }
193     BuildStateTree();
194     SetFirstState(pClosedState);
195     StartStateMachine();
196 
197 #ifndef OHOS_ARCH_LITE
198     NetSupplierInfo = std::make_unique<NetManagerStandard::NetSupplierInfo>().release();
199     m_NetWorkState = sptr<NetStateObserver>(new NetStateObserver());
200     if (m_NetWorkState == nullptr) {
201         WIFI_LOGE("%{public}s m_NetWorkState is null", __func__);
202         return WIFI_OPT_FAILED;
203     }
204     m_NetWorkState->SetNetStateCallback(
205         [this](SystemNetWorkState netState, std::string url) { this->NetStateObserverCallback(netState, url); });
206 #ifdef EXTENSIBLE_AUTHENTICATION
207     NetEapObserver::GetInstance().SetRegisterCustomEapCallback(
208         [this](const std::string &regCmd) { this->RegisterCustomEapCallback(regCmd); });
209     NetEapObserver::GetInstance().SetReplyCustomEapDataCallback(
210         [this](int result, const std::string &strEapData) { this->ReplyCustomEapDataCallback(result, strEapData); });
211     NetEapObserver::GetInstance().ReRegisterCustomEapCallback();
212 #endif
213 #endif
214 
215     return WIFI_OPT_SUCCESS;
216 }
217 
InitStaStates()218 ErrCode StaStateMachine::InitStaStates()
219 {
220     WIFI_LOGE("Enter InitStaStates\n");
221     int tmpErrNumber;
222 #ifndef OHOS_ARCH_LITE
223 #ifdef WIFI_DATA_REPORT_ENABLE
224     wifiDataReportService_ = new (std::nothrow) WifiDataReportService(this, this->m_instId);
225     if (wifiDataReportService_ == nullptr) {
226         WIFI_LOGE("wifiDataReportService_ new failed");
227         return WIFI_OPT_FAILED;
228     }
229 #endif
230 #endif
231     pClosedState = new (std::nothrow) ClosedState(this);
232     tmpErrNumber = JudgmentEmpty(pClosedState);
233     pInitState = new (std::nothrow) InitState(this);
234     tmpErrNumber = JudgmentEmpty(pInitState);
235     pLinkState = new (std::nothrow) LinkState(this);
236     tmpErrNumber += JudgmentEmpty(pLinkState);
237     pSeparatedState = new (std::nothrow) SeparatedState(this);
238     tmpErrNumber += JudgmentEmpty(pSeparatedState);
239     pApLinkingState = new (std::nothrow) ApLinkingState(this);
240     tmpErrNumber += JudgmentEmpty(pApLinkingState);
241     pApLinkedState = new (std::nothrow) ApLinkedState(this);
242     tmpErrNumber += JudgmentEmpty(pApLinkedState);
243     pGetIpState = new (std::nothrow) GetIpState(this);
244     tmpErrNumber += JudgmentEmpty(pGetIpState);
245     pLinkedState = new (std::nothrow) LinkedState(this);
246     tmpErrNumber += JudgmentEmpty(pLinkedState);
247     pApRoamingState = new (std::nothrow) ApRoamingState(this);
248     tmpErrNumber += JudgmentEmpty(pApRoamingState);
249     pDhcpResultNotify = new (std::nothrow) DhcpResultNotify(this);
250     tmpErrNumber += JudgmentEmpty(pDhcpResultNotify);
251     if (tmpErrNumber != 0) {
252         WIFI_LOGE("InitStaStates some one state is null\n");
253         return WIFI_OPT_FAILED;
254     }
255     return WIFI_OPT_SUCCESS;
256 }
257 
BuildStateTree()258 void StaStateMachine::BuildStateTree()
259 {
260     StatePlus(pClosedState, nullptr); //father state to handle enable/disable
261     StatePlus(pInitState, pClosedState); //father state to handle common event
262     StatePlus(pLinkState, pInitState);  //father state to handle link
263     StatePlus(pSeparatedState, pInitState); //disconnect state
264     StatePlus(pApLinkingState, pLinkState); //L2 connecting
265     StatePlus(pApLinkedState, pLinkState); //L2 connected
266     StatePlus(pGetIpState, pApLinkedState); //L3 connecting to get ip
267     StatePlus(pLinkedState, pApLinkedState); //L3 connected
268     StatePlus(pApRoamingState, pApLinkedState); //roaming state
269 }
270 
InitWifiLinkedInfo()271 void StaStateMachine::InitWifiLinkedInfo()
272 {
273     linkedInfo.networkId = INVALID_NETWORK_ID;
274     linkedInfo.ssid = "";
275     linkedInfo.bssid = "";
276     linkedInfo.macAddress = "";
277     linkedInfo.macType = 0;
278     linkedInfo.rxLinkSpeed = 0;
279     linkedInfo.txLinkSpeed = 0;
280     linkedInfo.rssi = 0;
281     linkedInfo.band = 0;
282     linkedInfo.frequency = 0;
283     linkedInfo.linkSpeed = 0;
284     linkedInfo.ipAddress = 0;
285     linkedInfo.connState = ConnState::DISCONNECTED;
286     linkedInfo.ifHiddenSSID = false;
287     linkedInfo.chload = 0;
288     linkedInfo.snr = 0;
289     linkedInfo.isDataRestricted = 0;
290     linkedInfo.platformType = "";
291     linkedInfo.portalUrl = "";
292     linkedInfo.supplicantState = SupplicantState::DISCONNECTED;
293     linkedInfo.detailedState = DetailedState::DISCONNECTED;
294     linkedInfo.wifiLinkType = WifiLinkType::DEFAULT_LINK;
295     linkedInfo.channelWidth = WifiChannelWidth::WIDTH_INVALID;
296     linkedInfo.lastPacketDirection = 0;
297     linkedInfo.lastRxPackets = 0;
298     linkedInfo.lastTxPackets = 0;
299     linkedInfo.isAncoConnected = 0;
300     linkedInfo.supportedWifiCategory = WifiCategory::DEFAULT;
301     linkedInfo.isMloConnected = false;
302     linkedInfo.isWurEnable = false;
303     linkedInfo.isHiLinkNetwork = 0;
304     std::vector<WifiLinkedInfo> emptyMloLinkInfo;
305     WifiConfigCenter::GetInstance().SaveMloLinkedInfo(emptyMloLinkInfo, m_instId);
306 }
307 
308 
309 /* --------------------------- state machine Init State ------------------------------ */
ClosedState(StaStateMachine * staStateMachine)310 StaStateMachine::ClosedState::ClosedState(StaStateMachine *staStateMachine)
311     : State("ClosedState"), pStaStateMachine(staStateMachine)
312 {}
313 
~ClosedState()314 StaStateMachine::ClosedState::~ClosedState()
315 {}
316 
GoInState()317 void StaStateMachine::ClosedState::GoInState()
318 {
319     WIFI_LOGI("ClosedState GoInState function.");
320     /* Initialize Connection Information. */
321     pStaStateMachine->InitWifiLinkedInfo();
322     return;
323 }
324 
GoOutState()325 void StaStateMachine::ClosedState::GoOutState()
326 {
327     WIFI_LOGI("ClosedState GoOutState function.");
328     return;
329 }
330 
ExecuteStateMsg(InternalMessagePtr msg)331 bool StaStateMachine::ClosedState::ExecuteStateMsg(InternalMessagePtr msg)
332 {
333     if (msg == nullptr) {
334         return false;
335     }
336 
337     WIFI_LOGI("ClosedState-msgCode=%{public}d is received. m_instId = %{public}d\n", msg->GetMessageName(),
338         pStaStateMachine->m_instId);
339     bool ret = NOT_EXECUTED;
340     switch (msg->GetMessageName()) {
341         case WIFI_SVR_CMD_STA_ENABLE_STA: {
342             ret = EXECUTED;
343             StartWifiProcess();
344             break;
345         }
346         case WIFI_SVR_CMD_STA_DISABLE_STA:{
347             ret = EXECUTED;
348             StopWifiProcess();
349             break;
350         }
351         default:
352             WIFI_LOGD("InitState-msgCode=%d not handled.\n", msg->GetMessageName());
353             break;
354     }
355     return ret;
356 }
357 
StartWifiProcess()358 void StaStateMachine::ClosedState::StartWifiProcess()
359 {
360     if (WifiStaHalInterface::GetInstance().WpaAutoConnect(false) != WIFI_HAL_OPT_OK) {
361         WIFI_LOGI("The automatic Wpa connection is disabled failed.");
362     }
363     int screenState = WifiConfigCenter::GetInstance().GetScreenState();
364     WIFI_LOGI("set suspend mode to chip when wifi started, screenState: %{public}d", screenState);
365     if (pStaStateMachine->m_instId == INSTID_WLAN0) {
366         if (WifiSupplicantHalInterface::GetInstance().WpaSetSuspendMode(screenState == MODE_STATE_CLOSE)
367             != WIFI_HAL_OPT_OK) {
368             WIFI_LOGE("%{public}s WpaSetSuspendMode failed!", __FUNCTION__);
369         }
370     }
371     /* Sets the MAC address of WifiSettings. */
372     std::string mac;
373     std::string ifaceName = WifiConfigCenter::GetInstance().GetStaIfaceName(pStaStateMachine->m_instId);
374     if ((WifiStaHalInterface::GetInstance().GetStaDeviceMacAddress(mac, ifaceName, WIFI_OEMINFO_MAC))
375         == WIFI_HAL_OPT_OK) {
376         WifiConfigCenter::GetInstance().SetMacAddress(mac, pStaStateMachine->m_instId);
377         std::string realMacAddress;
378         WifiSettings::GetInstance().GetRealMacAddress(realMacAddress, pStaStateMachine->m_instId);
379 #ifdef READ_MAC_FROM_OEM
380         if (realMacAddress.empty() || realMacAddress != mac) {
381 #else
382         if (realMacAddress.empty()) {
383 #endif
384             WifiSettings::GetInstance().SetRealMacAddress(mac, pStaStateMachine->m_instId);
385         }
386     } else {
387         WIFI_LOGI("GetStaDeviceMacAddress failed!");
388     }
389 
390 #ifndef OHOS_ARCH_LITE
391     WIFI_LOGI("Register netsupplier %{public}d", pStaStateMachine->m_instId);
392     WifiNetAgent::GetInstance().OnStaMachineWifiStart(pStaStateMachine->m_instId);
393 #endif
394 
395     pStaStateMachine->SwitchState(pStaStateMachine->pSeparatedState);
396 }
397 
398 
399 void StaStateMachine::ClosedState::StopWifiProcess()
400 {
401 #ifndef OHOS_ARCH_LITE
402     WifiNetAgent::GetInstance().UnregisterNetSupplier(pStaStateMachine->m_instId);
403     if (pStaStateMachine->m_NetWorkState != nullptr) {
404         pStaStateMachine->m_NetWorkState->StopNetStateObserver(pStaStateMachine->m_NetWorkState);
405     }
406     if (pStaStateMachine->hasNoInternetDialog_) {
407         pStaStateMachine->CloseNoInternetDialog();
408     }
409 #endif
410     WifiChrUtils::GetInstance().ClearSignalPollInfoArray();
411     WifiConfigCenter::GetInstance().SetUserLastSelectedNetworkId(INVALID_NETWORK_ID, pStaStateMachine->m_instId);
412 }
413 
414 /* --------------------------- state machine Init State ------------------------------ */
415 StaStateMachine::InitState::InitState(StaStateMachine *staStateMachine)
416     : State("InitState"), pStaStateMachine(staStateMachine)
417 {}
418 
419 StaStateMachine::InitState::~InitState()
420 {}
421 
422 void StaStateMachine::InitState::GoInState()
423 {
424     WIFI_LOGI("InitState GoInState function.");
425     /* Initialize Connection Information. */
426     pStaStateMachine->InitWifiLinkedInfo();
427     return;
428 }
429 
430 void StaStateMachine::InitState::GoOutState()
431 {
432     WIFI_LOGI("InitState GoOutState function.");
433     return;
434 }
435 
436 bool StaStateMachine::InitState::ExecuteStateMsg(InternalMessagePtr msg)
437 {
438     if (msg == nullptr) {
439         return false;
440     }
441 
442     WIFI_LOGI("InitState-msgCode=%{public}d is received. m_instId = %{public}d\n", msg->GetMessageName(),
443         pStaStateMachine->m_instId);
444     bool ret = NOT_EXECUTED;
445     switch (msg->GetMessageName()) {
446         case WIFI_SVR_CMD_UPDATE_COUNTRY_CODE: {
447             ret = EXECUTED;
448             UpdateCountryCode(msg);
449             break;
450         }
451         case WIFI_SVR_CMD_STA_CONNECT_NETWORK:
452         case WIFI_SVR_CMD_STA_CONNECT_SAVED_NETWORK: {
453             ret = EXECUTED;
454             StartConnectEvent(msg);
455             break;
456         }
457         case WIFI_SVR_COM_STA_ENABLE_HILINK:
458         case WIFI_SVR_COM_STA_HILINK_DELIVER_MAC:
459         case WIFI_SVR_COM_STA_HILINK_TRIGGER_WPS: {
460             ret = EXECUTED;
461             pStaStateMachine->DealHiLinkDataToWpa(msg);
462             break;
463         }
464         case WIFI_SVR_CMD_STA_NETWORK_CONNECTION_EVENT: {
465             ret = EXECUTED;
466             HandleNetworkConnectionEvent(msg);
467             break;
468         }
469         case WIFI_SVR_CMD_STA_FOLD_STATUS_NOTIFY_EVENT: {
470             ret = EXECUTED;
471             SaveFoldStatus(msg);
472             break;
473         }
474         case WIFI_SCREEN_STATE_CHANGED_NOTIFY_EVENT: {
475             ret = EXECUTED;
476             DealScreenStateChangedEvent(msg);
477             break;
478         }
479         case WIFI_AUDIO_STATE_CHANGED_NOTIFY_EVENT: {
480             ret = EXECUTED;
481             pStaStateMachine->DealAudioStateChangedEvent(msg);
482             break;
483         }
484         default:
485             WIFI_LOGD("InitState-msgCode=%d not handled.\n", msg->GetMessageName());
486             break;
487     }
488     return ret;
489 }
490 
491 void StaStateMachine::InitState::SaveFoldStatus(InternalMessagePtr msg)
492 {
493     if (msg == nullptr) {
494         WIFI_LOGE("SaveFoldStatus, msg is nullptr");
495         return;
496     }
497     pStaStateMachine->foldStatus_ = msg->GetParam1();
498 }
499 
500 void StaStateMachine::InitState::HandleNetworkConnectionEvent(InternalMessagePtr msg)
501 {
502     if (msg == nullptr) {
503         WIFI_LOGE("HandleNetWorkConnectionEvent, msg is nullptr.\n");
504         return;
505     }
506     WIFI_LOGI("enter HandleNetWorkConnectionEvent m_instId = %{public}d", pStaStateMachine->m_instId);
507     std::string bssid = msg->GetStringFromMessage();
508     pStaStateMachine->StopTimer(static_cast<int>(CMD_NETWORK_CONNECT_TIMEOUT));
509     if (pStaStateMachine->m_hilinkFlag) {
510         pStaStateMachine->HilinkSaveConfig();
511     }
512     WifiDeviceConfig deviceConfig;
513     int networkId = pStaStateMachine->targetNetworkId_;
514     int instId = pStaStateMachine->m_instId;
515     if (networkId == INVALID_NETWORK_ID ||
516         WifiSettings::GetInstance().GetDeviceConfig(networkId, deviceConfig, instId) != 0) {
517         WIFI_LOGE("%{public}s can not find config for networkId = %{public}d", __FUNCTION__, networkId);
518         WifiStaHalInterface::GetInstance().Disconnect(WifiConfigCenter::GetInstance().GetStaIfaceName(instId));
519         pStaStateMachine->SwitchState(pStaStateMachine->pSeparatedState);
520         return;
521     }
522     if (pStaStateMachine->CurrentIsRandomizedMac()) {
523         WifiSettings::GetInstance().SetDeviceRandomizedMacSuccessEver(networkId);
524     }
525     /* Save linkedinfo */
526     pStaStateMachine->linkedInfo.networkId = pStaStateMachine->targetNetworkId_;
527     pStaStateMachine->AfterApLinkedprocess(bssid);
528     WifiConfigCenter::GetInstance().SaveLinkedInfo(pStaStateMachine->linkedInfo, pStaStateMachine->m_instId);
529     pStaStateMachine->lastSignalLevel_ = INVALID_SIGNAL_LEVEL;   // Reset signal level when first start signal poll
530     pStaStateMachine->DealSignalPollResult();
531 
532     #ifndef OHOS_ARCH_LITE
533     pStaStateMachine->SaveWifiConfigForUpdate(pStaStateMachine->targetNetworkId_);
534     pStaStateMachine->UpdateLinkedInfoFromScanInfo();
535     pStaStateMachine->SetSupportedWifiCategory();
536     #endif
537     pStaStateMachine->DealMloConnectionLinkInfo();
538     WifiConfigCenter::GetInstance().SetUserLastSelectedNetworkId(INVALID_NETWORK_ID, pStaStateMachine->m_instId);
539 
540     pStaStateMachine->mConnectFailedCnt = 0;
541     /* The current state of StaStateMachine transfers to GetIpState. */
542     pStaStateMachine->SwitchState(pStaStateMachine->pGetIpState);
543 }
544 
545 void StaStateMachine::InitState::UpdateCountryCode(InternalMessagePtr msg)
546 {
547 #ifndef OHOS_ARCH_LITE
548     std::string wifiCountryCode = msg->GetStringFromMessage();
549     if (wifiCountryCode.empty()) {
550         return;
551     }
552     WifiErrorNo result = WifiSupplicantHalInterface::GetInstance().WpaSetCountryCode(wifiCountryCode);
553     if (result == WifiErrorNo::WIFI_HAL_OPT_OK) {
554         WIFI_LOGI("update wifi country code sucess, wifiCountryCode=%{public}s", wifiCountryCode.c_str());
555         return;
556     }
557     WIFI_LOGE("update wifi country code fail, wifiCountryCode=%{public}s, ret=%{public}d",
558         wifiCountryCode.c_str(), result);
559 #endif
560 }
561 
562 bool StaStateMachine::InitState::AllowAutoConnect()
563 {
564     if (pStaStateMachine->linkedInfo.connState == ConnState::CONNECTING || pStaStateMachine->isCurrentRoaming_) {
565         return false;
566     }
567     if (pStaStateMachine->linkedInfo.supplicantState == SupplicantState::ASSOCIATING ||
568         pStaStateMachine->linkedInfo.supplicantState == SupplicantState::ASSOCIATED ||
569         pStaStateMachine->linkedInfo.supplicantState == SupplicantState::AUTHENTICATING ||
570         pStaStateMachine->linkedInfo.supplicantState == SupplicantState::FOUR_WAY_HANDSHAKE ||
571         pStaStateMachine->linkedInfo.supplicantState == SupplicantState::GROUP_HANDSHAKE) {
572         return false;
573     }
574 
575     if (pStaStateMachine->m_hilinkFlag) {
576         WIFI_LOGI("HiLink is active, refuse auto connect\n");
577         return false;
578     }
579     return true;
580 }
581 
582 #ifdef FEATURE_WIFI_MDM_RESTRICTED_SUPPORT
583 bool StaStateMachine::InitState::RestrictedByMdm(WifiDeviceConfig &config)
584 {
585     WIFI_LOGI("Enter RestrictedByMdm");
586     if (WifiSettings::GetInstance().FindWifiBlockListConfig(config.ssid, config.bssid, 0)) {
587         pStaStateMachine->DealMdmRestrictedConnect(config);
588         return true;
589     }
590     if (!WifiSettings::GetInstance().WhetherSetWhiteListConfig() || config.bssid.empty()) {
591         return false;
592     }
593     if (!WifiSettings::GetInstance().FindWifiWhiteListConfig(config.ssid, config.bssid, 0)) {
594         pStaStateMachine->DealMdmRestrictedConnect(config);
595         return true;
596     }
597     return false;
598 }
599 #endif
600 
601 void StaStateMachine::InitState::DealHiddenSsidConnectMiss(int networkId) {
602     WifiLinkedInfo linkInfo = pStaStateMachine->linkedInfo;
603     linkInfo.networkId = networkId;
604     pStaStateMachine->InvokeOnStaConnChanged(OperateResState::CONNECT_MISS_MATCH, linkInfo);
605     WifiSettings::GetInstance().SetUserConnectChoice(networkId);
606 }
607 
608 void StaStateMachine::InitState::StartConnectEvent(InternalMessagePtr msg)
609 {
610     WIFI_LOGI("enter StartConnectEvent m_instId = %{public}d\n", pStaStateMachine->m_instId);
611     if (msg == nullptr) {
612         WIFI_LOGE("msg is null.\n");
613         return;
614     }
615     int networkId = msg->GetParam1();
616     int connTriggerMode = msg->GetParam2();
617     auto bssid = msg->GetStringFromMessage();
618 
619     if (NotAllowConnectToNetwork(networkId, bssid, connTriggerMode)) {
620         return;
621     }
622 
623     if (pStaStateMachine->StartConnectToNetwork(networkId, bssid, connTriggerMode) != WIFI_OPT_SUCCESS) {
624         WIFI_LOGE("Connect to network failed: %{public}d.\n", networkId);
625         pStaStateMachine->SaveLinkstate(ConnState::DISCONNECTED, DetailedState::FAILED);
626         pStaStateMachine->InvokeOnStaConnChanged(OperateResState::CONNECT_ENABLE_NETWORK_FAILED,
627             pStaStateMachine->linkedInfo);
628         pStaStateMachine->SwitchState(pStaStateMachine->pSeparatedState);
629         return;
630     }
631     pStaStateMachine->SwitchState(pStaStateMachine->pApLinkingState);
632     return;
633 }
634 
635 bool StaStateMachine::InitState::NotAllowConnectToNetwork(int networkId, const std::string& bssid, int connTriggerMode)
636 {
637     if (networkId == pStaStateMachine->targetNetworkId_) {
638         WIFI_LOGI("This network is connecting and does not need to be reconnected m_instId = %{public}d",
639             pStaStateMachine->m_instId);
640         return true;
641     }
642 
643     WifiDeviceConfig config;
644     if (WifiSettings::GetInstance().GetDeviceConfig(networkId, config, pStaStateMachine->m_instId) != 0) {
645         WIFI_LOGE("GetDeviceConfig failed, networkId = %{public}d", networkId);
646         return true;
647     }
648 
649     if (networkId == pStaStateMachine->linkedInfo.networkId && connTriggerMode != NETWORK_SELECTED_BY_SELFCURE) {
650         WIFI_LOGI("This network is connected and does not need to be reconnected m_instId = %{public}d",
651             pStaStateMachine->m_instId);
652         return true;
653     }
654 
655     if (connTriggerMode == NETWORK_SELECTED_BY_AUTO && !AllowAutoConnect()) {
656         WIFI_LOGI("SupplicantState is TransientState, refuse auto connect");
657         return true;
658     }
659 
660     if (config.hiddenSSID && NotExistInScanList(config)) {
661         DealHiddenSsidConnectMiss(networkId);
662         return true;
663     }
664 
665 #ifdef FEATURE_WIFI_MDM_RESTRICTED_SUPPORT
666     if (pStaStateMachine->WhetherRestrictedByMdm(config.ssid, config.bssid, !config.bssid.empty())) {
667         WIFI_LOGI("NotAllowConnectToNetwork, RestrictedByMdm");
668         BlockConnectService::GetInstance().UpdateNetworkSelectStatus(config.networkId,
669             DisabledReason::DISABLED_MDM_RESTRICTED);
670         return true;
671     }
672 #endif
673 
674     return false;
675 }
676 
677 bool StaStateMachine::InitState::NotExistInScanList(WifiDeviceConfig &config)
678 {
679     WIFI_LOGI("NotExistInScanList, networkId = %{public}d, ssid = %{public}s, km = %{public}s.",
680         config.networkId, SsidAnonymize(config.ssid).c_str(), (config.keyMgmt).c_str());
681     std::vector<WifiScanInfo> scanInfoList;
682     WifiConfigCenter::GetInstance().GetWifiScanConfig()->GetScanInfoList(scanInfoList);
683     std::string scanMgmt = "";
684     for (auto item : scanInfoList) {
685         item.GetDeviceMgmt(scanMgmt);
686         if (item.ssid == config.ssid && WifiSettings::GetInstance().InKeyMgmtBitset(config, scanMgmt)) {
687             return false;
688         }
689     }
690     return true;
691 }
692 
693 void StaStateMachine::InitState::DealScreenStateChangedEvent(InternalMessagePtr msg)
694 {
695     if (msg == nullptr) {
696         WIFI_LOGE("DealScreenStateChangedEvent InternalMessage msg is null.");
697         return;
698     }
699 
700     int screenState = msg->GetParam1();
701     WIFI_LOGI("InitState::DealScreenStateChangedEvent, Receive msg: screenState=%{public}d", screenState);
702     if (screenState == MODE_STATE_OPEN) {
703         pStaStateMachine->enableSignalPoll = true;
704     } else {
705         if (pStaStateMachine->isAudioOn_ == AUDIO_OFF) {
706             pStaStateMachine->enableSignalPoll = false;
707         } else {
708             pStaStateMachine->enableSignalPoll = true;
709         }
710     }
711 }
712 
713 /* --------------------------- state machine link State ------------------------------ */
714 StaStateMachine::LinkState::LinkState(StaStateMachine *staStateMachine)
715     : State("LinkState"), pStaStateMachine(staStateMachine)
716 {
717     InitStaSMHandleMap();
718 }
719 
720 StaStateMachine::LinkState::~LinkState()
721 {}
722 
723 void StaStateMachine::LinkState::GoInState()
724 {
725     WIFI_LOGI("LinkState GoInState function.");
726     int result = pStaStateMachine->RegisterDhcpCallBack();
727     if (result != WIFI_OPT_SUCCESS) {
728         WIFI_LOGE("Register dhcp callback failed, result = %{public}d", result);
729         return;
730     }
731     RouterConfig routerConfig;
732     routerConfig.bIpv6 = true;
733     routerConfig.bIpv4 = false;
734     std::string ifaceName = WifiConfigCenter::GetInstance().GetStaIfaceName(pStaStateMachine->m_instId);
735     if (strncpy_s(routerConfig.ifname, sizeof(routerConfig.ifname), ifaceName.c_str(), ifaceName.length()) < 0) {
736         WIFI_LOGE("LinkState GoInState, copy ifaceName failed");
737         return;
738     }
739     StartDhcpClient(routerConfig);
740     return;
741 }
742 
743 void StaStateMachine::LinkState::GoOutState()
744 {
745     WIFI_LOGI("LinkState GoOutState function.");
746     pStaStateMachine->linkedInfo.supplicantState = SupplicantState::DISCONNECTED;
747     return;
748 }
749 
750 bool StaStateMachine::LinkState::ExecuteStateMsg(InternalMessagePtr msg)
751 {
752     if (msg == nullptr) {
753         return false;
754     }
755     WIFI_LOGD("LinkState ExecuteStateMsg function:msgName=[%{public}d]. m_instId=%{public}d\n",
756         msg->GetMessageName(), pStaStateMachine->m_instId);
757     auto iter = staSmHandleFuncMap.find(msg->GetMessageName());
758     if (iter != staSmHandleFuncMap.end()) {
759         (iter->second)(msg);
760         return EXECUTED;
761     }
762     return NOT_EXECUTED;
763 }
764 
765 /* -- state machine Connect State Message processing function -- */
766 int StaStateMachine::LinkState::InitStaSMHandleMap()
767 {
768     staSmHandleFuncMap[WIFI_SVR_CMD_STA_NETWORK_DISCONNECTION_EVENT] = [this](InternalMessagePtr msg) {
769         return this->DealDisconnectEventInLinkState(msg);
770     };
771     staSmHandleFuncMap[WIFI_SVR_CMD_STA_REASSOCIATE_NETWORK] = [this](InternalMessagePtr msg) {
772         return this->pStaStateMachine->DealReassociateCmd(msg);
773     };
774     staSmHandleFuncMap[WIFI_SCREEN_STATE_CHANGED_NOTIFY_EVENT] = [this](InternalMessagePtr msg) {
775         return this->pStaStateMachine->DealScreenStateChangedEvent(msg);
776     };
777 #ifndef OHOS_ARCH_LITE
778     staSmHandleFuncMap[WIFI_SVR_CMD_STA_WPA_EAP_SIM_AUTH_EVENT] = [this](InternalMessagePtr msg) {
779         return this->pStaStateMachine->DealWpaEapSimAuthEvent(msg);
780     };
781     staSmHandleFuncMap[WIFI_SVR_CMD_STA_WPA_EAP_UMTS_AUTH_EVENT] = [this](InternalMessagePtr msg) {
782         return this->pStaStateMachine->DealWpaEapUmtsAuthEvent(msg);
783     };
784 #ifdef EXTENSIBLE_AUTHENTICATION
785     staSmHandleFuncMap[WIFI_SVR_CMD_STA_WPA_EAP_CUSTOM_AUTH_EVENT] = [this](InternalMessagePtr msg) {
786         return this->DealWpaCustomEapAuthEvent(msg);
787     };
788 #endif
789 #endif
790     staSmHandleFuncMap[WIFI_SVR_CMD_STA_WPA_STATE_CHANGE_EVENT] = [this](InternalMessagePtr msg) {
791         return this->DealWpaStateChange(msg);
792     };
793     staSmHandleFuncMap[WIFI_SVR_CMD_STA_MLO_WORK_STATE_EVENT] = [this](InternalMessagePtr msg) {
794         return this->DealMloStateChange(msg);
795     };
796     staSmHandleFuncMap[WIFI_SVR_COM_STA_NETWORK_REMOVED] = [this](InternalMessagePtr msg) {
797         return this->DealNetworkRemoved(msg);
798     };
799     staSmHandleFuncMap[WIFI_SVR_CMD_STA_DISABLE_STA] = [this](InternalMessagePtr msg) {
800         return this->StopWifiProcessInLinkState(msg);
801     };
802     staSmHandleFuncMap[CMD_NETWORK_CONNECT_TIMEOUT] = [this](InternalMessagePtr msg) {
803         return this->DealConnectTimeOutCmd(msg);
804     };
805     return WIFI_OPT_SUCCESS;
806 }
807 
808 bool StaStateMachine::IsNewConnectionInProgress()
809 {
810     int currentLinkedId = linkedInfo.networkId;
811     int targetId = targetNetworkId_;
812     if (targetId == INVALID_NETWORK_ID) {
813         return false;
814     }
815     std::string targetSsid = "";
816     // Get the target network's SSID, can get empty result if it is hillink network
817     if (!m_hilinkFlag) {
818         WifiDeviceConfig config;
819         if (WifiSettings::GetInstance().GetDeviceConfig(targetId, config, m_instId) != 0) {
820             WIFI_LOGE("GetDeviceConfig failed, targetId = %{public}d", targetId);
821             return false;
822         }
823         targetSsid = config.ssid;
824     }
825 
826     // When connecting to another network while already connected, the old network will first
827     // disconnect before the new connection can begin.
828     bool isConnectingWhileAlreadyConnected =
829             currentLinkedId != INVALID_NETWORK_ID && currentLinkedId != targetId;
830     // 2 simultaneous connections happen back-to-back.
831     std::string disconnectingSsid = linkedInfo.ssid;
832     bool isConnectingToAnotherNetwork = (disconnectingSsid != targetSsid);
833     bool result = isConnectingWhileAlreadyConnected || isConnectingToAnotherNetwork;
834     WIFI_LOGI("Enter IsNewConnectionInProgress targetId = %{public}d currentLinkedId = %{public}d"
835         " disconnectingSsid = %{public}s, targetSsid = %{public}s, result = %{public}d",
836         targetId, currentLinkedId, SsidAnonymize(disconnectingSsid).c_str(),
837         SsidAnonymize(targetSsid).c_str(), static_cast<int>(result));
838     return result;
839 }
840 
841 void StaStateMachine::LinkState::DealWpaCustomEapAuthEvent(InternalMessagePtr msg)
842 {
843 #ifdef EXTENSIBLE_AUTHENTICATION
844     if (msg == nullptr) {
845         LOGE("%{public}s InternalMessage msg is null.", __func__);
846         return;
847     }
848 
849     WpaEapData wpaEapData = {0};
850     msg->GetMessageObj(wpaEapData);
851     NetEapObserver::GetInstance().NotifyWpaEapInterceptInfo(wpaEapData);
852     LOGI("%{public}s code=%{public}d, type=%{public}d, msgId:%{public}d success", __func__, wpaEapData.code,
853         wpaEapData.type, wpaEapData.msgId);
854 #endif
855 }
856 
857 void StaStateMachine::LinkState::DealDisconnectEventInLinkState(InternalMessagePtr msg)
858 {
859     if (msg == nullptr) {
860         WIFI_LOGE("msg is null");
861         return;
862     }
863     int reason = msg->GetParam1();
864     int locallyGenerated = msg->GetParam2();
865     std::string bssid = msg->GetStringFromMessage();
866     WIFI_LOGI("Enter DealDisconnectEventInLinkState m_instId = %{public}d reason:%{public}d, bssid:%{public}s",
867         pStaStateMachine->m_instId, reason, MacAnonymize(bssid).c_str());
868 
869     pStaStateMachine->mIsWifiInternetCHRFlag = false;
870 #ifndef OHOS_ARCH_LITE
871     if (pStaStateMachine->hasNoInternetDialog_) {
872         pStaStateMachine->CloseNoInternetDialog();
873     }
874 #endif
875     if (!WifiConfigCenter::GetInstance().GetWifiSelfcureReset()) {
876         WifiConfigCenter::GetInstance().SetWifiSelfcureResetEntered(false);
877     }
878     WifiChrUtils::GetInstance().ClearSignalPollInfoArray();
879     WriteWifiLinkTypeHiSysEvent(pStaStateMachine->linkedInfo.ssid, -1, "DISCONNECT");
880     if (!pStaStateMachine->IsNewConnectionInProgress()) {
881         bool shouldStopTimer = pStaStateMachine->IsDisConnectReasonShouldStopTimer(reason);
882         if (shouldStopTimer) {
883             pStaStateMachine->StopTimer(static_cast<int>(CMD_NETWORK_CONNECT_TIMEOUT));
884         }
885         int curNetworkId = (pStaStateMachine->linkedInfo.networkId == INVALID_NETWORK_ID) ?
886             pStaStateMachine->targetNetworkId_ : pStaStateMachine->linkedInfo.networkId;
887         BlockConnectService::GetInstance().UpdateNetworkSelectStatus(curNetworkId,
888             DisabledReason::DISABLED_DISASSOC_REASON, reason);
889         if (BlockConnectService::GetInstance().IsFrequentDisconnect(bssid, reason, locallyGenerated)) {
890             BlockConnectService::GetInstance().UpdateNetworkSelectStatus(curNetworkId,
891                 DisabledReason::DISABLED_CONSECUTIVE_FAILURES);
892         }
893         WriteWifiAbnormalDisconnectHiSysEvent(reason, locallyGenerated);
894         pStaStateMachine->SwitchState(pStaStateMachine->pSeparatedState);
895     } else { //connecting to another network while already connected
896         pStaStateMachine->mPortalUrl = "";
897         pStaStateMachine->StopDhcp(true, false);
898         pStaStateMachine->SaveLinkstate(ConnState::DISCONNECTED, DetailedState::DISCONNECTED);
899         pStaStateMachine->InvokeOnStaConnChanged(OperateResState::DISCONNECT_DISCONNECTED,
900             pStaStateMachine->linkedInfo);
901         pStaStateMachine->InitWifiLinkedInfo();
902         WifiConfigCenter::GetInstance().SaveLinkedInfo(pStaStateMachine->linkedInfo, pStaStateMachine->m_instId);
903     }
904     return;
905 }
906 
907 void StaStateMachine::LinkState::StopWifiProcessInLinkState(InternalMessagePtr msg)
908 {
909     WIFI_LOGI("Enter StaStateMachine::StopWifiProcessInLinkState m_instId = %{public}d\n", pStaStateMachine->m_instId);
910     WriteWifiLinkTypeHiSysEvent(pStaStateMachine->linkedInfo.ssid, -1, "DISCONNECT");
911     WifiStaHalInterface::GetInstance().Disconnect(
912         WifiConfigCenter::GetInstance().GetStaIfaceName(pStaStateMachine->m_instId));
913     pStaStateMachine->DelayMessage(msg);
914     pStaStateMachine->SwitchState(pStaStateMachine->pSeparatedState);
915 }
916 
917 void StaStateMachine::LinkState::DealNetworkRemoved(InternalMessagePtr msg)
918 {
919     if (msg == nullptr) {
920         WIFI_LOGE("DealNetworkRemoved InternalMessage msg is null.");
921         return;
922     }
923     int networkId = msg->GetParam1();
924     WIFI_LOGI("DealNetworkRemoved networkid = %{public}d linkinfo.networkid = %{public}d targetNetworkId_ = %{public}d",
925         networkId, pStaStateMachine->linkedInfo.networkId, pStaStateMachine->targetNetworkId_);
926     std::string ssid = pStaStateMachine->linkedInfo.ssid;
927     std::string bssid = pStaStateMachine->linkedInfo.bssid;
928     IpCacheInfo ipCacheInfo;
929     if ((strncpy_s(ipCacheInfo.bssid, MAC_ADDR_MAX_LEN, bssid.c_str(), bssid.length()) == EOK) &&
930         (strncpy_s(ipCacheInfo.ssid, SSID_MAX_LEN, ssid.c_str(), ssid.length()) == EOK)) {
931         DealWifiDhcpCache(WIFI_DHCP_CACHE_REMOVE, ipCacheInfo);
932     }
933     if (pStaStateMachine->linkedInfo.networkId == networkId || pStaStateMachine->targetNetworkId_ == networkId) {
934         std::string ifaceName = WifiConfigCenter::GetInstance().GetStaIfaceName(pStaStateMachine->m_instId);
935         WIFI_LOGI("Enter StartDisConnectToNetwork ifaceName:%{public}s!", ifaceName.c_str());
936         WifiStaHalInterface::GetInstance().Disconnect(ifaceName);
937     }
938     return;
939 }
940 void StaStateMachine::LinkState::DealWpaStateChange(InternalMessagePtr msg)
941 {
942     if (msg == nullptr) {
943         WIFI_LOGE("DealWpaStateChange InternalMessage msg is null.");
944         return;
945     }
946     int status = msg->GetParam1();
947     WIFI_LOGI("DealWpaStateChange status: %{public}d", status);
948     if (static_cast<SupplicantState>(status) == SupplicantState::ASSOCIATING) {
949         std::string ssid = msg->GetStringFromMessage();
950         if (ssid.length() != 0 && !WifiCodeConvertUtil::IsUtf8(ssid)) {
951             pStaStateMachine->linkedInfo.ssid = WifiCodeConvertUtil::GbkToUtf8(ssid);
952         } else {
953             pStaStateMachine->linkedInfo.ssid = ssid;
954         }
955         pStaStateMachine->InvokeOnStaConnChanged(OperateResState::CONNECT_ASSOCIATING, pStaStateMachine->linkedInfo);
956         WriteWifiOperateStateHiSysEvent(static_cast<int>(WifiOperateType::STA_ASSOC),
957             static_cast<int>(WifiOperateState::STA_ASSOCIATING));
958         WIFI_LOGI("DealWpaStateChange ASSOCIATING:ssid = %{public}s",
959             SsidAnonymize(pStaStateMachine->linkedInfo.ssid).c_str());
960     } else if (static_cast<SupplicantState>(status) == SupplicantState::ASSOCIATED) {
961         pStaStateMachine->InvokeOnStaConnChanged(OperateResState::CONNECT_ASSOCIATED, pStaStateMachine->linkedInfo);
962         WriteWifiOperateStateHiSysEvent(static_cast<int>(WifiOperateType::STA_ASSOC),
963             static_cast<int>(WifiOperateState::STA_ASSOCIATED));
964     }
965     pStaStateMachine->linkedInfo.supplicantState = static_cast<SupplicantState>(status);
966     WifiConfigCenter::GetInstance().SaveLinkedInfo(pStaStateMachine->linkedInfo, pStaStateMachine->m_instId);
967 }
968 
969 void StaStateMachine::LinkState::DealMloStateChange(InternalMessagePtr msg)
970 {
971     if (msg == nullptr) {
972         LOGE("DealMloStateChange InternalMessage msg is null.");
973         return;
974     }
975 
976     MloStateParam param = {0};
977     msg->GetMessageObj(param);
978     uint8_t feature = param.feature;
979     uint8_t state = param.state;
980     uint16_t reasonCode = param.reasonCode;
981     pStaStateMachine->DealSignalPollResult();
982     if (feature == CoFeatureType::COFEATURE_TYPE_MLO) {
983         if (pStaStateMachine->linkedInfo.wifiLinkType == WifiLinkType::WIFI7_EMLSR &&
984             static_cast<int32_t>(state) != WifiLinkType::WIFI7_EMLSR) {
985             pStaStateMachine->linkedInfo.wifiLinkType = static_cast<WifiLinkType>(state);
986             pStaStateMachine->InvokeOnStaConnChanged(OperateResState::CONNECT_EMLSR_END, pStaStateMachine->linkedInfo);
987             WriteEmlsrExitReasonHiSysEvent(pStaStateMachine->linkedInfo.ssid, static_cast<int>(reasonCode));
988         }
989         if (static_cast<int32_t>(state) == WifiLinkType::WIFI7_EMLSR) {
990             pStaStateMachine->linkedInfo.wifiLinkType = static_cast<WifiLinkType>(state);
991             pStaStateMachine->InvokeOnStaConnChanged(OperateResState::CONNECT_EMLSR_START,
992                 pStaStateMachine->linkedInfo);
993             pStaStateMachine->DealMloLinkSignalPollResult();
994         }
995         pStaStateMachine->linkedInfo.wifiLinkType = static_cast<WifiLinkType>(state);
996         WriteWifiLinkTypeHiSysEvent(pStaStateMachine->linkedInfo.ssid,
997             pStaStateMachine->linkedInfo.wifiLinkType, "MLO_STATE_CHANGED");
998 #ifndef OHOS_ARCH_LITE
999         if (pStaStateMachine->enhanceService_ != nullptr) {
1000             pStaStateMachine->enhanceService_->OnWifiLinkTypeChanged(pStaStateMachine->linkedInfo.wifiLinkType);
1001         }
1002 #endif
1003     }
1004     if (feature == CoFeatureType::COFEATURE_TYPE_WUR) {
1005         if (state == WurState::WUR_ENABLE) {
1006             pStaStateMachine->linkedInfo.isWurEnable = true;
1007         } else {
1008             pStaStateMachine->linkedInfo.isWurEnable = false;
1009         }
1010 #ifndef OHOS_ARCH_LITE
1011         if (pStaStateMachine->enhanceService_ != nullptr) {
1012             pStaStateMachine->enhanceService_->NotifyWurState(state, reasonCode);
1013         }
1014 #endif
1015     }
1016 
1017     LOGI("DealMloStateChange wifiLinkType=%{public}d isWurEnable=%{public}d reasonCode=%{public}u",
1018         pStaStateMachine->linkedInfo.wifiLinkType, pStaStateMachine->linkedInfo.isWurEnable, reasonCode);
1019     WifiConfigCenter::GetInstance().SaveLinkedInfo(pStaStateMachine->linkedInfo, pStaStateMachine->m_instId);
1020 }
1021 
1022 void StaStateMachine::LinkState::DealConnectTimeOutCmd(InternalMessagePtr msg)
1023 {
1024     WIFI_LOGW("enter DealConnectTimeOutCmd.\n");
1025     if (msg == nullptr) {
1026         WIFI_LOGE("msg is nul\n");
1027     }
1028     WriteAssocFailHiSysEvent("WPA_TIMEOUT");
1029     if (pStaStateMachine->targetNetworkId_ == pStaStateMachine->mLastConnectNetId) {
1030         pStaStateMachine->mConnectFailedCnt++;
1031     }
1032     pStaStateMachine->DealSetStaConnectFailedCount(1, false);
1033     WifiConfigCenter::GetInstance().SetConnectTimeoutBssid(pStaStateMachine->linkedInfo.bssid,
1034         pStaStateMachine->m_instId);
1035     pStaStateMachine->SaveDiscReason(DisconnectedReason::DISC_REASON_DEFAULT);
1036     pStaStateMachine->SaveLinkstate(ConnState::DISCONNECTED, DetailedState::CONNECTION_TIMEOUT);
1037     pStaStateMachine->InvokeOnStaConnChanged(OperateResState::CONNECT_CONNECTING_TIMEOUT, pStaStateMachine->linkedInfo);
1038     pStaStateMachine->SwitchState(pStaStateMachine->pSeparatedState);
1039 }
1040 
1041 void StaStateMachine::StopDhcp(bool isStopV4, bool isStopV6)
1042 {
1043     std::string ifname = WifiConfigCenter::GetInstance().GetStaIfaceName(m_instId);
1044     StopTimer(static_cast<int>(CMD_START_NETCHECK));
1045     WIFI_LOGI("StopDhcp, isStopV4: %{public}d, isStopV6: %{public}d", isStopV4, isStopV6);
1046     pDhcpResultNotify->Clear();
1047     if (isStopV4) {
1048         StopDhcpClient(ifname.c_str(), false, true);
1049         IpInfo ipInfo;
1050         WifiConfigCenter::GetInstance().SaveIpInfo(ipInfo, m_instId);
1051 #ifdef OHOS_ARCH_LITE
1052         IfConfig::GetInstance().FlushIpAddr(WifiConfigCenter::GetInstance().GetStaIfaceName(m_instId), IPTYPE_IPV4);
1053 #endif
1054         getIpSucNum = 0;
1055         getIpFailNum = 0;
1056     }
1057     if (isStopV6) {
1058         StopDhcpClient(ifname.c_str(), true, false);
1059         IpV6Info ipV6Info;
1060         WifiConfigCenter::GetInstance().SaveIpV6Info(ipV6Info, m_instId);
1061     }
1062 
1063 #ifndef OHOS_ARCH_LITE
1064     if (NetSupplierInfo != nullptr) {
1065         NetSupplierInfo->isAvailable_ = false;
1066         NetSupplierInfo->ident_ = "";
1067         WIFI_LOGI("On disconnect update net supplier info\n");
1068         WifiNetAgent::GetInstance().OnStaMachineUpdateNetSupplierInfo(NetSupplierInfo, m_instId);
1069     }
1070 #endif
1071     HandlePostDhcpSetup();
1072 }
1073 
1074 bool StaStateMachine::SetRandomMac(WifiDeviceConfig &deviceConfig, const std::string &bssid)
1075 {
1076 #ifdef SUPPORT_LOCAL_RANDOM_MAC
1077     std::string currentMac, realMac;
1078     WifiSettings::GetInstance().GetRealMacAddress(realMac, m_instId);
1079     if (deviceConfig.wifiPrivacySetting == WifiPrivacyConfig::DEVICEMAC || ShouldUseFactoryMac(deviceConfig)) {
1080         currentMac = realMac;
1081     } else {
1082         WifiStoreRandomMac randomMacInfo;
1083         InitRandomMacInfo(deviceConfig, bssid, randomMacInfo);
1084         if (randomMacInfo.peerBssid.empty()) {
1085             LOGI("scanInfo has no target wifi and bssid is empty!");
1086         }
1087         if (!MacAddress::IsValidMac(deviceConfig.macAddress) || deviceConfig.macAddress == realMac) {
1088             WifiSettings::GetInstance().GetRandomMac(randomMacInfo);
1089             if (MacAddress::IsValidMac(randomMacInfo.randomMac) && randomMacInfo.randomMac != realMac) {
1090                 currentMac = randomMacInfo.randomMac;
1091             } else {
1092                 SetRandomMacConfig(randomMacInfo, deviceConfig, currentMac);
1093                 WifiSettings::GetInstance().AddRandomMac(randomMacInfo);
1094             }
1095         } else if (IsPskEncryption(deviceConfig.keyMgmt)) {
1096             WifiSettings::GetInstance().GetRandomMac(randomMacInfo);
1097             if (MacAddress::IsValidMac(randomMacInfo.randomMac) && randomMacInfo.randomMac != realMac) {
1098                 currentMac = randomMacInfo.randomMac;
1099             } else {
1100                 randomMacInfo.randomMac = deviceConfig.macAddress;
1101                 currentMac = randomMacInfo.randomMac;
1102                 WifiSettings::GetInstance().AddRandomMac(randomMacInfo);
1103             }
1104         } else {
1105             currentMac = deviceConfig.macAddress;
1106         }
1107     }
1108     if (!SetMacToHal(currentMac, realMac, m_instId)) {
1109         return false;
1110     }
1111     deviceConfig.macAddress = currentMac;
1112     deviceConfig.wifiPrivacySetting =
1113         (currentMac == realMac) ? WifiPrivacyConfig::DEVICEMAC : WifiPrivacyConfig::RANDOMMAC;
1114     WifiSettings::GetInstance().AddDeviceConfig(deviceConfig);
1115     WifiSettings::GetInstance().SyncDeviceConfig();
1116     LOGI("SetRandomMac wifiPrivacySetting:%{public}d,ssid:%{public}s,keyMgmt:%{public}s,macAddress:%{public}s",
1117         deviceConfig.wifiPrivacySetting, SsidAnonymize(deviceConfig.ssid).c_str(), deviceConfig.keyMgmt.c_str(),
1118         MacAnonymize(deviceConfig.macAddress).c_str());
1119 #endif
1120     return true;
1121 }
1122 
1123 /* --------------------------- state machine Disconnected State ------------------------------ */
1124 StaStateMachine::SeparatedState::SeparatedState(StaStateMachine *staStateMachine)
1125     : State("SeparatedState"), pStaStateMachine(staStateMachine)
1126 {}
1127 
1128 StaStateMachine::SeparatedState::~SeparatedState()
1129 {}
1130 
1131 void StaStateMachine::SeparatedState::GoInState()
1132 {
1133     pStaStateMachine->SetConnectMethod(NETWORK_SELECTED_BY_UNKNOWN);
1134     pStaStateMachine->StopTimer(static_cast<int>(CMD_SIGNAL_POLL));
1135     std::string ifname = WifiConfigCenter::GetInstance().GetStaIfaceName(pStaStateMachine->m_instId);
1136 #ifndef OHOS_ARCH_LITE
1137 #ifdef WIFI_DATA_REPORT_ENABLE
1138     pStaStateMachine->wifiDataReportService_->ReportApConnEventInfo(ConnReportReason::CONN_DISCONNECTED,
1139         pStaStateMachine->linkedInfo.networkId);
1140 #endif
1141 #endif
1142     pStaStateMachine->StopDhcp(true, true);
1143     pStaStateMachine->isRoam = false;
1144     pStaStateMachine->mPortalUrl = "";
1145     /* Callback result to InterfaceService. */
1146     pStaStateMachine->SaveLinkstate(ConnState::DISCONNECTED, DetailedState::DISCONNECTED);
1147     pStaStateMachine->InvokeOnStaConnChanged(OperateResState::DISCONNECT_DISCONNECTED, pStaStateMachine->linkedInfo);
1148     pStaStateMachine->InvokeOnStaConnChanged(OperateResState::CONNECT_EMLSR_END, pStaStateMachine->linkedInfo);
1149     /* clear connection information. */
1150     pStaStateMachine->InitWifiLinkedInfo();
1151     pStaStateMachine->targetNetworkId_ = INVALID_NETWORK_ID;
1152     pStaStateMachine->linkSwitchDetectingFlag_ = false;
1153 #ifdef FEATURE_SELF_CURE_SUPPORT
1154     if ((pStaStateMachine->selfCureService_ != nullptr &&
1155         !pStaStateMachine->selfCureService_->IsSelfCureL2Connecting())) {
1156         pStaStateMachine->noInternetAccessCnt_ = 0;
1157         pStaStateMachine->StopTimer(CMD_NO_INTERNET_TIMEOUT);
1158     }
1159 #endif
1160     WifiConfigCenter::GetInstance().SaveLinkedInfo(pStaStateMachine->linkedInfo, pStaStateMachine->m_instId);
1161     WifiConfigCenter::GetInstance().SetMacAddress("", pStaStateMachine->m_instId);
1162     WriteIsInternetHiSysEvent(DISCONNECTED_NETWORK);
1163     WIFI_LOGI("SeparatedState GoInState function.");
1164     return;
1165 }
1166 
1167 void StaStateMachine::SeparatedState::GoOutState()
1168 {
1169     WIFI_LOGI("SeparatedState GoOutState function.");
1170     return;
1171 }
1172 
1173 bool StaStateMachine::SeparatedState::ExecuteStateMsg(InternalMessagePtr msg)
1174 {
1175     if (msg == nullptr) {
1176         return false;
1177     }
1178 
1179     WIFI_LOGI("SeparatedState-msgCode=%{public}d received. m_instId=%{public}d\n", msg->GetMessageName(),
1180         pStaStateMachine->m_instId);
1181     bool ret = NOT_EXECUTED;
1182     switch (msg->GetMessageName()) {
1183         case WIFI_SVR_CMD_STA_NETWORK_DISCONNECTION_EVENT: {
1184             ret = EXECUTED;
1185             break;
1186         }
1187         case WIFI_SVR_CMD_STA_ENABLE_STA: {
1188             ret = EXECUTED;
1189             WIFI_LOGE("Wifi has already started!");
1190             break;
1191         }
1192         case WIFI_SVR_CMD_STA_DISABLE_STA: {
1193             pStaStateMachine->DelayMessage(msg);
1194             pStaStateMachine->SwitchState(pStaStateMachine->pClosedState);
1195             ret = EXECUTED;
1196             break;
1197         }
1198         case WIFI_SVR_CMD_STA_RECONNECT_NETWORK: {
1199             ret = EXECUTED;
1200             DealReConnectCmdInSeparatedState(msg);
1201             break;
1202         }
1203         case WIFI_SCREEN_STATE_CHANGED_NOTIFY_EVENT: {
1204             ret = EXECUTED;
1205             pStaStateMachine->DealScreenStateChangedEvent(msg);
1206             break;
1207         }
1208         default:
1209             break;
1210     }
1211 
1212     return ret;
1213 }
1214 
1215 void StaStateMachine::SeparatedState::DealReConnectCmdInSeparatedState(InternalMessagePtr msg)
1216 {
1217     WIFI_LOGI("enter DealReConnectCmdInSeparatedState.\n");
1218     if (msg == nullptr) {
1219         WIFI_LOGE("msg is null\n");
1220     }
1221     pStaStateMachine->targetNetworkId_ = pStaStateMachine->mLastConnectNetId;
1222     if (WifiStaHalInterface::GetInstance().Reconnect() == WIFI_HAL_OPT_OK) {
1223         pStaStateMachine->DealSetStaConnectFailedCount(0, true);
1224         WIFI_LOGI("StaStateMachine ReConnect successfully!");
1225         pStaStateMachine->SwitchState(pStaStateMachine->pApLinkingState);
1226     } else {
1227         pStaStateMachine->DealSetStaConnectFailedCount(1, false);
1228         WIFI_LOGE("ReConnect failed!");
1229     }
1230 }
1231 
1232 
1233 /* --------------------------- state machine ApConnecting State ------------------------------ */
1234 StaStateMachine::ApLinkingState::ApLinkingState(StaStateMachine *staStateMachine)
1235     : State("ApLinkingState"), pStaStateMachine(staStateMachine)
1236 {}
1237 
1238 StaStateMachine::ApLinkingState::~ApLinkingState()
1239 {}
1240 
1241 void StaStateMachine::ApLinkingState::GoInState()
1242 {
1243     WIFI_LOGI("ApLinkingState GoInState function.");
1244     pStaStateMachine->StopTimer(static_cast<int>(CMD_NETWORK_CONNECT_TIMEOUT));
1245     pStaStateMachine->StartTimer(static_cast<int>(CMD_NETWORK_CONNECT_TIMEOUT), STA_NETWORK_CONNECTTING_DELAY);
1246     pStaStateMachine->SaveDiscReason(DisconnectedReason::DISC_REASON_DEFAULT);
1247     pStaStateMachine->SaveLinkstate(ConnState::CONNECTING, DetailedState::CONNECTING);
1248     pStaStateMachine->networkStatusHistoryInserted = false;
1249     pStaStateMachine->InvokeOnStaConnChanged(OperateResState::CONNECT_CONNECTING, pStaStateMachine->linkedInfo);
1250     WriteWifiOperateStateHiSysEvent(static_cast<int>(WifiOperateType::STA_CONNECT),
1251         static_cast<int>(WifiOperateState::STA_CONNECTING));
1252     return;
1253 }
1254 
1255 void StaStateMachine::ApLinkingState::GoOutState()
1256 {
1257     WIFI_LOGI("ApLinkingState GoOutState function.");
1258     return;
1259 }
1260 
1261 bool StaStateMachine::ApLinkingState::ExecuteStateMsg(InternalMessagePtr msg)
1262 {
1263     if (msg == nullptr) {
1264         return false;
1265     }
1266 
1267     WIFI_LOGD("ApLinkingState-msgCode=%{public}d received. m_instId = %{public}d\n", msg->GetMessageName(),
1268         pStaStateMachine->m_instId);
1269     bool ret = NOT_EXECUTED;
1270     switch (msg->GetMessageName()) {
1271         case WIFI_SVR_CMD_STA_DISCONNECT: {
1272             ret = EXECUTED;
1273             pStaStateMachine->StartDisConnectToNetwork();
1274             break;
1275         }
1276         case WIFI_SVR_CMD_STA_BSSID_CHANGED_EVENT: {
1277             ret = EXECUTED;
1278             HandleStaBssidChangedEvent(msg);
1279             break;
1280         }
1281         case WIFI_SVR_CMD_STA_WPA_PASSWD_WRONG_EVENT:
1282         case WIFI_SVR_CMD_STA_WPA_FULL_CONNECT_EVENT:
1283         case WIFI_SVR_CMD_STA_WPA_ASSOC_REJECT_EVENT: {
1284             ret = EXECUTED;
1285             DealWpaLinkFailEvent(msg);
1286             break;
1287         }
1288         default:
1289             break;
1290     }
1291     return ret;
1292 }
1293 
1294 void StaStateMachine::ApLinkingState::HandleStaBssidChangedEvent(InternalMessagePtr msg)
1295 {
1296     std::string reason = msg->GetStringFromMessage();
1297     std::string bssid = msg->GetStringFromMessage();
1298     WIFI_LOGI("ApLinkingState reveived bssid changed event, reason:%{public}s,bssid:%{public}s.\n",
1299         reason.c_str(), MacAnonymize(bssid).c_str());
1300     if (strcmp(reason.c_str(), "ASSOC_COMPLETE") != 0) {
1301         WIFI_LOGE("Bssid change not for ASSOC_COMPLETE, do nothing.");
1302         return;
1303     }
1304     pStaStateMachine->linkedInfo.bssid = bssid;
1305     pStaStateMachine->UpdateHiLinkAttribute();
1306 #ifndef OHOS_ARCH_LITE
1307     pStaStateMachine->SetSupportedWifiCategory();
1308 #endif
1309     pStaStateMachine->DealMloConnectionLinkInfo();
1310     WifiConfigCenter::GetInstance().SaveLinkedInfo(pStaStateMachine->linkedInfo, pStaStateMachine->m_instId);
1311     /* BSSID change is not received during roaming, only set BSSID */
1312     if (WifiStaHalInterface::GetInstance().SetBssid(WPA_DEFAULT_NETWORKID, bssid,
1313         WifiConfigCenter::GetInstance().GetStaIfaceName(pStaStateMachine->m_instId)) != WIFI_HAL_OPT_OK) {
1314         WIFI_LOGE("SetBssid return fail.");
1315     }
1316 }
1317 
1318 void StaStateMachine::ApLinkingState::DealWpaLinkPasswdWrongFailEvent(InternalMessagePtr msg)
1319 {
1320     std::string bssid = msg->GetStringFromMessage();
1321     WIFI_LOGI("ApLinkingState reveived wpa passwd wrong event, bssid:%{public}s.\n", MacAnonymize(bssid).c_str());
1322     if (bssid != "") {
1323         pStaStateMachine->linkedInfo.bssid = bssid;
1324     }
1325     pStaStateMachine->SaveDiscReason(DisconnectedReason::DISC_REASON_WRONG_PWD);
1326     pStaStateMachine->SaveLinkstate(ConnState::DISCONNECTED, DetailedState::PASSWORD_ERROR);
1327     if (BlockConnectService::GetInstance().IsWrongPassword(pStaStateMachine->targetNetworkId_)) {
1328         BlockConnectService::GetInstance().UpdateNetworkSelectStatus(pStaStateMachine->targetNetworkId_,
1329             DisabledReason::DISABLED_BY_WRONG_PASSWORD);
1330 #ifndef OHOS_ARCH_LITE
1331 #ifdef WIFI_DATA_REPORT_ENABLE
1332         pStaStateMachine->wifiDataReportService_->ReportApConnEventInfo(ConnReportReason::CONN_WRONG_PASSWORD,
1333             pStaStateMachine->targetNetworkId_);
1334 #endif
1335 #endif
1336     } else {
1337         BlockConnectService::GetInstance().UpdateNetworkSelectStatus(pStaStateMachine->targetNetworkId_,
1338             DisabledReason::DISABLED_AUTHENTICATION_FAILURE);
1339 #ifndef OHOS_ARCH_LITE
1340 #ifdef WIFI_DATA_REPORT_ENABLE
1341         pStaStateMachine->wifiDataReportService_->ReportApConnEventInfo(ConnReportReason::CONN_AUTHENTICATION_FAILURE,
1342             pStaStateMachine->targetNetworkId_);
1343 #endif
1344 #endif
1345     }
1346 #ifndef OHOS_ARCH_LITE
1347     BlockConnectService::GetInstance().NotifyWifiConnFailedInfo(pStaStateMachine->targetNetworkId_,
1348         pStaStateMachine->linkedInfo.bssid, DisabledReason::DISABLED_AUTHENTICATION_FAILURE);
1349 #endif
1350     pStaStateMachine->InvokeOnStaConnChanged(OperateResState::CONNECT_PASSWORD_WRONG,
1351         pStaStateMachine->linkedInfo);
1352     return;
1353 }
1354 
1355 void StaStateMachine::ApLinkingState::DealWpaLinkFullConnectFailEvent(InternalMessagePtr msg)
1356 {
1357     pStaStateMachine->SaveDiscReason(DisconnectedReason::DISC_REASON_CONNECTION_FULL);
1358     pStaStateMachine->SaveLinkstate(ConnState::DISCONNECTED, DetailedState::CONNECTION_FULL);
1359     BlockConnectService::GetInstance().UpdateNetworkSelectStatus(pStaStateMachine->targetNetworkId_,
1360         DisabledReason::DISABLED_ASSOCIATION_REJECTION);
1361 #ifndef OHOS_ARCH_LITE
1362 #ifdef WIFI_DATA_REPORT_ENABLE
1363     pStaStateMachine->wifiDataReportService_->ReportApConnEventInfo(ConnReportReason::CONN_ASSOCIATION_FULL,
1364         pStaStateMachine->targetNetworkId_);
1365 #endif
1366 #endif
1367     pStaStateMachine->AddRandomMacCure();
1368     pStaStateMachine->InvokeOnStaConnChanged(OperateResState::CONNECT_CONNECTION_FULL,
1369         pStaStateMachine->linkedInfo);
1370     return;
1371 }
1372 
1373 void StaStateMachine::ApLinkingState::DealWpaLinkAssocRejectFailEvent(InternalMessagePtr msg)
1374 {
1375     pStaStateMachine->linkedInfo.bssid = msg->GetStringFromMessage();
1376     pStaStateMachine->SaveDiscReason(DisconnectedReason::DISC_REASON_CONNECTION_REJECTED);
1377     pStaStateMachine->SaveLinkstate(ConnState::DISCONNECTED, DetailedState::CONNECTION_REJECT);
1378     BlockConnectService::GetInstance().UpdateNetworkSelectStatus(pStaStateMachine->targetNetworkId_,
1379         DisabledReason::DISABLED_ASSOCIATION_REJECTION);
1380 #ifndef OHOS_ARCH_LITE
1381     BlockConnectService::GetInstance().NotifyWifiConnFailedInfo(pStaStateMachine->targetNetworkId_,
1382         pStaStateMachine->linkedInfo.bssid, DisabledReason::DISABLED_ASSOCIATION_REJECTION);
1383 #ifdef WIFI_DATA_REPORT_ENABLE
1384     pStaStateMachine->wifiDataReportService_->ReportApConnEventInfo(ConnReportReason::CONN_ASSOCIATION_REJECTION,
1385         pStaStateMachine->targetNetworkId_);
1386 #endif
1387 #endif
1388     pStaStateMachine->AddRandomMacCure();
1389     pStaStateMachine->InvokeOnStaConnChanged(OperateResState::CONNECT_CONNECTION_REJECT,
1390         pStaStateMachine->linkedInfo);
1391     return;
1392 }
1393 
1394 void StaStateMachine::ApLinkingState::DealWpaLinkFailEvent(InternalMessagePtr msg)
1395 {
1396     WIFI_LOGW("enter DealWpaLinkFailEvent.\n");
1397     if (msg == nullptr) {
1398         WIFI_LOGE("msg is null.\n");
1399         return;
1400     }
1401     if (pStaStateMachine->IsNewConnectionInProgress()) {
1402         return;
1403     }
1404     pStaStateMachine->DealSetStaConnectFailedCount(1, false);
1405     int eventName = msg->GetMessageName();
1406     std::string ifaceName = WifiConfigCenter::GetInstance().GetStaIfaceName(pStaStateMachine->m_instId);
1407     switch (eventName) {
1408         case WIFI_SVR_CMD_STA_WPA_PASSWD_WRONG_EVENT:
1409             DealWpaLinkPasswdWrongFailEvent(msg);
1410             break;
1411         case WIFI_SVR_CMD_STA_WPA_FULL_CONNECT_EVENT:
1412             DealWpaLinkFullConnectFailEvent(msg);
1413             break;
1414         case WIFI_SVR_CMD_STA_WPA_ASSOC_REJECT_EVENT:
1415             DealWpaLinkAssocRejectFailEvent(msg);
1416             break;
1417         default:
1418             WIFI_LOGW("DealWpaLinkFailEvent unhandled %{public}d", eventName);
1419             return;
1420     }
1421     pStaStateMachine->SwitchState(pStaStateMachine->pSeparatedState);
1422 }
1423 
1424 /* --------------------------- state machine ApConnected State ------------------------------ */
1425 StaStateMachine::ApLinkedState::ApLinkedState(StaStateMachine *staStateMachine)
1426     : State("ApLinkedState"), pStaStateMachine(staStateMachine)
1427 {}
1428 
1429 StaStateMachine::ApLinkedState::~ApLinkedState()
1430 {}
1431 
1432 void StaStateMachine::ApLinkedState::GoInState()
1433 {
1434     WIFI_LOGI("ApLinkedState GoInState function.");
1435     if ((WifiConfigCenter::GetInstance().GetScreenState() == MODE_STATE_CLOSE) &&
1436         (pStaStateMachine->isAudioOn_ == AUDIO_OFF)) {
1437         pStaStateMachine->enableSignalPoll = false;
1438     } else {
1439         pStaStateMachine->enableSignalPoll = true;
1440     }
1441     return;
1442 }
1443 
1444 void StaStateMachine::ApLinkedState::GoOutState()
1445 {
1446     WIFI_LOGI("ApLinkedState GoOutState function.");
1447     pStaStateMachine->lastCheckNetState_ = OperateResState::CONNECT_NETWORK_NORELATED;
1448     pStaStateMachine->lastInternetIconStatus_ = SystemNetWorkState::NETWORK_DEFAULT_STATE;
1449     return;
1450 }
1451 
1452 bool StaStateMachine::ApLinkedState::ExecuteStateMsg(InternalMessagePtr msg)
1453 {
1454     if (msg == nullptr) {
1455         return false;
1456     }
1457 
1458     WIFI_LOGD("ApLinkedState-msgCode=%{public}d received. m_instId = %{public}d\n", msg->GetMessageName(),
1459         pStaStateMachine->m_instId);
1460     bool ret = EXECUTED;
1461     switch (msg->GetMessageName()) {
1462         case WIFI_SVR_CMD_STA_DISCONNECT: {
1463             pStaStateMachine->StartDisConnectToNetwork();
1464             break;
1465         }
1466         case WIFI_SVR_CMD_STA_NETWORK_CONNECTION_EVENT: {
1467             HandleNetWorkConnectionEvent(msg);
1468             break;
1469         }
1470         case WIFI_SVR_CMD_STA_BSSID_CHANGED_EVENT: {
1471             HandleStaBssidChangedEvent(msg);
1472             break;
1473         }
1474         case WIFI_SVR_CMD_STA_LINK_SWITCH_EVENT:
1475             HandleLinkSwitchEvent(msg);
1476             break;
1477         case CMD_SIGNAL_POLL:
1478             pStaStateMachine->DealSignalPollResult();
1479             break;
1480         case CMD_LINK_SWITCH_DETECT_TIMEOUT:
1481             pStaStateMachine->linkSwitchDetectingFlag_ = false;
1482             break;
1483 #ifndef OHOS_ARCH_LITE
1484         case WIFI_SVR_CMD_STA_FOREGROUND_APP_CHANGED_EVENT:
1485             pStaStateMachine->HandleForegroundAppChangedAction(msg);
1486             break;
1487 #endif
1488         case WIFI_SVR_COM_STA_START_ROAM:
1489             DealStartRoamCmdInApLinkedState(msg);
1490             break;
1491         case WIFI_SVR_CMD_STA_CSA_CHANNEL_SWITCH_EVENT:
1492             DealCsaChannelChanged(msg);
1493             break;
1494         case CMD_NO_INTERNET_TIMEOUT:
1495             DealNoInternetTimeout();
1496             break;
1497         default:
1498             ret = NOT_EXECUTED;
1499             break;
1500     }
1501     return ret;
1502 }
1503 
1504 void StaStateMachine::ApLinkedState::HandleNetWorkConnectionEvent(InternalMessagePtr msg)
1505 {
1506     if (msg == nullptr) {
1507         WIFI_LOGE("HandleNetWorkConnectionEvent, msg is nullptr.\n");
1508         return;
1509     }
1510     std::string bssid = msg->GetStringFromMessage();
1511     WIFI_LOGI("ApLinkedState reveived network connection event,bssid:%{public}s, ignore it.\n",
1512         MacAnonymize(bssid).c_str());
1513     pStaStateMachine->StopTimer(static_cast<int>(CMD_NETWORK_CONNECT_TIMEOUT));
1514     pStaStateMachine->DealSignalPollResult();
1515     pStaStateMachine->linkedInfo.detailedState = DetailedState::CONNECTED;
1516     WifiConfigCenter::GetInstance().SaveLinkedInfo(pStaStateMachine->linkedInfo, pStaStateMachine->m_instId);
1517     pStaStateMachine->InvokeOnStaConnChanged(OperateResState::CONNECT_AP_CONNECTED, pStaStateMachine->linkedInfo);
1518     if (!pStaStateMachine->CanArpReachable()) {
1519         WIFI_LOGI("Arp not reachable, start to dhcp.");
1520         WriteWifiSelfcureHisysevent(static_cast<int>(WifiSelfcureType::ROAMING_ABNORMAL));
1521         pStaStateMachine->SwitchState(pStaStateMachine->pGetIpState);
1522     } else {
1523         WIFI_LOGI("Arp reachable, stay in linked state.");
1524     }
1525 }
1526 
1527 void StaStateMachine::ApLinkedState::HandleStaBssidChangedEvent(InternalMessagePtr msg)
1528 {
1529     std::string reason = msg->GetStringFromMessage();
1530     std::string bssid = msg->GetStringFromMessage();
1531     WIFI_LOGI("ApLinkedState received bssid changed event, reason:%{public}s,bssid:%{public}s.\n",
1532         reason.c_str(), MacAnonymize(bssid).c_str());
1533     if (strcmp(reason.c_str(), "ASSOC_COMPLETE") != 0) {
1534         WIFI_LOGE("Bssid change not for ASSOC_COMPLETE, do nothing.");
1535         return;
1536     }
1537     // do not switch to roaming state when it is not directed to roam by framework
1538     pStaStateMachine->linkedInfo.bssid = bssid;
1539     pStaStateMachine->UpdateHiLinkAttribute();
1540     pStaStateMachine->UpdateLinkedBssid(bssid);
1541 #ifndef OHOS_ARCH_LITE
1542     pStaStateMachine->ResetWifi7WurInfo();
1543     pStaStateMachine->UpdateLinkedInfoFromScanInfo();
1544     pStaStateMachine->SetSupportedWifiCategory();
1545 #endif
1546     pStaStateMachine->DealMloConnectionLinkInfo();
1547     WifiConfigCenter::GetInstance().SaveLinkedInfo(pStaStateMachine->linkedInfo, pStaStateMachine->m_instId);
1548 #ifdef FEATURE_WIFI_MDM_RESTRICTED_SUPPORT
1549     WifiDeviceConfig config;
1550     if (WifiSettings::GetInstance().GetDeviceConfig(pStaStateMachine->linkedInfo.networkId, config,
1551         pStaStateMachine->m_instId) != 0) {
1552         WIFI_LOGE("GetDeviceConfig failed, networkId = %{public}d", pStaStateMachine->linkedInfo.networkId);
1553         return;
1554     }
1555     if (pStaStateMachine->WhetherRestrictedByMdm(config.ssid, config.bssid, true)) {
1556         pStaStateMachine->DealMdmRestrictedConnect(config);
1557         return;
1558     }
1559 #endif
1560 }
1561 
1562 void StaStateMachine::ApLinkedState::HandleLinkSwitchEvent(InternalMessagePtr msg)
1563 {
1564     std::string bssid = msg->GetStringFromMessage();
1565     WIFI_LOGI("%{public}s enter, bssid:%{public}s, current linkedBssid: %{public}s",
1566         __FUNCTION__, MacAnonymize(bssid).c_str(), MacAnonymize(pStaStateMachine->linkedInfo.bssid).c_str());
1567     if (bssid == pStaStateMachine->linkedInfo.bssid) {
1568         return;
1569     }
1570     pStaStateMachine->linkSwitchDetectingFlag_ = true;
1571     pStaStateMachine->StopTimer(CMD_LINK_SWITCH_DETECT_TIMEOUT);
1572     pStaStateMachine->StartTimer(CMD_LINK_SWITCH_DETECT_TIMEOUT, STA_LINK_SWITCH_DETECT_DURATION);
1573     pStaStateMachine->AfterApLinkedprocess(bssid);
1574     pStaStateMachine->UpdateLinkedInfoFromScanInfo();
1575     pStaStateMachine->SetSupportedWifiCategory();
1576     pStaStateMachine->DealSignalPollResult();
1577     pStaStateMachine->InvokeOnStaConnChanged(OperateResState::CONNECT_AP_CONNECTED, pStaStateMachine->linkedInfo);
1578 }
1579 
1580 
1581 void StaStateMachine::ApLinkedState::DealStartRoamCmdInApLinkedState(InternalMessagePtr msg)
1582 {
1583     if (msg == nullptr) {
1584         WIFI_LOGE("%{public}s msg is null", __FUNCTION__);
1585         return;
1586     }
1587     WriteConnectTypeHiSysEvent(NETWORK_SELECTED_BY_ROAM);
1588     std::string bssid = msg->GetStringFromMessage();
1589     pStaStateMachine->targetRoamBssid = bssid;
1590     pStaStateMachine->linkSwitchDetectingFlag_ = false;
1591     WIFI_LOGI("%{public}s current bssid:%{public}s, target bssid:%{public}s,", __FUNCTION__,
1592         MacAnonymize(pStaStateMachine->linkedInfo.bssid).c_str(),
1593         MacAnonymize(pStaStateMachine->targetRoamBssid).c_str());
1594     std::string ifaceName = WifiConfigCenter::GetInstance().GetStaIfaceName(pStaStateMachine->m_instId);
1595     if (WifiStaHalInterface::GetInstance().SetBssid(WPA_DEFAULT_NETWORKID, pStaStateMachine->targetRoamBssid, ifaceName)
1596         != WIFI_HAL_OPT_OK) {
1597         WIFI_LOGE("%{public}s set roam target bssid fail", __FUNCTION__);
1598         return;
1599     }
1600     if (WifiStaHalInterface::GetInstance().Reassociate(ifaceName) != WIFI_HAL_OPT_OK) {
1601         WIFI_LOGE("%{public}s START_ROAM-ReAssociate() failed!", __FUNCTION__);
1602         return;
1603     }
1604     WIFI_LOGI("%{public}s START_ROAM-ReAssociate() succeeded!", __FUNCTION__);
1605     /* Start roaming */
1606     /* 只处理主动漫游*/
1607     pStaStateMachine->SwitchState(pStaStateMachine->pApRoamingState);
1608 }
1609 
1610 void StaStateMachine::ApLinkedState::DealCsaChannelChanged(InternalMessagePtr msg)
1611 {
1612     if (msg == nullptr) {
1613         WIFI_LOGE("%{public}s msg is null", __FUNCTION__);
1614         return;
1615     }
1616     int newFrq = msg->GetParam1();
1617     WIFI_LOGI("%{public}s update freq from %{public}d to %{public}d", __FUNCTION__,
1618         pStaStateMachine->linkedInfo.frequency, newFrq);
1619     if (newFrq == pStaStateMachine->linkedInfo.frequency) {
1620         return;
1621     }
1622     pStaStateMachine->linkedInfo.frequency = newFrq;
1623     // trigger wifi connection broadcast to notify sta channel has changed for p2penhance
1624     pStaStateMachine->InvokeOnStaConnChanged(OperateResState::CONNECT_AP_CONNECTED, pStaStateMachine->linkedInfo);
1625 }
1626 
1627 void StaStateMachine::ApLinkedState::DealNoInternetTimeout()
1628 {
1629 #ifndef OHOS_ARCH_LITE
1630     if (pStaStateMachine->m_NetWorkState) {
1631         pStaStateMachine->m_NetWorkState->StartWifiDetection();
1632     }
1633 #endif
1634 }
1635 
1636 void StaStateMachine::StartDisConnectToNetwork()
1637 {
1638     WIFI_LOGI("Enter StartDisConnectToNetwork m_instId:%{public}d!", m_instId);
1639     /* Save connection information to WifiSettings. */
1640     SaveLinkstate(ConnState::DISCONNECTING, DetailedState::DISCONNECTING);
1641     InvokeOnStaConnChanged(OperateResState::DISCONNECT_DISCONNECTING, linkedInfo);
1642     std::string ifaceName = WifiConfigCenter::GetInstance().GetStaIfaceName(m_instId);
1643     if (WifiStaHalInterface::GetInstance().Disconnect(ifaceName) == WIFI_HAL_OPT_OK) {
1644         WIFI_LOGI("Disconnect() succeed!");
1645         WifiStaHalInterface::GetInstance().DisableNetwork(WPA_DEFAULT_NETWORKID, ifaceName);
1646     } else {
1647         SaveLinkstate(ConnState::DISCONNECTING, DetailedState::FAILED);
1648         InvokeOnStaConnChanged(OperateResState::DISCONNECT_DISCONNECT_FAILED, linkedInfo);
1649         WIFI_LOGE("Disconnect() failed m_instId:%{public}d!", m_instId);
1650     }
1651 }
1652 
1653 int StaStateMachine::RegisterDhcpCallBack()
1654 {
1655     dhcpclientCallBack_.OnIpSuccessChanged = DhcpResultNotify::OnSuccess;
1656     dhcpclientCallBack_.OnIpFailChanged = DhcpResultNotify::OnFailed;
1657     std::string ifname = WifiConfigCenter::GetInstance().GetStaIfaceName(m_instId);
1658     DhcpErrorCode dhcpRet = RegisterDhcpClientCallBack(ifname.c_str(), &dhcpclientCallBack_);
1659     if (dhcpRet != DHCP_SUCCESS) {
1660         WIFI_LOGE("RegisterDhcpClientCallBack failed. dhcpRet=%{public}d", dhcpRet);
1661         return DHCP_FAILED;
1662     }
1663     dhcpClientReport_.OnDhcpClientReport = DhcpResultNotify::OnDhcpOffer;
1664     RegisterDhcpClientReportCallBack(ifname.c_str(), &dhcpClientReport_);
1665     WIFI_LOGI("RegisterDhcpClientCallBack ok");
1666     return DHCP_SUCCESS;
1667 }
1668 /* --------------------------- state machine GetIp State ------------------------------ */
1669 StaStateMachine::GetIpState::GetIpState(StaStateMachine *staStateMachine)
1670     : State("GetIpState"), pStaStateMachine(staStateMachine)
1671 {}
1672 
1673 StaStateMachine::GetIpState::~GetIpState()
1674 {}
1675 
1676 void StaStateMachine::GetIpState::GoInState()
1677 {
1678     WIFI_LOGI("GetIpState GoInState function. m_instId=%{public}d", pStaStateMachine->m_instId);
1679 #ifdef WIFI_DHCP_DISABLED
1680     pStaStateMachine->SaveDiscReason(DisconnectedReason::DISC_REASON_DEFAULT);
1681     pStaStateMachine->SaveLinkstate(ConnState::CONNECTED, DetailedState::WORKING);
1682     pStaStateMachine->InvokeOnStaConnChanged(OperateResState::CONNECT_NETWORK_ENABLED, pStaStateMachine->linkedInfo);
1683     pStaStateMachine->SwitchState(pStaStateMachine->pLinkedState);
1684     return;
1685 #endif
1686 #ifndef OHOS_ARCH_LITE
1687     if (pStaStateMachine->NetSupplierInfo != nullptr) {
1688         pStaStateMachine->NetSupplierInfo->isAvailable_ = true;
1689         pStaStateMachine->NetSupplierInfo->isRoaming_ = pStaStateMachine->isRoam;
1690         pStaStateMachine->NetSupplierInfo->ident_ =
1691             WifiConfigCenter::GetInstance().GetStaIfaceName(pStaStateMachine->m_instId);
1692         WIFI_LOGI("On connect update net supplier info\n");
1693         WifiNetAgent::GetInstance().OnStaMachineUpdateNetSupplierInfo(pStaStateMachine->NetSupplierInfo,
1694             pStaStateMachine->m_instId);
1695     }
1696 #endif
1697     /* Callback result to InterfaceService. */
1698     pStaStateMachine->SaveLinkstate(ConnState::CONNECTING, DetailedState::OBTAINING_IPADDR);
1699     pStaStateMachine->InvokeOnStaConnChanged(OperateResState::CONNECT_OBTAINING_IP, pStaStateMachine->linkedInfo);
1700     pStaStateMachine->getIpSucNum = 0;
1701     WifiDeviceConfig config;
1702     AssignIpMethod assignMethod = AssignIpMethod::DHCP;
1703     int ret = WifiSettings::GetInstance().GetDeviceConfig(pStaStateMachine->linkedInfo.networkId, config,
1704         pStaStateMachine->m_instId);
1705     if (ret == 0) {
1706         assignMethod = config.wifiIpConfig.assignMethod;
1707     }
1708 
1709     if (assignMethod == AssignIpMethod::STATIC) {
1710         pStaStateMachine->currentTpType = config.wifiIpConfig.staticIpAddress.ipAddress.address.family;
1711         if (!pStaStateMachine->ConfigStaticIpAddress(config.wifiIpConfig.staticIpAddress)) {
1712             pStaStateMachine->InvokeOnStaConnChanged(
1713                 OperateResState::CONNECT_NETWORK_DISABLED, pStaStateMachine->linkedInfo);
1714             pStaStateMachine->StartDisConnectToNetwork();
1715             WIFI_LOGE("ConfigstaticIpAddress failed!\n");
1716         }
1717     }
1718     pStaStateMachine->HandlePreDhcpSetup();
1719     do {
1720         int dhcpRet;
1721         std::string ifname = WifiConfigCenter::GetInstance().GetStaIfaceName(pStaStateMachine->m_instId);
1722         pStaStateMachine->currentTpType = static_cast<int>(
1723             WifiSettings::GetInstance().GetDhcpIpType(pStaStateMachine->m_instId));
1724 
1725         RouterConfig config;
1726         if (strncpy_s(config.bssid, sizeof(config.bssid),
1727             pStaStateMachine->linkedInfo.bssid.c_str(), pStaStateMachine->linkedInfo.bssid.size()) == EOK) {
1728             config.prohibitUseCacheIp = IsProhibitUseCacheIp();
1729         }
1730         config.isStaticIpv4 = assignMethod == AssignIpMethod::STATIC;
1731         config.bIpv6 = false;
1732         config.bSpecificNetwork = pStaStateMachine->IsSpecificNetwork();
1733         if (strncpy_s(config.ifname, sizeof(config.ifname), ifname.c_str(), ifname.length()) != EOK) {
1734             break;
1735         }
1736         config.bIpv4 = true;
1737         pStaStateMachine->RegisterDhcpCallBack();
1738         dhcpRet = StartDhcpClient(config);
1739         LOGI("StartDhcpClient type:%{public}d dhcpRet:%{public}d isRoam:%{public}d m_instId=%{public}d" \
1740             "IsSpecificNetwork %{public}d", pStaStateMachine->currentTpType, dhcpRet, pStaStateMachine->isRoam,
1741             pStaStateMachine->m_instId, config.bSpecificNetwork);
1742         if (dhcpRet == 0) {
1743             if (!config.isStaticIpv4) {
1744                 WIFI_LOGI("StartTimer CMD_START_GET_DHCP_IP_TIMEOUT 30s");
1745                 pStaStateMachine->StartTimer(static_cast<int>(CMD_START_GET_DHCP_IP_TIMEOUT),
1746                     STA_SIGNAL_START_GET_DHCP_IP_DELAY);
1747             }
1748             return;
1749         }
1750     } while (0);
1751     WriteDhcpFailHiSysEvent("START_DHCP_CLIENT_FAIL");
1752     WIFI_LOGE("Dhcp connection failed, isRoam:%{public}d", pStaStateMachine->isRoam);
1753     pStaStateMachine->SaveLinkstate(ConnState::DISCONNECTED, DetailedState::OBTAINING_IPADDR_FAIL);
1754     pStaStateMachine->InvokeOnStaConnChanged(OperateResState::CONNECT_OBTAINING_IP_FAILED,
1755         pStaStateMachine->linkedInfo);
1756     if (!pStaStateMachine->isRoam) {
1757         pStaStateMachine->StartDisConnectToNetwork();
1758     }
1759     return;
1760 }
1761 
1762 void StaStateMachine::GetIpState::GoOutState()
1763 {
1764     WIFI_LOGI("GetIpState GoOutState function.");
1765     pStaStateMachine->StopTimer(static_cast<int>(CMD_START_GET_DHCP_IP_TIMEOUT));
1766     pStaStateMachine->HandlePostDhcpSetup();
1767 }
1768 
1769 bool StaStateMachine::GetIpState::ExecuteStateMsg(InternalMessagePtr msg)
1770 {
1771     if (msg == nullptr) {
1772         return false;
1773     }
1774 
1775     bool ret = NOT_EXECUTED;
1776     WIFI_LOGI("GetIpState-msgCode=%{public}d received. m_instId = %{public}d\n", msg->GetMessageName(),
1777         pStaStateMachine->m_instId);
1778     switch (msg->GetMessageName()) {
1779         case WIFI_SVR_CMD_STA_DHCP_RESULT_NOTIFY_EVENT: {
1780             ret = EXECUTED;
1781             int result = msg->GetParam1();
1782             int ipType = msg->GetParam2();
1783             WIFI_LOGI("GetIpState, get ip result:%{public}d, ipType = %{public}d, m_instId = %{public}d\n",
1784                 result, ipType, pStaStateMachine->m_instId);
1785             switch (result) {
1786                 case DhcpReturnCode::DHCP_RESULT: {
1787                     pStaStateMachine->pDhcpResultNotify->DealDhcpResult(ipType);
1788                     break;
1789                 }
1790                 case DhcpReturnCode::DHCP_JUMP: {
1791                     pStaStateMachine->SwitchState(pStaStateMachine->pLinkedState);
1792                     break;
1793                 }
1794                 case DhcpReturnCode::DHCP_FAIL: {
1795                     pStaStateMachine->pDhcpResultNotify->DealDhcpResultFailed();
1796                     break;
1797                 }
1798                 case DhcpReturnCode::DHCP_OFFER_REPORT: {
1799                     pStaStateMachine->pDhcpResultNotify->DealDhcpOfferResult();
1800                     break;
1801                 }
1802                 default:
1803                     break;
1804             }
1805             break;
1806         }
1807         case CMD_START_GET_DHCP_IP_TIMEOUT: {
1808             ret = EXECUTED;
1809             DealGetDhcpIpTimeout(msg);
1810             break;
1811         }
1812         default:
1813             break;
1814     }
1815 
1816     return ret;
1817 }
1818 
1819 void StaStateMachine::GetIpState::DealGetDhcpIpTimeout(InternalMessagePtr msg)
1820 {
1821     if (msg == nullptr) {
1822         WIFI_LOGE("DealGetDhcpIpTimeout InternalMessage msg is null.");
1823         return;
1824     }
1825     WIFI_LOGI("StopTimer CMD_START_GET_DHCP_IP_TIMEOUT DealGetDhcpIpTimeout");
1826     BlockConnectService::GetInstance().UpdateNetworkSelectStatus(pStaStateMachine->targetNetworkId_,
1827                                                                  DisabledReason::DISABLED_DHCP_FAILURE);
1828     BlockConnectService::GetInstance().NotifyWifiConnFailedInfo(pStaStateMachine->targetNetworkId_,
1829         pStaStateMachine->linkedInfo.bssid, DisabledReason::DISABLED_DHCP_FAILURE);
1830     pStaStateMachine->StopTimer(static_cast<int>(CMD_START_GET_DHCP_IP_TIMEOUT));
1831     pStaStateMachine->StartDisConnectToNetwork();
1832     WriteDhcpFailHiSysEvent("DHCP_TIMEOUT");
1833 }
1834 
1835 bool StaStateMachine::GetIpState::IsPublicESS()
1836 {
1837     constexpr int32_t BSS_NUM_MIN = 3;
1838     std::vector<WifiScanInfo> scanResults;
1839     WifiConfigCenter::GetInstance().GetWifiScanConfig()->GetScanInfoList(scanResults);
1840     if (scanResults.empty()) {
1841         WIFI_LOGI("IsPublicESS scanResults is empty");
1842         return false;
1843     }
1844 
1845     WifiLinkedInfo wifiLinkedInfo;
1846     WifiConfigCenter::GetInstance().GetLinkedInfo(wifiLinkedInfo);
1847     std::string currentSsid = wifiLinkedInfo.ssid;
1848     if (currentSsid.empty()) {
1849         WIFI_LOGI("IsPublicESS currentSsid is empty");
1850         return false;
1851     }
1852 
1853     std::string capabilities = "";
1854     for (WifiScanInfo result : scanResults) {
1855         if (currentSsid == result.ssid) {
1856             capabilities = result.capabilities;
1857             break;
1858         }
1859     }
1860     if (capabilities.empty()) {
1861         WIFI_LOGI("IsPublicESS capabilities is empty");
1862         return false;
1863     }
1864 
1865     int32_t counter = 0;
1866     for (WifiScanInfo nextResult : scanResults) {
1867         if (currentSsid == nextResult.ssid && (strcmp(capabilities.c_str(), nextResult.capabilities.c_str()) == 0)) {
1868             counter += 1;
1869         }
1870     }
1871     WIFI_LOGI("IsPublicESS counter is %{public}d", counter);
1872     return counter >= BSS_NUM_MIN;
1873 }
1874 
1875 bool StaStateMachine::GetIpState::IsProhibitUseCacheIp()
1876 {
1877     if (IsPublicESS()) {
1878         return true;
1879     }
1880 
1881     WifiDeviceConfig config;
1882     WifiSettings::GetInstance().GetDeviceConfig(pStaStateMachine->linkedInfo.networkId, config,
1883         pStaStateMachine->m_instId);
1884     if (config.keyMgmt == KEY_MGMT_WEP) {
1885         WIFI_LOGE("current keyMgmt is WEP, not use cache ip if dhcp timeout");
1886         return true;
1887     }
1888 #ifndef OHOS_ARCH_LITE
1889     if (pStaStateMachine->enhanceService_ != nullptr) {
1890         if (pStaStateMachine->enhanceService_->IsCustomNetwork(config)) {
1891             WIFI_LOGE("current network not use cache ip if dhcp timeout");
1892             return true;
1893         }
1894     }
1895 #endif
1896     int currentSignalLevel = WifiSettings::GetInstance().GetSignalLevel(
1897         pStaStateMachine->linkedInfo.rssi, pStaStateMachine->linkedInfo.band, pStaStateMachine->m_instId);
1898     if (currentSignalLevel < RSSI_LEVEL_3) {
1899         WIFI_LOGE("current rssi level is less than 3");
1900         return true;
1901     }
1902     return false;
1903 }
1904 
1905 void StaStateMachine::ReplaceEmptyDns(DhcpResult *result)
1906 {
1907     if (result == nullptr) {
1908         WIFI_LOGE("Enter ReplaceEmptyDns::result is nullptr");
1909         return;
1910     }
1911     std::string strDns1 = result->strOptDns1;
1912     std::string strDns2 = result->strOptDns2;
1913     char wifiFirstDns[DNS_IP_ADDR_LEN + 1] = { 0 };
1914     char wifiSecondDns[DNS_IP_ADDR_LEN + 1] = { 0 };
1915     if (GetParamValue(WIFI_FIRST_DNS_NAME, 0, wifiFirstDns, DNS_IP_ADDR_LEN) <= 0) {
1916         WIFI_LOGE("ReplaceEmptyDns Get wifiFirstDns error");
1917         return;
1918     }
1919     if (GetParamValue(WIFI_SECOND_DNS_NAME, 0, wifiSecondDns, DNS_IP_ADDR_LEN) <= 0) {
1920         WIFI_LOGE("ReplaceEmptyDns Get wifiSecondDns error");
1921         return;
1922     }
1923     std::string strWifiFirstDns(wifiFirstDns);
1924     if (strDns1.empty()) {
1925         WIFI_LOGI("Enter ReplaceEmptyDns::dns1 is null");
1926         if (strDns2 == strWifiFirstDns) {
1927             if (strcpy_s(result->strOptDns1, INET_ADDRSTRLEN, wifiSecondDns) != EOK) {
1928                 WIFI_LOGE("ReplaceEmptyDns strDns1 strcpy_s wifiSecondDns failed!");
1929             }
1930         } else {
1931             if (strcpy_s(result->strOptDns1, INET_ADDRSTRLEN, wifiFirstDns) != EOK) {
1932                 WIFI_LOGE("ReplaceEmptyDns strDns1 strcpy_s wifiFirstDns failed!");
1933             }
1934         }
1935     }
1936     if (strDns2.empty()) {
1937         WIFI_LOGI("Enter ReplaceEmptyDns::dns2 is null");
1938         if (strDns1 == strWifiFirstDns) {
1939             if (strcpy_s(result->strOptDns2, INET_ADDRSTRLEN, wifiSecondDns) != EOK) {
1940                 WIFI_LOGE("ReplaceEmptyDns strDns2 strcpy_s wifiSecondDns failed!");
1941             }
1942         } else {
1943             if (strcpy_s(result->strOptDns2, INET_ADDRSTRLEN, wifiFirstDns) != EOK) {
1944                 WIFI_LOGE("ReplaceEmptyDns strDns2 strcpy_s wifiFirstDns failed!");
1945             }
1946         }
1947     }
1948 }
1949 
1950 /* --- state machine GetIp State functions ----- */
1951 bool StaStateMachine::ConfigStaticIpAddress(StaticIpAddress &staticIpAddress)
1952 {
1953     WIFI_LOGI("Enter StaStateMachine::SetDhcpResultFromStatic.");
1954     std::string ifname = WifiConfigCenter::GetInstance().GetStaIfaceName(m_instId);
1955     DhcpResult result;
1956     switch (currentTpType) {
1957         case IPTYPE_IPV4: {
1958             result.iptype = IPTYPE_IPV4;
1959             if (strcpy_s(result.strOptClientId, DHCP_MAX_FILE_BYTES,
1960                 staticIpAddress.ipAddress.address.GetIpv4Address().c_str()) != EOK) {
1961                 WIFI_LOGE("ConfigStaticIpAddress strOptClientId strcpy_s failed!");
1962             }
1963             if (strcpy_s(result.strOptRouter1, DHCP_MAX_FILE_BYTES,
1964                 staticIpAddress.gateway.GetIpv4Address().c_str()) != EOK) {
1965                 WIFI_LOGE("ConfigStaticIpAddress strOptRouter1 strcpy_s failed!");
1966             }
1967             if (strcpy_s(result.strOptSubnet, DHCP_MAX_FILE_BYTES, staticIpAddress.GetIpv4Mask().c_str()) != EOK) {
1968                 WIFI_LOGE("ConfigStaticIpAddress strOptSubnet strcpy_s failed!");
1969             }
1970             if (strcpy_s(result.strOptDns1, DHCP_MAX_FILE_BYTES,
1971                 staticIpAddress.dnsServer1.GetIpv4Address().c_str()) != EOK) {
1972                 WIFI_LOGE("ConfigStaticIpAddress strOptDns1 strcpy_s failed!");
1973             }
1974             if (strcpy_s(result.strOptDns2, DHCP_MAX_FILE_BYTES,
1975                 staticIpAddress.dnsServer2.GetIpv4Address().c_str()) != EOK) {
1976                 WIFI_LOGE("ConfigStaticIpAddress strOptDns2 strcpy_s failed!");
1977             }
1978             ReplaceEmptyDns(&result);
1979             pDhcpResultNotify->OnSuccess(1, ifname.c_str(), &result);
1980             break;
1981         }
1982         case IPTYPE_IPV6: {
1983             result.iptype = IPTYPE_IPV6;
1984             if (strcpy_s(result.strOptClientId, DHCP_MAX_FILE_BYTES,
1985                 staticIpAddress.ipAddress.address.GetIpv6Address().c_str()) != EOK) {
1986                 WIFI_LOGE("ConfigStaticIpAddress strOptClientId strcpy_s failed!");
1987             }
1988             if (strcpy_s(result.strOptRouter1, DHCP_MAX_FILE_BYTES,
1989                 staticIpAddress.gateway.GetIpv6Address().c_str()) != EOK) {
1990                 WIFI_LOGE("ConfigStaticIpAddress strOptRouter1 strcpy_s failed!");
1991             }
1992             if (strcpy_s(result.strOptSubnet, DHCP_MAX_FILE_BYTES, staticIpAddress.GetIpv6Mask().c_str()) != EOK) {
1993                 WIFI_LOGE("ConfigStaticIpAddress strOptSubnet strcpy_s failed!");
1994             }
1995             if (strcpy_s(result.strOptDns1, DHCP_MAX_FILE_BYTES,
1996                 staticIpAddress.dnsServer1.GetIpv6Address().c_str()) != EOK) {
1997                 WIFI_LOGE("ConfigStaticIpAddress strOptDns1 strcpy_s failed!");
1998             }
1999             if (strcpy_s(result.strOptDns2, DHCP_MAX_FILE_BYTES,
2000                 staticIpAddress.dnsServer2.GetIpv6Address().c_str()) != EOK) {
2001                 WIFI_LOGE("ConfigStaticIpAddress strOptDns2 strcpy_s failed!");
2002             }
2003             pDhcpResultNotify->OnSuccess(1, ifname.c_str(), &result);
2004             break;
2005         }
2006         case IPTYPE_MIX: {
2007             result.iptype = IPTYPE_IPV4;
2008             if (strcpy_s(result.strOptClientId, DHCP_MAX_FILE_BYTES,
2009                 staticIpAddress.ipAddress.address.GetIpv4Address().c_str()) != EOK) {
2010                 WIFI_LOGE("ConfigStaticIpAddress strOptClientId strcpy_s failed!");
2011             }
2012             if (strcpy_s(result.strOptRouter1, DHCP_MAX_FILE_BYTES,
2013                 staticIpAddress.gateway.GetIpv4Address().c_str()) != EOK) {
2014                 WIFI_LOGE("ConfigStaticIpAddress strOptRouter1 strcpy_s failed!");
2015             }
2016             if (strcpy_s(result.strOptSubnet, DHCP_MAX_FILE_BYTES,
2017                 staticIpAddress.GetIpv4Mask().c_str()) != EOK) {
2018                 WIFI_LOGE("ConfigStaticIpAddress strOptSubnet strcpy_s failed!");
2019             }
2020             if (strcpy_s(result.strOptDns1, DHCP_MAX_FILE_BYTES,
2021                 staticIpAddress.dnsServer1.GetIpv4Address().c_str()) != EOK) {
2022                 WIFI_LOGE("ConfigStaticIpAddress strOptDns1 strcpy_s failed!");
2023             }
2024             if (strcpy_s(result.strOptDns2, DHCP_MAX_FILE_BYTES,
2025                 staticIpAddress.dnsServer2.GetIpv4Address().c_str()) != EOK) {
2026                 WIFI_LOGE("ConfigStaticIpAddress strOptDns2 strcpy_s failed!");
2027             }
2028             pDhcpResultNotify->OnSuccess(1, ifname.c_str(), &result);
2029             if (strcpy_s(result.strOptClientId, DHCP_MAX_FILE_BYTES,
2030                 staticIpAddress.ipAddress.address.GetIpv6Address().c_str()) != EOK) {
2031                 WIFI_LOGE("ConfigStaticIpAddress strOptClientId strcpy_s failed!");
2032             }
2033             if (strcpy_s(result.strOptRouter1, DHCP_MAX_FILE_BYTES,
2034                 staticIpAddress.gateway.GetIpv6Address().c_str()) != EOK) {
2035                 WIFI_LOGE("ConfigStaticIpAddress strOptRouter1 strcpy_s failed!");
2036             }
2037             if (strcpy_s(result.strOptSubnet, DHCP_MAX_FILE_BYTES, staticIpAddress.GetIpv6Mask().c_str()) != EOK) {
2038                 WIFI_LOGE("ConfigStaticIpAddress strOptSubnet strcpy_s failed!");
2039             }
2040             if (strcpy_s(result.strOptDns1, DHCP_MAX_FILE_BYTES,
2041                 staticIpAddress.dnsServer1.GetIpv6Address().c_str()) != EOK) {
2042                 WIFI_LOGE("ConfigStaticIpAddress strOptDns1 strcpy_s failed!");
2043             }
2044             if (strcpy_s(result.strOptDns2, DHCP_MAX_FILE_BYTES,
2045                 staticIpAddress.dnsServer2.GetIpv6Address().c_str()) != EOK) {
2046                 WIFI_LOGE("ConfigStaticIpAddress strOptDns2 strcpy_s failed!");
2047             }
2048             pDhcpResultNotify->OnSuccess(1, ifname.c_str(), &result);
2049             break;
2050         }
2051 
2052         default:
2053             WIFI_LOGE("Invalid currentTpType: %{public}d", currentTpType);
2054             return false;
2055     }
2056     return true;
2057 }
2058 
2059 void StaStateMachine::HandlePortalNetworkPorcess()
2060 {
2061 #ifndef OHOS_ARCH_LITE
2062     if (mPortalUrl.empty()) {
2063         WIFI_LOGE("portal uri is nullptr\n");
2064     }
2065     if (!m_NetWorkState) {
2066         WIFI_LOGE("m_NetWorkState is nullptr\n");
2067         return;
2068     }
2069     int netId = m_NetWorkState->GetWifiNetId();
2070     AAFwk::Want want;
2071     want.SetParam("netId", netId);
2072     int deviceType = WifiConfigCenter::GetInstance().GetDeviceType();
2073 #ifndef SUPPORT_PORTAL_LOGIN
2074     std::string bundle = WifiSettings::GetInstance().GetPackageName("BROWSER_BUNDLE");
2075     want.SetAction(PORTAL_ACTION);
2076     want.SetUri(mPortalUrl);
2077     want.AddEntity(PORTAL_ENTITY);
2078     want.SetBundle(bundle);
2079     WIFI_LOGI("want browser wifi netId is %{public}d, deviceType is %{public}d", netId, deviceType);
2080     OHOS::ErrCode err = WifiNotificationUtil::GetInstance().StartAbility(want);
2081     if (err != ERR_OK) {
2082         WIFI_LOGI("want browser StartAbility is failed %{public}d", err);
2083         WriteBrowserFailedForPortalHiSysEvent(err, mPortalUrl);
2084         AAFwk::Want wantPortalLogin;
2085         wantPortalLogin.SetParam("netId", netId);
2086         wantPortalLogin.SetElementName("com.wifiservice.portallogin", "EntryAbility");
2087         wantPortalLogin.SetParam("url", mPortalUrl);
2088         wantPortalLogin.SetParam("shouldShowBrowseItem", deviceType != ProductDeviceType::TV);
2089         WIFI_LOGI("wantPortalLogin wifi netId is %{public}d, deviceType is %{public}d", netId, deviceType);
2090         OHOS::ErrCode err = WifiNotificationUtil::GetInstance().StartAbility(wantPortalLogin);
2091         if (err != ERR_OK) {
2092             WIFI_LOGI("wantPortalLogin portal StartAbility is failed %{public}d", err);
2093         }
2094     }
2095 #else
2096     want.SetElementName("com.wifiservice.portallogin", "EntryAbility");
2097     want.SetParam("url", mPortalUrl);
2098     want.SetParam("shouldShowBrowseItem", deviceType != ProductDeviceType::TV);
2099     WIFI_LOGI("portal login wifi netId is %{public}d, deviceType is %{public}d", netId, deviceType);
2100     OHOS::ErrCode err = WifiNotificationUtil::GetInstance().StartAbility(want);
2101     if (err != ERR_OK) {
2102         WIFI_LOGI("want portal login StartAbility is failed %{public}d", err);
2103         WriteBrowserFailedForPortalHiSysEvent(err, mPortalUrl);
2104     }
2105 #endif
2106 #endif
2107 }
2108 
2109 void StaStateMachine::SetPortalBrowserFlag(bool flag)
2110 {
2111     autoPullBrowserFlag = flag;
2112     mIsWifiInternetCHRFlag = false;
2113     if (!WifiConfigCenter::GetInstance().GetWifiSelfcureReset()) {
2114         WifiConfigCenter::GetInstance().SetWifiSelfcureResetEntered(false);
2115     }
2116     if (!flag) {
2117         portalState = PortalState::UNCHECKED;
2118     }
2119 }
2120 
2121 #ifndef OHOS_ARCH_LITE
2122 void StaStateMachine::ShowPortalNitification()
2123 {
2124     WifiDeviceConfig wifiDeviceConfig = getCurrentWifiDeviceConfig();
2125     bool hasInternetEver =
2126         NetworkStatusHistoryManager::HasInternetEverByHistory(wifiDeviceConfig.networkStatusHistory);
2127     if (hasInternetEver) {
2128         WifiNotificationUtil::GetInstance().PublishWifiNotification(
2129             WifiNotificationId::WIFI_PORTAL_NOTIFICATION_ID, linkedInfo.ssid,
2130             WifiNotificationStatus::WIFI_PORTAL_TIMEOUT);
2131     } else {
2132         std::string bundle = WifiSettings::GetInstance().GetPackageName("SETTINGS");
2133         if (WifiAppStateAware::GetInstance().IsForegroundApp(bundle)) {
2134             WifiNotificationUtil::GetInstance().PublishWifiNotification(
2135                 WifiNotificationId::WIFI_PORTAL_NOTIFICATION_ID, linkedInfo.ssid,
2136                 WifiNotificationStatus::WIFI_PORTAL_CONNECTED);
2137             autoPullBrowserFlag = false;
2138         } else {
2139             WifiNotificationUtil::GetInstance().PublishWifiNotification(
2140                 WifiNotificationId::WIFI_PORTAL_NOTIFICATION_ID, linkedInfo.ssid,
2141                 WifiNotificationStatus::WIFI_PORTAL_FOUND);
2142         }
2143     }
2144 }
2145 #endif
2146 
2147 void StaStateMachine::StartDetectTimer(int detectType)
2148 {
2149     if (detectType == DETECT_TYPE_PERIODIC) {
2150         /* Obtains the current time, accurate to milliseconds. */
2151         struct timespec curTime = {0, 0};
2152         if (clock_gettime(CLOCK_BOOTTIME, &curTime) != 0) {
2153             WIFI_LOGE("HandleNetCheckResult clock_gettime failed.");
2154             return;
2155         }
2156         int64_t nowTime = static_cast<int64_t>(curTime.tv_sec) * PORTAL_MILLSECOND +
2157             curTime.tv_nsec / (PORTAL_MILLSECOND * PORTAL_MILLSECOND);
2158         if (nowTime - lastTimestamp > PORTAL_CHECK_TIME * PORTAL_MILLSECOND) {
2159             detectNum++;
2160             StartTimer(static_cast<int>(CMD_START_NETCHECK), PORTAL_CHECK_TIME * PORTAL_MILLSECOND);
2161             lastTimestamp = nowTime;
2162         }
2163     } else if (detectType == DETECT_TYPE_DEFAULT) {
2164         StartTimer(static_cast<int>(CMD_START_NETCHECK), 0);
2165     } else if (detectType == DETECT_TYPE_CHECK_PORTAL_EXPERIED) {
2166         StartTimer(static_cast<int>(CMD_START_NETCHECK), PORTAL_AUTH_EXPIRED_CHECK_TIME * PORTAL_MILLSECOND);
2167     }
2168 }
2169 
2170 void StaStateMachine::PortalExpiredDetect()
2171 {
2172     if (portalState == PortalState::EXPERIED) {
2173         if (portalExpiredDetectCount < PORTAL_EXPERIED_DETECT_MAX_COUNT) {
2174             portalExpiredDetectCount++;
2175             StartDetectTimer(DETECT_TYPE_CHECK_PORTAL_EXPERIED);
2176         } else if (portalExpiredDetectCount == PORTAL_EXPERIED_DETECT_MAX_COUNT) {
2177             portalExpiredDetectCount = 0;
2178             auto config = getCurrentWifiDeviceConfig();
2179             WritePortalAuthExpiredHisysevent(static_cast<int>(SystemNetWorkState::NETWORK_IS_PORTAL),
2180                 detectNum, config.lastConnectTime, config.portalAuthTime, false);
2181         }
2182     }
2183 }
2184 
2185 void StaStateMachine::GetDetectNetState(OperateResState &state)
2186 {
2187     state = lastCheckNetState_;
2188 }
2189 
2190 void StaStateMachine::UpdatePortalState(SystemNetWorkState netState, bool &updatePortalAuthTime)
2191 {
2192     if (netState == SystemNetWorkState::NETWORK_IS_WORKING) {
2193         if (portalState == PortalState::UNCHECKED) {
2194             auto config = getCurrentWifiDeviceConfig();
2195             portalState = config.isPortal ? PortalState::AUTHED : PortalState::NOT_PORTAL;
2196         } else if (portalState == PortalState::UNAUTHED || portalState == PortalState::EXPERIED) {
2197             portalState = PortalState::AUTHED;
2198             updatePortalAuthTime = true;
2199         }
2200     } else if (netState == SystemNetWorkState::NETWORK_IS_PORTAL) {
2201         if (portalState == PortalState::UNCHECKED) {
2202             portalState = PortalState::UNAUTHED;
2203         } else if (portalState == PortalState::AUTHED || portalState == PortalState::NOT_PORTAL) {
2204             portalState = PortalState::EXPERIED;
2205             portalExpiredDetectCount = 0;
2206         }
2207         PortalExpiredDetect();
2208     }
2209     WritePortalStateHiSysEvent(portalEventValues.count(portalState) > 0 ?
2210         portalEventValues.at(portalState) : HISYS_EVENT_DEFAULT_VALUE);
2211 }
2212 
2213 void StaStateMachine::NetStateObserverCallback(SystemNetWorkState netState, std::string url)
2214 {
2215     SendMessage(WIFI_SVR_CMD_STA_NET_DETECTION_NOTIFY_EVENT, netState, 0, url);
2216 #ifndef OHOS_ARCH_LITE
2217     if (enhanceService_ == nullptr) {
2218         WIFI_LOGE("NetStateObserverCallback, enhanceService is null");
2219         return;
2220     }
2221     enhanceService_->NotifyInternetState(static_cast<int>(netState));
2222 #endif
2223 }
2224 
2225 void StaStateMachine::RegisterCustomEapCallback(const std::string &regCmd) //netType:regSize:reg1:reg2
2226 {
2227 #ifdef EXTENSIBLE_AUTHENTICATION
2228     const int preNumberCount = 2;
2229     auto CheckStrEapData = [regCmd](const std::string &data) -> bool {
2230         if (data.empty()) {
2231             WIFI_LOGI("%{public}s regCmd is empty", __func__);
2232             return false;
2233         }
2234         std::vector<std::string> vecEapDatas = GetSplitInfo(data, ":");
2235         if (vecEapDatas.size() < 2) {
2236             WIFI_LOGI("%{public}s regCmd invalid, regCmd[%{public}s]", __func__, regCmd.c_str());
2237             return false;
2238         }
2239         if (CheckDataToUint(vecEapDatas[0]) != static_cast<int>(NetManagerStandard::NetType::WLAN0)) {
2240             WIFI_LOGI("%{public}s netType not WLAN0, regCmd[%{public}s]", __func__, regCmd.c_str());
2241             return false;
2242         }
2243         if (CheckDataToUint(vecEapDatas[1]) + preNumberCount != vecEapDatas.size()) {
2244             WIFI_LOGI("%{public}s reg eapdata size error, regCmd[%{public}s]", __func__, regCmd.c_str());
2245             return false;
2246         }
2247         return true;
2248     };
2249     if (!CheckStrEapData(regCmd)) {
2250         WIFI_LOGI("%{public}s regcmd error, regCmd[%{public}s]", __func__, regCmd.c_str());
2251         return;
2252     }
2253     std::string cmd = "EXT_AUTH_REG ";
2254     cmd += regCmd;
2255     WIFI_LOGI("%{public}s regCmd:%{public}s", __func__, cmd.c_str());
2256     if (WifiStaHalInterface::GetInstance().ShellCmd("wlan0", cmd) != WIFI_HAL_OPT_OK) {
2257         WIFI_LOGI("%{public}s: failed to send the message, Custom Eap cmd: %{private}s", __func__, cmd.c_str());
2258         return;
2259     }
2260 #endif
2261 }
2262 
2263 void StaStateMachine::ReplyCustomEapDataCallback(int result, const std::string &strEapData)
2264 {
2265 #ifdef EXTENSIBLE_AUTHENTICATION
2266     std::string cmd = "EXT_AUTH_DATA ";
2267     cmd += std::to_string(result);
2268     cmd += std::string(":");
2269     cmd += strEapData;
2270     WIFI_LOGI("%{public}s, reply result:%{public}d", __func__, result);
2271     if (WifiStaHalInterface::GetInstance().ShellCmd("wlan0", cmd) != WIFI_HAL_OPT_OK) {
2272         WIFI_LOGI("%{public}s: failed to send the message", __func__);
2273         return;
2274     }
2275 #endif
2276 }
2277 
2278 void StaStateMachine::HandleNetCheckResult(SystemNetWorkState netState, const std::string &portalUrl)
2279 {
2280     WIFI_LOGD("Enter HandleNetCheckResult, netState:%{public}d screen:%{public}d "
2281         "oldPortalState:%{public}d chrFlag:%{public}d.",
2282         netState, enableSignalPoll, portalState, mIsWifiInternetCHRFlag);
2283     if (linkedInfo.connState != ConnState::CONNECTED) {
2284         WIFI_LOGE("connState is NOT in connected state, connState:%{public}d\n", linkedInfo.connState);
2285         WriteIsInternetHiSysEvent(NO_NETWORK);
2286         return;
2287     }
2288     if (!portalUrl.empty()) {
2289         mPortalUrl = portalUrl;
2290     }
2291     /*when detect result is NETWORK_NOTWORKING but tx rx is good, considered as NETWORK_IS_WORKING*/
2292     if (netState == SystemNetWorkState::NETWORK_NOTWORKING &&
2293         IpQosMonitor::GetInstance().GetTxRxStatus() &&
2294         WifiConfigCenter::GetInstance().GetScreenState() == MODE_STATE_OPEN) {
2295         WIFI_LOGI("net detection result is NETWORK_NOTWORKING but tx rx is good, considered as NETWORK_IS_WORKING");
2296         netState = SystemNetWorkState::NETWORK_IS_WORKING;
2297     }
2298     bool updatePortalAuthTime = false;
2299     if (netState == SystemNetWorkState::NETWORK_IS_WORKING) {
2300         mIsWifiInternetCHRFlag = false;
2301         UpdatePortalState(netState, updatePortalAuthTime);
2302         /* Save connection information to WifiSettings. */
2303         WriteIsInternetHiSysEvent(NETWORK);
2304         WifiConfigCenter::GetInstance().SetWifiSelfcureResetEntered(false);
2305         SaveLinkstate(ConnState::CONNECTED, DetailedState::WORKING);
2306         InvokeOnStaConnChanged(OperateResState::CONNECT_NETWORK_ENABLED, linkedInfo);
2307         lastCheckNetState_ = OperateResState::CONNECT_NETWORK_ENABLED;
2308         InsertOrUpdateNetworkStatusHistory(NetworkStatus::HAS_INTERNET, updatePortalAuthTime);
2309         if (getCurrentWifiDeviceConfig().isPortal) {
2310             StartDetectTimer(DETECT_TYPE_PERIODIC);
2311         }
2312         mPortalUrl = "";
2313 #ifndef OHOS_ARCH_LITE
2314         UpdateAcceptUnvalidatedState();
2315         WifiNotificationUtil::GetInstance().CancelWifiNotification(
2316             WifiNotificationId::WIFI_PORTAL_NOTIFICATION_ID);
2317         if (hasNoInternetDialog_) {
2318             CloseNoInternetDialog();
2319         }
2320 #endif
2321     } else if (netState == SystemNetWorkState::NETWORK_IS_PORTAL) {
2322         HandleNetCheckResultIsPortal(netState, updatePortalAuthTime);
2323         if (!mIsWifiInternetCHRFlag) {
2324             WriteWifiAccessIntFailedHiSysEvent(1, NetworkFailReason::DNS_STATE_UNREACHABLE, 1, "");
2325             mIsWifiInternetCHRFlag = true;
2326         }
2327     } else {
2328         WriteIsInternetHiSysEvent(NO_NETWORK);
2329 #ifndef OHOS_ARCH_LITE
2330         SyncDeviceEverConnectedState(false);
2331 #endif
2332         SaveLinkstate(ConnState::CONNECTED, DetailedState::NOTWORKING);
2333         InvokeOnStaConnChanged(OperateResState::CONNECT_NETWORK_DISABLED, linkedInfo);
2334         lastCheckNetState_ = OperateResState::CONNECT_NETWORK_DISABLED;
2335         InsertOrUpdateNetworkStatusHistory(NetworkStatus::NO_INTERNET, false);
2336 // if wifipro is open, wifipro will notify selfcure no internet, if not, sta should notify
2337 #ifndef FEATURE_WIFI_PRO_SUPPORT
2338 #ifdef FEATURE_SELF_CURE_SUPPORT
2339         if (selfCureService_ != nullptr) {
2340             selfCureService_->NotifyInternetFailureDetected(false);
2341         }
2342 #endif
2343 #endif
2344     }
2345 #ifndef OHOS_ARCH_LITE
2346     SyncDeviceEverConnectedState(true);
2347 #endif
2348     autoPullBrowserFlag = true;
2349     TryModifyPortalAttribute(netState);
2350     HandleInternetAccessChanged(netState);
2351 }
2352 
2353 void StaStateMachine::HandleNetCheckResultIsPortal(SystemNetWorkState netState, bool updatePortalAuthTime)
2354 {
2355     WifiLinkedInfo linkedInfo;
2356     WifiConfigCenter::GetInstance().GetLinkedInfo(linkedInfo);
2357     UpdatePortalState(netState, updatePortalAuthTime);
2358     /* The tv doesn't need to publish the portal login page when connecting to a Hilink router without internet. */
2359     if (GetDeviceType() != ProductDeviceType::TV) {
2360         PublishPortalNitificationAndLogin();
2361     }
2362     bool isHomeAp = false;
2363     bool isHomeRouter = false;
2364 #ifndef OHOS_ARCH_LITE
2365     isHomeAp = WifiHistoryRecordManager::GetInstance().IsHomeAp(linkedInfo.bssid);
2366     isHomeRouter = WifiHistoryRecordManager::GetInstance().IsHomeRouter(mPortalUrl);
2367 #endif
2368     WriteIsInternetHiSysEvent(NO_NETWORK);
2369     lastCheckNetState_ = OperateResState::CONNECT_CHECK_PORTAL;
2370     WifiDeviceConfig config;
2371     WifiSettings::GetInstance().GetDeviceConfig(linkedInfo.networkId, config, m_instId);
2372     WIFI_LOGD("%{public}s, isHiLinkNetwork : %{public}d isHomeAp : %{public}d isHomeRouter : %{public}d keyMgmt : "
2373               "%{public}s", __func__, linkedInfo.isHiLinkNetwork, isHomeAp, isHomeRouter, config.keyMgmt.c_str());
2374     if ((InternalHiLinkNetworkToBool(linkedInfo.isHiLinkNetwork) || isHomeAp || isHomeRouter)
2375         && config.keyMgmt != KEY_MGMT_NONE) {
2376         // Change the value of PORTAL in networkStatusHistory to NO_INTERNET
2377         WifiDeviceConfig wifiDeviceConfig = getCurrentWifiDeviceConfig();
2378         NetworkStatusHistoryManager::ModifyAllHistoryRecord(wifiDeviceConfig.networkStatusHistory,
2379             NetworkStatus::PORTAL, NetworkStatus::NO_INTERNET);
2380         WifiSettings::GetInstance().AddDeviceConfig(wifiDeviceConfig);
2381         WifiSettings::GetInstance().SyncDeviceConfig();
2382 
2383         InsertOrUpdateNetworkStatusHistory(NetworkStatus::NO_INTERNET, false);
2384         SaveLinkstate(ConnState::CONNECTED, DetailedState::NOTWORKING);
2385         InvokeOnStaConnChanged(OperateResState::CONNECT_NETWORK_DISABLED, linkedInfo);
2386     } else {
2387         if (GetDeviceType() == ProductDeviceType::TV) {
2388             PublishPortalNitificationAndLogin();
2389         }
2390         InsertOrUpdateNetworkStatusHistory(NetworkStatus::PORTAL, false);
2391         SaveLinkstate(ConnState::CONNECTED, DetailedState::CAPTIVE_PORTAL_CHECK);
2392         InvokeOnStaConnChanged(OperateResState::CONNECT_CHECK_PORTAL, linkedInfo);
2393     }
2394 }
2395 
2396 void StaStateMachine::PublishPortalNitificationAndLogin()
2397 {
2398 #ifndef OHOS_ARCH_LITE
2399     bool shouldShowNotification =
2400         (lastCheckNetState_ != OperateResState::CONNECT_CHECK_PORTAL) && WifiConfigCenter::GetInstance().IsAllowPopUp();
2401 
2402     if (shouldShowNotification) {
2403         if (selfCureService_ == nullptr || (selfCureService_ != nullptr && !selfCureService_->IsSelfCureOnGoing())) {
2404             WIFI_LOGI("%{public}s, ShowPortalNitification", __func__);
2405             ShowPortalNitification();
2406         }
2407     }
2408 #endif
2409     if (autoPullBrowserFlag == false) {
2410         HandlePortalNetworkPorcess();
2411         autoPullBrowserFlag = true;
2412     }
2413 }
2414 
2415 void StaStateMachine::TryModifyPortalAttribute(SystemNetWorkState netState)
2416 {
2417     WifiDeviceConfig config;
2418     int ret = WifiSettings::GetInstance().GetDeviceConfig(linkedInfo.networkId, config, m_instId);
2419     if (linkedInfo.networkId == INVALID_NETWORK_ID || ret != 0 || !config.isPortal ||
2420         config.keyMgmt == KEY_MGMT_NONE) {
2421         return;
2422     }
2423     bool needChangePortalFlag = false;
2424     bool isHomeAp = false;
2425     bool isHomeRouter = false;
2426 #ifndef OHOS_ARCH_LITE
2427     isHomeAp = WifiHistoryRecordManager::GetInstance().IsHomeAp(linkedInfo.bssid);
2428     isHomeRouter = WifiHistoryRecordManager::GetInstance().IsHomeRouter(mPortalUrl);
2429 #endif
2430     bool isPortalByHistory = NetworkStatusHistoryManager::IsPortalByHistory(config.networkStatusHistory);
2431     switch (netState) {
2432         case SystemNetWorkState::NETWORK_NOTWORKING:
2433             if (isPortalByHistory) {
2434                 WIFI_LOGI("%{public}s, no internet and has portal status in history, not modify", __func__);
2435                 break;
2436             }
2437             needChangePortalFlag = true;
2438             break;
2439         case SystemNetWorkState::NETWORK_IS_WORKING:
2440             if (!InternalHiLinkNetworkToBool(linkedInfo.isHiLinkNetwork) && !isHomeAp && !isHomeRouter) {
2441                 WIFI_LOGI("%{public}s, has internet and not hilink/homeAp/homeRouter network, not modify", __func__);
2442                 break;
2443             }
2444             if (isPortalByHistory) {
2445                 WIFI_LOGI("%{public}s, has internet and has portal status in history, not modify", __func__);
2446                 break;
2447             }
2448             needChangePortalFlag = true;
2449             break;
2450         case SystemNetWorkState::NETWORK_IS_PORTAL:
2451             if (!InternalHiLinkNetworkToBool(linkedInfo.isHiLinkNetwork) && !isHomeAp && !isHomeRouter) {
2452                 WIFI_LOGI("%{public}s, portal and not hilink/homeAp/homeRouter network, not modify", __func__);
2453                 break;
2454             }
2455             needChangePortalFlag = true;
2456             break;
2457         default:
2458             break;
2459     }
2460     ChangePortalAttribute(needChangePortalFlag, config);
2461 }
2462 
2463 void StaStateMachine::ChangePortalAttribute(bool isNeedChange, WifiDeviceConfig &config)
2464 {
2465     if (!isNeedChange) {
2466         return;
2467     }
2468     WIFI_LOGI("change the value of the portal attribute to false, bssid=%{public}s",
2469         MacAnonymize(config.bssid).c_str());
2470     config.isPortal = false;
2471     WifiSettings::GetInstance().AddDeviceConfig(config);
2472     WifiSettings::GetInstance().SyncDeviceConfig();
2473 }
2474 
2475 #ifndef OHOS_ARCH_LITE
2476 void StaStateMachine::SyncDeviceEverConnectedState(bool hasNet)
2477 {
2478     if (WifiConfigCenter::GetInstance().GetSystemMode() == SystemMode::M_FACTORY_MODE
2479         || !WifiConfigCenter::GetInstance().IsAllowPopUp()
2480         || !WifiConfigCenter::GetInstance().IsAllowPcPopUp()) {
2481         WIFI_LOGI("factory version or device type no need to pop up diag");
2482         return;
2483     }
2484     WifiLinkedInfo linkedInfo;
2485     WifiConfigCenter::GetInstance().GetLinkedInfo(linkedInfo);
2486     int networkId = linkedInfo.networkId;
2487     std::string settings = WifiSettings::GetInstance().GetPackageName("SETTINGS");
2488     if (!WifiSettings::GetInstance().GetDeviceEverConnected(networkId)) {
2489         if (!hasNet) {
2490             /*If it is the first time to connect and no network status, a pop-up window is displayed.*/
2491             WifiNotificationUtil::GetInstance().ShowSettingsDialog(WifiDialogType::CDD, settings);
2492             hasNoInternetDialog_ = true;
2493         }
2494         WifiSettings::GetInstance().SetDeviceEverConnected(networkId);
2495         WIFI_LOGI("First connection, Set DeviceEverConnected true, network is %{public}d", networkId);
2496         WifiSettings::GetInstance().SyncDeviceConfig();
2497     }
2498 }
2499 #endif
2500 
2501 #ifndef OHOS_ARCH_LITE
2502 void StaStateMachine::UpdateAcceptUnvalidatedState()
2503 {
2504     WifiLinkedInfo linkedInfo;
2505     WifiConfigCenter::GetInstance().GetLinkedInfo(linkedInfo);
2506     int networkId = linkedInfo.networkId;
2507     if (WifiSettings::GetInstance().GetAcceptUnvalidated(networkId)) {
2508         WIFI_LOGI("network is recover, change the value of AcceptUnvalidated to false");
2509         WifiSettings::GetInstance().SetAcceptUnvalidated(networkId, false);
2510         WifiSettings::GetInstance().SyncDeviceConfig();
2511     }
2512 }
2513 #endif
2514 
2515 #ifndef OHOS_ARCH_LITE
2516 void StaStateMachine::CloseNoInternetDialog()
2517 {
2518     bool sendsuccess = WifiCommonEventHelper::PublishNotAvailableDialog();
2519     hasNoInternetDialog_ = false;
2520     WIFI_LOGI("Notification cancellation SettingsDialog is %{public}d", sendsuccess);
2521 }
2522 #endif
2523 /* --------------------------- state machine Connected State ------------------------------ */
2524 StaStateMachine::LinkedState::LinkedState(StaStateMachine *staStateMachine)
2525     : State("LinkedState"), pStaStateMachine(staStateMachine)
2526 {}
2527 
2528 StaStateMachine::LinkedState::~LinkedState()
2529 {}
2530 
2531 void StaStateMachine::LinkedState::GoInState()
2532 {
2533     WIFI_LOGI("LinkedState GoInState function. m_instId = %{public}d", pStaStateMachine->m_instId);
2534     WriteWifiOperateStateHiSysEvent(static_cast<int>(WifiOperateType::STA_CONNECT),
2535         static_cast<int>(WifiOperateState::STA_CONNECTED));
2536     WriteWifiLinkTypeHiSysEvent(pStaStateMachine->linkedInfo.ssid,
2537         pStaStateMachine->linkedInfo.wifiLinkType, "CONNECT");
2538 #ifndef OHOS_ARCH_LITE
2539     CheckIfRestoreWifi();
2540 #endif
2541 #ifndef OHOS_ARCH_LITE
2542     if (pStaStateMachine != nullptr && pStaStateMachine->m_NetWorkState != nullptr) {
2543         pStaStateMachine->m_NetWorkState->StartNetStateObserver(pStaStateMachine->m_NetWorkState);
2544         pStaStateMachine->lastTimestamp = 0;
2545         pStaStateMachine->StartDetectTimer(DETECT_TYPE_DEFAULT);
2546     }
2547 #endif
2548 #ifndef OHOS_ARCH_LITE
2549 #ifdef WIFI_DATA_REPORT_ENABLE
2550     pStaStateMachine->wifiDataReportService_->ReportApConnEventInfo(ConnReportReason::CONN_SUC_START,
2551         pStaStateMachine->targetNetworkId_);
2552 #endif
2553 #endif
2554     pStaStateMachine->targetNetworkId_ = INVALID_NETWORK_ID;
2555     WifiSettings::GetInstance().SetDeviceAfterConnect(pStaStateMachine->linkedInfo.networkId);
2556     WifiSettings::GetInstance().ClearAllNetworkConnectChoice();
2557     BlockConnectService::GetInstance().EnableNetworkSelectStatus(pStaStateMachine->linkedInfo.networkId);
2558 #ifndef OHOS_ARCH_LITE
2559     BlockConnectService::GetInstance().ReleaseUnusableBssidSet();
2560     BlockConnectService::GetInstance().ReleaseDhcpFailBssidSet();
2561 #endif
2562     WifiSettings::GetInstance().SyncDeviceConfig();
2563     pStaStateMachine->SaveDiscReason(DisconnectedReason::DISC_REASON_DEFAULT);
2564     pStaStateMachine->SaveLinkstate(ConnState::CONNECTED, DetailedState::CONNECTED);
2565     pStaStateMachine->InvokeOnStaConnChanged(OperateResState::CONNECT_AP_CONNECTED, pStaStateMachine->linkedInfo);
2566     return;
2567 }
2568 
2569 void StaStateMachine::LinkedState::GoOutState()
2570 {
2571     WIFI_LOGI("LinkedState GoOutState function.");
2572 }
2573 
2574 bool StaStateMachine::LinkedState::ExecuteStateMsg(InternalMessagePtr msg)
2575 {
2576     if (msg == nullptr) {
2577         WIFI_LOGI("msg is nullptr.");
2578         return false;
2579     }
2580 
2581     bool ret = NOT_EXECUTED;
2582     switch (msg->GetMessageName()) {
2583         case WIFI_SVR_CMD_STA_DHCP_RESULT_NOTIFY_EVENT: {
2584             ret = EXECUTED;
2585             DhcpResultNotify(msg);
2586             break;
2587         }
2588         case WIFI_SVR_CMD_STA_NET_DETECTION_NOTIFY_EVENT: {
2589             ret = EXECUTED;
2590             NetDetectionNotify(msg);
2591             break;
2592         }
2593         case WIFI_SVR_CMD_STA_PORTAL_BROWSE_NOTIFY_EVENT: {
2594             ret = EXECUTED;
2595             pStaStateMachine->HandlePortalNetworkPorcess();
2596             break;
2597         }
2598         case CMD_START_NETCHECK : {
2599             ret = EXECUTED;
2600             DealNetworkCheck(msg);
2601             break;
2602         }
2603         case WIFI_SVR_CMD_STA_FOLD_STATUS_NOTIFY_EVENT: {
2604             ret = EXECUTED;
2605             FoldStatusNotify(msg);
2606             break;
2607         }
2608 #ifdef FEATURE_ITNETWORK_PREFERRED_SUPPORT
2609         case WIFI_SVR_CMD_STA_WPA_STATE_CHANGE_EVENT: {
2610             ret = EXECUTED;
2611             int wpaState = msg->GetParam1();
2612             WIFI_LOGI("Report wpaState = %{public}d", wpaState);
2613             if (wpaState == static_cast<int>(SupplicantState::COMPLETED)) {
2614                 pStaStateMachine->InvokeOnStaConnChanged(OperateResState::CONNECT_AP_CONNECTED,
2615                     pStaStateMachine->linkedInfo);
2616             }
2617             break;
2618         }
2619 #endif
2620         default:
2621             break;
2622     }
2623 
2624     return ret;
2625 }
2626 
2627 void StaStateMachine::LinkedState::DhcpResultNotify(InternalMessagePtr msg)
2628 {
2629     if (msg == nullptr) {
2630         WIFI_LOGE("msg is nullptr.");
2631         return;
2632     }
2633 
2634     int result = msg->GetParam1();
2635     int ipType = msg->GetParam2();
2636     WIFI_LOGI("LinkedState, result:%{public}d, ipType = %{public}d\n", result, ipType);
2637     if (result == DhcpReturnCode::DHCP_RENEW_FAIL) {
2638         pStaStateMachine->StopTimer(static_cast<int>(CMD_START_GET_DHCP_IP_TIMEOUT));
2639     } else if (result == DhcpReturnCode::DHCP_RESULT) {
2640         pStaStateMachine->pDhcpResultNotify->DealDhcpResult(ipType);
2641     } else if (result == DhcpReturnCode::DHCP_IP_EXPIRED) {
2642         pStaStateMachine->StartDisConnectToNetwork();
2643     } else if (result == DhcpReturnCode::DHCP_OFFER_REPORT) {
2644         pStaStateMachine->pDhcpResultNotify->DealDhcpOfferResult();
2645     }
2646 }
2647 
2648 void StaStateMachine::LinkedState::FoldStatusNotify(InternalMessagePtr msg)
2649 {
2650     if (msg == nullptr) {
2651         WIFI_LOGE("msg is nullptr.");
2652         return;
2653     }
2654     pStaStateMachine->foldStatus_ = msg->GetParam1();
2655     if (pStaStateMachine->foldStatus_ == HALF_FOLD) {
2656         isExpandUpdateRssi_ = true;
2657         pStaStateMachine->StopTimer(static_cast<int>(CMD_SIGNAL_POLL));
2658         pStaStateMachine->DealSignalPollResult();
2659     } else if (pStaStateMachine->foldStatus_ == EXPAND) {
2660         isExpandUpdateRssi_ = false;
2661     } else {
2662         isExpandUpdateRssi_ = true;
2663     }
2664 }
2665 
2666 void StaStateMachine::LinkedState::UpdateExpandOffset()
2667 {
2668     if (!isExpandUpdateRssi_) {
2669         expandRssi_ = pStaStateMachine->linkedInfo.rssi;
2670         rssiOffset_ = expandRssi_ - halfFoldRssi_;
2671     }
2672     if (rssiOffset_ < RSSI_OFFSET_MIN) {
2673         rssiOffset_ = RSSI_OFFSET_MIN;
2674     } else if (rssiOffset_ >= RSSI_OFFSET_MAX) {
2675         rssiOffset_ = RSSI_OFFSET_MAX;
2676     }
2677     isExpandUpdateRssi_ = true;
2678 }
2679 void StaStateMachine::LinkedState::NetDetectionNotify(InternalMessagePtr msg)
2680 {
2681     if (msg == nullptr) {
2682         WIFI_LOGE("msg is nullptr.");
2683         return;
2684     }
2685 
2686     SystemNetWorkState netstate = (SystemNetWorkState)msg->GetParam1();
2687     std::string url;
2688     if (!msg->GetMessageObj(url)) {
2689         WIFI_LOGW("Failed to obtain portal url.");
2690     }
2691     WIFI_LOGI("netdetection, netstate:%{public}d url:%{private}s\n", netstate, url.c_str());
2692     pStaStateMachine->HandleNetCheckResult(netstate, url);
2693 }
2694 
2695 void StaStateMachine::LinkedState::DealNetworkCheck(InternalMessagePtr msg)
2696 {
2697     WIFI_LOGD("enter DealNetworkCheck.\n");
2698     if (msg == nullptr || pStaStateMachine->enableSignalPoll == false) {
2699         WIFI_LOGE("detection screen state [%{public}d].", pStaStateMachine->enableSignalPoll);
2700         return;
2701     }
2702 #ifndef OHOS_ARCH_LITE
2703     if (pStaStateMachine->m_NetWorkState) {
2704         pStaStateMachine->m_NetWorkState->StartWifiDetection();
2705     }
2706 #endif
2707 }
2708 
2709 #ifndef OHOS_ARCH_LITE
2710 void StaStateMachine::LinkedState::CheckIfRestoreWifi()
2711 {
2712     WifiLinkedInfo linkedInfo;
2713     WifiConfigCenter::GetInstance().GetLinkedInfo(linkedInfo);
2714     int networkId = linkedInfo.networkId;
2715     if (WifiSettings::GetInstance().GetAcceptUnvalidated(networkId)) {
2716         WIFI_LOGI("The user has chosen to use the current WiFi.");
2717         WifiNetAgent::GetInstance().RestoreWifiConnection();
2718     }
2719 }
2720 #endif
2721 
2722 void StaStateMachine::HilinkSetMacAddress(std::string &cmd)
2723 {
2724     std::string::size_type begPos = 0;
2725     if ((begPos = cmd.find("=")) == std::string::npos) {
2726         WIFI_LOGI("HilinkSetMacAddress() cmd not find =");
2727         return;
2728     }
2729     std::string macAddress = cmd.substr(begPos + 1);
2730     if (macAddress.empty()) {
2731         WIFI_LOGI("HilinkSetMacAddress() macAddress is empty");
2732         return;
2733     }
2734 
2735     m_hilinkDeviceConfig.macAddress = macAddress;
2736     std::string realMacAddress = "";
2737 
2738     WifiSettings::GetInstance().GetRealMacAddress(realMacAddress, m_instId);
2739     m_hilinkDeviceConfig.wifiPrivacySetting = (macAddress == realMacAddress ?
2740         WifiPrivacyConfig::DEVICEMAC : WifiPrivacyConfig::RANDOMMAC);
2741     WIFI_LOGI("HilinkSetMacAddress() wifiPrivacySetting= %{public}d realMacAddress= %{public}s",
2742         m_hilinkDeviceConfig.wifiPrivacySetting, MacAnonymize(realMacAddress).c_str());
2743 
2744     return;
2745 }
2746 
2747 void StaStateMachine::DealHiLinkDataToWpa(InternalMessagePtr msg)
2748 {
2749     if (msg == nullptr) {
2750         WIFI_LOGE("DealHiLinkDataToWpa InternalMessage msg is null.");
2751         return;
2752     }
2753     WIFI_LOGI("DealHiLinkDataToWpa=%{public}d received.\n", msg->GetMessageName());
2754     switch (msg->GetMessageName()) {
2755         case WIFI_SVR_COM_STA_ENABLE_HILINK: {
2756             m_hilinkDeviceConfig.bssidType = msg->GetParam1();
2757             bool uiFlag = msg->GetParam2();
2758             m_hilinkDeviceConfig.ssid = msg->GetStringFromMessage();
2759             m_hilinkDeviceConfig.bssid = msg->GetStringFromMessage();
2760             m_hilinkDeviceConfig.keyMgmt = msg->GetStringFromMessage();
2761             std::string cmd = msg->GetStringFromMessage();
2762             WIFI_LOGI("DealEnableHiLinkHandshake start shell uiflag = %{public}d, cmd = %{public}s",
2763                 static_cast<int>(uiFlag), MacAnonymize(cmd).c_str());
2764             WifiStaHalInterface::GetInstance().ShellCmd("wlan0", cmd);
2765             break;
2766         }
2767         case WIFI_SVR_COM_STA_HILINK_DELIVER_MAC: {
2768             std::string cmd;
2769             msg->GetMessageObj(cmd);
2770             HilinkSetMacAddress(cmd);
2771             WIFI_LOGI("DealHiLinkMacDeliver start shell cmd, cmd = %{public}s", MacAnonymize(cmd).c_str());
2772             WifiStaHalInterface::GetInstance().ShellCmd("wlan0", cmd);
2773             break;
2774         }
2775         case WIFI_SVR_COM_STA_HILINK_TRIGGER_WPS: {
2776             WIFI_LOGI("DealHiLinkTriggerWps start ClearDeviceConfig");
2777             WifiStaHalInterface::GetInstance().ClearDeviceConfig(
2778                 WifiConfigCenter::GetInstance().GetStaIfaceName(m_instId));
2779             WIFI_LOGI("DealHiLinkTriggerWps SPECIAL_CONNECTED");
2780             InvokeOnStaConnChanged(OperateResState::SPECIAL_CONNECTED, linkedInfo);
2781             WIFI_LOGI("DealHiLinkTriggerWps start startWpsPbc");
2782             std::string bssid;
2783             msg->GetMessageObj(bssid);
2784             WifiHalWpsConfig config;
2785             config.anyFlag = 0;
2786             config.multiAp = 0;
2787             config.bssid = bssid;
2788             WifiStaHalInterface::GetInstance().StartWpsPbcMode(config);
2789             m_hilinkFlag = true;
2790             targetNetworkId_ = UNKNOWN_HILINK_NETWORK_ID;
2791             break;
2792         }
2793         default:
2794             return;
2795     }
2796 }
2797 
2798 void StaStateMachine::DealWpaStateChange(InternalMessagePtr msg)
2799 {
2800     if (msg == nullptr) {
2801         LOGE("DealWpaStateChange InternalMessage msg is null.");
2802         return;
2803     }
2804     int status = msg->GetParam1();
2805     LOGI("DealWpaStateChange status: %{public}d", status);
2806     linkedInfo.supplicantState = static_cast<SupplicantState>(status);
2807     WifiConfigCenter::GetInstance().SaveLinkedInfo(linkedInfo, m_instId);
2808 }
2809 /* --------------------------- state machine Roaming State ------------------------------ */
2810 StaStateMachine::ApRoamingState::ApRoamingState(StaStateMachine *staStateMachine)
2811     : State("ApRoamingState"), pStaStateMachine(staStateMachine)
2812 {}
2813 
2814 StaStateMachine::ApRoamingState::~ApRoamingState()
2815 {}
2816 
2817 void StaStateMachine::ApRoamingState::GoInState()
2818 {
2819     WIFI_LOGI("ApRoamingState GoInState function. start aproaming timer!");
2820     pStaStateMachine->isCurrentRoaming_ = true;
2821     pStaStateMachine->StartTimer(static_cast<int>(CMD_AP_ROAMING_TIMEOUT_CHECK), STA_AP_ROAMING_TIMEOUT);
2822 }
2823 
2824 void StaStateMachine::ApRoamingState::GoOutState()
2825 {
2826     WIFI_LOGI("ApRoamingState GoOutState function. stop aproaming timer!");
2827     pStaStateMachine->isCurrentRoaming_ = false;
2828     pStaStateMachine->StopTimer(static_cast<int>(CMD_AP_ROAMING_TIMEOUT_CHECK));
2829 }
2830 
2831 bool StaStateMachine::ApRoamingState::ExecuteStateMsg(InternalMessagePtr msg)
2832 {
2833     if (msg == nullptr) {
2834         return false;
2835     }
2836 
2837     WIFI_LOGI("ApRoamingState, reveived msgCode=%{public}d msg. m_instId = %{public}d",
2838         msg->GetMessageName(), pStaStateMachine->m_instId);
2839     bool ret = NOT_EXECUTED;
2840     switch (msg->GetMessageName()) {
2841         case WIFI_SVR_CMD_STA_NETWORK_CONNECTION_EVENT: {
2842             WIFI_LOGI("ApRoamingState, receive WIFI_SVR_CMD_STA_NETWORK_CONNECTION_EVENT event.");
2843             ret = HandleNetworkConnectionEvent(msg);
2844             break;
2845         }
2846         case CMD_AP_ROAMING_TIMEOUT_CHECK: {
2847             ret = EXECUTED;
2848             DealApRoamingStateTimeout(msg);
2849             break;
2850         }
2851         default:
2852             WIFI_LOGI("ApRoamingState-msgCode=%d not handled.", msg->GetMessageName());
2853             break;
2854     }
2855     return ret;
2856 }
2857 
2858 void StaStateMachine::ApRoamingState::DealApRoamingStateTimeout(InternalMessagePtr msg)
2859 {
2860     if (msg == nullptr) {
2861         WIFI_LOGE("DealApRoamingStateTimeout InternalMessage msg is null.");
2862         return;
2863     }
2864     WIFI_LOGI("DealApRoamingStateTimeout StopTimer aproaming timer");
2865     pStaStateMachine->StopTimer(static_cast<int>(CMD_AP_ROAMING_TIMEOUT_CHECK));
2866     pStaStateMachine->StartDisConnectToNetwork();
2867 }
2868 
2869 bool StaStateMachine::ApRoamingState::HandleNetworkConnectionEvent(InternalMessagePtr msg)
2870 {
2871     bool ret = EXECUTED;
2872     std::string bssid = msg->GetStringFromMessage();
2873     pStaStateMachine->isRoam = true;
2874     pStaStateMachine->StopTimer(static_cast<int>(CMD_AP_ROAMING_TIMEOUT_CHECK));
2875     pStaStateMachine->StopTimer(static_cast<int>(CMD_NETWORK_CONNECT_TIMEOUT));
2876     pStaStateMachine->AfterApLinkedprocess(bssid);
2877     if (!pStaStateMachine->CanArpReachable()) {
2878         WIFI_LOGI("Arp is not reachable");
2879         WriteWifiSelfcureHisysevent(static_cast<int>(WifiSelfcureType::ROAMING_ABNORMAL));
2880         /* The current state of StaStateMachine transfers to GetIpState. */
2881         pStaStateMachine->SwitchState(pStaStateMachine->pGetIpState);
2882     } else {
2883         WIFI_LOGI("Arp is reachable");
2884         pStaStateMachine->SwitchState(pStaStateMachine->pLinkedState);
2885     }
2886     return ret;
2887 }
2888 
2889 bool StaStateMachine::CanArpReachable()
2890 {
2891     ArpChecker arpChecker;
2892     std::string macAddress;
2893     WifiConfigCenter::GetInstance().GetMacAddress(macAddress, m_instId);
2894     IpInfo ipInfo;
2895     WifiConfigCenter::GetInstance().GetIpInfo(ipInfo, m_instId);
2896     std::string ipAddress = IpTools::ConvertIpv4Address(ipInfo.ipAddress);
2897     std::string ifName = WifiConfigCenter::GetInstance().GetStaIfaceName(m_instId);
2898     if (ipInfo.gateway == 0) {
2899         WIFI_LOGI("gateway is empty");
2900         return false;
2901     }
2902     uint64_t arpRtt = 0;
2903     std::string gateway = IpTools::ConvertIpv4Address(ipInfo.gateway);
2904     arpChecker.Start(ifName, macAddress, ipAddress, gateway);
2905     for (int i = 0; i < DEFAULT_NUM_ARP_PINGS; i++) {
2906         if (arpChecker.DoArpCheck(MAX_ARP_CHECK_TIME, true, arpRtt)) {
2907             WriteArpInfoHiSysEvent(arpRtt, 0);
2908             return true;
2909         }
2910     }
2911     WriteArpInfoHiSysEvent(arpRtt, 1);
2912     return false;
2913 }
2914 
2915 ErrCode StaStateMachine::ConfigRandMacSelfCure(const int networkId)
2916 {
2917     WifiDeviceConfig config;
2918     if (WifiSettings::GetInstance().GetDeviceConfig(networkId, config, m_instId) != 0) {
2919         WIFI_LOGE("GetDeviceConfig failed!");
2920         return WIFI_OPT_FAILED;
2921     }
2922     if (config.isReassocSelfCureWithFactoryMacAddress == SELF_CURE_FAC_MAC_REASSOC) {
2923         config.wifiPrivacySetting = WifiPrivacyConfig::DEVICEMAC;
2924     } else if (config.isReassocSelfCureWithFactoryMacAddress == SELF_CURE_RAND_MAC_REASSOC) {
2925         config.wifiPrivacySetting = WifiPrivacyConfig::RANDOMMAC;
2926     }
2927     WifiSettings::GetInstance().AddDeviceConfig(config);
2928     WifiSettings::GetInstance().SyncDeviceConfig();
2929     return WIFI_OPT_SUCCESS;
2930 }
2931 
2932 void StaStateMachine::AfterApLinkedprocess(std::string bssid)
2933 {
2934     WIFI_LOGI("AfterApLinkedprocess, Receive bssid=%{public}s m_instId = %{public}d",
2935         MacAnonymize(bssid).c_str(), m_instId);
2936     WifiDeviceConfig deviceConfig;
2937     if (WifiSettings::GetInstance().GetDeviceConfig(linkedInfo.networkId, deviceConfig, m_instId) != 0) {
2938         WIFI_LOGE("%{public}s cannot find config for networkId = %{public}d", __FUNCTION__, linkedInfo.networkId);
2939         StartDisConnectToNetwork();
2940         return;
2941     }
2942     deviceConfig.bssid = bssid;
2943     WifiSettings::GetInstance().AddDeviceConfig(deviceConfig);
2944     WifiSettings::GetInstance().SyncDeviceConfig();
2945 
2946     std::string ifaceName = WifiConfigCenter::GetInstance().GetStaIfaceName(m_instId);
2947     WifiStaHalInterface::GetInstance().SetBssid(WPA_DEFAULT_NETWORKID, ANY_BSSID, ifaceName);
2948 
2949     std::string macAddr;
2950     std::string realMacAddr;
2951     WifiConfigCenter::GetInstance().GetMacAddress(macAddr, m_instId);
2952     WifiSettings::GetInstance().GetRealMacAddress(realMacAddr, m_instId);
2953 
2954 #ifdef FEATURE_WIFI_MDM_RESTRICTED_SUPPORT
2955     if (WhetherRestrictedByMdm(deviceConfig.ssid, deviceConfig.bssid, true)) {
2956         DealMdmRestrictedConnect(deviceConfig);
2957         return;
2958     }
2959 #endif
2960 
2961     linkedInfo.ssid = deviceConfig.ssid;
2962     linkedInfo.bssid = bssid;
2963     linkedInfo.macType = (macAddr == realMacAddr ?
2964         static_cast<int>(WifiPrivacyConfig::DEVICEMAC) : static_cast<int>(WifiPrivacyConfig::RANDOMMAC));
2965     linkedInfo.macAddress = macAddr;
2966     linkedInfo.ifHiddenSSID = deviceConfig.hiddenSSID;
2967     WifiConfigCenter::GetInstance().SetWifiLinkedStandardAndMaxSpeed(linkedInfo);
2968 }
2969 
2970 void StaStateMachine::EnableScreenOffSignalPoll()
2971 {
2972     enableSignalPoll = true;
2973     lastSignalLevel_ = INVALID_SIGNAL_LEVEL; // Reset signal level when first start signal poll
2974     staSignalPollDelayTime_ = STA_SIGNAL_POLL_DELAY_WITH_TASK;
2975     StopTimer(static_cast<int>(CMD_SIGNAL_POLL));
2976     StartTimer(static_cast<int>(CMD_SIGNAL_POLL), 0);
2977 }
2978 
2979 void StaStateMachine::DealScreenStateChangedEvent(InternalMessagePtr msg)
2980 {
2981     if (msg == nullptr) {
2982         WIFI_LOGE("DealScreenStateChangedEvent InternalMessage msg is null.");
2983         return;
2984     }
2985 
2986     int screenState = msg->GetParam1();
2987     WIFI_LOGI("DealScreenStateChangedEvent, Receive msg: screenState=%{public}d", screenState);
2988     if (screenState == MODE_STATE_OPEN) {
2989         enableSignalPoll = true;
2990         lastSignalLevel_ = INVALID_SIGNAL_LEVEL;   // Reset signal level when first start signal poll
2991         StopTimer(static_cast<int>(CMD_SIGNAL_POLL));
2992         StartTimer(static_cast<int>(CMD_SIGNAL_POLL), 0);
2993         StartDetectTimer(DETECT_TYPE_DEFAULT);
2994     }
2995     if (screenState == MODE_STATE_CLOSE) {
2996         if (isAudioOn_) {
2997             EnableScreenOffSignalPoll();
2998             WIFI_LOGI("DealScreenOffPoll, screen off poll start");
2999         } else {
3000             enableSignalPoll = false;
3001             StopTimer(static_cast<int>(CMD_SIGNAL_POLL));
3002             WIFI_LOGI("DealScreenOffPoll, screen off poll stop");
3003         }
3004         StopTimer(static_cast<int>(CMD_START_NETCHECK));
3005     }
3006 #ifndef OHOS_ARCH_LITE
3007     WifiProtectManager::GetInstance().HandleScreenStateChanged(screenState == MODE_STATE_OPEN);
3008 #endif
3009     if (m_instId == INSTID_WLAN0) {
3010         if (WifiSupplicantHalInterface::GetInstance().WpaSetSuspendMode(screenState == MODE_STATE_CLOSE)
3011             != WIFI_HAL_OPT_OK) {
3012             WIFI_LOGE("WpaSetSuspendMode failed!");
3013         }
3014     }
3015     return;
3016 }
3017 
3018 void StaStateMachine::DealAudioStateChangedEvent(InternalMessagePtr msg)
3019 {
3020     if (msg == nullptr) {
3021         WIFI_LOGE("DealScreenOffPoll InternalMessage msg is null.");
3022         return;
3023     }
3024     int isAudioOn = msg->GetParam1();
3025     WIFI_LOGI("DealScreenOffPoll, Receive msg: isAudioOn=%{public}d", isAudioOn);
3026     isAudioOn_ = isAudioOn;
3027     if ((WifiConfigCenter::GetInstance().GetScreenState() == MODE_STATE_CLOSE) && (isAudioOn_ == AUDIO_OFF)) {
3028         WIFI_LOGI("DealScreenOffPoll, poll stop when screen off and audio off");
3029         enableSignalPoll = false;
3030         staSignalPollDelayTime_ = STA_SIGNAL_POLL_DELAY;
3031     } else if ((WifiConfigCenter::GetInstance().GetScreenState() == MODE_STATE_CLOSE) && (isAudioOn_ == AUDIO_ON)) {
3032         WIFI_LOGI("DealScreenOffPoll, poll start when screen off and audio on");
3033         EnableScreenOffSignalPoll();
3034     }
3035 #ifndef OHOS_ARCH_LITE
3036     if (enhanceService_ == nullptr) {
3037         WIFI_LOGE("%{public}s enhanceService NULL", __FUNCTION__);
3038         return;
3039     }
3040     bool isAudioScene = isAudioOn_ == AUDIO_ON ? true : false;
3041     enhanceService_->NotifyAudioSceneChanged(isAudioScene);
3042 #endif
3043 }
3044 
3045 void StaStateMachine::ResetWifi7WurInfo()
3046 {
3047     linkedInfo.isWurEnable = false;
3048 }
3049 
3050 void StaStateMachine::DhcpResultNotify::SaveDhcpResult(DhcpResult *dest, DhcpResult *source)
3051 {
3052     if (dest == nullptr || source == nullptr) {
3053         WIFI_LOGE("SaveDhcpResult dest or source is nullptr.");
3054         return;
3055     }
3056 
3057     dest->iptype = source->iptype;
3058     dest->isOptSuc = source->isOptSuc;
3059     dest->uOptLeasetime = source->uOptLeasetime;
3060     dest->uAddTime = source->uAddTime;
3061     dest->uGetTime = source->uGetTime;
3062     if (strcpy_s(dest->strOptClientId, DHCP_MAX_FILE_BYTES, source->strOptClientId) != EOK) {
3063         WIFI_LOGE("SaveDhcpResult strOptClientId strcpy_s failed!");
3064         return;
3065     }
3066     if (strcpy_s(dest->strOptServerId, DHCP_MAX_FILE_BYTES, source->strOptServerId) != EOK) {
3067         WIFI_LOGE("SaveDhcpResult strOptServerId strcpy_s failed!");
3068         return;
3069     }
3070     if (strcpy_s(dest->strOptSubnet, DHCP_MAX_FILE_BYTES, source->strOptSubnet) != EOK) {
3071         WIFI_LOGE("SaveDhcpResult strOptSubnet strcpy_s failed!");
3072         return;
3073     }
3074     if (strcpy_s(dest->strOptDns1, DHCP_MAX_FILE_BYTES, source->strOptDns1) != EOK) {
3075         WIFI_LOGE("SaveDhcpResult strOptDns1 strcpy_s failed!");
3076         return;
3077     }
3078     if (strcpy_s(dest->strOptDns2, DHCP_MAX_FILE_BYTES, source->strOptDns2) != EOK) {
3079         WIFI_LOGE("SaveDhcpResult strOptDns2 strcpy_s failed!");
3080         return;
3081     }
3082     if (strcpy_s(dest->strOptRouter1, DHCP_MAX_FILE_BYTES, source->strOptRouter1) != EOK) {
3083         WIFI_LOGE("SaveDhcpResult strOptRouter1 strcpy_s failed!");
3084         return;
3085     }
3086     if (strcpy_s(dest->strOptRouter2, DHCP_MAX_FILE_BYTES, source->strOptRouter2) != EOK) {
3087         WIFI_LOGE("SaveDhcpResult strOptRouter2 strcpy_s failed!");
3088         return;
3089     }
3090     if (strcpy_s(dest->strOptVendor, DHCP_MAX_FILE_BYTES, source->strOptVendor) != EOK) {
3091         WIFI_LOGE("SaveDhcpResult strOptVendor strcpy_s failed!");
3092         return;
3093     }
3094     WIFI_LOGI("SaveDhcpResult ok, ipType:%{public}d", dest->iptype);
3095     StaStateMachine::DhcpResultNotify::SaveDhcpResultExt(dest, source);
3096 }
3097 
3098 void StaStateMachine::DhcpResultNotify::SaveDhcpResultExt(DhcpResult *dest, DhcpResult *source)
3099 {
3100     if (dest == nullptr || source == nullptr) {
3101         WIFI_LOGE("SaveDhcpResultExt dest or source is nullptr.");
3102         return;
3103     }
3104     if (strcpy_s(dest->strOptLinkIpv6Addr, DHCP_MAX_FILE_BYTES, source->strOptLinkIpv6Addr) != EOK) {
3105         WIFI_LOGE("SaveDhcpResultExt strOptLinkIpv6Addr strcpy_s failed!");
3106         return;
3107     }
3108     if (strcpy_s(dest->strOptRandIpv6Addr, DHCP_MAX_FILE_BYTES, source->strOptRandIpv6Addr) != EOK) {
3109         WIFI_LOGE("SaveDhcpResultExt strOptRandIpv6Addr strcpy_s failed!");
3110         return;
3111     }
3112     if (strcpy_s(dest->strOptLocalAddr1, DHCP_MAX_FILE_BYTES, source->strOptLocalAddr1) != EOK) {
3113         WIFI_LOGE("SaveDhcpResultExt strOptLocalAddr1 strcpy_s failed!");
3114         return;
3115     }
3116     if (strcpy_s(dest->strOptLocalAddr2, DHCP_MAX_FILE_BYTES, source->strOptLocalAddr2) != EOK) {
3117         WIFI_LOGE("SaveDhcpResultExt strOptLocalAddr2 strcpy_s failed!");
3118         return;
3119     }
3120     if (source->dnsList.dnsNumber > 0 && source->dnsList.dnsNumber <= DHCP_DNS_MAX_NUMBER) {
3121         dest->dnsList.dnsNumber = 0;
3122         for (uint32_t i = 0; i < source->dnsList.dnsNumber; i++) {
3123             if (memcpy_s(dest->dnsList.dnsAddr[i], DHCP_LEASE_DATA_MAX_LEN, source->dnsList.dnsAddr[i],
3124                 DHCP_LEASE_DATA_MAX_LEN -1) != EOK) {
3125                 WIFI_LOGE("SaveDhcpResultExt memcpy_s failed! i:%{public}d", i);
3126             } else {
3127                 dest->dnsList.dnsNumber++;
3128             }
3129         }
3130         WIFI_LOGI("SaveDhcpResultExt destDnsNumber:%{public}d sourceDnsNumber:%{public}d", dest->dnsList.dnsNumber,
3131             source->dnsList.dnsNumber);
3132     }
3133     WIFI_LOGI("SaveDhcpResultExt ok, ipType:%{public}d", dest->iptype);
3134 }
3135 
3136 /* ------------------ state machine dhcp callback function ----------------- */
3137 StaStateMachine* StaStateMachine::DhcpResultNotify::pStaStateMachineList[STA_INSTANCE_MAX_NUM] = {nullptr};
3138 
3139 StaStateMachine::DhcpResultNotify::DhcpResultNotify(StaStateMachine *staStateMachine)
3140 {
3141     // Save the instance of StaStateMachine to the static array.
3142     pStaStateMachineList[staStateMachine->m_instId] = staStateMachine;
3143     // Save the instance of StaStateMachine to the member variable.
3144     pStaStateMachine = staStateMachine;
3145 }
3146 StaStateMachine::DhcpResultNotify::~DhcpResultNotify()
3147 {
3148 }
3149 
3150 void StaStateMachine::DhcpResultNotify::OnSuccess(int status, const char *ifname, DhcpResult *result)
3151 {
3152     if (ifname == nullptr || result == nullptr) {
3153         WIFI_LOGE("StaStateMachine DhcpResultNotify OnSuccess ifname or result is nullptr.");
3154         return;
3155     }
3156     for (int instId = 0; instId < STA_INSTANCE_MAX_NUM; instId++) {
3157         if (pStaStateMachineList[instId] != nullptr
3158             && strcmp(ifname, WifiConfigCenter::GetInstance().GetStaIfaceName(instId).c_str()) == 0) {
3159             pStaStateMachineList[instId]->pDhcpResultNotify->OnSuccessDhcpResult(status, ifname, result);
3160         }
3161     }
3162 }
3163 
3164 void StaStateMachine::DhcpResultNotify::OnSuccessDhcpResult(int status, const char *ifname, DhcpResult *result)
3165 {
3166     if (ifname == nullptr || result == nullptr || pStaStateMachine == nullptr) {
3167         WIFI_LOGE("StaStateMachine DhcpResultNotify OnSuccess ifname or result is nullptr.");
3168         return;
3169     }
3170     WIFI_LOGI("Enter Sta DhcpResultNotify OnSuccess. ifname=[%{public}s] status=[%{public}d]", ifname, status);
3171     WIFI_LOGI("iptype=%{public}d, isOptSuc=%{public}d, clientip =%{private}s, \
3172         serverip=%{private}s, subnet=%{private}s", result->iptype, result->isOptSuc,
3173         result->strOptClientId,  result->strOptServerId, result->strOptSubnet);
3174     WIFI_LOGI("gateway1=%{private}s, gateway2=%{private}s, strDns1=%{private}s, strDns2=%{private}s, \
3175         strVendor=%{public}s, uOptLeasetime=%{public}d, uAddTime=%{public}d, uGetTime=%{public}d, \
3176         currentTpType=%{public}d", result->strOptRouter1, result->strOptRouter2, result->strOptDns1,
3177         result->strOptDns2, result->strOptVendor, result->uOptLeasetime, result->uAddTime,
3178         result->uGetTime, pStaStateMachine->currentTpType);
3179 
3180     WriteWifiOperateStateHiSysEvent(static_cast<int>(WifiOperateType::STA_DHCP),
3181         static_cast<int>(WifiOperateState::STA_DHCP_SUCCESS));
3182     if (result->iptype == 0) { /* 0-ipv4,1-ipv6 */
3183         WIFI_LOGI("StopTimer CMD_START_GET_DHCP_IP_TIMEOUT OnSuccess");
3184         pStaStateMachine->StopTimer(static_cast<int>(CMD_START_GET_DHCP_IP_TIMEOUT));
3185         {
3186             std::unique_lock<std::mutex> lock(dhcpResultMutex);
3187             SaveDhcpResult(&DhcpIpv4Result, result);
3188         }
3189     } else {
3190         std::unique_lock<std::mutex> lock(dhcpResultMutex);
3191         SaveDhcpResult(&DhcpIpv6Result, result);
3192     }
3193     DhcpResultNotifyEvent(DhcpReturnCode::DHCP_RESULT, result->iptype);
3194 }
3195 
3196 void StaStateMachine::DhcpResultNotify::OnDhcpOffer(int status, const char *ifname, DhcpResult *result)
3197 {
3198     if (ifname == nullptr || result == nullptr) {
3199         WIFI_LOGE("StaStateMachine DhcpResultNotify OnDhcpOffer ifname or result is nullptr.");
3200         return;
3201     }
3202     for (int instId = 0; instId < STA_INSTANCE_MAX_NUM; instId++) {
3203         if (pStaStateMachineList[instId] != nullptr
3204             && strcmp(ifname, WifiConfigCenter::GetInstance().GetStaIfaceName(instId).c_str()) == 0) {
3205             pStaStateMachineList[instId]->pDhcpResultNotify->OnDhcpOfferResult(status, ifname, result);
3206         }
3207     }
3208 }
3209 
3210 void StaStateMachine::DhcpResultNotify::OnDhcpOfferResult(int status, const char *ifname, DhcpResult *result)
3211 {
3212     if (ifname == nullptr || pStaStateMachine == nullptr) {
3213         WIFI_LOGE("StaStateMachine DhcpResultNotify OnDhcpOfferResult ifname or result is nullptr.");
3214         return;
3215     }
3216     WIFI_LOGI("DhcpResultNotify TYPE_DHCP_OFFER");
3217     {
3218         std::unique_lock<std::mutex> lock(dhcpResultMutex);
3219         SaveDhcpResult(&DhcpOfferInfo, result);
3220     }
3221     DhcpResultNotifyEvent(DhcpReturnCode::DHCP_OFFER_REPORT, result->iptype);
3222 }
3223 
3224 void StaStateMachine::DhcpResultNotify::DealDhcpResult(int ipType)
3225 {
3226     DhcpResult *result = nullptr;
3227     IpInfo ipInfo;
3228     IpV6Info ipv6Info;
3229     WifiConfigCenter::GetInstance().GetIpInfo(ipInfo, pStaStateMachine->m_instId);
3230     WifiConfigCenter::GetInstance().GetIpv6Info(ipv6Info, pStaStateMachine->m_instId);
3231     if (ipType == 0) { /* 0-ipv4,1-ipv6 */
3232         {
3233             std::unique_lock<std::mutex> lock(dhcpResultMutex);
3234             result = &(StaStateMachine::DhcpResultNotify::DhcpIpv4Result);
3235             TryToSaveIpV4Result(ipInfo, ipv6Info, result);
3236         }
3237         IpCacheInfo ipCacheInfo;
3238         std::string ssid = pStaStateMachine->linkedInfo.ssid;
3239         std::string bssid = pStaStateMachine->linkedInfo.bssid;
3240         if ((strncpy_s(ipCacheInfo.ssid, SSID_MAX_LEN, ssid.c_str(), ssid.length()) == EOK) &&
3241             (strncpy_s(ipCacheInfo.bssid, MAC_ADDR_MAX_LEN, bssid.c_str(), bssid.length()) == EOK)) {
3242             DealWifiDhcpCache(WIFI_DHCP_CACHE_ADD, ipCacheInfo);
3243         }
3244     } else {
3245         std::unique_lock<std::mutex> lock(dhcpResultMutex);
3246         result = &(StaStateMachine::DhcpResultNotify::DhcpIpv6Result);
3247         TryToSaveIpV6Result(ipInfo, ipv6Info, result);
3248     }
3249     TryToCloseDhcpClient(result->iptype);
3250 
3251     WifiDeviceConfig config;
3252     AssignIpMethod assignMethod = AssignIpMethod::DHCP;
3253     int ret = WifiSettings::GetInstance().GetDeviceConfig(pStaStateMachine->linkedInfo.networkId, config,
3254         pStaStateMachine->m_instId);
3255     if (ret == 0) {
3256         assignMethod = config.wifiIpConfig.assignMethod;
3257     }
3258     WIFI_LOGI("DhcpResultNotify OnSuccess, uLeaseTime=%{public}d %{public}d %{public}d m_instId = %{public}d",
3259         result->uOptLeasetime, assignMethod, pStaStateMachine->currentTpType, pStaStateMachine->m_instId);
3260     return;
3261 }
3262 
3263 void StaStateMachine::DhcpResultNotify::TryToSaveIpV4ResultExt(IpInfo &ipInfo, IpV6Info &ipv6Info, DhcpResult *result)
3264 {
3265     if (result == nullptr) {
3266         WIFI_LOGE("TryToSaveIpV4ResultExt result nullptr.");
3267         return;
3268     }
3269     ipInfo.ipAddress = IpTools::ConvertIpv4Address(result->strOptClientId);
3270     ipInfo.gateway = IpTools::ConvertIpv4Address(result->strOptRouter1);
3271     ipInfo.netmask = IpTools::ConvertIpv4Address(result->strOptSubnet);
3272     ipInfo.primaryDns = IpTools::ConvertIpv4Address(result->strOptDns1);
3273     ipInfo.secondDns = IpTools::ConvertIpv4Address(result->strOptDns2);
3274     ipInfo.serverIp = IpTools::ConvertIpv4Address(result->strOptServerId);
3275     ipInfo.leaseDuration = result->uOptLeasetime;
3276     ipInfo.dnsAddr.clear();
3277     if (ipInfo.primaryDns != 0) {
3278         ipInfo.dnsAddr.push_back(ipInfo.primaryDns);
3279     }
3280     if (ipInfo.secondDns != 0) {
3281         ipInfo.dnsAddr.push_back(ipInfo.secondDns);
3282     }
3283     if (result->dnsList.dnsNumber > 0 && result->dnsList.dnsNumber <= DHCP_DNS_MAX_NUMBER) {
3284         for (uint32_t i = 0; i < result->dnsList.dnsNumber; i++) {
3285             unsigned int ipv4Address = IpTools::ConvertIpv4Address(result->dnsList.dnsAddr[i]);
3286             if (std::find(ipInfo.dnsAddr.begin(), ipInfo.dnsAddr.end(), ipv4Address) != ipInfo.dnsAddr.end()) {
3287                 WIFI_LOGD("TryToSaveIpV4ResultExt dnsAddr already exists, skip it.");
3288                 continue;
3289             }
3290             ipInfo.dnsAddr.push_back(ipv4Address);
3291         }
3292     }
3293     WifiConfigCenter::GetInstance().SaveIpInfo(ipInfo, pStaStateMachine->m_instId);
3294 }
3295 
3296 void StaStateMachine::DhcpResultNotify::TryToSaveIpV4Result(IpInfo &ipInfo, IpV6Info &ipv6Info, DhcpResult *result)
3297 {
3298     if (result == nullptr) {
3299         WIFI_LOGE("TryToSaveIpV4Result resultis nullptr.");
3300         return;
3301     }
3302 
3303     if (!((IpTools::ConvertIpv4Address(result->strOptClientId) == ipInfo.ipAddress) &&
3304         (IpTools::ConvertIpv4Address(result->strOptRouter1) == ipInfo.gateway))) {
3305         if (result->iptype == 0) {  /* 0-ipv4,1-ipv6 */
3306             TryToSaveIpV4ResultExt(ipInfo, ipv6Info, result);
3307             pStaStateMachine->linkedInfo.ipAddress = IpTools::ConvertIpv4Address(result->strOptClientId);
3308             /* If not phone hotspot, set .isDataRestricted = 0. */
3309             std::string strVendor = result->strOptVendor;
3310             std::string ipAddress = result->strOptClientId;
3311             pStaStateMachine->linkedInfo.isDataRestricted =
3312                 (strVendor.find("ANDROID_METERED") == std::string::npos &&
3313                 strVendor.find("OPEN_HARMONY") == std::string::npos) ? 0 : 1;
3314             if (!pStaStateMachine->linkedInfo.isDataRestricted) {
3315                 pStaStateMachine->linkedInfo.isDataRestricted =
3316                     (strVendor.find("hostname:") != std::string::npos &&
3317                     ipAddress.find("172.20.10.") != std::string::npos);
3318             }
3319             pStaStateMachine->linkedInfo.platformType = strVendor;
3320             WIFI_LOGI("WifiLinkedInfo.isDataRestricted = %{public}d, WifiLinkedInfo.platformType = %{public}s",
3321                 pStaStateMachine->linkedInfo.isDataRestricted, pStaStateMachine->linkedInfo.platformType.c_str());
3322             WifiConfigCenter::GetInstance().SaveLinkedInfo(pStaStateMachine->linkedInfo,
3323                 pStaStateMachine->m_instId);
3324             WriteDhcpInfoHiSysEvent(ipInfo, ipv6Info);
3325 #ifndef OHOS_ARCH_LITE
3326             WIFI_LOGI("TryToSaveIpV4Result Update NetLink info, strYourCli=%{private}s, strSubnet=%{private}s, \
3327                 strRouter1=%{private}s, strDns1=%{private}s, strDns2=%{private}s",
3328                 IpAnonymize(result->strOptClientId).c_str(), IpAnonymize(result->strOptSubnet).c_str(),
3329                 IpAnonymize(result->strOptRouter1).c_str(), IpAnonymize(result->strOptDns1).c_str(),
3330                 IpAnonymize(result->strOptDns2).c_str());
3331             WIFI_LOGI("On dhcp success update net linke info");
3332             WifiDeviceConfig config;
3333             WifiSettings::GetInstance().GetDeviceConfig(pStaStateMachine->linkedInfo.networkId, config,
3334                 pStaStateMachine->m_instId);
3335             WifiNetAgent::GetInstance().OnStaMachineUpdateNetLinkInfo(ipInfo, ipv6Info, config.wifiProxyconfig,
3336                 pStaStateMachine->m_instId);
3337 #endif
3338         }
3339 #ifdef OHOS_ARCH_LITE
3340         IfConfig::GetInstance().SetIfDnsAndRoute(result, result->iptype, pStaStateMachine->m_instId);
3341 #endif
3342     } else {
3343         WIFI_LOGI("TryToSaveIpV4Result not UpdateNetLinkInfo");
3344     }
3345 }
3346 
3347 void StaStateMachine::DhcpResultNotify::TryToSaveIpV6Result(IpInfo &ipInfo, IpV6Info &ipv6Info, DhcpResult *result)
3348 {
3349     if (result == nullptr) {
3350         WIFI_LOGE("TryToSaveIpV6Result resultis nullptr.");
3351         return;
3352     }
3353 
3354     ipv6Info.linkIpV6Address = result->strOptLinkIpv6Addr;
3355     ipv6Info.globalIpV6Address = result->strOptClientId;
3356     ipv6Info.randGlobalIpV6Address = result->strOptRandIpv6Addr;
3357     ipv6Info.gateway = result->strOptRouter1;
3358     ipv6Info.netmask = result->strOptSubnet;
3359     ipv6Info.primaryDns = result->strOptDns1;
3360     ipv6Info.secondDns = result->strOptDns2;
3361     ipv6Info.uniqueLocalAddress1 = result->strOptLocalAddr1;
3362     ipv6Info.uniqueLocalAddress2 = result->strOptLocalAddr2;
3363     ipv6Info.dnsAddr.clear();
3364     if (ipv6Info.primaryDns.length() > 0 && ipv6Info.primaryDns != "0") {
3365         ipv6Info.dnsAddr.push_back(ipv6Info.primaryDns);
3366     }
3367     if (ipv6Info.secondDns.length() > 0 && ipv6Info.secondDns != "0") {
3368         ipv6Info.dnsAddr.push_back(ipv6Info.secondDns);
3369     }
3370     if (result->dnsList.dnsNumber <= DHCP_DNS_MAX_NUMBER) {
3371         for (uint32_t i = 0; i < result->dnsList.dnsNumber; i++) {
3372             if (std::find(ipv6Info.dnsAddr.begin(), ipv6Info.dnsAddr.end(), result->dnsList.dnsAddr[i]) ==
3373                 ipv6Info.dnsAddr.end()) {
3374                 ipv6Info.dnsAddr.push_back(result->dnsList.dnsAddr[i]);
3375             }
3376         }
3377         WIFI_LOGI("TryToSaveIpV6Result ipv6Info dnsAddr size:%{public}zu", ipv6Info.dnsAddr.size());
3378     }
3379     WifiConfigCenter::GetInstance().SaveIpV6Info(ipv6Info, pStaStateMachine->m_instId);
3380     WIFI_LOGI("SaveIpV6 addr=%{private}s, linkaddr=%{private}s, randaddr=%{private}s, gateway=%{private}s, "
3381         "mask=%{private}s, dns=%{private}s, dns2=%{private}s",
3382         ipv6Info.globalIpV6Address.c_str(), ipv6Info.linkIpV6Address.c_str(),
3383         ipv6Info.randGlobalIpV6Address.c_str(), ipv6Info.gateway.c_str(), ipv6Info.netmask.c_str(),
3384         ipv6Info.primaryDns.c_str(), ipv6Info.secondDns.c_str());
3385 #ifndef OHOS_ARCH_LITE
3386     WifiDeviceConfig config;
3387     WifiSettings::GetInstance().GetDeviceConfig(pStaStateMachine->linkedInfo.networkId, config,
3388         pStaStateMachine->m_instId);
3389     WifiNetAgent::GetInstance().OnStaMachineUpdateNetLinkInfo(ipInfo, ipv6Info, config.wifiProxyconfig,
3390         pStaStateMachine->m_instId);
3391     WriteDhcpInfoHiSysEvent(ipInfo, ipv6Info);
3392 #endif
3393 }
3394 
3395 void StaStateMachine::DhcpResultNotify::DhcpResultNotifyEvent(DhcpReturnCode result, int ipType)
3396 {
3397     InternalMessagePtr msg = pStaStateMachine->CreateMessage();
3398     if (msg == nullptr) {
3399         WIFI_LOGE("msg is nullptr.\n");
3400         return;
3401     }
3402 
3403     msg->SetMessageName(WIFI_SVR_CMD_STA_DHCP_RESULT_NOTIFY_EVENT);
3404     msg->SetParam1(result);
3405     msg->SetParam2(ipType);
3406     pStaStateMachine->SendMessage(msg);
3407 }
3408 
3409 void StaStateMachine::DhcpResultNotify::TryToCloseDhcpClient(int iptype)
3410 {
3411     std::string ifname = WifiConfigCenter::GetInstance().GetStaIfaceName(pStaStateMachine->m_instId);
3412     if (iptype == 1) {
3413         WIFI_LOGI("TryToCloseDhcpClient iptype ipv6 return");
3414         return;
3415     }
3416 
3417     WIFI_LOGI("TryToCloseDhcpClient, getIpSucNum=%{public}d, isRoam=%{public}d",
3418         pStaStateMachine->getIpSucNum, pStaStateMachine->isRoam);
3419     DhcpResultNotifyEvent(DhcpReturnCode::DHCP_JUMP);
3420     WriteIsInternetHiSysEvent(CONNECTED_NETWORK);
3421     if (pStaStateMachine->getIpSucNum == 0) {
3422         pStaStateMachine->SaveDiscReason(DisconnectedReason::DISC_REASON_DEFAULT);
3423         pStaStateMachine->SaveLinkstate(ConnState::CONNECTED, DetailedState::CONNECTED);
3424         pStaStateMachine->InvokeOnStaConnChanged(
3425             OperateResState::CONNECT_AP_CONNECTED, pStaStateMachine->linkedInfo);
3426         /* Delay to wait for the network adapter information to take effect. */
3427         pStaStateMachine->DealSetStaConnectFailedCount(0, true);
3428     }
3429     pStaStateMachine->getIpSucNum++;
3430     WIFI_LOGI("TryToCloseDhcpClient, getIpSucNum=%{public}d", pStaStateMachine->getIpSucNum);
3431 }
3432 
3433 void StaStateMachine::DhcpResultNotify::OnFailed(int status, const char *ifname, const char *reason)
3434 {
3435     if (ifname == nullptr || reason == nullptr) {
3436         WIFI_LOGE("StaStateMachine DhcpResultNotify OnFailed ifname or reason is nullptr.");
3437         return;
3438     }
3439     for (int instId = 0; instId < STA_INSTANCE_MAX_NUM; instId++) {
3440         if (pStaStateMachineList[instId] != nullptr
3441             && strcmp(ifname, WifiConfigCenter::GetInstance().GetStaIfaceName(instId).c_str()) == 0) {
3442             pStaStateMachineList[instId]->pDhcpResultNotify->OnFailedDhcpResult(status, ifname, reason);
3443         }
3444     }
3445 }
3446 
3447 void StaStateMachine::DhcpResultNotify::OnFailedDhcpResult(int status, const char *ifname, const char *reason)
3448 {
3449     // for dhcp: 4-DHCP_OPT_RENEW_FAILED  5-DHCP_OPT_RENEW_TIMEOUT
3450     if ((status == DHCP_RENEW_FAILED) || (status == DHCP_RENEW_TIMEOUT)) {
3451         WIFI_LOGI("DhcpResultNotify::OnFailed, ifname[%{public}s], status[%{public}d], reason[%{public}s]",
3452             ifname, status, reason);
3453         DhcpResultNotifyEvent(DhcpReturnCode::DHCP_RENEW_FAIL);
3454         return;
3455     }
3456     if (status == DHCP_LEASE_EXPIRED) {
3457         DhcpResultNotifyEvent(DhcpReturnCode::DHCP_IP_EXPIRED);
3458         return;
3459     }
3460     WIFI_LOGI("Enter DhcpResultNotify::OnFailed. ifname=%{public}s, status=%{public}d, reason=%{public}s",
3461         ifname, status, reason);
3462     WriteDhcpFailHiSysEvent("DHCP_FAIL", status);
3463     DhcpResultNotifyEvent(DhcpReturnCode::DHCP_FAIL);
3464 }
3465 
3466 void StaStateMachine::DhcpResultNotify::DealDhcpResultFailed()
3467 {
3468     pStaStateMachine->StopTimer(static_cast<int>(CMD_START_GET_DHCP_IP_TIMEOUT));
3469     BlockConnectService::GetInstance().UpdateNetworkSelectStatus(pStaStateMachine->linkedInfo.networkId,
3470         DisabledReason::DISABLED_DHCP_FAILURE);
3471     BlockConnectService::GetInstance().NotifyWifiConnFailedInfo(pStaStateMachine->targetNetworkId_,
3472         pStaStateMachine->linkedInfo.bssid, DisabledReason::DISABLED_DHCP_FAILURE);
3473 
3474     WIFI_LOGI("DhcpResultNotify OnFailed type: %{public}d, sucNum: %{public}d, failNum: %{public}d",
3475         pStaStateMachine->currentTpType, pStaStateMachine->getIpSucNum, pStaStateMachine->getIpFailNum);
3476     if (pStaStateMachine->getIpFailNum == 0) {
3477         pStaStateMachine->InvokeOnStaConnChanged(OperateResState::CONNECT_OBTAINING_IP_FAILED,
3478             pStaStateMachine->linkedInfo);
3479         pStaStateMachine->SaveLinkstate(ConnState::DISCONNECTED, DetailedState::OBTAINING_IPADDR_FAIL);
3480         pStaStateMachine->StartDisConnectToNetwork();
3481     }
3482     pStaStateMachine->getIpFailNum++;
3483 }
3484 
3485 void StaStateMachine::DhcpResultNotify::DealDhcpOfferResult()
3486 {
3487     WIFI_LOGI("DhcpResultNotify DealDhcpOfferResult enter");
3488     IpInfo ipInfo;
3489     {
3490         std::unique_lock<std::mutex> lock(dhcpResultMutex);
3491         ipInfo.ipAddress = IpTools::ConvertIpv4Address(DhcpOfferInfo.strOptClientId);
3492         ipInfo.gateway = IpTools::ConvertIpv4Address(DhcpOfferInfo.strOptRouter1);
3493         ipInfo.netmask = IpTools::ConvertIpv4Address(DhcpOfferInfo.strOptSubnet);
3494         ipInfo.primaryDns = IpTools::ConvertIpv4Address(DhcpOfferInfo.strOptDns1);
3495         ipInfo.secondDns = IpTools::ConvertIpv4Address(DhcpOfferInfo.strOptDns2);
3496         ipInfo.serverIp = IpTools::ConvertIpv4Address(DhcpOfferInfo.strOptServerId);
3497         ipInfo.leaseDuration = DhcpOfferInfo.uOptLeasetime;
3498         ipInfo.dnsAddr.clear();
3499         if (ipInfo.primaryDns != 0) {
3500             ipInfo.dnsAddr.push_back(ipInfo.primaryDns);
3501         }
3502         if (ipInfo.secondDns != 0) {
3503             ipInfo.dnsAddr.push_back(ipInfo.secondDns);
3504         }
3505         if (DhcpOfferInfo.dnsList.dnsNumber > 0 && DhcpOfferInfo.dnsList.dnsNumber <= DHCP_DNS_MAX_NUMBER) {
3506             for (uint32_t i = 0; i < DhcpOfferInfo.dnsList.dnsNumber; i++) {
3507                 uint32_t ipv4Address = IpTools::ConvertIpv4Address(DhcpOfferInfo.dnsList.dnsAddr[i]);
3508                 if (std::find(ipInfo.dnsAddr.begin(), ipInfo.dnsAddr.end(), ipv4Address) != ipInfo.dnsAddr.end()) {
3509                     WIFI_LOGD("DealDhcpOfferResult dnsAddr already exists, skip it.");
3510                     continue;
3511                 }
3512                 ipInfo.dnsAddr.push_back(ipv4Address);
3513             }
3514         }
3515     }
3516     pStaStateMachine->InvokeOnDhcpOfferReport(ipInfo);
3517 }
3518 
3519 void StaStateMachine::DhcpResultNotify::Clear()
3520 {
3521     std::unique_lock<std::mutex> lock(dhcpResultMutex);
3522     ClearDhcpResult(&DhcpIpv4Result);
3523     ClearDhcpResult(&DhcpIpv6Result);
3524     ClearDhcpResult(&DhcpOfferInfo);
3525     WIFI_LOGI("Clear all DHCP results for StaStateMachine instance %{public}d",
3526         pStaStateMachine->m_instId);
3527 }
3528 
3529 void StaStateMachine::DhcpResultNotify::ClearDhcpResult(DhcpResult *result)
3530 {
3531     if (result == nullptr) {
3532         return;
3533     }
3534     memset_s(result, sizeof(DhcpResult), 0, sizeof(DhcpResult));
3535 }
3536 
3537 /* ------------------ state machine Commont function ----------------- */
3538 ErrCode StaStateMachine::FillEapCfg(const WifiDeviceConfig &config, WifiHalDeviceConfig &halDeviceConfig) const
3539 {
3540     halDeviceConfig.eapConfig.eap = config.wifiEapConfig.eap;
3541     halDeviceConfig.eapConfig.phase2Method = static_cast<int>(config.wifiEapConfig.phase2Method);
3542     halDeviceConfig.eapConfig.identity = config.wifiEapConfig.identity;
3543     halDeviceConfig.eapConfig.anonymousIdentity = config.wifiEapConfig.anonymousIdentity;
3544     if (memcpy_s(halDeviceConfig.eapConfig.password, sizeof(halDeviceConfig.eapConfig.password),
3545         config.wifiEapConfig.password.c_str(), config.wifiEapConfig.password.length()) != EOK) {
3546         WIFI_LOGE("%{public}s: failed to copy the content", __func__);
3547         return WIFI_OPT_FAILED;
3548     }
3549     halDeviceConfig.eapConfig.caCertPath = config.wifiEapConfig.caCertPath;
3550     halDeviceConfig.eapConfig.caCertAlias = config.wifiEapConfig.caCertAlias;
3551     halDeviceConfig.eapConfig.clientCert = config.wifiEapConfig.clientCert;
3552     if (memcpy_s(halDeviceConfig.eapConfig.certPassword, sizeof(halDeviceConfig.eapConfig.certPassword),
3553         config.wifiEapConfig.certPassword, sizeof(config.wifiEapConfig.certPassword)) != EOK) {
3554         WIFI_LOGE("%{public}s: failed to copy the content", __func__);
3555         return WIFI_OPT_FAILED;
3556     }
3557     halDeviceConfig.eapConfig.privateKey = config.wifiEapConfig.privateKey;
3558     halDeviceConfig.eapConfig.altSubjectMatch = config.wifiEapConfig.altSubjectMatch;
3559     halDeviceConfig.eapConfig.domainSuffixMatch = config.wifiEapConfig.domainSuffixMatch;
3560     halDeviceConfig.eapConfig.realm = config.wifiEapConfig.realm;
3561     halDeviceConfig.eapConfig.plmn = config.wifiEapConfig.plmn;
3562     halDeviceConfig.eapConfig.eapSubId = config.wifiEapConfig.eapSubId;
3563     return WIFI_OPT_SUCCESS;
3564 }
3565 
3566 ErrCode StaStateMachine::SetExternalSim(const std::string ifName, const std::string &eap, int value) const
3567 {
3568     if ((eap != EAP_METHOD_SIM) &&
3569         (eap != EAP_METHOD_AKA) &&
3570         (eap != EAP_METHOD_AKA_PRIME)) {
3571         return WIFI_OPT_SUCCESS;
3572     }
3573 
3574     WIFI_LOGI("%{public}s ifName: %{public}s, eap: %{public}s, value: %{public}d",
3575         __func__, ifName.c_str(), eap.c_str(), value);
3576     char cmd[CMD_BUFFER_SIZE] = { 0 };
3577     if (snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "set external_sim %d", value) < 0) {
3578         WIFI_LOGE("StaStateMachine::ConvertDeviceCfg: failed to snprintf_s");
3579         return WIFI_OPT_FAILED;
3580     }
3581 
3582     if (WifiStaHalInterface::GetInstance().ShellCmd(ifName, cmd) != WIFI_HAL_OPT_OK) {
3583         WIFI_LOGI("%{public}s: failed to set StaShellCmd, cmd:%{private}s", __func__, cmd);
3584         return WIFI_OPT_FAILED;
3585     }
3586     return WIFI_OPT_SUCCESS;
3587 }
3588 
3589 void StaStateMachine::FillSuiteB192Cfg(WifiHalDeviceConfig &halDeviceConfig) const
3590 {
3591     if (halDeviceConfig.keyMgmt.find("WPA-EAP-SUITE-B-192") != std::string::npos) {
3592         halDeviceConfig.allowedProtocols = 0x02; // RSN
3593         halDeviceConfig.allowedPairwiseCiphers = 0x20; // GCMP-256
3594         halDeviceConfig.allowedGroupCiphers = 0x20; // GCMP-256
3595         halDeviceConfig.isRequirePmf = true;
3596         halDeviceConfig.allowedGroupMgmtCiphers = 0x4; // BIP-GMAC-256
3597     }
3598 }
3599 
3600 void StaStateMachine::FillWapiCfg(const WifiDeviceConfig &config, WifiHalDeviceConfig &halDeviceConfig) const
3601 {
3602     if ((strcmp(config.keyMgmt.c_str(), KEY_MGMT_WAPI_CERT.c_str()) != 0) &&
3603         (strcmp(config.keyMgmt.c_str(), KEY_MGMT_WAPI_PSK.c_str()) != 0)) {
3604         WIFI_LOGI("wapiPskType is not wapi_cert nor wapi_psk");
3605         return;
3606     }
3607     halDeviceConfig.wapiPskType = config.wifiWapiConfig.wapiPskType;
3608     halDeviceConfig.wapiAsCertData = config.wifiWapiConfig.wapiAsCertData;
3609     halDeviceConfig.wapiUserCertData = config.wifiWapiConfig.wapiUserCertData;
3610     halDeviceConfig.allowedProtocols = 0x10; // WAPI
3611     halDeviceConfig.allowedPairwiseCiphers = 0x40; // SMS4
3612     halDeviceConfig.allowedGroupCiphers = 0x40; // SMS4
3613     halDeviceConfig.wepKeyIdx = -1;
3614     return;
3615 }
3616 
3617 void StaStateMachine::TransHalDeviceConfig(WifiHalDeviceConfig &halDeviceConfig, const WifiDeviceConfig &config) const
3618 {
3619     halDeviceConfig.ssid = config.ssid;
3620     halDeviceConfig.bssid = config.bssid;
3621     halDeviceConfig.psk = config.preSharedKey;
3622     halDeviceConfig.keyMgmt = config.keyMgmt;
3623     halDeviceConfig.priority = config.priority;
3624     halDeviceConfig.scanSsid = config.hiddenSSID ? 1 : 0;
3625     FillEapCfg(config, halDeviceConfig);
3626     FillSuiteB192Cfg(halDeviceConfig);
3627     halDeviceConfig.wepKeyIdx = config.wepTxKeyIndex;
3628     FillWapiCfg(config, halDeviceConfig);
3629 }
3630 
3631 void StaStateMachine::AppendFastTransitionKeyMgmt(
3632     const WifiScanInfo &scanInfo, WifiHalDeviceConfig &halDeviceConfig) const
3633 {
3634     if (scanInfo.capabilities.find("FT/EAP") != std::string::npos) {
3635         halDeviceConfig.keyMgmt.append(" FT-EAP ");
3636     } else if (scanInfo.capabilities.find("FT/PSK") != std::string::npos) {
3637         halDeviceConfig.keyMgmt.append(" FT-PSK ");
3638     } else {
3639         WIFI_LOGI("No need append ft keyMgmt!");
3640     }
3641 }
3642 
3643 void StaStateMachine::ConvertSsidToOriginalSsid(
3644     const WifiDeviceConfig &config, WifiHalDeviceConfig &halDeviceConfig) const
3645 {
3646     std::vector<WifiScanInfo> scanInfoList;
3647     WifiConfigCenter::GetInstance().GetWifiScanConfig()->GetScanInfoList(scanInfoList);
3648     for (auto &scanInfo : scanInfoList) {
3649         std::string deviceKeyMgmt;
3650         scanInfo.GetDeviceMgmt(deviceKeyMgmt);
3651         if (config.ssid == scanInfo.ssid
3652             && ((deviceKeyMgmt == "WPA-PSK+SAE" && deviceKeyMgmt.find(config.keyMgmt) != std::string::npos)
3653                 || (config.keyMgmt == deviceKeyMgmt))) { // 混合加密目前只支持WPA-PSK+SAE,此处特殊处理
3654             AppendFastTransitionKeyMgmt(scanInfo, halDeviceConfig);
3655             halDeviceConfig.ssid = scanInfo.oriSsid;
3656             WIFI_LOGI("ConvertSsidToOriginalSsid back to oriSsid:%{public}s, keyMgmt:%{public}s",
3657                 SsidAnonymize(halDeviceConfig.ssid).c_str(), halDeviceConfig.keyMgmt.c_str());
3658             break;
3659         }
3660     }
3661 }
3662 
3663 std::string StaStateMachine::GetSuitableKeyMgmtForWpaMixed(const WifiDeviceConfig &config,
3664     const std::string &bssid) const
3665 {
3666     std::vector<WifiScanInfo> scanInfoList;
3667     std::vector<std::string> candidateKeyMgmtList;
3668     WifiConfigCenter::GetInstance().GetWifiScanConfig()->GetScanInfoList(scanInfoList);
3669     for (auto scanInfo : scanInfoList) {
3670         // bssid.empty or match scanInfo's bssid
3671         if (config.ssid == scanInfo.ssid && (bssid.empty() || bssid == scanInfo.bssid)) {
3672             std::string deviceKeyMgmt;
3673             scanInfo.GetDeviceMgmt(deviceKeyMgmt);
3674             if (WifiSettings::GetInstance().InKeyMgmtBitset(config, deviceKeyMgmt)) {
3675                 WifiSettings::GetInstance().GetAllSuitableEncryption(config, deviceKeyMgmt, candidateKeyMgmtList);
3676                 break;
3677             }
3678         }
3679     }
3680     for (auto keyMgmt : candidateKeyMgmtList) {
3681         if (keyMgmt == KEY_MGMT_SAE) {
3682             return KEY_MGMT_SAE;
3683         }
3684     }
3685     return KEY_MGMT_WPA_PSK;
3686 }
3687 
3688 ErrCode StaStateMachine::ConvertDeviceCfg(WifiDeviceConfig &config, std::string bssid) const
3689 {
3690     WIFI_LOGI("Enter ConvertDeviceCfg.\n");
3691     WifiHalDeviceConfig halDeviceConfig;
3692     TransHalDeviceConfig(halDeviceConfig, config);
3693     if (strcmp(config.keyMgmt.c_str(), "WEP") == 0) {
3694         /* for wep */
3695         halDeviceConfig.authAlgorithms = 0x02;
3696     }
3697 
3698     if (config.keyMgmt == KEY_MGMT_WPA_PSK || config.keyMgmt == KEY_MGMT_SAE) {
3699         halDeviceConfig.keyMgmt = GetSuitableKeyMgmtForWpaMixed(config, bssid);
3700         if (config.keyMgmt != halDeviceConfig.keyMgmt) {
3701             config.keyMgmt = halDeviceConfig.keyMgmt;
3702             WifiSettings::GetInstance().AddDeviceConfig(config);
3703             WifiSettings::GetInstance().SyncDeviceConfig();
3704         }
3705     }
3706 
3707     halDeviceConfig.isRequirePmf = halDeviceConfig.keyMgmt == KEY_MGMT_SAE;
3708     if (halDeviceConfig.isRequirePmf) {
3709         halDeviceConfig.allowedProtocols = 0x02; // RSN
3710         halDeviceConfig.allowedPairwiseCiphers = 0x2c; // CCMP|GCMP|GCMP-256
3711         halDeviceConfig.allowedGroupCiphers = 0x2c; // CCMP|GCMP|GCMP-256
3712     }
3713 
3714     for (int i = 0; i < HAL_MAX_WEPKEYS_SIZE; i++) {
3715         halDeviceConfig.wepKeys[i] = config.wepKeys[i];
3716     }
3717     WIFI_LOGI("ConvertDeviceCfg SetDeviceConfig selected network ssid=%{public}s, bssid=%{public}s, instId=%{public}d",
3718         SsidAnonymize(halDeviceConfig.ssid).c_str(), MacAnonymize(halDeviceConfig.bssid).c_str(), m_instId);
3719     ConvertSsidToOriginalSsid(config, halDeviceConfig);
3720 
3721     std::string ifaceName = WifiConfigCenter::GetInstance().GetStaIfaceName(m_instId);
3722     if (WifiStaHalInterface::GetInstance().SetDeviceConfig(WPA_DEFAULT_NETWORKID, halDeviceConfig, ifaceName) !=
3723         WIFI_HAL_OPT_OK) {
3724         WIFI_LOGE("ConvertDeviceCfg SetDeviceConfig failed!");
3725         return WIFI_OPT_FAILED;
3726     }
3727 
3728     if (SetExternalSim("wlan0", halDeviceConfig.eapConfig.eap, WIFI_EAP_OPEN_EXTERNAL_SIM)) {
3729         WIFI_LOGE("StaStateMachine::ConvertDeviceCfg: failed to set external_sim");
3730         return WIFI_OPT_FAILED;
3731     }
3732     return WIFI_OPT_SUCCESS;
3733 }
3734 
3735 void StaStateMachine::SaveDiscReason(DisconnectedReason discReason)
3736 {
3737     WifiConfigCenter::GetInstance().SaveDisconnectedReason(discReason, m_instId);
3738 }
3739 
3740 void StaStateMachine::SaveLinkstate(ConnState state, DetailedState detailState)
3741 {
3742     linkedInfo.connState = state;
3743     linkedInfo.detailedState = detailState;
3744     linkedInfo.isAncoConnected = WifiConfigCenter::GetInstance().GetWifiConnectedMode(m_instId);
3745     WifiConfigCenter::GetInstance().SaveLinkedInfo(linkedInfo, m_instId);
3746 }
3747 
3748 #ifndef OHOS_ARCH_LITE
3749 void StaStateMachine::OnNetManagerRestart(void)
3750 {
3751     WIFI_LOGI("OnNetManagerRestart()");
3752     WifiNetAgent::GetInstance().OnStaMachineNetManagerRestart(NetSupplierInfo, m_instId);
3753 }
3754 
3755 void StaStateMachine::ReUpdateNetLinkInfo(const WifiDeviceConfig &config)
3756 {
3757     WifiLinkedInfo linkedInfo;
3758     WifiConfigCenter::GetInstance().GetLinkedInfo(linkedInfo, m_instId);
3759     WIFI_LOGI("ReUpdateNetLinkInfo, detailedState:%{public}d, connState:%{public}d",
3760         linkedInfo.detailedState, linkedInfo.connState);
3761     if ((linkedInfo.connState == ConnState::CONNECTED) && (linkedInfo.ssid == config.ssid) &&
3762         (linkedInfo.bssid == config.bssid)) {
3763         IpInfo wifiIpInfo;
3764         WifiConfigCenter::GetInstance().GetIpInfo(wifiIpInfo, m_instId);
3765         IpV6Info wifiIpV6Info;
3766         WifiConfigCenter::GetInstance().GetIpv6Info(wifiIpV6Info, m_instId);
3767         WifiDeviceConfig config;
3768         WifiSettings::GetInstance().GetDeviceConfig(linkedInfo.networkId, config, m_instId);
3769         WifiNetAgent::GetInstance().OnStaMachineUpdateNetLinkInfo(wifiIpInfo,
3770             wifiIpV6Info, config.wifiProxyconfig, m_instId);
3771     }
3772 }
3773 
3774 void StaStateMachine::SaveWifiConfigForUpdate(int networkId)
3775 {
3776 #ifdef WIFI_CONFIG_UPDATE
3777     WIFI_LOGI("Enter SaveWifiConfigForUpdate.");
3778     WifiDeviceConfig config;
3779     if (WifiSettings::GetInstance().GetDeviceConfig(networkId, config, m_instId) == -1) {
3780         WIFI_LOGE("SaveWifiConfigForUpdate, get current config failed.");
3781         return;
3782     }
3783     WifiConfigUpdate mWifiConfigUpdate;
3784     if (config.keyMgmt != KEY_MGMT_WEP) {
3785         mWifiConfigUpdate.SaveWifiConfig(config.ssid.c_str(), config.keyMgmt.c_str(), config.preSharedKey.c_str());
3786     } else {
3787         mWifiConfigUpdate.SaveWifiConfig(config.ssid.c_str(), config.keyMgmt.c_str(), config.wepKeys[0].c_str());
3788     }
3789 #endif
3790 }
3791 #endif
3792 
3793 void StaStateMachine::HandlePreDhcpSetup()
3794 {
3795     WifiSupplicantHalInterface::GetInstance().WpaSetPowerMode(false, m_instId);
3796     if (m_instId == INSTID_WLAN0) {
3797         WifiSupplicantHalInterface::GetInstance().WpaSetSuspendMode(false);
3798     }
3799 }
3800 
3801 bool StaStateMachine::IsSpecificNetwork()
3802 {
3803 #ifndef OHOS_ARCH_LITE
3804     WifiDeviceConfig config;
3805     WifiSettings::GetInstance().GetDeviceConfig(linkedInfo.networkId, config, m_instId);
3806     if (enhanceService_ == nullptr) {
3807         WIFI_LOGE("IsSpecificNetwork, enhanceService is null");
3808         return false;
3809     }
3810     return enhanceService_->IsSpecificNetwork(config);
3811 #else
3812     return false;
3813 #endif
3814 }
3815 
3816 void StaStateMachine::HandlePostDhcpSetup()
3817 {
3818     WifiSupplicantHalInterface::GetInstance().WpaSetPowerMode(true, m_instId);
3819     if (m_instId == INSTID_WLAN0) {
3820         int screenState = WifiConfigCenter::GetInstance().GetScreenState();
3821         WifiSupplicantHalInterface::GetInstance().WpaSetSuspendMode(screenState == MODE_STATE_CLOSE);
3822     }
3823 }
3824 
3825 WifiDeviceConfig StaStateMachine::getCurrentWifiDeviceConfig()
3826 {
3827     WIFI_LOGI("getCurrentWifiDeviceConfig, networkId %{public}d.", linkedInfo.networkId);
3828     WifiDeviceConfig wifiDeviceConfig;
3829     WifiSettings::GetInstance().GetDeviceConfig(linkedInfo.networkId, wifiDeviceConfig, m_instId);
3830     return wifiDeviceConfig;
3831 }
3832 
3833 void StaStateMachine::InsertOrUpdateNetworkStatusHistory(const NetworkStatus &networkStatus,
3834     bool updatePortalAuthTime)
3835 {
3836     WifiDeviceConfig wifiDeviceConfig = getCurrentWifiDeviceConfig();
3837     if (networkStatusHistoryInserted) {
3838         auto lastStatus = NetworkStatusHistoryManager::GetLastNetworkStatus(wifiDeviceConfig.networkStatusHistory);
3839         int screenState = WifiConfigCenter::GetInstance().GetScreenState();
3840         if (networkStatus == NetworkStatus::NO_INTERNET && (lastStatus == NetworkStatus::HAS_INTERNET ||
3841             screenState == MODE_STATE_CLOSE)) {
3842             WIFI_LOGI("No updated, current network status is %{public}d, last network status:%{public}d, "
3843                 "screen state:%{public}d.",
3844                 static_cast<int>(networkStatus), static_cast<int>(lastStatus), screenState);
3845         } else if (IsGoodSignalQuality() || (networkStatus == NetworkStatus::HAS_INTERNET) ||
3846             (networkStatus == NetworkStatus::PORTAL)) {
3847             NetworkStatusHistoryManager::Update(wifiDeviceConfig.networkStatusHistory, networkStatus);
3848             WIFI_LOGI("After updated, current network status history is %{public}s.",
3849                       NetworkStatusHistoryManager::ToString(wifiDeviceConfig.networkStatusHistory).c_str());
3850         } else {
3851             WIFI_LOGI("No updated, current network status history is %{public}s.",
3852                 NetworkStatusHistoryManager::ToString(wifiDeviceConfig.networkStatusHistory).c_str());
3853         }
3854     } else {
3855         NetworkStatusHistoryManager::Insert(wifiDeviceConfig.networkStatusHistory, networkStatus);
3856         networkStatusHistoryInserted = true;
3857         WIFI_LOGI("After inserted, current network status history is %{public}s.",
3858                   NetworkStatusHistoryManager::ToString(wifiDeviceConfig.networkStatusHistory).c_str());
3859     }
3860     if (updatePortalAuthTime) {
3861         auto now = time(nullptr);
3862         wifiDeviceConfig.portalAuthTime = now;
3863     }
3864     if (networkStatus == NetworkStatus::PORTAL) {
3865         wifiDeviceConfig.isPortal = true;
3866         wifiDeviceConfig.noInternetAccess = true;
3867     }
3868     if (networkStatus == NetworkStatus::HAS_INTERNET) {
3869         wifiDeviceConfig.lastHasInternetTime = time(0);
3870         wifiDeviceConfig.noInternetAccess = false;
3871         WifiConfigCenter::GetInstance().GetIpInfo(wifiDeviceConfig.lastDhcpResult, m_instId);
3872     }
3873     if (networkStatus == NetworkStatus::NO_INTERNET && IsGoodSignalQuality()) {
3874         wifiDeviceConfig.noInternetAccess = true;
3875     }
3876     WifiSettings::GetInstance().AddDeviceConfig(wifiDeviceConfig);
3877     WifiSettings::GetInstance().SyncDeviceConfig();
3878 }
3879 
3880 void StaStateMachine::SetConnectMethod(int connectMethod)
3881 {
3882     if (m_instId != INSTID_WLAN0) {
3883         WIFI_LOGI("instId:%{public}d, no need to set connect method.", m_instId);
3884         return;
3885     }
3886     std::string isConnectFromUser = "-1";
3887     switch (connectMethod) {
3888         case NETWORK_SELECTED_BY_AUTO:
3889             isConnectFromUser = AUTO_CONNECT;
3890             break;
3891         case NETWORK_SELECTED_BY_USER:
3892             isConnectFromUser = USER_CONNECT;
3893             break;
3894         case NETWORK_SELECTED_BY_RETRY:
3895             break;
3896         default:
3897             break;
3898     }
3899     int ret = SetParamValue(WIFI_IS_CONNECT_FROM_USER, isConnectFromUser.c_str());
3900     std::string retStr = (ret == 0) ? "success" : ("fail,ret="+std::to_string(ret));
3901     WIFI_LOGI("SetConnectMethod %{public}s,connectMethod:%{public}d",
3902         retStr.c_str(), connectMethod);
3903     return;
3904 }
3905 
3906 bool StaStateMachine::IsGoodSignalQuality()
3907 {
3908     const WifiLinkedInfo singalInfo = linkedInfo;
3909     bool isGoodSignal = true;
3910     int currentSignalLevel = WifiSettings::GetInstance().GetSignalLevel(singalInfo.rssi, singalInfo.band, m_instId);
3911     if (currentSignalLevel <= RSSI_LEVEL_2) {
3912         isGoodSignal = false;
3913     }
3914     if (singalInfo.chload >= MAX_CHLOAD) {
3915         isGoodSignal = false;
3916     }
3917     return isGoodSignal;
3918 }
3919 
3920 void StaStateMachine::DealMloConnectionLinkInfo()
3921 {
3922     if (linkedInfo.supportedWifiCategory != WifiCategory::WIFI7
3923         && linkedInfo.supportedWifiCategory != WifiCategory::WIFI7_PLUS) {
3924         WIFI_LOGI("%{public}s not support wifi7", __FUNCTION__);
3925         return;
3926     }
3927     if (!linkedInfo.isMloConnected) {
3928         WIFI_LOGI("%{public}s not support mlo connect", __FUNCTION__);
3929         return;
3930     }
3931     std::vector<WifiLinkedInfo> mloLinkedInfo;
3932     std::string ifname = WifiConfigCenter::GetInstance().GetStaIfaceName(m_instId);
3933     if (WifiStaHalInterface::GetInstance().GetConnectionMloLinkedInfo(ifname, mloLinkedInfo) != 0) {
3934         WIFI_LOGI("%{public}s GetConnectionMloLinkedInfo from wpas fail", __FUNCTION__);
3935         return;
3936     }
3937     WifiConfigCenter::GetInstance().SaveMloLinkedInfo(mloLinkedInfo, m_instId);
3938     WifiConfigCenter::GetInstance().SetMloWifiLinkedMaxSpeed(m_instId);
3939 }
3940 
3941 void StaStateMachine::UpdateLinkedBssid(std::string &bssid)
3942 {
3943 #ifdef SUPPORT_RANDOM_MAC_ADDR
3944     WIFI_LOGI("linked bssid changed, %{public}s", MacAnonymize(bssid).c_str());
3945     WifiConfigCenter::GetInstance().StoreWifiMacAddrPairInfo(WifiMacAddrInfoType::WIFI_SCANINFO_MACADDR_INFO,
3946         bssid, "");
3947 #endif
3948     return;
3949 }
3950 
3951 #ifndef OHOS_ARCH_LITE
3952 void StaStateMachine::UpdateLinkedInfoFromScanInfo()
3953 {
3954     WIFI_LOGI("UpdateLinkedInfoFromScanInfo");
3955     std::vector<InterScanInfo> scanInfos;
3956     if (WifiStaHalInterface::GetInstance().QueryScanInfos(
3957         WifiConfigCenter::GetInstance().GetStaIfaceName(m_instId), scanInfos) != WIFI_HAL_OPT_OK) {
3958         WIFI_LOGE("WifiStaHalInterface::GetInstance().GetScanInfos failed.");
3959     }
3960     int chipsetCategory = static_cast<int>(WifiCategory::DEFAULT);
3961     if (WifiStaHalInterface::GetInstance().GetChipsetCategory(
3962         WifiConfigCenter::GetInstance().GetStaIfaceName(m_instId), chipsetCategory) != WIFI_HAL_OPT_OK) {
3963         WIFI_LOGE("GetChipsetCategory failed.\n");
3964     }
3965     int chipsetFeatrureCapability = 0;
3966     if (WifiStaHalInterface::GetInstance().GetChipsetWifiFeatrureCapability(
3967         WifiConfigCenter::GetInstance().GetStaIfaceName(m_instId), chipsetFeatrureCapability) != WIFI_HAL_OPT_OK) {
3968         WIFI_LOGE("GetChipsetWifiFeatrureCapability failed.\n");
3969     }
3970 
3971     for (auto iter = scanInfos.begin(); iter != scanInfos.end(); iter++) {
3972         if (enhanceService_ != nullptr) {
3973             WifiCategory category = enhanceService_->GetWifiCategory(iter->infoElems,
3974                 chipsetCategory, chipsetFeatrureCapability);
3975             WifiConfigCenter::GetInstance().GetWifiScanConfig()->RecordWifiCategory(iter->bssid, category);
3976         }
3977 
3978         if (iter->bssid == linkedInfo.bssid) {
3979             linkedInfo.channelWidth = iter->channelWidth;
3980             LOGI("centerFrequency0:%{public}d, centerFrequency1:%{public}d.",
3981                 iter->centerFrequency0, iter->centerFrequency1);
3982             if ((iter->centerFrequency0 != 0) && (linkedInfo.centerFrequency0 != iter->centerFrequency0)) {
3983                 linkedInfo.centerFrequency0 = iter->centerFrequency0;
3984             }
3985             if ((iter->centerFrequency1 != 0) && (linkedInfo.centerFrequency1 != iter->centerFrequency1)) {
3986                 linkedInfo.centerFrequency1 = iter->centerFrequency1;
3987             }
3988         }
3989     }
3990 }
3991 
3992 void StaStateMachine::SetSupportedWifiCategory()
3993 {
3994     if (m_instId != INSTID_WLAN0) {
3995         return;
3996     }
3997     if (linkedInfo.bssid.empty()) {
3998         WIFI_LOGE("%{public}s linked bssid is empty", __FUNCTION__);
3999         return;
4000     }
4001     WifiCategory category =
4002         WifiConfigCenter::GetInstance().GetWifiScanConfig()->GetWifiCategoryRecord(linkedInfo.bssid);
4003     linkedInfo.supportedWifiCategory = category;
4004     if (category == WifiCategory::WIFI7 || category == WifiCategory::WIFI7_PLUS) {
4005         int chipsetFeatrureCapability = 0;
4006         if (WifiStaHalInterface::GetInstance().GetChipsetWifiFeatrureCapability(
4007             WifiConfigCenter::GetInstance().GetStaIfaceName(m_instId), chipsetFeatrureCapability) != WIFI_HAL_OPT_OK) {
4008             WIFI_LOGE("%{public}s GetChipsetWifiFeatrureCapability failed.", __FUNCTION__);
4009             return;
4010         }
4011         if (static_cast<unsigned int>(chipsetFeatrureCapability) & BIT_MLO_CONNECT) {
4012             WIFI_LOGD("%{public}s MLO linked", __FUNCTION__);
4013             linkedInfo.isMloConnected = true;
4014         } else {
4015             linkedInfo.isMloConnected = false;
4016         }
4017     } else {
4018         linkedInfo.isMloConnected = false;
4019     }
4020     WifiConfigCenter::GetInstance().SaveLinkedInfo(linkedInfo, m_instId);
4021     WIFI_LOGI("%{public}s supportedWifiCategory:%{public}d, isMloConnected:%{public}d", __FUNCTION__,
4022         static_cast<int>(linkedInfo.supportedWifiCategory), linkedInfo.isMloConnected);
4023 }
4024 
4025 void StaStateMachine::SetEnhanceService(IEnhanceService* enhanceService)
4026 {
4027     enhanceService_ = enhanceService;
4028 }
4029 
4030 void StaStateMachine::SetSelfCureService(ISelfCureService *selfCureService)
4031 {
4032     selfCureService_ = selfCureService;
4033 }
4034 #endif
4035 
4036 int setRssi(int rssi)
4037 {
4038     if (rssi < INVALID_RSSI_VALUE) {
4039         rssi = INVALID_RSSI_VALUE;
4040     }
4041 
4042     if (rssi > MAX_RSSI_VALUE) {
4043         rssi = MAX_RSSI_VALUE;
4044     }
4045     return rssi;
4046 }
4047 
4048 int StaStateMachine::UpdateLinkInfoRssi(int inRssi)
4049 {
4050     int outRssi = 0;
4051     if (inRssi > INVALID_RSSI_VALUE && inRssi < MAX_RSSI_VALUE) {
4052         if (inRssi > 0) {
4053             outRssi = setRssi((inRssi - SIGNAL_INFO));
4054         } else {
4055             outRssi = setRssi(inRssi);
4056         }
4057     } else {
4058         outRssi = INVALID_RSSI_VALUE;
4059     }
4060     return outRssi;
4061 }
4062 
4063 void StaStateMachine::DealSignalPollResult()
4064 {
4065     WifiSignalPollInfo signalInfo;
4066     WifiErrorNo ret = WifiStaHalInterface::GetInstance().GetConnectSignalInfo(
4067         WifiConfigCenter::GetInstance().GetStaIfaceName(m_instId), linkedInfo.bssid, signalInfo);
4068     if (ret != WIFI_HAL_OPT_OK) {
4069         WIFI_LOGE("GetConnectSignalInfo return fail: %{public}d.", ret);
4070         return;
4071     }
4072     DealMloLinkSignalPollResult();
4073     if (signalInfo.frequency > 0) {
4074         linkedInfo.frequency = signalInfo.frequency;
4075     }
4076     ConvertFreqToChannel();
4077     if (foldStatus_ == HALF_FOLD) {
4078         pLinkedState->halfFoldRssi_ = signalInfo.signal;
4079         WIFI_LOGI("rssiOffset_: %{public}d, halfFoldRssi_: %{public}d, foldStatus_: %{public}d\n",
4080             pLinkedState->rssiOffset_, pLinkedState->halfFoldRssi_, foldStatus_);
4081         if (pLinkedState->halfFoldRssi_ + pLinkedState->rssiOffset_ < 0) {
4082             pLinkedState->halfFoldUpdateRssi_ = pLinkedState->halfFoldRssi_ + pLinkedState->rssiOffset_;
4083         } else {
4084             pLinkedState->halfFoldUpdateRssi_ = pLinkedState->halfFoldRssi_;
4085         }
4086         UpdateLinkRssi(signalInfo, pLinkedState->halfFoldUpdateRssi_);
4087     } else {
4088         UpdateLinkRssi(signalInfo);
4089     }
4090 
4091     if (signalInfo.txrate > 0) {
4092         linkedInfo.txLinkSpeed = signalInfo.txrate / TRANSFORMATION_TO_MBPS;
4093         linkedInfo.linkSpeed = signalInfo.txrate / TRANSFORMATION_TO_MBPS;
4094     }
4095 
4096     if (signalInfo.rxrate > 0) {
4097         linkedInfo.rxLinkSpeed = signalInfo.rxrate / TRANSFORMATION_TO_MBPS;
4098     }
4099 
4100     linkedInfo.snr = signalInfo.snr;
4101     linkedInfo.chload = signalInfo.chload;
4102     signalInfo.timeStamp = GetCurrentTimeSeconds();
4103     if (linkedInfo.wifiStandard == WIFI_MODE_UNDEFINED) {
4104         WifiConfigCenter::GetInstance().SetWifiLinkedStandardAndMaxSpeed(linkedInfo);
4105     }
4106     pLinkedState->UpdateExpandOffset();
4107     WifiChrUtils::GetInstance().AddSignalPollInfoArray(signalInfo);
4108     LogSignalInfo(signalInfo);
4109 #ifndef OHOS_ARCH_LITE
4110 #ifdef WIFI_DATA_REPORT_ENABLE
4111     wifiDataReportService_->ReportQoeInfo(signalInfo, ConnReportReason::CONN_SUC_KEEP, linkedInfo.networkId);
4112 #endif
4113 #endif
4114     WifiConfigCenter::GetInstance().SaveLinkedInfo(linkedInfo, m_instId);
4115     DealSignalPacketChanged(signalInfo.txPackets, signalInfo.rxPackets);
4116     JudgeEnableSignalPoll(signalInfo);
4117 }
4118 
4119 void StaStateMachine::DealMloLinkSignalPollResult()
4120 {
4121     if (linkedInfo.wifiLinkType != WifiLinkType::WIFI7_EMLSR) {
4122         WIFI_LOGD("%{public}s current linkType is not EMLSR", __FUNCTION__);
4123         return;
4124     }
4125     std::vector<WifiMloSignalInfo> mloSignalInfo;
4126     std::string ifName = WifiConfigCenter::GetInstance().GetStaIfaceName(m_instId);
4127     if (WifiStaHalInterface::GetInstance().GetConnectionMloSignalInfo(ifName, mloSignalInfo) != WIFI_HAL_OPT_OK ||
4128         mloSignalInfo.size() != WIFI_MAX_MLO_LINK_NUM) {
4129         return;
4130     }
4131     std::vector<WifiLinkedInfo> mloLinkedInfo;
4132     if (WifiConfigCenter::GetInstance().GetMloLinkedInfo(mloLinkedInfo, m_instId) < 0) {
4133         WIFI_LOGE("%{public}s get mlo linkInfo fail", __FUNCTION__);
4134         return;
4135     }
4136     for (auto &linkInfo : mloLinkedInfo) {
4137         bool isLinkedMatch = false;
4138         for (auto signalInfo : mloSignalInfo) {
4139             if (signalInfo.linkId != linkInfo.linkId) {
4140                 continue;
4141             }
4142             isLinkedMatch = true;
4143             int rssi = UpdateLinkInfoRssi(signalInfo.rssi);
4144             WIFI_LOGI("MloSignalPollResult ssid:%{public}s, bssid:%{public}s, linkId:%{public}d, rssi: %{public}d,"
4145                 "fre: %{public}d, txSpeed: %{public}d, rxSpeed: %{public}d, deltaTxPackets: %{public}d, deltaRxPackets:"
4146                 "%{public}d", SsidAnonymize(linkedInfo.ssid).c_str(), MacAnonymize(linkInfo.bssid).c_str(),
4147                 linkInfo.linkId, rssi, signalInfo.frequency, signalInfo.txLinkSpeed, signalInfo.rxLinkSpeed,
4148                 signalInfo.txPackets - linkInfo.lastTxPackets, signalInfo.rxPackets - linkInfo.lastRxPackets);
4149 
4150             linkInfo.rssi = rssi;
4151             linkInfo.frequency = signalInfo.frequency;
4152             linkInfo.linkSpeed = signalInfo.txLinkSpeed;
4153             linkInfo.txLinkSpeed = signalInfo.txLinkSpeed;
4154             linkInfo.rxLinkSpeed = signalInfo.rxLinkSpeed;
4155             linkInfo.lastTxPackets = signalInfo.txPackets;
4156             linkInfo.lastRxPackets = signalInfo.rxPackets;
4157         }
4158         if (!isLinkedMatch) {
4159             WIFI_LOGE("%{public}s linkId:%{public}d not match", __FUNCTION__, linkInfo.linkId);
4160             return;
4161         }
4162     }
4163     WifiConfigCenter::GetInstance().SaveMloLinkedInfo(mloLinkedInfo, m_instId);
4164 }
4165 
4166 void StaStateMachine::JudgeEnableSignalPoll(WifiSignalPollInfo &signalInfo)
4167 {
4168 #ifndef OHOS_ARCH_LITE
4169     if (enhanceService_ != nullptr) {
4170         enhanceService_->SetEnhanceSignalPollInfo(signalInfo);
4171     }
4172 #endif
4173     WriteLinkInfoHiSysEvent(lastSignalLevel_, linkedInfo.rssi, linkedInfo.band, linkedInfo.linkSpeed);
4174     std::shared_lock<std::shared_mutex> lock(m_staCallbackMutex);
4175     for (const auto &callBackItem : m_staCallback) {
4176         if (callBackItem.second.OnWifiHalSignalInfoChange != nullptr) {
4177             callBackItem.second.OnWifiHalSignalInfoChange(signalInfo);
4178         }
4179         if (callBackItem.second.OnSignalPollReport != nullptr && linkedInfo.wifiLinkType != WifiLinkType::WIFI7_EMLSR) {
4180             callBackItem.second.OnSignalPollReport(linkedInfo.bssid, lastSignalLevel_, m_instId);
4181         }
4182     }
4183     if (enableSignalPoll) {
4184         WIFI_LOGD("SignalPoll, StartTimer for SIGNAL_POLL.\n");
4185         StopTimer(static_cast<int>(CMD_SIGNAL_POLL));
4186         StartTimer(static_cast<int>(CMD_SIGNAL_POLL), staSignalPollDelayTime_);
4187     }
4188 }
4189 
4190 #ifndef OHOS_ARCH_LITE
4191 void StaStateMachine::HandleForegroundAppChangedAction(InternalMessagePtr msg)
4192 {
4193     AppExecFwk::AppStateData appStateData;
4194     if (!msg->GetMessageObj(appStateData)) {
4195         WIFI_LOGE("Failed to obtain appStateData information");
4196         return;
4197     }
4198     if (appStateData.state == static_cast<int>(AppExecFwk::AppProcessState::APP_STATE_FOREGROUND) &&
4199         appStateData.isFocused) {
4200         curForegroundAppBundleName_ = appStateData.bundleName;
4201         std::string sceneboardBundle = WifiSettings::GetInstance().GetPackageName("SCENEBOARD_BUNDLE");
4202         if (curForegroundAppBundleName_ != "" && sceneboardBundle != "" &&
4203             curForegroundAppBundleName_ != sceneboardBundle) {
4204             staSignalPollDelayTime_ = STA_SIGNAL_POLL_DELAY_WITH_TASK;
4205         } else {
4206             staSignalPollDelayTime_ = STA_SIGNAL_POLL_DELAY;
4207         }
4208     }
4209 }
4210 #endif
4211 
4212 void StaStateMachine::UpdateLinkRssi(const WifiSignalPollInfo &signalInfo, int foldStateRssi)
4213 {
4214     if (linkSwitchDetectingFlag_) {
4215         WIFI_LOGI("%{public}s link switch detecting, not update rssi", __FUNCTION__);
4216         return;
4217     }
4218     int curRssi = signalInfo.signal;
4219     std::vector<WifiLinkedInfo> mloLinkedInfo;
4220     if (linkedInfo.wifiLinkType == WifiLinkType::WIFI7_EMLSR &&
4221         WifiConfigCenter::GetInstance().GetMloLinkedInfo(mloLinkedInfo, m_instId) == 0) {
4222         for (auto& info : mloLinkedInfo) {
4223             if (info.rssi > curRssi) {
4224                 curRssi = info.rssi;
4225             }
4226         }
4227         WIFI_LOGD("%{public}s signalInfoRssi: %{public}d, maxRssi: %{public}d",
4228             __FUNCTION__, signalInfo.signal, curRssi);
4229     }
4230 
4231     int currentSignalLevel = 0;
4232     if (foldStateRssi != INVALID_RSSI_VALUE) {
4233         linkedInfo.rssi = setRssi(foldStateRssi);
4234     } else if (curRssi > INVALID_RSSI_VALUE && curRssi < MAX_RSSI_VALUE) {
4235         if (curRssi > 0) {
4236             linkedInfo.rssi = setRssi((curRssi - SIGNAL_INFO));
4237         } else {
4238             linkedInfo.rssi = setRssi(curRssi);
4239         }
4240     } else {
4241         linkedInfo.rssi = INVALID_RSSI_VALUE;
4242     }
4243 
4244     if (linkedInfo.rssi != INVALID_RSSI_VALUE) {
4245         currentSignalLevel = WifiSettings::GetInstance().GetSignalLevel(linkedInfo.rssi, linkedInfo.band, m_instId);
4246         if (currentSignalLevel != lastSignalLevel_) {
4247             WifiConfigCenter::GetInstance().SaveLinkedInfo(linkedInfo, m_instId);
4248             InvokeOnStaRssiLevelChanged(linkedInfo.rssi);
4249             lastSignalLevel_ = currentSignalLevel;
4250         }
4251     }
4252 
4253     linkedInfo.c0Rssi = UpdateLinkInfoRssi(signalInfo.c0Rssi);
4254     linkedInfo.c1Rssi = UpdateLinkInfoRssi(signalInfo.c1Rssi);
4255 }
4256 
4257 void StaStateMachine::DealSignalPacketChanged(int txPackets, int rxPackets)
4258 {
4259     int send = txPackets - linkedInfo.lastTxPackets;
4260     int received = rxPackets - linkedInfo.lastRxPackets;
4261     int direction = 0;
4262     if (send > STREAM_TXPACKET_THRESHOLD) {
4263         direction |= static_cast<int>(StreamDirection::STREAM_DIRECTION_UP);
4264     }
4265     if (received > STREAM_RXPACKET_THRESHOLD) {
4266         direction |= static_cast<int>(StreamDirection::STREAM_DIRECTION_DOWN);
4267     }
4268     if (direction != linkedInfo.lastPacketDirection) {
4269         WriteWifiSignalHiSysEvent(direction, txPackets, rxPackets);
4270         InvokeOnStaStreamChanged(static_cast<StreamDirection>(direction));
4271     }
4272     linkedInfo.lastPacketDirection = direction;
4273     linkedInfo.lastRxPackets = rxPackets;
4274     linkedInfo.lastTxPackets = txPackets;
4275 }
4276 
4277 void StaStateMachine::ConvertFreqToChannel()
4278 {
4279     WifiDeviceConfig config;
4280     if (WifiSettings::GetInstance().GetDeviceConfig(linkedInfo.networkId, config, m_instId) != 0) {
4281         WIFI_LOGE("GetDeviceConfig failed!");
4282         return;
4283     }
4284     int lastBand = linkedInfo.band;
4285     config.frequency = linkedInfo.frequency;
4286     if (linkedInfo.frequency >= FREQ_2G_MIN && linkedInfo.frequency <= FREQ_2G_MAX) {
4287         config.band = linkedInfo.band = static_cast<int>(BandType::BAND_2GHZ);
4288         config.channel = (linkedInfo.frequency - FREQ_2G_MIN) / CENTER_FREQ_DIFF + CHANNEL_2G_MIN;
4289     } else if (linkedInfo.frequency == CHANNEL_14_FREQ) {
4290         config.channel = CHANNEL_14;
4291     } else if (linkedInfo.frequency >= FREQ_5G_MIN && linkedInfo.frequency <= FREQ_5G_MAX) {
4292         config.band = linkedInfo.band = static_cast<int>(BandType::BAND_5GHZ);
4293         config.channel = (linkedInfo.frequency - FREQ_5G_MIN) / CENTER_FREQ_DIFF + CHANNEL_5G_MIN;
4294     }
4295     if (lastBand != linkedInfo.band) {
4296         WriteWifiBandHiSysEvent(linkedInfo.band);
4297     }
4298     WifiSettings::GetInstance().AddDeviceConfig(config);
4299     return;
4300 }
4301 
4302 bool StaStateMachine::CurrentIsRandomizedMac()
4303 {
4304     std::string curMacAddress = "";
4305     std::string ifaceName = WifiConfigCenter::GetInstance().GetStaIfaceName(m_instId);
4306     if ((WifiStaHalInterface::GetInstance().GetStaDeviceMacAddress(curMacAddress, ifaceName)) != WIFI_HAL_OPT_OK) {
4307         WIFI_LOGE("CurrentIsRandomizedMac GetStaDeviceMacAddress failed!");
4308         return false;
4309     }
4310     std::string realMacAddress = "";
4311     WifiSettings::GetInstance().GetRealMacAddress(realMacAddress, m_instId);
4312     WIFI_LOGI("CurrentIsRandomizedMac curMacAddress:%{public}s realMacAddress:%{public}s",
4313         MacAnonymize(curMacAddress).c_str(), MacAnonymize(realMacAddress).c_str());
4314     return curMacAddress != realMacAddress;
4315 }
4316 
4317 void StaStateMachine::HilinkSaveConfig(void)
4318 {
4319     WIFI_LOGI("enter HilinkSaveConfig");
4320     WifiDeviceConfig outConfig;
4321     if (WifiSettings::GetInstance().GetDeviceConfig(m_hilinkDeviceConfig.ssid, m_hilinkDeviceConfig.keyMgmt,
4322         outConfig, m_instId) == 0) {
4323         m_hilinkDeviceConfig.networkId = outConfig.networkId;
4324     } else {
4325         m_hilinkDeviceConfig.networkId = WifiSettings::GetInstance().GetNextNetworkId();
4326     }
4327     targetNetworkId_ = m_hilinkDeviceConfig.networkId;
4328     WifiSettings::GetInstance().SetKeyMgmtBitset(m_hilinkDeviceConfig);
4329     WifiStaHalInterface::GetInstance().GetPskPassphrase("wlan0", m_hilinkDeviceConfig.preSharedKey);
4330     m_hilinkDeviceConfig.version = -1;
4331     if (!WifiSettings::GetInstance().EncryptionDeviceConfig(m_hilinkDeviceConfig)) {
4332         WIFI_LOGE("HilinkSaveConfig EncryptionDeviceConfig failed");
4333     }
4334     WifiSettings::GetInstance().AddDeviceConfig(m_hilinkDeviceConfig);
4335     WifiSettings::GetInstance().SyncDeviceConfig();
4336     WifiSettings::GetInstance().SetUserConnectChoice(targetNetworkId_);
4337 
4338     WifiConfigCenter::GetInstance().SetMacAddress(m_hilinkDeviceConfig.macAddress, m_instId);
4339     m_hilinkFlag = false;
4340 }
4341 
4342 static constexpr int DIS_REASON_DISASSOC_STA_HAS_LEFT = 8;
4343 
4344 bool StaStateMachine::IsDisConnectReasonShouldStopTimer(int reason)
4345 {
4346     return reason == DIS_REASON_DISASSOC_STA_HAS_LEFT;
4347 }
4348 
4349 void StaStateMachine::AddRandomMacCure()
4350 {
4351     if (targetNetworkId_ == mLastConnectNetId) {
4352         mConnectFailedCnt++;
4353     }
4354 }
4355 
4356 void StaStateMachine::DealSetStaConnectFailedCount(int count, bool set)
4357 {
4358     WifiDeviceConfig config;
4359     int ret = WifiSettings::GetInstance().GetDeviceConfig(targetNetworkId_, config, m_instId);
4360     if (ret != 0) {
4361         WIFI_LOGW("DealSetStaConnectFailedCount get device[%{public}d] config failed.\n", targetNetworkId_);
4362         return;
4363     }
4364     if (set) {
4365         WifiSettings::GetInstance().SetDeviceConnFailedCount(config.bssid, DEVICE_CONFIG_INDEX_BSSID,
4366             count);
4367     } else {
4368         WifiSettings::GetInstance().IncreaseDeviceConnFailedCount(config.bssid, DEVICE_CONFIG_INDEX_BSSID,
4369             count);
4370     }
4371 }
4372 
4373 void StaStateMachine::DealReassociateCmd(InternalMessagePtr msg)
4374 {
4375     WIFI_LOGI("enter DealReassociateCmd.\n");
4376     if (msg == nullptr) {
4377         WIFI_LOGE("msg is null\n");
4378     }
4379     std::string ifaceName = WifiConfigCenter::GetInstance().GetStaIfaceName(m_instId);
4380     WriteConnectTypeHiSysEvent(NETWORK_SELECTED_BY_REASSOC);
4381     if (linkedInfo.isMloConnected && WifiStaHalInterface::GetInstance().SetBssid(
4382         WPA_DEFAULT_NETWORKID, linkedInfo.bssid,
4383         WifiConfigCenter::GetInstance().GetStaIfaceName(m_instId)) == WIFI_HAL_OPT_OK) {
4384         WIFI_LOGI("Reassociate to same bssid for wifi7 mlo!\n");
4385     }
4386     if (WifiStaHalInterface::GetInstance().Reassociate(ifaceName) == WIFI_HAL_OPT_OK) {
4387         /* Callback result to InterfaceService */
4388         InvokeOnStaConnChanged(OperateResState::CONNECT_ASSOCIATING, linkedInfo);
4389         WIFI_LOGD("StaStateMachine ReAssociate successfully!");
4390         StopTimer(static_cast<int>(CMD_NETWORK_CONNECT_TIMEOUT));
4391         StartTimer(static_cast<int>(CMD_NETWORK_CONNECT_TIMEOUT), STA_NETWORK_CONNECTTING_DELAY);
4392     } else {
4393         WIFI_LOGE("ReAssociate failed!");
4394     }
4395 }
4396 
4397 void StaStateMachine::UserSelectConnectToNetwork(WifiDeviceConfig& deviceConfig, std::string& ifaceName)
4398 {
4399     if (!deviceConfig.userSelectBssid.empty()) {
4400         WIFI_LOGI("SetBssid userSelectBssid=%{public}s", MacAnonymize(deviceConfig.userSelectBssid).c_str());
4401         WifiStaHalInterface::GetInstance().SetBssid(WPA_DEFAULT_NETWORKID, deviceConfig.userSelectBssid, ifaceName);
4402     } else {
4403         std::string autoSelectBssid;
4404         std::unique_ptr<NetworkSelectionManager> networkSelectionManager = std::make_unique<NetworkSelectionManager>();
4405         networkSelectionManager->SelectNetworkWithSsid(deviceConfig, autoSelectBssid);
4406         WIFI_LOGI("SetBssid autoSelectBssid=%{public}s", MacAnonymize(autoSelectBssid).c_str());
4407         WifiStaHalInterface::GetInstance().SetBssid(WPA_DEFAULT_NETWORKID, autoSelectBssid, ifaceName);
4408     }
4409     deviceConfig.userSelectBssid = "";
4410     WifiSettings::GetInstance().AddDeviceConfig(deviceConfig);
4411     WifiSettings::GetInstance().SyncDeviceConfig();
4412     return;
4413 }
4414 
4415 void StaStateMachine::AutoSelectConnectToNetwork(const std::string& bssid, std::string& ifaceName)
4416 {
4417     WIFI_LOGI("SetBssid bssid=%{public}s", MacAnonymize(bssid).c_str());
4418     WifiStaHalInterface::GetInstance().SetBssid(WPA_DEFAULT_NETWORKID, bssid, ifaceName);
4419     return;
4420 }
4421 
4422 ErrCode StaStateMachine::StartConnectToNetwork(int networkId, const std::string & bssid, int connTriggerMode)
4423 {
4424     if (m_instId == INSTID_WLAN0 && ConfigRandMacSelfCure(networkId) != WIFI_OPT_SUCCESS) {
4425         WIFI_LOGE("ConfigRandMacSelfCure failed!");
4426         return WIFI_OPT_FAILED;
4427     }
4428     if (connTriggerMode == NETWORK_SELECTED_BY_USER) {
4429         BlockConnectService::GetInstance().EnableNetworkSelectStatus(networkId);
4430 #ifndef OHOS_ARCH_LITE
4431         BlockConnectService::GetInstance().ReleaseUnusableBssidSet();
4432 #ifdef WIFI_SECURITY_DETECT_ENABLE
4433         WifiSecurityDetect::GetInstance().SetChangeNetworkid(networkId);
4434 #endif
4435 #endif
4436         WifiSettings::GetInstance().SetUserConnectChoice(networkId);
4437     }
4438     WifiDeviceConfig deviceConfig;
4439     if (WifiSettings::GetInstance().GetDeviceConfig(networkId, deviceConfig, m_instId) != 0) {
4440         WIFI_LOGE("StartConnectToNetwork get GetDeviceConfig failed!");
4441         return WIFI_OPT_FAILED;
4442     }
4443     targetNetworkId_ = networkId;
4444     linkSwitchDetectingFlag_ = false;
4445     SetRandomMac(deviceConfig, bssid);
4446     WIFI_LOGI("StartConnectToNetwork SetRandomMac targetNetworkId_:%{public}d, bssid:%{public}s", targetNetworkId_,
4447         MacAnonymize(bssid).c_str());
4448     std::string ifaceName = WifiConfigCenter::GetInstance().GetStaIfaceName(m_instId);
4449     WriteWifiConnectionInfoHiSysEvent(networkId);
4450     WriteConnectTypeHiSysEvent(connTriggerMode, deviceConfig.lastConnectTime <= 0);
4451     WriteStaConnectIface(ifaceName);
4452     WifiStaHalInterface::GetInstance().ClearDeviceConfig(ifaceName);
4453     int wpaNetworkId = WPA_DEFAULT_NETWORKID;
4454     if (WifiStaHalInterface::GetInstance().GetNextNetworkId(wpaNetworkId, ifaceName) != WIFI_HAL_OPT_OK) {
4455         WIFI_LOGE("StartConnectToNetwork GetNextNetworkId failed!");
4456         return WIFI_OPT_FAILED;
4457     }
4458     ConvertDeviceCfg(deviceConfig, bssid);
4459 #ifndef OHOS_ARCH_LITE
4460 #ifdef WIFI_DATA_REPORT_ENABLE
4461     wifiDataReportService_->InitReportApAllInfo();
4462 #endif
4463 #endif
4464     if (bssid.empty()) {
4465         // user select connect
4466         UserSelectConnectToNetwork(deviceConfig, ifaceName);
4467     } else {
4468         // auto connect
4469         AutoSelectConnectToNetwork(bssid, ifaceName);
4470     }
4471 
4472     if (WifiStaHalInterface::GetInstance().Connect(WPA_DEFAULT_NETWORKID, ifaceName) != WIFI_HAL_OPT_OK) {
4473         WIFI_LOGE("Connect failed!");
4474         InvokeOnStaConnChanged(OperateResState::CONNECT_SELECT_NETWORK_FAILED, linkedInfo);
4475         return WIFI_OPT_FAILED;
4476     }
4477     SetConnectMethod(connTriggerMode);
4478     WifiConfigCenter::GetInstance().EnableNetwork(networkId, connTriggerMode == NETWORK_SELECTED_BY_USER, m_instId);
4479     return WIFI_OPT_SUCCESS;
4480 }
4481 
4482 void StaStateMachine::MacAddressGenerate(WifiStoreRandomMac &randomMacInfo)
4483 {
4484     WIFI_LOGD("enter MacAddressGenerate\n");
4485     constexpr int arraySize = 4;
4486     constexpr int macBitSize = 12;
4487     constexpr int firstBit = 1;
4488     constexpr int lastBit = 11;
4489     constexpr int two = 2;
4490     constexpr int hexBase = 16;
4491     constexpr int octBase = 8;
4492     int ret = 0;
4493     char strMacTmp[arraySize] = {0};
4494     std::mt19937_64 gen(std::chrono::high_resolution_clock::now().time_since_epoch().count()
4495         + std::hash<std::string>{}(randomMacInfo.peerBssid) + std::hash<std::string>{}(randomMacInfo.preSharedKey));
4496     for (int i = 0; i < macBitSize; i++) {
4497         if (i != firstBit) {
4498             std::uniform_int_distribution<> distribution(0, hexBase - 1);
4499             ret = sprintf_s(strMacTmp, arraySize, "%x", distribution(gen));
4500         } else {
4501             std::uniform_int_distribution<> distribution(0, octBase - 1);
4502             ret = sprintf_s(strMacTmp, arraySize, "%x", two * distribution(gen));
4503         }
4504         if (ret == -1) {
4505             WIFI_LOGE("StaStateMachine::MacAddressGenerate failed, sprintf_s return -1!\n");
4506         }
4507         randomMacInfo.randomMac += strMacTmp;
4508         if ((i % two) != 0 && (i != lastBit)) {
4509             randomMacInfo.randomMac.append(":");
4510         }
4511     }
4512 }
4513 
4514 int StaStateMachine::GetWpa3FailCount(int failreason, std::string ssid) const
4515 {
4516     if (failreason < 0 || failreason >= WPA3_FAIL_REASON_MAX) {
4517         WIFI_LOGE("GetWpa3FailCount, Err failreason");
4518         return 0;
4519     }
4520     auto iter = wpa3ConnectFailCountMapArray[failreason].find(ssid);
4521     if (iter == wpa3ConnectFailCountMapArray[failreason].end()) {
4522         WIFI_LOGI("GetWpa3FailCount, no failreason count");
4523         return 0;
4524     }
4525     WIFI_LOGI("GetWpa3FailCount, failreason=%{public}d, count=%{public}d",
4526         failreason, iter->second);
4527     return iter->second;
4528 }
4529 
4530 void StaStateMachine::AddWpa3FailCount(int failreason, std::string ssid)
4531 {
4532     if (failreason < 0 || failreason >= WPA3_FAIL_REASON_MAX) {
4533         WIFI_LOGE("AddWpa3FailCount, Err failreason");
4534         return;
4535     }
4536     auto iter = wpa3ConnectFailCountMapArray[failreason].find(ssid);
4537     if (iter == wpa3ConnectFailCountMapArray[failreason].end()) {
4538         WIFI_LOGI("AddWpa3FailCount, new failreason count");
4539         wpa3ConnectFailCountMapArray[failreason].insert(std::make_pair(ssid, 1));
4540     } else {
4541         WIFI_LOGI("AddWpa3FailCount, existed failreason count");
4542         iter->second = iter->second + 1;
4543     }
4544 }
4545 
4546 void StaStateMachine::AddWpa3BlackMap(std::string ssid)
4547 {
4548     if (wpa3BlackMap.size() == WPA3_BLACKMAP_MAX_NUM) {
4549         auto iter = wpa3BlackMap.begin();
4550         auto oldestIter = wpa3BlackMap.begin();
4551         for (; iter != wpa3BlackMap.end(); iter++) {
4552             if (iter->second < oldestIter->second) {
4553                 oldestIter = iter;
4554             }
4555         }
4556         WIFI_LOGI("AddWpa3BlackMap, map full, delete oldest");
4557         wpa3BlackMap.erase(oldestIter);
4558     }
4559     WIFI_LOGI("AddWpa3BlackMap success");
4560     wpa3BlackMap.insert(std::make_pair(ssid, time(0)));
4561 }
4562 
4563 bool StaStateMachine::IsInWpa3BlackMap(std::string ssid) const
4564 {
4565     auto iter = wpa3BlackMap.find(ssid);
4566     if (iter != wpa3BlackMap.end()) {
4567         WIFI_LOGI("check is InWpa3BlackMap");
4568         return true;
4569     }
4570     return false;
4571 }
4572 
4573 void StaStateMachine::OnWifiWpa3SelfCure(int failreason, int networkId)
4574 {
4575     WifiDeviceConfig config;
4576     int failCountReason = 0;
4577 
4578     WIFI_LOGI("OnWifiWpa3SelfCure Enter.");
4579     auto iter = wpa3FailreasonMap.find(failreason);
4580     if (iter == wpa3FailreasonMap.end()) {
4581         WIFI_LOGE("OnWifiWpa3SelfCure, Invalid fail reason");
4582         return;
4583     }
4584     failCountReason = iter->second;
4585     if (WifiSettings::GetInstance().GetDeviceConfig(networkId, config, m_instId) == -1) {
4586         WIFI_LOGE("OnWifiWpa3SelfCure, get deviceconfig failed");
4587         return;
4588     }
4589     if (!IsWpa3Transition(config.ssid, config.bssid)) {
4590         WIFI_LOGE("OnWifiWpa3SelfCure, is not wpa3 transition");
4591         return;
4592     }
4593     if (linkedInfo.rssi <= WPA3_BLACKMAP_RSSI_THRESHOLD) {
4594         WIFI_LOGE("OnWifiWpa3SelfCure, rssi less then -70");
4595         return;
4596     }
4597     if (config.lastConnectTime > 0) {
4598         WIFI_LOGE("OnWifiWpa3SelfCure, has ever connected");
4599         return;
4600     }
4601     AddWpa3FailCount(failCountReason, config.ssid);
4602     if (GetWpa3FailCount(failCountReason, config.ssid) < WPA3_CONNECT_FAIL_COUNT_THRESHOLD) {
4603         WIFI_LOGI("OnWifiWpa3SelfCure, fail count not enough.");
4604         return;
4605     }
4606     AddWpa3BlackMap(config.ssid);
4607     StopTimer(static_cast<int>(CMD_NETWORK_CONNECT_TIMEOUT));
4608     SendMessage(WIFI_SVR_CMD_STA_CONNECT_NETWORK, networkId, NETWORK_SELECTED_BY_USER);
4609 }
4610 
4611 bool StaStateMachine::IsWpa3Transition(std::string ssid, std::string bssid) const
4612 {
4613     std::vector<WifiScanInfo> scanInfoList;
4614     WifiConfigCenter::GetInstance().GetWifiScanConfig()->GetScanInfoList(scanInfoList);
4615     for (auto scanInfo : scanInfoList) {
4616         if (ssid != scanInfo.ssid) {
4617             continue;
4618         }
4619         if (bssid.empty()) {
4620             if (scanInfo.capabilities.find("PSK+SAE") != std::string::npos) {
4621                 LOGI("IsWpa3Transition, check is transition ");
4622                 return true;
4623             }
4624         } else {
4625             if ((bssid == scanInfo.bssid) &&
4626                 (scanInfo.capabilities.find("PSK+SAE") != std::string::npos)) {
4627                 LOGI("IsWpa3Transition, check is transition bssid same");
4628                 return true;
4629             }
4630         }
4631     }
4632     return false;
4633 }
4634 
4635 void StaStateMachine::InitRandomMacInfo(const WifiDeviceConfig &deviceConfig, const std::string &bssid,
4636     WifiStoreRandomMac &randomMacInfo)
4637 {
4638     randomMacInfo.ssid = deviceConfig.ssid;
4639     randomMacInfo.keyMgmt = deviceConfig.keyMgmt;
4640     randomMacInfo.preSharedKey = deviceConfig.preSharedKey;
4641 
4642     if (!bssid.empty()) {
4643         randomMacInfo.peerBssid = bssid;
4644     } else {
4645         std::vector<WifiScanInfo> scanInfoList;
4646         WifiConfigCenter::GetInstance().GetWifiScanConfig()->GetScanInfoList(scanInfoList);
4647         for (auto scanInfo : scanInfoList) {
4648             std::string deviceKeyMgmt;
4649             scanInfo.GetDeviceMgmt(deviceKeyMgmt);
4650             if ((deviceConfig.ssid == scanInfo.ssid) && deviceKeyMgmt.find(deviceConfig.keyMgmt) != std::string::npos) {
4651                 randomMacInfo.peerBssid = scanInfo.bssid;
4652                 break;
4653             }
4654         }
4655     }
4656 }
4657 
4658 static constexpr int STA_CONNECT_RANDOMMAC_MAX_FAILED_COUNT = 2;
4659 
4660 bool StaStateMachine::ShouldUseFactoryMac(const WifiDeviceConfig &deviceConfig)
4661 {
4662     if (deviceConfig.keyMgmt == KEY_MGMT_NONE) {
4663         return false;
4664     }
4665     if (mLastConnectNetId != deviceConfig.networkId) {
4666         mLastConnectNetId = deviceConfig.networkId;
4667         mConnectFailedCnt = 0;
4668     }
4669     WIFI_LOGI("ShouldUseFactoryMac mLastConnectNetId:%{public}d networkId:%{public}d mConnectFailedCnt:%{public}d",
4670         mLastConnectNetId, deviceConfig.networkId, mConnectFailedCnt);
4671     if (mConnectFailedCnt >= STA_CONNECT_RANDOMMAC_MAX_FAILED_COUNT && !deviceConfig.randomizedMacSuccessEver) {
4672         return true;
4673     }
4674     return false;
4675 }
4676 
4677 void StaStateMachine::SetRandomMacConfig(WifiStoreRandomMac &randomMacInfo, const WifiDeviceConfig &deviceConfig,
4678     std::string &currentMac)
4679 {
4680 #ifdef SUPPORT_LOCAL_RANDOM_MAC
4681     std::string macAddress;
4682     std::string deviceConfigKey = deviceConfig.ssid + deviceConfig.keyMgmt;
4683     int ret = WifiRandomMacHelper::CalculateRandomMacForWifiDeviceConfig(deviceConfigKey, macAddress);
4684     if (ret != 0) {
4685         ret = WifiRandomMacHelper::CalculateRandomMacForWifiDeviceConfig(deviceConfigKey, macAddress);
4686     }
4687     if (ret != 0) {
4688         WIFI_LOGI("%{public}s Failed to generate MAC address from huks even after retrying."
4689             "Using locally generated MAC address instead.", __func__);
4690         WifiRandomMacHelper::GenerateRandomMacAddress(macAddress);
4691     }
4692     randomMacInfo.randomMac = macAddress;
4693     currentMac = randomMacInfo.randomMac;
4694     WIFI_LOGI("%{public}s: generate a random mac, randomMac:%{public}s, ssid:%{public}s, peerbssid:%{public}s",
4695         __func__, MacAnonymize(randomMacInfo.randomMac).c_str(), SsidAnonymize(randomMacInfo.ssid).c_str(),
4696         MacAnonymize(randomMacInfo.peerBssid).c_str());
4697 #endif
4698 }
4699 
4700 bool StaStateMachine::SetMacToHal(const std::string &currentMac, const std::string &realMac, int instId)
4701 {
4702     std::string lastMac;
4703     std::string ifaceName = WifiConfigCenter::GetInstance().GetStaIfaceName(instId);
4704     if ((WifiStaHalInterface::GetInstance().GetStaDeviceMacAddress(lastMac, ifaceName)) != WIFI_HAL_OPT_OK) {
4705         WIFI_LOGE("%{public}s randommac, GetStaDeviceMacAddress failed!", __func__);
4706         return false;
4707     }
4708     bool isRealMac = currentMac == realMac;
4709     WIFI_LOGI("%{public}s, randommac, use %{public}s mac to connect, currentMac:%{public}s, lastMac:%{public}s",
4710         __func__, isRealMac ? "factory" : "random", MacAnonymize(currentMac).c_str(), MacAnonymize(lastMac).c_str());
4711     std::string actualConfiguredMac = currentMac;
4712     if (!isRealMac && instId == 1) {
4713         if (!WifiRandomMacHelper::GetWifi2RandomMac(actualConfiguredMac)) {
4714             actualConfiguredMac = realMac;
4715         }
4716         WIFI_LOGI("%{public}s wifi2 actualConfiguredMac: %{public}s", __func__,
4717             MacAnonymize(actualConfiguredMac).c_str());
4718     }
4719     if (MacAddress::IsValidMac(actualConfiguredMac.c_str())) {
4720         // always set mac to hal to update drivers mac
4721         // In the subsequent evolution, will set a pure random mac in disconneting process. and don't duplicate set mac
4722         // when start connect
4723         if (WifiStaHalInterface::GetInstance().SetConnectMacAddr(
4724             WifiConfigCenter::GetInstance().GetStaIfaceName(instId), actualConfiguredMac) != WIFI_HAL_OPT_OK) {
4725                 WIFI_LOGE("set Mac [%{public}s] failed", MacAnonymize(actualConfiguredMac).c_str());
4726                 return false;
4727             }
4728         WifiConfigCenter::GetInstance().SetMacAddress(actualConfiguredMac, instId);
4729         return true;
4730     } else {
4731         WIFI_LOGE("%{public}s randommac, Check MacAddress error", __func__);
4732         return false;
4733     }
4734 }
4735 
4736 #ifdef FEATURE_WIFI_MDM_RESTRICTED_SUPPORT
4737 void StaStateMachine::DealMdmRestrictedConnect(WifiDeviceConfig &config)
4738 {
4739     WIFI_LOGI("WIFI Disconnect by MdmRestricted");
4740     SaveDiscReason(DisconnectedReason::DISC_REASON_CONNECTION_MDM_BLOCKLIST_FAIL);
4741     BlockConnectService::GetInstance().UpdateNetworkSelectStatus(config.networkId,
4742         DisabledReason::DISABLED_MDM_RESTRICTED);
4743     AddRandomMacCure();
4744     InvokeOnStaConnChanged(OperateResState::CONNECT_ENABLE_NETWORK_FAILED,
4745         linkedInfo);
4746     StartDisConnectToNetwork();
4747 }
4748 
4749 bool StaStateMachine::WhetherRestrictedByMdm(const std::string &ssid, const std::string &bssid, bool checkBssid)
4750 {
4751     if (checkBssid) {
4752         return WifiSettings::GetInstance().FindWifiBlockListConfig(ssid, bssid, 0) ||
4753         (WifiSettings::GetInstance().WhetherSetWhiteListConfig() &&
4754         !WifiSettings::GetInstance().FindWifiWhiteListConfig(ssid, bssid, 0));
4755     } else {
4756         if (WifiSettings::GetInstance().FindWifiBlockListConfig(ssid, bssid, 0)) {
4757             return true;
4758         }
4759         if (!WifiSettings::GetInstance().WhetherSetWhiteListConfig() || bssid.empty()) {
4760             return false;
4761         }
4762         if (!WifiSettings::GetInstance().FindWifiWhiteListConfig(ssid, bssid)) {
4763             return true;
4764         }
4765         return false;
4766     }
4767 }
4768 #endif
4769 
4770 void StaStateMachine::StartConnectToBssid(const int32_t networkId, std::string bssid)
4771 {
4772     InternalMessagePtr msg = CreateMessage();
4773     if (msg == nullptr) {
4774         return;
4775     }
4776 #ifdef FEATURE_WIFI_MDM_RESTRICTED_SUPPORT
4777     WifiDeviceConfig config;
4778     if (WifiSettings::GetInstance().GetDeviceConfig(networkId, config, m_instId) != 0) {
4779         WIFI_LOGE("GetDeviceConfig failed, networkId = %{public}d", networkId);
4780         return;
4781     }
4782     if (WifiSettings::GetInstance().FindWifiBlockListConfig(config.ssid, config.bssid, 0)) {
4783         return;
4784     }
4785     if (WifiSettings::GetInstance().WhetherSetWhiteListConfig() &&
4786         !WifiSettings::GetInstance().FindWifiWhiteListConfig(config.ssid, config.bssid, 0)) {
4787         return;
4788     }
4789 #endif
4790     msg->SetMessageName(WIFI_SVR_COM_STA_START_ROAM);
4791     msg->AddStringMessageBody(bssid);
4792     SendMessage(msg);
4793 }
4794 
4795 #ifndef OHOS_ARCH_LITE
4796 bool StaStateMachine::IsValidSimId(int32_t simId)
4797 {
4798     if (simId > 0) {
4799         return true;
4800     }
4801     return false;
4802 }
4803 
4804 
4805 /* Calculate SRES and KC as 2G authentication.
4806  * Protocol: 3GPP TS 31.102 2G_authentication
4807  * Request messge: [Length][RAND1][Length][RAND2]...[Length][RANDn]
4808  * Response messge: [SRES Length][SRES][KC Length][Cipher Key Kc]
4809 */
4810 std::string StaStateMachine::GetGsmAuthResponseWithLength(EapSimGsmAuthParam param)
4811 {
4812     int i = 0;
4813     std::string authRsp;
4814     uint8_t randArray[GSM_AUTH_RAND_LEN] = { 0 };
4815 
4816     WIFI_LOGI("%{public}s size:%{public}zu", __func__, param.rands.size());
4817     for (auto iter = param.rands.begin(); iter != param.rands.end(); ++iter) {
4818         // data pre-processing
4819         if (memset_s(randArray, sizeof(randArray), 0x0, sizeof(randArray)) != EOK) {
4820             WIFI_LOGE("%{public}s: memset_s is failed", __func__);
4821             return "";
4822         }
4823         char tmpRand[MAX_RAND_STR_LEN + 1] = { 0 };
4824         if (strncpy_s(tmpRand, sizeof(tmpRand), (*iter).c_str(), (*iter).length()) != EOK) {
4825             WIFI_LOGE("%{public}s: failed to copy", __func__);
4826             return "";
4827         }
4828         WIFI_LOGD("%{public}s rand[%{public}d]: %{private}s, tmpRand: %{private}s",
4829             __func__, i, (*iter).c_str(), tmpRand);
4830 
4831         // converting a hexadecimal character string to an array
4832         int ret = HexString2Byte(tmpRand, randArray, sizeof(randArray));
4833         if (ret != 0) {
4834             WIFI_LOGE("%{public}s: failed to convert a hexadecimal character string to integer", __func__);
4835             return "";
4836         }
4837         std::vector<uint8_t> randVec;
4838         randVec.push_back(sizeof(randArray));
4839         for (size_t j = 0; j < sizeof(randArray); j++) {
4840             randVec.push_back(randArray[j]);
4841         }
4842 
4843         // encode data and initiate a challenge request
4844         std::string base64Challenge = EncodeBase64(randVec);
4845         WifiDeviceConfig deviceConfig;
4846         WifiSettings::GetInstance().GetDeviceConfig(targetNetworkId_, deviceConfig, m_instId);
4847         std::string response = WifiTelephonyUtils::SimAkaAuth(
4848             base64Challenge, WifiTelephonyUtils::AuthType::SIM_TYPE, deviceConfig.wifiEapConfig.eapSubId);
4849         if (response.empty()) {
4850             WIFI_LOGE("%{public}s: fail to sim authentication", __func__);
4851             return "";
4852         }
4853         WIFI_LOGD("telephony response: %{private}s", response.c_str());
4854 
4855         // decode data: data format is [SRES Length][SRES][KC Length][Cipher Key Kc]
4856         std::vector<uint8_t> nonce;
4857         if (!DecodeBase64(response, nonce)) {
4858             WIFI_LOGE("%{public}s: failed to decode sim authentication, size:%{public}zu", __func__, nonce.size());
4859             return "";
4860         }
4861 
4862         // [SRES Length]: the length is 4 bytes
4863         uint8_t sresLen = nonce[0];
4864         if (sresLen >= nonce.size()) {
4865             WIFI_LOGE("%{public}s: invalid length, sresLen: %{public}d, size: %{public}zu",
4866                 __func__, sresLen, nonce.size());
4867             return "";
4868         }
4869 
4870         // [SRES]
4871         int offset = 1; // offset [SRES Length]
4872         char sresBuf[MAX_SRES_STR_LEN + 1] = { 0 };
4873         Byte2HexString(&nonce[offset], sresLen, sresBuf, sizeof(sresBuf));
4874         WIFI_LOGD("%{public}s sresLen: %{public}d, sresBuf: %{private}s", __func__, sresLen, sresBuf);
4875 
4876         // [KC Length]: the length is 8 bytes
4877         size_t kcOffset = 1 + sresLen; // offset [SRES Length][SRES]
4878         if (kcOffset >= nonce.size()) {
4879             WIFI_LOGE("%{public}s: invalid kcOffset: %{public}zu", __func__, kcOffset);
4880             return "";
4881         }
4882         uint8_t kcLen = nonce[kcOffset];
4883         if ((kcLen + kcOffset) >= nonce.size()) {
4884             WIFI_LOGE("%{public}s: invalid kcLen: %{public}d, kcOffset: %{public}zu", __func__, kcLen, kcOffset);
4885             return "";
4886         }
4887 
4888         // [Cipher Key Kc]
4889         char kcBuf[MAX_KC_STR_LEN + 1] = {0};
4890         Byte2HexString(&nonce[kcOffset + 1], kcLen, kcBuf, sizeof(kcBuf));
4891         WIFI_LOGD("%{public}s kcLen:%{public}d, kcBuf:%{private}s", __func__, kcLen, kcBuf);
4892 
4893         // strcat request message
4894         if (i == 0) {
4895             authRsp += std::string(kcBuf) + ":" + std::string(sresBuf);
4896         } else {
4897             authRsp += ":" + std::string(kcBuf) + ":" + std::string(sresBuf);
4898         }
4899         i++;
4900     }
4901     WIFI_LOGD("%{public}s authRsp: %{private}s, len: %{public}zu", __func__, authRsp.c_str(), authRsp.length());
4902     return authRsp;
4903 }
4904 
4905 /* Calculate SRES and KC as 2G authentication.
4906  * Protocol: 3GPP TS 11.11  2G_authentication
4907  * Request messge: [RAND1][RAND2]...[RANDn]
4908  * Response messge: [SRES][Cipher Key Kc]
4909 */
4910 std::string StaStateMachine::GetGsmAuthResponseWithoutLength(EapSimGsmAuthParam param)
4911 {
4912     int i = 0;
4913     std::string authRsp;
4914     uint8_t randArray[GSM_AUTH_RAND_LEN];
4915 
4916     WIFI_LOGI("%{public}s size: %{public}zu", __func__, param.rands.size());
4917     for (auto iter = param.rands.begin(); iter != param.rands.end(); ++iter) {
4918         // data pre-processing
4919         if (memset_s(randArray, sizeof(randArray), 0x0, sizeof(randArray)) != EOK) {
4920             WIFI_LOGE("%{public}s: memset_s is failed", __func__);
4921             return "";
4922         }
4923         char tmpRand[MAX_RAND_STR_LEN + 1] = { 0 };
4924         if (strncpy_s(tmpRand, sizeof(tmpRand), (*iter).c_str(), (*iter).length()) != EOK) {
4925             WIFI_LOGE("%{public}s: failed to copy", __func__);
4926             return "";
4927         }
4928 
4929         // converting a hexadecimal character string to an array
4930         int ret = HexString2Byte(tmpRand, randArray, sizeof(randArray));
4931         if (ret != 0) {
4932             WIFI_LOGE("%{public}s: fail to data conversion", __func__);
4933             return "";
4934         }
4935 
4936         std::vector<uint8_t> randVec;
4937         for (size_t j = 0; j < sizeof(randArray); j++) {
4938             randVec.push_back(randArray[j]);
4939         }
4940 
4941         // encode data and initiate a challenge request
4942         std::string base64Challenge = EncodeBase64(randVec);
4943         WifiDeviceConfig deviceConfig;
4944         WifiSettings::GetInstance().GetDeviceConfig(targetNetworkId_, deviceConfig, m_instId);
4945         std::string response = WifiTelephonyUtils::SimAkaAuth(
4946             base64Challenge, WifiTelephonyUtils::AuthType::SIM_TYPE, deviceConfig.wifiEapConfig.eapSubId);
4947         if (response.empty()) {
4948             WIFI_LOGE("%{public}s: fail to authenticate", __func__);
4949             return "";
4950         }
4951         WIFI_LOGD("telephony response: %{private}s", response.c_str());
4952 
4953         // data format: [SRES][Cipher Key Kc]
4954         std::vector<uint8_t> nonce;
4955         if (!DecodeBase64(response, nonce)) {
4956             WIFI_LOGE("%{public}s: failed to decode sim authentication, size:%{public}zu", __func__, nonce.size());
4957             return "";
4958         }
4959 
4960         if (GSM_AUTH_CHALLENGE_SRES_LEN + GSM_AUTH_CHALLENGE_KC_LEN != nonce.size()) {
4961             WIFI_LOGE("%{public}s: invalid length, size: %{public}zu", __func__, nonce.size());
4962             return "";
4963         }
4964 
4965         // [SRES]
4966         std::string sres;
4967         char sresBuf[MAX_SRES_STR_LEN + 1] = {0};
4968         Byte2HexString(&nonce[0], GSM_AUTH_CHALLENGE_SRES_LEN, sresBuf, sizeof(sresBuf));
4969 
4970         // [Cipher Key Kc]
4971         size_t kcOffset = GSM_AUTH_CHALLENGE_SRES_LEN;
4972         if (kcOffset >= nonce.size()) {
4973             WIFI_LOGE("%{public}s: invalid length, kcOffset: %{public}zu", __func__, kcOffset);
4974             return "";
4975         }
4976 
4977         std::string kc;
4978         char kcBuf[MAX_KC_STR_LEN + 1] = {0};
4979         Byte2HexString(&nonce[kcOffset], GSM_AUTH_CHALLENGE_KC_LEN, kcBuf, sizeof(kcBuf));
4980 
4981         // strcat request message
4982         if (i == 0) {
4983             authRsp += std::string(kcBuf) + ":" + std::string(sresBuf);
4984         } else {
4985             authRsp += ":" + std::string(kcBuf) + ":" + std::string(sresBuf);
4986         }
4987         i++;
4988     }
4989     WIFI_LOGI("%{public}s authReq: %{private}s, len: %{public}zu", __func__, authRsp.c_str(), authRsp.length());
4990     return authRsp;
4991 }
4992 
4993 bool StaStateMachine::PreWpaEapUmtsAuthEvent()
4994 {
4995     WifiDeviceConfig deviceConfig;
4996     WifiSettings::GetInstance().GetDeviceConfig(targetNetworkId_, deviceConfig, m_instId);
4997     return WifiTelephonyUtils::IsSupportCardType(deviceConfig.wifiEapConfig.eapSubId);
4998 }
4999 
5000 std::vector<uint8_t> StaStateMachine::FillUmtsAuthReq(EapSimUmtsAuthParam &param)
5001 {
5002     // request data format: [RAND LENGTH][RAND][AUTN LENGTH][AUTN]
5003     std::vector<uint8_t> inputChallenge;
5004 
5005     // rand hexadecimal string convert to binary
5006     char rand[MAX_RAND_STR_LEN + 1] = { 0 };
5007     if (strncpy_s(rand, sizeof(rand), param.rand.c_str(), param.rand.length()) != EOK) {
5008         WIFI_LOGE("%{public}s: failed to copy rand", __func__);
5009         return inputChallenge;
5010     }
5011     uint8_t randArray[UMTS_AUTH_CHALLENGE_RAND_LEN];
5012     int32_t ret = HexString2Byte(rand, randArray, sizeof(randArray));
5013     if (ret != 0) {
5014         WIFI_LOGE("%{public}s: failed to convert to rand", __func__);
5015         return inputChallenge;
5016     }
5017 
5018     // [RAND LENGTH]: rand length
5019     inputChallenge.push_back(sizeof(randArray));
5020 
5021     // [RAND]: rand data
5022     for (size_t i = 0; i < sizeof(randArray); i++) {
5023         inputChallenge.push_back(randArray[i]);
5024     }
5025 
5026     // autn hexadecimal string convert to binary
5027     char autn[MAX_AUTN_STR_LEN + 1] = { 0 };
5028     if (strncpy_s(autn, sizeof(autn), param.autn.c_str(), param.autn.length()) != EOK) {
5029         WIFI_LOGE("%{public}s: failed to copy autn", __func__);
5030         return inputChallenge;
5031     }
5032     uint8_t autnArray[UMTS_AUTH_CHALLENGE_RAND_LEN];
5033     ret = HexString2Byte(autn, autnArray, sizeof(autnArray));
5034     if (ret != 0) {
5035         WIFI_LOGE("%{public}s: failed to convert to autn", __func__);
5036         return inputChallenge;
5037     }
5038 
5039     // [AUTN LENGTH]: autn length
5040     inputChallenge.push_back(sizeof(autnArray));
5041 
5042     // [AUTN]: autn data
5043     for (size_t i = 0; i < sizeof(autnArray); i++) {
5044         inputChallenge.push_back(autnArray[i]);
5045     }
5046     return inputChallenge;
5047 }
5048 
5049 std::string StaStateMachine::ParseAndFillUmtsAuthParam(std::vector<uint8_t> &nonce)
5050 {
5051     std::string authReq;
5052     uint8_t tag = nonce[UMTS_AUTH_CHALLENGE_RESULT_INDEX]; // nonce[0]: the 1st byte is authentication type
5053     if (tag == UMTS_AUTH_TYPE_TAG) {
5054         char nonceBuf[UMTS_AUTH_RESPONSE_CONENT_LEN * 2 + 1] = { 0 }; // length of auth data
5055         Byte2HexString(&nonce[0], UMTS_AUTH_RESPONSE_CONENT_LEN, nonceBuf, sizeof(nonceBuf));
5056         WIFI_LOGD("Raw Response: %{private}s", nonceBuf);
5057 
5058         authReq = "UMTS-AUTH:";
5059 
5060         // res
5061         uint8_t resLen = nonce[UMTS_AUTH_CHALLENGE_DATA_START_IDNEX]; // nonce[1]: the 2nd byte is the length of res
5062         int resOffset = UMTS_AUTH_CHALLENGE_DATA_START_IDNEX + 1;
5063         std::string res;
5064         char resBuf[MAX_RES_STR_LEN + 1] = { 0 };
5065         /* nonce[2]~nonce[9]: the 3rd byte ~ 10th byte is res data */
5066         Byte2HexString(&nonce[resOffset], resLen, resBuf, sizeof(resBuf));
5067         WIFI_LOGD("%{public}s resLen: %{public}d, resBuf: %{private}s", __func__, resLen, resBuf);
5068 
5069         // ck
5070         int ckOffset = resOffset + resLen;
5071         uint8_t ckLen = nonce[ckOffset]; // nonce[10]: the 11th byte is ck length
5072         std::string ck;
5073         char ckBuf[MAX_CK_STR_LEN + 1] = { 0 };
5074 
5075         /* nonce[11]~nonce[26]: the 12th byte ~ 27th byte is ck data */
5076         Byte2HexString(&nonce[ckOffset + 1], ckLen, ckBuf, sizeof(ckBuf));
5077         WIFI_LOGD("ckLen: %{public}d, ckBuf:%{private}s", ckLen, ckBuf);
5078 
5079         // ik
5080         int ikOffset = ckOffset + ckLen + 1;
5081         uint8_t ikLen = nonce[ikOffset]; // nonce[27]: the 28th byte is the length of ik
5082         std::string ik;
5083         char ikBuf[MAX_IK_STR_LEN + 1] = { 0 };
5084         /* nonce[28]~nonce[43]: the 29th byte ~ 44th byte is ck data */
5085         Byte2HexString(&nonce[ikOffset + 1], ikLen, ikBuf, sizeof(ikBuf));
5086         WIFI_LOGD("ikLen: %{public}d, ikBuf:%{private}s", ikLen, ikBuf);
5087 
5088         std::string authRsp = std::string(ikBuf) + ":" + std::string(ckBuf) + ":" + std::string(resBuf);
5089         authReq += authRsp;
5090         WIFI_LOGD("%{public}s ik: %{private}s, ck: %{private}s, res: %{private}s, authRsp: %{private}s",
5091             __func__, ikBuf, ckBuf, resBuf, authRsp.c_str());
5092     } else {
5093         authReq = "UMTS-AUTS:";
5094 
5095         // auts
5096         uint8_t autsLen = nonce[UMTS_AUTH_CHALLENGE_DATA_START_IDNEX];
5097         WIFI_LOGD("autsLen: %{public}d", autsLen);
5098         int offset = UMTS_AUTH_CHALLENGE_DATA_START_IDNEX + 1;
5099         std::string auts;
5100         char autsBuf[MAX_AUTN_STR_LEN + 1] = { 0 };
5101         Byte2HexString(&nonce[offset], autsLen, autsBuf, sizeof(autsBuf));
5102         WIFI_LOGD("%{public}s auts: %{private}s", __func__, auts.c_str());
5103 
5104         std::string authRsp = auts;
5105         authReq += authRsp;
5106         WIFI_LOGD("%{public}s authRsp: %{private}s", __func__, authRsp.c_str());
5107     }
5108     return authReq;
5109 }
5110 
5111 std::string StaStateMachine::GetUmtsAuthResponse(EapSimUmtsAuthParam &param)
5112 {
5113     // request data format: [RAND LENGTH][RAND][AUTN LENGTH][AUTN]
5114     std::vector<uint8_t> inputChallenge = FillUmtsAuthReq(param);
5115     if (inputChallenge.size() != UMTS_AUTH_REQUEST_CONTENT_LEN) {
5116         return "";
5117     }
5118     std::string challenge = EncodeBase64(inputChallenge);
5119     WifiDeviceConfig deviceConfig;
5120     WifiSettings::GetInstance().GetDeviceConfig(targetNetworkId_, deviceConfig, m_instId);
5121     return WifiTelephonyUtils::SimAkaAuth(
5122         challenge, WifiTelephonyUtils::AuthType::AKA_TYPE, deviceConfig.wifiEapConfig.eapSubId);
5123 }
5124 
5125 void StaStateMachine::DealWpaEapSimAuthEvent(InternalMessagePtr msg)
5126 {
5127     if (msg == NULL) {
5128         WIFI_LOGE("%{public}s: msg is null", __func__);
5129         return;
5130     }
5131 
5132     EapSimGsmAuthParam param;
5133     msg->GetMessageObj(param);
5134     WIFI_LOGI("%{public}s size: %{public}zu", __func__, param.rands.size());
5135 
5136     std::string cmd = "GSM-AUTH:";
5137     if (param.rands.size() <= 0) {
5138         WIFI_LOGE("%{public}s: invalid rands", __func__);
5139         return;
5140     }
5141 
5142     std::string authRsp = GetGsmAuthResponseWithLength(param);
5143     if (authRsp.empty()) {
5144         authRsp = GetGsmAuthResponseWithoutLength(param);
5145         if (authRsp.empty()) {
5146             WIFI_LOGE("failed to sim authentication");
5147             return;
5148         }
5149     }
5150 
5151     cmd += authRsp;
5152     if (WifiStaHalInterface::GetInstance().ShellCmd("wlan0", cmd) != WIFI_HAL_OPT_OK) {
5153         WIFI_LOGI("%{public}s: failed to send the message, authReq: %{private}s", __func__, cmd.c_str());
5154         return;
5155     }
5156     WIFI_LOGD("%{public}s: success to send the message, authReq: %{private}s", __func__, cmd.c_str());
5157 }
5158 
5159 void StaStateMachine::DealWpaEapUmtsAuthEvent(InternalMessagePtr msg)
5160 {
5161     if (msg == NULL) {
5162         WIFI_LOGE("%{public}s: msg is null", __func__);
5163         return;
5164     }
5165 
5166     EapSimUmtsAuthParam param;
5167     msg->GetMessageObj(param);
5168     if (param.rand.empty() || param.autn.empty()) {
5169         WIFI_LOGE("invalid rand = %{public}zu or autn = %{public}zu", param.rand.length(), param.autn.length());
5170         return;
5171     }
5172 
5173     WIFI_LOGD("%{public}s rand: %{private}s, autn: %{private}s", __func__, param.rand.c_str(), param.autn.c_str());
5174 
5175     if (!PreWpaEapUmtsAuthEvent()) {
5176         return;
5177     }
5178 
5179     // get challenge information
5180     std::string response = GetUmtsAuthResponse(param);
5181     if (response.empty()) {
5182         WIFI_LOGE("response is empty");
5183         return;
5184     }
5185 
5186     // parse authentication information
5187     std::vector<uint8_t> nonce;
5188     if (!DecodeBase64(response, nonce)) {
5189         WIFI_LOGE("%{public}s: failed to decode aka authentication, size:%{public}zu", __func__, nonce.size());
5190         return;
5191     }
5192 
5193     // data format: [0xdb][RES Length][RES][CK Length][CK][IK Length][IK]
5194     uint8_t tag = nonce[UMTS_AUTH_CHALLENGE_RESULT_INDEX];
5195     if ((tag != UMTS_AUTH_TYPE_TAG) && (tag != UMTS_AUTS_TYPE_TAG)) {
5196         WIFI_LOGE("%{public}s: unsupport type: 0x%{public}02x", __func__, tag);
5197         return;
5198     }
5199 
5200     WIFI_LOGI("tag: 0x%{public}02x", tag);
5201 
5202     // request authentication to wpa
5203     std::string reqCmd = ParseAndFillUmtsAuthParam(nonce);
5204     if (WifiStaHalInterface::GetInstance().ShellCmd("wlan0", reqCmd) != WIFI_HAL_OPT_OK) {
5205         WIFI_LOGI("%{public}s: failed to send the message, authReq: %{private}s", __func__, reqCmd.c_str());
5206         return;
5207     }
5208     WIFI_LOGD("%{public}s: success to send the message, authReq: %{private}s", __func__, reqCmd.c_str());
5209 }
5210 #endif
5211 
5212 /* ------------------ state machine call back ----------------- */
5213 void StaStateMachine::RegisterStaServiceCallback(const StaServiceCallback &callback)
5214 {
5215     WIFI_LOGI("RegisterStaServiceCallback, callback module name: %{public}s", callback.callbackModuleName.c_str());
5216     std::unique_lock<std::shared_mutex> lock(m_staCallbackMutex);
5217     m_staCallback.insert_or_assign(callback.callbackModuleName, callback);
5218 }
5219 
5220 void StaStateMachine::UnRegisterStaServiceCallback(const StaServiceCallback &callback)
5221 {
5222     WIFI_LOGI("UnRegisterStaServiceCallback, callback module name: %{public}s", callback.callbackModuleName.c_str());
5223     std::unique_lock<std::shared_mutex> lock(m_staCallbackMutex);
5224     m_staCallback.erase(callback.callbackModuleName);
5225 }
5226 
5227 void StaStateMachine::InvokeOnStaConnChanged(OperateResState state, const WifiLinkedInfo &info)
5228 {
5229 #ifndef OHOS_ARCH_LITE
5230     if (selfCureService_ != nullptr) {
5231         if ((state == OperateResState::DISCONNECT_DISCONNECTED) || (state == OperateResState::CONNECT_AP_CONNECTED)
5232             || (state == OperateResState::CONNECT_CONNECTION_REJECT)) {
5233             selfCureService_->CheckSelfCureWifiResult(SCE_EVENT_NET_INFO_CHANGED);
5234         }
5235         if (selfCureService_->IsSelfCureL2Connecting() && info.detailedState != DetailedState::CONNECTED) {
5236             WIFI_LOGI("selfcure ignore network state changed");
5237             return;
5238         }
5239     }
5240 #endif
5241     {
5242         std::shared_lock<std::shared_mutex> lock(m_staCallbackMutex);
5243         for (const auto &callBackItem : m_staCallback) {
5244             if (callBackItem.second.OnStaConnChanged != nullptr) {
5245                 callBackItem.second.OnStaConnChanged(state, info, m_instId);
5246             }
5247         }
5248     }
5249     switch (state) {
5250         case OperateResState::CONNECT_AP_CONNECTED:
5251             WriteWifiConnectionHiSysEvent(static_cast<int>(WifiConnectionType::CONNECT), "");
5252             if (m_instId == INSTID_WLAN0) {
5253 #ifndef OHOS_ARCH_LITE
5254                 WifiNetStatsManager::GetInstance().StartNetStats();
5255 #endif
5256             }
5257             break;
5258         case OperateResState::DISCONNECT_DISCONNECTED:
5259             WriteWifiConnectionHiSysEvent(static_cast<int>(WifiConnectionType::DISCONNECT), "");
5260             if (m_instId == INSTID_WLAN0) {
5261 #ifndef OHOS_ARCH_LITE
5262                 WifiNetStatsManager::GetInstance().StopNetStats();
5263 #endif
5264             }
5265             break;
5266         default:
5267             break;
5268     }
5269 }
5270 
5271 void StaStateMachine::InvokeOnStaStreamChanged(StreamDirection direction)
5272 {
5273     std::shared_lock<std::shared_mutex> lock(m_staCallbackMutex);
5274     for (const auto &callBackItem : m_staCallback) {
5275         if (callBackItem.second.OnStaStreamChanged != nullptr) {
5276             callBackItem.second.OnStaStreamChanged(direction, m_instId);
5277         }
5278     }
5279 }
5280 
5281 void StaStateMachine::InvokeOnStaRssiLevelChanged(int level)
5282 {
5283     std::shared_lock<std::shared_mutex> lock(m_staCallbackMutex);
5284 #ifndef OHOS_ARCH_LITE
5285     if (selfCureService_ != nullptr) {
5286         if (selfCureService_->IsSelfCureL2Connecting()) {
5287             WIFI_LOGI("selfcure ignore rssi changed");
5288             return;
5289         }
5290     }
5291 #endif
5292     for (const auto &callBackItem : m_staCallback) {
5293         if (callBackItem.second.OnStaRssiLevelChanged != nullptr) {
5294             callBackItem.second.OnStaRssiLevelChanged(level, m_instId);
5295         }
5296     }
5297 }
5298 
5299 void StaStateMachine::InvokeOnDhcpOfferReport(IpInfo ipInfo)
5300 {
5301     std::shared_lock<std::shared_mutex> lock(m_staCallbackMutex);
5302     for (const auto &callBackItem : m_staCallback) {
5303         if (callBackItem.second.OnDhcpOfferReport != nullptr) {
5304             callBackItem.second.OnDhcpOfferReport(ipInfo, m_instId);
5305         }
5306     }
5307 }
5308 
5309 void StaStateMachine::InvokeOnInternetAccessChanged(SystemNetWorkState internetAccessStatus)
5310 {
5311     std::shared_lock<std::shared_mutex> lock(m_staCallbackMutex);
5312     for (const auto &callBackItem : m_staCallback) {
5313         if (callBackItem.second.OnInternetAccessChange != nullptr) {
5314             callBackItem.second.OnInternetAccessChange(static_cast<int32_t>(internetAccessStatus), m_instId);
5315         }
5316     }
5317 }
5318 
5319 void StaStateMachine::HandleInternetAccessChanged(SystemNetWorkState internetAccessStatus)
5320 {
5321     WIFI_LOGI("HandleInternetAccessChanged internetAccessStatus: %{public}d, lastInternetAccessStatus: %{public}d,"
5322         "noInternetAccessCnt_: %{public}d", internetAccessStatus, lastInternetIconStatus_, noInternetAccessCnt_);
5323     if (internetAccessStatus == SystemNetWorkState::NETWORK_IS_WORKING) {
5324         noInternetAccessCnt_ = 0;
5325         StopTimer(CMD_NO_INTERNET_TIMEOUT);
5326     }
5327 
5328     if (internetAccessStatus == SystemNetWorkState::NETWORK_NOTWORKING &&
5329         lastInternetIconStatus_ == SystemNetWorkState::NETWORK_IS_WORKING) {
5330         noInternetAccessCnt_++;
5331         if (noInternetAccessCnt_ < MAX_NO_INTERNET_CNT) {
5332             StopTimer(CMD_NO_INTERNET_TIMEOUT);
5333             StartTimer(CMD_NO_INTERNET_TIMEOUT, STA_NO_INTERNET_TIMEOUT);
5334             return;
5335         } else if (noInternetAccessCnt_ == MAX_NO_INTERNET_CNT) {
5336             StopTimer(CMD_NO_INTERNET_TIMEOUT);
5337         }
5338         if (lastSignalLevel_ <= RSSI_LEVEL_3) {
5339             WIFI_LOGW("HandleInternetAccessChanged, signal level less 3");
5340             return;
5341         }
5342 #ifdef FEATURE_SELF_CURE_SUPPORT
5343         if ((selfCureService_ != nullptr && !selfCureService_->IsWifiSelfcureDone())) {
5344             WIFI_LOGW("HandleInternetAccessChanged, selfcure is not finish");
5345             return;
5346         }
5347 #endif
5348     }
5349 
5350     if (lastInternetIconStatus_ == internetAccessStatus) {
5351         return;
5352     }
5353     lastInternetIconStatus_ = internetAccessStatus;
5354     InvokeOnInternetAccessChanged(internetAccessStatus);
5355 }
5356 
5357 void StaStateMachine::UpdateHiLinkAttribute()
5358 {
5359     std::vector<WifiScanInfo> wifiScanInfoList;
5360     WifiConfigCenter::GetInstance().GetWifiScanConfig()->GetScanInfoList(wifiScanInfoList);
5361     for (auto iter = wifiScanInfoList.begin(); iter != wifiScanInfoList.end(); ++iter) {
5362         if (iter->bssid == linkedInfo.bssid) {
5363             linkedInfo.isHiLinkNetwork = iter->isHiLinkNetwork;
5364             WIFI_LOGI("set hilink=%{public}d, bssid=%{public}s", iter->isHiLinkNetwork,
5365                 MacAnonymize(linkedInfo.bssid).c_str());
5366             break;
5367         }
5368     }
5369 }
5370 void StaStateMachine::LogSignalInfo(WifiSignalPollInfo &signalInfo)
5371 {
5372     WIFI_LOGI("SignalPoll,bssid:%{public}s,ssid:%{public}s,networkId:%{public}d,band:%{public}d,freq:%{public}d,"
5373         "rssi:%{public}d,noise:%{public}d,chload:%{public}d,snr:%{public}d,ulDelay:%{public}d,txLinkSpeed:%{public}d,"
5374         "rxLinkSpeed:%{public}d,txBytes:%{public}u,rxBytes:%{public}u,txFailed:%{public}d,txPackets:%{public}d,"
5375         "rxPackets:%{public}d,wifiCategory:%{public}d, wifiLinkType:%{public}d,GetWifiStandard:%{public}d,"
5376         "rxmax:%{public}d,txmax:%{public}d,connState:%{public}d,detState:%{public}d,lastSignal:%{public}d,"
5377         "chloadSelf:%{public}d,c0Rssi:%{public}d,c1Rssi:%{public}d", MacAnonymize(linkedInfo.bssid).c_str(),
5378         SsidAnonymize(linkedInfo.ssid).c_str(), linkedInfo.networkId, linkedInfo.band, signalInfo.frequency,
5379         signalInfo.signal, signalInfo.noise, signalInfo.chload, signalInfo.snr, signalInfo.ulDelay, signalInfo.txrate,
5380         signalInfo.rxrate, signalInfo.txBytes, signalInfo.rxBytes, signalInfo.txFailed, signalInfo.txPackets,
5381         signalInfo.rxPackets, static_cast<int>(linkedInfo.supportedWifiCategory),
5382         static_cast<int>(linkedInfo.wifiLinkType), linkedInfo.wifiStandard, linkedInfo.maxSupportedRxLinkSpeed,
5383         linkedInfo.maxSupportedTxLinkSpeed, linkedInfo.connState, linkedInfo.detailedState, lastSignalLevel_,
5384         signalInfo.chloadSelf, signalInfo.c0Rssi, signalInfo.c1Rssi);
5385 }
5386 } // namespace Wifi
5387 } // namespace OHOS
5388