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