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