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 ¤tMac)
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 ¤tMac, 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 ¶m)
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 ¶m)
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