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 "sta_state_machine.h"
17 #include <cstdio>
18 #include <thread>
19 #include "if_config.h"
20 #include "ip_tools.h"
21 #include "log_helper.h"
22 #include "mac_address.h"
23 #include "sta_monitor.h"
24 #include "wifi_chip_capability.h"
25 #include "wifi_common_util.h"
26 #include "wifi_logger.h"
27 #include "wifi_settings.h"
28 #include "wifi_sta_hal_interface.h"
29 #include "wifi_supplicant_hal_interface.h"
30 #ifndef OHOS_ARCH_LITE
31 #include "iservice_registry.h"
32 #include "system_ability_definition.h"
33 #endif // OHOS_ARCH_LITE
34
35 #ifndef OHOS_WIFI_STA_TEST
36 #include "dhcp_service.h"
37 #else
38 #include "mock_dhcp_service.h"
39 #endif
40
41 namespace OHOS {
42 namespace Wifi {
43 DEFINE_WIFILOG_LABEL("StaStateMachine");
44 #define PBC_ANY_BSSID "any"
StaStateMachine()45 StaStateMachine::StaStateMachine()
46 : StateMachine("StaStateMachine"),
47 lastNetworkId(INVALID_NETWORK_ID),
48 operationalMode(STA_CONNECT_MODE),
49 targetNetworkId(INVALID_NETWORK_ID),
50 pinCode(0),
51 wpsState(SetupMethod::INVALID),
52 lastSignalLevel(-1),
53 targetRoamBssid(WPA_BSSID_ANY),
54 currentTpType(IPTYPE_IPV4),
55 isWpsConnect(IsWpsConnected::WPS_INVALID),
56 getIpSucNum(0),
57 getIpFailNum(0),
58 isRoam(false),
59 pDhcpService(nullptr),
60 pDhcpResultNotify(nullptr),
61 pNetcheck(nullptr),
62 pRootState(nullptr),
63 pInitState(nullptr),
64 pWpaStartingState(nullptr),
65 pWpaStartedState(nullptr),
66 pWpaStoppingState(nullptr),
67 pLinkState(nullptr),
68 pSeparatingState(nullptr),
69 pSeparatedState(nullptr),
70 pApLinkedState(nullptr),
71 pWpsState(nullptr),
72 pGetIpState(nullptr),
73 pLinkedState(nullptr),
74 pApRoamingState(nullptr)
75 {
76 #ifndef OHOS_ARCH_LITE
77 SubscribeSystemAbilityChanged();
78 #endif // OHOS_ARCH_LITE
79 }
80
~StaStateMachine()81 StaStateMachine::~StaStateMachine()
82 {
83 WIFI_LOGI("StaStateMachine::~StaStateMachine");
84 StopHandlerThread();
85 ParsePointer(pRootState);
86 ParsePointer(pInitState);
87 ParsePointer(pWpaStartingState);
88 ParsePointer(pWpaStartedState);
89 ParsePointer(pWpaStoppingState);
90 ParsePointer(pLinkState);
91 ParsePointer(pSeparatingState);
92 ParsePointer(pSeparatedState);
93 ParsePointer(pApLinkedState);
94 ParsePointer(pWpsState);
95 ParsePointer(pGetIpState);
96 ParsePointer(pLinkedState);
97 ParsePointer(pApRoamingState);
98 if (pDhcpService != nullptr) {
99 if (currentTpType == IPTYPE_IPV4) {
100 pDhcpService->StopDhcpClient(IF_NAME, false);
101 } else {
102 pDhcpService->StopDhcpClient(IF_NAME, true);
103 }
104 pDhcpService->RemoveDhcpResult(pDhcpResultNotify);
105 }
106 ParsePointer(pDhcpResultNotify);
107 ParsePointer(pDhcpService);
108 ParsePointer(pNetcheck);
109 }
110
111 /* ---------------------------Initialization functions------------------------------ */
InitStaStateMachine()112 ErrCode StaStateMachine::InitStaStateMachine()
113 {
114 WIFI_LOGI("Enter StaStateMachine::InitStaStateMachine.\n");
115 if (!InitialStateMachine()) {
116 WIFI_LOGE("Initial StateMachine failed.\n");
117 return WIFI_OPT_FAILED;
118 }
119
120 if (InitStaStates() == WIFI_OPT_FAILED) {
121 return WIFI_OPT_FAILED;
122 }
123 BuildStateTree();
124 SetFirstState(pInitState);
125 StartStateMachine();
126 InitStaSMHandleMap();
127
128 pDhcpService = new (std::nothrow) DhcpService();
129 if (pDhcpService == nullptr) {
130 WIFI_LOGE("pDhcpServer is null\n");
131 return WIFI_OPT_FAILED;
132 }
133
134 pNetcheck = new (std::nothrow)
135 StaNetworkCheck(std::bind(&StaStateMachine::HandleNetCheckResult, this,
136 std::placeholders::_1, std::placeholders::_2));
137 if (pNetcheck == nullptr) {
138 WIFI_LOGE("pNetcheck is null\n");
139 return WIFI_OPT_FAILED;
140 }
141 pNetcheck->InitNetCheckThread();
142 #ifndef OHOS_ARCH_LITE
143 NetSupplierInfo = std::make_unique<NetManagerStandard::NetSupplierInfo>().release();
144 #endif
145 return WIFI_OPT_SUCCESS;
146 }
147
InitStaStates()148 ErrCode StaStateMachine::InitStaStates()
149 {
150 WIFI_LOGE("Enter InitStaStates\n");
151 int tmpErrNumber;
152 pRootState = new (std::nothrow)RootState();
153 tmpErrNumber = JudgmentEmpty(pRootState);
154 pInitState = new (std::nothrow)InitState(this);
155 tmpErrNumber += JudgmentEmpty(pInitState);
156 pWpaStartingState = new (std::nothrow)WpaStartingState(this);
157 tmpErrNumber += JudgmentEmpty(pWpaStartingState);
158 pWpaStartedState = new (std::nothrow)WpaStartedState(this);
159 tmpErrNumber += JudgmentEmpty(pWpaStartedState);
160 pWpaStoppingState = new (std::nothrow)WpaStoppingState(this);
161 tmpErrNumber += JudgmentEmpty(pWpaStoppingState);
162 pLinkState = new (std::nothrow)LinkState(this);
163 tmpErrNumber += JudgmentEmpty(pLinkState);
164 pSeparatingState = new (std::nothrow)SeparatingState();
165 tmpErrNumber += JudgmentEmpty(pSeparatingState);
166 pSeparatedState = new (std::nothrow)SeparatedState(this);
167 tmpErrNumber += JudgmentEmpty(pSeparatedState);
168 pApLinkedState = new (std::nothrow)ApLinkedState(this);
169 tmpErrNumber += JudgmentEmpty(pApLinkedState);
170 pWpsState = new (std::nothrow)StaWpsState(this);
171 tmpErrNumber += JudgmentEmpty(pWpsState);
172 pGetIpState = new (std::nothrow)GetIpState(this);
173 tmpErrNumber += JudgmentEmpty(pGetIpState);
174 pLinkedState = new (std::nothrow)LinkedState(this);
175 tmpErrNumber += JudgmentEmpty(pLinkedState);
176 pApRoamingState = new (std::nothrow)ApRoamingState(this);
177 tmpErrNumber += JudgmentEmpty(pApRoamingState);
178 pDhcpResultNotify = new (std::nothrow)DhcpResultNotify(this);
179 tmpErrNumber += JudgmentEmpty(pDhcpResultNotify);
180 if (tmpErrNumber != 0) {
181 WIFI_LOGE("InitStaStates some one state is null\n");
182 return WIFI_OPT_FAILED;
183 }
184 return WIFI_OPT_SUCCESS;
185 }
186
InitWifiLinkedInfo()187 void StaStateMachine::InitWifiLinkedInfo()
188 {
189 linkedInfo.networkId = INVALID_NETWORK_ID;
190 linkedInfo.ssid = "";
191 linkedInfo.bssid = "";
192 linkedInfo.macAddress = "";
193 linkedInfo.macType = 0;
194 linkedInfo.rxLinkSpeed = 0;
195 linkedInfo.txLinkSpeed = 0;
196 linkedInfo.rssi = 0;
197 linkedInfo.band = 0;
198 linkedInfo.frequency = 0;
199 linkedInfo.linkSpeed = 0;
200 linkedInfo.ipAddress = 0;
201 linkedInfo.connState = ConnState::DISCONNECTED;
202 linkedInfo.ifHiddenSSID = false;
203 linkedInfo.chload = 0;
204 linkedInfo.snr = 0;
205 linkedInfo.isDataRestricted = 0;
206 linkedInfo.portalUrl = "";
207 linkedInfo.detailedState = DetailedState::DISCONNECTED;
208 }
209
InitLastWifiLinkedInfo()210 void StaStateMachine::InitLastWifiLinkedInfo()
211 {
212 lastLinkedInfo.networkId = INVALID_NETWORK_ID;
213 lastLinkedInfo.ssid = "";
214 lastLinkedInfo.bssid = "";
215 lastLinkedInfo.macAddress = "";
216 linkedInfo.macType = 0;
217 lastLinkedInfo.rxLinkSpeed = 0;
218 lastLinkedInfo.txLinkSpeed = 0;
219 lastLinkedInfo.rssi = 0;
220 lastLinkedInfo.band = 0;
221 lastLinkedInfo.frequency = 0;
222 lastLinkedInfo.linkSpeed = 0;
223 lastLinkedInfo.ipAddress = 0;
224 lastLinkedInfo.connState = ConnState::DISCONNECTED;
225 lastLinkedInfo.ifHiddenSSID = false;
226 lastLinkedInfo.chload = 0;
227 lastLinkedInfo.snr = 0;
228 linkedInfo.isDataRestricted = 0;
229 linkedInfo.portalUrl = "";
230 lastLinkedInfo.detailedState = DetailedState::DISCONNECTED;
231 }
232
BuildStateTree()233 void StaStateMachine::BuildStateTree()
234 {
235 StatePlus(pRootState, nullptr);
236 StatePlus(pInitState, pRootState);
237 StatePlus(pWpaStartingState, pRootState);
238 StatePlus(pWpaStartedState, pRootState);
239 StatePlus(pLinkState, pWpaStartedState);
240 StatePlus(pSeparatingState, pLinkState);
241 StatePlus(pSeparatedState, pLinkState);
242 StatePlus(pApLinkedState, pLinkState);
243 StatePlus(pGetIpState, pApLinkedState);
244 StatePlus(pLinkedState, pApLinkedState);
245 StatePlus(pApRoamingState, pApLinkedState);
246 StatePlus(pWpsState, pLinkState);
247 StatePlus(pWpaStoppingState, pRootState);
248 }
249
RegisterStaServiceCallback(const StaServiceCallback & callbacks)250 void StaStateMachine::RegisterStaServiceCallback(const StaServiceCallback &callbacks)
251 {
252 WIFI_LOGI("RegisterStaServiceCallback.");
253 staCallback = callbacks;
254 }
255
256 /* --------------------------- state machine root state ------------------------------ */
RootState()257 StaStateMachine::RootState::RootState() : State("RootState")
258 {}
259
~RootState()260 StaStateMachine::RootState::~RootState()
261 {}
262
GoInState()263 void StaStateMachine::RootState::GoInState()
264 {
265 WIFI_LOGI("RootState GoInState function.");
266 return;
267 }
268
GoOutState()269 void StaStateMachine::RootState::GoOutState()
270 {
271 WIFI_LOGI("RootState GoOutState function.");
272 return;
273 }
274
ExecuteStateMsg(InternalMessage * msg)275 bool StaStateMachine::RootState::ExecuteStateMsg(InternalMessage *msg)
276 {
277 if (msg == nullptr) {
278 return false;
279 }
280
281 WIFI_LOGI("RootState-msgCode=%{public}d not handled.\n", msg->GetMessageName());
282 return true;
283 }
284
285 /* --------------------------- state machine Init State ------------------------------ */
InitState(StaStateMachine * staStateMachine)286 StaStateMachine::InitState::InitState(StaStateMachine *staStateMachine)
287 : State("InitState"), pStaStateMachine(staStateMachine)
288 {}
289
~InitState()290 StaStateMachine::InitState::~InitState()
291 {}
292
GoInState()293 void StaStateMachine::InitState::GoInState()
294 {
295 WIFI_LOGI("InitState GoInState function.");
296 return;
297 }
298
GoOutState()299 void StaStateMachine::InitState::GoOutState()
300 {
301 WIFI_LOGI("InitState GoOutState function.");
302 return;
303 }
304
ExecuteStateMsg(InternalMessage * msg)305 bool StaStateMachine::InitState::ExecuteStateMsg(InternalMessage *msg)
306 {
307 if (msg == nullptr) {
308 return false;
309 }
310
311 WIFI_LOGI("InitState-msgCode=%{public}d is received.\n", msg->GetMessageName());
312 bool ret = NOT_EXECUTED;
313 switch (msg->GetMessageName()) {
314 case WIFI_SVR_CMD_STA_ENABLE_WIFI: {
315 ret = EXECUTED;
316 pStaStateMachine->operationalMode = msg->GetParam1();
317 pStaStateMachine->StartWifiProcess();
318 break;
319 }
320
321 case WIFI_SVR_CMD_STA_OPERATIONAL_MODE:
322 break;
323
324 default:
325 WIFI_LOGI("InitState-msgCode=%d not handled.\n", msg->GetMessageName());
326 break;
327 }
328 return ret;
329 }
330
ConvertDeviceCfg(const WifiDeviceConfig & config) const331 ErrCode StaStateMachine::ConvertDeviceCfg(const WifiDeviceConfig &config) const
332 {
333 LOGI("Enter StaStateMachine::ConvertDeviceCfg.\n");
334 WifiIdlDeviceConfig idlConfig;
335 idlConfig.networkId = config.networkId;
336 idlConfig.ssid = config.ssid;
337 idlConfig.bssid = config.bssid;
338 idlConfig.psk = config.preSharedKey;
339 idlConfig.keyMgmt = config.keyMgmt;
340 idlConfig.priority = config.priority;
341 idlConfig.scanSsid = config.hiddenSSID ? 1 : 0;
342 idlConfig.eap = config.wifiEapConfig.eap;
343 idlConfig.identity = config.wifiEapConfig.identity;
344 idlConfig.password = config.wifiEapConfig.password;
345 idlConfig.clientCert = config.wifiEapConfig.clientCert;
346 idlConfig.privateKey = config.wifiEapConfig.privateKey;
347 idlConfig.phase2Method = static_cast<int>(config.wifiEapConfig.phase2Method);
348 idlConfig.wepKeyIdx = config.wepTxKeyIndex;
349 if (strcmp(config.keyMgmt.c_str(), "WEP") == 0) {
350 /* for wep */
351 idlConfig.authAlgorithms = 0x02;
352 }
353
354 for (int i = 0; i < MAX_WEPKEYS_SIZE; i++) {
355 idlConfig.wepKeys[i] = config.wepKeys[i];
356 }
357
358 if (WifiStaHalInterface::GetInstance().SetDeviceConfig(config.networkId, idlConfig) != WIFI_IDL_OPT_OK) {
359 LOGE("StaStateMachine::ConvertDeviceCfg SetDeviceConfig failed!");
360 return WIFI_OPT_FAILED;
361 }
362
363 if (WifiStaHalInterface::GetInstance().SaveDeviceConfig() != WIFI_IDL_OPT_OK) {
364 LOGW("StaStateMachine::ConvertDeviceCfg SaveDeviceConfig failed!");
365 }
366 return WIFI_OPT_SUCCESS;
367 }
368
SyncDeviceConfigToWpa() const369 void StaStateMachine::SyncDeviceConfigToWpa() const
370 {
371 WIFI_LOGI("SyncDeviceConfigToWpa");
372 /* Reload wifi Configurations. */
373 if (WifiSettings::GetInstance().ReloadDeviceConfig() != 0) {
374 WIFI_LOGE("ReloadDeviceConfig is failed!");
375 }
376
377 if (WifiStaHalInterface::GetInstance().ClearDeviceConfig() != WIFI_IDL_OPT_OK) {
378 WIFI_LOGE("ClearDeviceConfig() failed!");
379 } else {
380 WIFI_LOGD("ClearDeviceConfig() succeeded!");
381 std::vector<WifiDeviceConfig> results;
382 WifiSettings::GetInstance().GetDeviceConfig(results);
383 for(WifiDeviceConfig result : results) {
384 WIFI_LOGD("SyncDeviceConfigToWpa:result.networkId=[%d]!", result.networkId);
385 int networkId = INVALID_NETWORK_ID;
386 if (WifiStaHalInterface::GetInstance().GetNextNetworkId(networkId) != WIFI_IDL_OPT_OK) {
387 WIFI_LOGE("GetNextNetworkId failed.");
388 return;
389 }
390 if (networkId != result.networkId) {
391 WIFI_LOGE("DeviceConfig networkId different from wpa config networkId.");
392 return;
393 }
394 ConvertDeviceCfg(result);
395 }
396 WIFI_LOGD("SyncDeviceConfigToWpa-SaveDeviceConfig() succeed!");
397 }
398 }
399
StartWifiProcess()400 void StaStateMachine::StartWifiProcess()
401 {
402 WifiSettings::GetInstance().SetWifiState(static_cast<int>(WifiState::ENABLING));
403 staCallback.OnStaOpenRes(OperateResState::OPEN_WIFI_OPENING);
404 int res = WifiStaHalInterface::GetInstance().StartWifi();
405 if (res == static_cast<int>(WIFI_IDL_OPT_OK)) {
406 WIFI_LOGI("Start wifi successfully!");
407 if (WifiStaHalInterface::GetInstance().WpaAutoConnect(false) != WIFI_IDL_OPT_OK) {
408 WIFI_LOGI("The automatic Wpa connection is disabled failed.");
409 }
410
411 /* callback the InterfaceService that wifi is enabled successfully. */
412 WifiSettings::GetInstance().SetWifiState(static_cast<int>(WifiState::ENABLED));
413 staCallback.OnStaOpenRes(OperateResState::OPEN_WIFI_SUCCEED);
414 /* Sets the MAC address of WifiSettings. */
415 std::string mac;
416 if ((WifiStaHalInterface::GetInstance().GetStaDeviceMacAddress(mac)) == WIFI_IDL_OPT_OK) {
417 WifiSettings::GetInstance().SetMacAddress(mac);
418 } else {
419 WIFI_LOGI("GetStaDeviceMacAddress failed!");
420 }
421 #ifndef OHOS_ARCH_LITE
422 WIFI_LOGI("Register netsupplier");
423 WifiNetAgent::GetInstance().OnStaMachineWifiStart(staCallback);
424 #endif
425 /* Initialize Connection Information. */
426 InitWifiLinkedInfo();
427 InitLastWifiLinkedInfo();
428 WifiSettings::GetInstance().SaveLinkedInfo(linkedInfo);
429 SyncDeviceConfigToWpa();
430 #ifndef OHOS_ARCH_LITE
431 ChipCapability::GetInstance().InitializeChipCapability();
432 #endif
433 /* The current state of StaStateMachine transfers to SeparatedState after
434 * enable supplicant.
435 */
436 SwitchState(pSeparatedState);
437 } else {
438 /* Notify the InterfaceService that wifi is failed to enable wifi. */
439 LOGE("StartWifi failed, and errcode is %d.", res);
440 WifiSettings::GetInstance().SetWifiState(static_cast<int>(WifiState::DISABLED));
441 WifiSettings::GetInstance().SetUserLastSelectedNetworkId(INVALID_NETWORK_ID);
442 staCallback.OnStaOpenRes(OperateResState::OPEN_WIFI_FAILED);
443 }
444 }
445
446 /* --------------------------- state machine WpaStarting State ------------------------------ */
WpaStartingState(StaStateMachine * staStateMachine)447 StaStateMachine::WpaStartingState::WpaStartingState(StaStateMachine *staStateMachine)
448 : State("WpaStartingState"), pStaStateMachine(staStateMachine)
449 {}
450
~WpaStartingState()451 StaStateMachine::WpaStartingState::~WpaStartingState()
452 {}
453
InitWpsSettings()454 void StaStateMachine::WpaStartingState::InitWpsSettings()
455 {
456 WIFI_LOGI("WpaStartingState InitWpsSettings function.");
457 return;
458 }
459
GoInState()460 void StaStateMachine::WpaStartingState::GoInState()
461 {
462 WIFI_LOGI("WpaStartingState GoInState function.");
463 return;
464 }
465
GoOutState()466 void StaStateMachine::WpaStartingState::GoOutState()
467 {
468 LOGI("WpaStartingState GoOutState function.");
469 return;
470 }
471
ExecuteStateMsg(InternalMessage * msg)472 bool StaStateMachine::WpaStartingState::ExecuteStateMsg(InternalMessage *msg)
473 {
474 if (msg == nullptr) {
475 return false;
476 }
477
478 bool ret = NOT_EXECUTED;
479 switch (msg->GetMessageName()) {
480 case WIFI_SVR_CMD_STA_SUP_CONNECTION_EVENT: {
481 ret = EXECUTED;
482 pStaStateMachine->SwitchState(pStaStateMachine->pWpaStartedState);
483 break;
484 }
485 default:
486 break;
487 }
488 return ret;
489 }
490
491 /* --------------------------- state machine WpaStarted State ------------------------------ */
WpaStartedState(StaStateMachine * staStateMachine)492 StaStateMachine::WpaStartedState::WpaStartedState(StaStateMachine *staStateMachine)
493 : State("WpaStartedState"), pStaStateMachine(staStateMachine)
494 {}
495
~WpaStartedState()496 StaStateMachine::WpaStartedState::~WpaStartedState()
497 {}
498
GoInState()499 void StaStateMachine::WpaStartedState::GoInState()
500 {
501 WIFI_LOGI("WpaStartedState GoInState function.");
502 if (pStaStateMachine->operationalMode == STA_CONNECT_MODE) {
503 pStaStateMachine->SwitchState(pStaStateMachine->pSeparatedState);
504 } else if (pStaStateMachine->operationalMode == STA_DISABLED_MODE) {
505 pStaStateMachine->SwitchState(pStaStateMachine->pWpaStoppingState);
506 }
507 return;
508 }
GoOutState()509 void StaStateMachine::WpaStartedState::GoOutState()
510 {
511 WIFI_LOGI("WpaStartedState GoOutState function.");
512 return;
513 }
514
ExecuteStateMsg(InternalMessage * msg)515 bool StaStateMachine::WpaStartedState::ExecuteStateMsg(InternalMessage *msg)
516 {
517 if (msg == nullptr) {
518 LOGI("msg is nullptr");
519 return false;
520 }
521
522 WIFI_LOGI("WpaStartedState ExecuteStateMsg-msgCode:%{public}d.\n", msg->GetMessageName());
523 bool ret = NOT_EXECUTED;
524 switch (msg->GetMessageName()) {
525 case WIFI_SVR_CMD_STA_DISABLE_WIFI: {
526 ret = EXECUTED;
527 pStaStateMachine->StopWifiProcess();
528 break;
529 }
530
531 default:
532 break;
533 }
534 return ret;
535 }
536
StopWifiProcess()537 void StaStateMachine::StopWifiProcess()
538 {
539 WIFI_LOGI("Enter StaStateMachine::StopWifiProcess.\n");
540 #ifndef OHOS_ARCH_LITE
541 WifiNetAgent::GetInstance().UnregisterNetSupplier();
542 #endif
543 WIFI_LOGI("Stop wifi is in process...\n");
544 WifiSettings::GetInstance().SetWifiState(static_cast<int>(WifiState::DISABLING));
545 staCallback.OnStaCloseRes(OperateResState::CLOSE_WIFI_CLOSING);
546 StopTimer(static_cast<int>(CMD_SIGNAL_POLL));
547 if (currentTpType == IPTYPE_IPV4) {
548 pDhcpService->StopDhcpClient(IF_NAME, false);
549 } else {
550 pDhcpService->StopDhcpClient(IF_NAME, true);
551 }
552 isRoam = false;
553 WifiSettings::GetInstance().SetMacAddress("");
554
555 IpInfo ipInfo;
556 WifiSettings::GetInstance().SaveIpInfo(ipInfo);
557 #ifdef OHOS_ARCH_LITE
558 IfConfig::GetInstance().FlushIpAddr(IF_NAME, IPTYPE_IPV4);
559 #endif
560
561 /* clear connection information. */
562 InitWifiLinkedInfo();
563 WifiSettings::GetInstance().SaveLinkedInfo(linkedInfo);
564
565 if (WifiStaHalInterface::GetInstance().StopWifi() == WIFI_IDL_OPT_OK) {
566 /* Callback result to InterfaceService. */
567 WifiSettings::GetInstance().SetWifiState(static_cast<int>(WifiState::DISABLED));
568 staCallback.OnStaCloseRes(OperateResState::CLOSE_WIFI_SUCCEED);
569 WIFI_LOGI("Stop WifiProcess successfully!");
570
571 /* The current state of StaStateMachine transfers to InitState. */
572 SwitchState(pInitState);
573 } else {
574 WIFI_LOGE("StopWifiProcess failed.");
575 WifiSettings::GetInstance().SetWifiState(static_cast<int>(WifiState::UNKNOWN));
576 staCallback.OnStaCloseRes(OperateResState::CLOSE_WIFI_FAILED);
577 }
578 WifiSettings::GetInstance().SetUserLastSelectedNetworkId(INVALID_NETWORK_ID);
579 }
580
581 /* --------------------------- state machine WpaStopping State ------------------------------ */
WpaStoppingState(StaStateMachine * staStateMachine)582 StaStateMachine::WpaStoppingState::WpaStoppingState(StaStateMachine *staStateMachine)
583 : State("WpaStoppingState"), pStaStateMachine(staStateMachine)
584 {}
585
~WpaStoppingState()586 StaStateMachine::WpaStoppingState::~WpaStoppingState()
587 {}
588
GoInState()589 void StaStateMachine::WpaStoppingState::GoInState()
590 {
591 WIFI_LOGI("WpaStoppingState GoInState function.");
592 pStaStateMachine->SwitchState(pStaStateMachine->pInitState);
593 return;
594 }
595
GoOutState()596 void StaStateMachine::WpaStoppingState::GoOutState()
597 {
598 WIFI_LOGI("WpaStoppingState GoOutState function.");
599 return;
600 }
601
ExecuteStateMsg(InternalMessage * msg)602 bool StaStateMachine::WpaStoppingState::ExecuteStateMsg(InternalMessage *msg)
603 {
604 if (msg == nullptr) {
605 return false;
606 }
607
608 bool ret = NOT_EXECUTED;
609 WIFI_LOGI("WpaStoppingState-msgCode=%{public}d not handled.\n", msg->GetMessageName());
610 return ret;
611 }
612
613 /* --------------------------- state machine link State ------------------------------ */
LinkState(StaStateMachine * staStateMachine)614 StaStateMachine::LinkState::LinkState(StaStateMachine *staStateMachine)
615 : State("LinkState"), pStaStateMachine(staStateMachine)
616 {}
617
~LinkState()618 StaStateMachine::LinkState::~LinkState()
619 {}
620
GoInState()621 void StaStateMachine::LinkState::GoInState()
622 {
623 WIFI_LOGI("LinkState GoInState function.");
624 return;
625 }
626
GoOutState()627 void StaStateMachine::LinkState::GoOutState()
628 {
629 WIFI_LOGI("LinkState GoOutState function.");
630 return;
631 }
632
ExecuteStateMsg(InternalMessage * msg)633 bool StaStateMachine::LinkState::ExecuteStateMsg(InternalMessage *msg)
634 {
635 if (msg == nullptr) {
636 return false;
637 }
638 LOGI("LinkState ExecuteStateMsg function:msgName=[%{public}d].\n", msg->GetMessageName());
639 auto iter = pStaStateMachine->staSmHandleFuncMap.find(msg->GetMessageName());
640 if (iter != pStaStateMachine->staSmHandleFuncMap.end()) {
641 (pStaStateMachine->*(iter->second))(msg);
642 return EXECUTED;
643 }
644 return NOT_EXECUTED;
645 }
646
647 /* -- state machine Connect State Message processing function -- */
InitStaSMHandleMap()648 int StaStateMachine::InitStaSMHandleMap()
649 {
650 staSmHandleFuncMap[CMD_SIGNAL_POLL] = &StaStateMachine::DealSignalPollResult;
651 staSmHandleFuncMap[WIFI_SVR_CMD_STA_CONNECT_NETWORK] = &StaStateMachine::DealConnectToUserSelectedNetwork;
652 staSmHandleFuncMap[WIFI_SVR_CMD_STA_CONNECT_SAVED_NETWORK] = &StaStateMachine::DealConnectToUserSelectedNetwork;
653 staSmHandleFuncMap[WIFI_SVR_CMD_STA_NETWORK_DISCONNECTION_EVENT] = &StaStateMachine::DealDisconnectEvent;
654 staSmHandleFuncMap[WIFI_SVR_CMD_STA_NETWORK_CONNECTION_EVENT] = &StaStateMachine::DealConnectionEvent;
655 staSmHandleFuncMap[CMD_NETWORK_CONNECT_TIMEOUT] = &StaStateMachine::DealConnectTimeOutCmd;
656 staSmHandleFuncMap[WPA_BLOCK_LIST_CLEAR_EVENT] = &StaStateMachine::DealWpaBlockListClearEvent;
657 staSmHandleFuncMap[WIFI_SVR_CMD_STA_STARTWPS] = &StaStateMachine::DealStartWpsCmd;
658 staSmHandleFuncMap[WIFI_SVR_CMD_STA_WPS_TIMEOUT_EVNET] = &StaStateMachine::DealWpsConnectTimeOutEvent;
659 staSmHandleFuncMap[WIFI_SVR_CMD_STA_CANCELWPS] = &StaStateMachine::DealCancelWpsCmd;
660 staSmHandleFuncMap[WIFI_SVR_CMD_STA_RECONNECT_NETWORK] = &StaStateMachine::DealReConnectCmd;
661 staSmHandleFuncMap[WIFI_SVR_CMD_STA_REASSOCIATE_NETWORK] = &StaStateMachine::DealReassociateCmd;
662 staSmHandleFuncMap[WIFI_SVR_COM_STA_START_ROAM] = &StaStateMachine::DealStartRoamCmd;
663 staSmHandleFuncMap[WIFI_SVR_CMD_STA_WPA_PASSWD_WRONG_EVENT] = &StaStateMachine::DealWpaLinkFailEvent;
664 staSmHandleFuncMap[WIFI_SVR_CMD_STA_WPA_FULL_CONNECT_EVENT] = &StaStateMachine::DealWpaLinkFailEvent;
665 staSmHandleFuncMap[WIFI_SVR_CMD_STA_WPA_ASSOC_REJECT_EVENT] = &StaStateMachine::DealWpaLinkFailEvent;
666 staSmHandleFuncMap[CMD_START_NETCHECK] = &StaStateMachine::DealNetworkCheck;
667 return WIFI_OPT_SUCCESS;
668 }
669
setRssi(int rssi)670 int setRssi(int rssi)
671 {
672 if (rssi < INVALID_RSSI_VALUE) {
673 rssi = INVALID_RSSI_VALUE;
674 }
675
676 if (rssi > MAX_RSSI_VALUE) {
677 rssi = MAX_RSSI_VALUE;
678 }
679 return rssi;
680 }
681
DealSignalPollResult(InternalMessage * msg)682 void StaStateMachine::DealSignalPollResult(InternalMessage *msg)
683 {
684 LOGI("enter DealSignalPollResult.\n");
685 if (msg == nullptr) {
686 LOGE("InternalMessage msg is null.");
687 return;
688 }
689 WifiWpaSignalInfo signalInfo;
690 WifiStaHalInterface::GetInstance().GetConnectSignalInfo(linkedInfo.bssid, signalInfo);
691 LOGI("DealSignalPollResult, signal:%{public}d, txLinkSpeed:%{public}d, rxLinkSpeed:%{public}d, "
692 "freq:%{public}d, noise:%{public}d.\n",
693 signalInfo.signal, signalInfo.txrate, signalInfo.rxrate, signalInfo.frequency,
694 signalInfo.noise);
695 if (signalInfo.signal > INVALID_RSSI_VALUE && signalInfo.signal < MAX_RSSI_VALUE) {
696 if (signalInfo.signal > 0) {
697 linkedInfo.rssi = setRssi((signalInfo.signal - SIGNAL_INFO));
698 } else {
699 linkedInfo.rssi = setRssi(signalInfo.signal);
700 }
701 int currentSignalLevel = WifiSettings::GetInstance().GetSignalLevel(linkedInfo.rssi, linkedInfo.band);
702 LOGI("DealSignalPollResult, networkId:%{public}d, ssid:%{private}s, rssi:%{public}d, band:%{public}d, "
703 "connState:%{public}d, detailedState:%{public}d.\n",
704 linkedInfo.networkId, SsidAnonymize(linkedInfo.ssid).c_str(), linkedInfo.rssi, linkedInfo.band,
705 linkedInfo.connState, linkedInfo.detailedState);
706 LOGI("DealSignalPollResult currentSignalLevel:%{public}d, lastSignalLevel:%{public}d.\n",
707 currentSignalLevel, lastSignalLevel);
708 if (currentSignalLevel != lastSignalLevel) {
709 if (staCallback.OnStaRssiLevelChanged != nullptr) {
710 staCallback.OnStaRssiLevelChanged(linkedInfo.rssi);
711 }
712 #ifndef OHOS_ARCH_LITE
713 if (NetSupplierInfo != nullptr) {
714 TimeStats timeStats("Call UpdateNetSupplierInfo");
715 NetSupplierInfo->isAvailable_ = true;
716 NetSupplierInfo->isRoaming_ = isRoam;
717 NetSupplierInfo->strength_ = linkedInfo.rssi;
718 NetSupplierInfo->frequency_ = linkedInfo.frequency;
719 WifiNetAgent::GetInstance().UpdateNetSupplierInfo(NetSupplierInfo);
720 }
721 #endif
722 lastSignalLevel = currentSignalLevel;
723 }
724 } else {
725 linkedInfo.rssi = INVALID_RSSI_VALUE;
726 }
727
728 if (signalInfo.txrate > 0) {
729 linkedInfo.txLinkSpeed = signalInfo.txrate;
730 linkedInfo.linkSpeed = signalInfo.txrate;
731 if (staCallback.OnStaStreamChanged != nullptr) {
732 staCallback.OnStaStreamChanged(StreamDirection::STREAM_DIRECTION_UP);
733 }
734 }
735
736 if (signalInfo.rxrate > 0) {
737 linkedInfo.rxLinkSpeed = signalInfo.rxrate;
738 if (staCallback.OnStaStreamChanged != nullptr) {
739 staCallback.OnStaStreamChanged(StreamDirection::STREAM_DIRECTION_DOWN);
740 }
741 }
742
743 if (signalInfo.frequency > 0) {
744 linkedInfo.frequency = signalInfo.frequency;
745 }
746 linkedInfo.snr = linkedInfo.rssi - signalInfo.noise;
747 WifiSettings::GetInstance().SaveLinkedInfo(linkedInfo);
748 ConvertFreqToChannel();
749 StartTimer(static_cast<int>(CMD_SIGNAL_POLL), STA_SIGNAL_POLL_DELAY);
750 }
751
ConvertFreqToChannel()752 void StaStateMachine::ConvertFreqToChannel()
753 {
754 WifiDeviceConfig config;
755 if (WifiSettings::GetInstance().GetDeviceConfig(linkedInfo.networkId, config) != 0) {
756 LOGE("GetDeviceConfig failed!");
757 return;
758 }
759 if (linkedInfo.frequency >= FREQ_2G_MIN && linkedInfo.frequency <= FREQ_2G_MAX) {
760 config.band = linkedInfo.band = static_cast<int>(BandType::BAND_2GHZ);
761 config.channel = (linkedInfo.frequency - FREQ_2G_MIN) / CENTER_FREQ_DIFF + CHANNEL_2G_MIN;
762 } else if (linkedInfo.frequency == CHANNEL_14_FREQ) {
763 config.channel = CHANNEL_14;
764 } else if (linkedInfo.frequency >= FREQ_5G_MIN && linkedInfo.frequency <= FREQ_5G_MAX) {
765 config.band = linkedInfo.band = static_cast<int>(BandType::BAND_5GHZ);
766 config.channel = (linkedInfo.frequency - FREQ_5G_MIN) / CENTER_FREQ_DIFF + CHANNEL_5G_MIN;
767 }
768
769 WifiSettings::GetInstance().AddDeviceConfig(config);
770 WifiSettings::GetInstance().SyncDeviceConfig();
771 return;
772 }
773
OnConnectFailed(int networkId)774 void StaStateMachine::OnConnectFailed(int networkId)
775 {
776 WIFI_LOGE("Connect to network failed: %{public}d.\n", networkId);
777 SaveLinkstate(ConnState::DISCONNECTED, DetailedState::FAILED);
778 staCallback.OnStaConnChanged(OperateResState::CONNECT_ENABLE_NETWORK_FAILED, linkedInfo);
779 staCallback.OnStaConnChanged(OperateResState::DISCONNECT_DISCONNECTED, linkedInfo);
780 }
781
DealConnectToUserSelectedNetwork(InternalMessage * msg)782 void StaStateMachine::DealConnectToUserSelectedNetwork(InternalMessage *msg)
783 {
784 LOGI("enter DealConnectToUserSelectedNetwork.\n");
785 if (msg == nullptr) {
786 LOGE("msg is null.\n");
787 return;
788 }
789
790 int networkId = msg->GetParam1();
791 bool forceReconnect = msg->GetParam2();
792 if (linkedInfo.connState == ConnState::CONNECTED && networkId == linkedInfo.networkId) {
793 WIFI_LOGE("This network is in use and does not need to be reconnected.\n");
794 return;
795 }
796
797 /* Save connection information. */
798 SaveLinkstate(ConnState::CONNECTING, DetailedState::CONNECTING);
799 /* Callback result to InterfaceService. */
800 staCallback.OnStaConnChanged(OperateResState::CONNECT_CONNECTING, linkedInfo);
801 if (StartConnectToNetwork(networkId) != WIFI_OPT_SUCCESS) {
802 OnConnectFailed(networkId);
803 return;
804 }
805 /* Sets network status. */
806 WifiSettings::GetInstance().EnableNetwork(networkId, forceReconnect);
807 WifiSettings::GetInstance().SetDeviceState(networkId, (int)WifiDeviceConfigStatus::ENABLED, false);
808 }
809
DealConnectTimeOutCmd(InternalMessage * msg)810 void StaStateMachine::DealConnectTimeOutCmd(InternalMessage *msg)
811 {
812 LOGW("enter DealConnectTimeOutCmd.\n");
813 if (msg == nullptr) {
814 WIFI_LOGE("msg is nul\n");
815 }
816
817 if (linkedInfo.connState == ConnState::CONNECTED) {
818 WIFI_LOGE("Currently connected and do not process timeout.\n");
819 return;
820 }
821
822 WifiSettings::GetInstance().SetConnectTimeoutBssid(linkedInfo.bssid);
823 InitWifiLinkedInfo();
824 SaveLinkstate(ConnState::DISCONNECTED, DetailedState::CONNECTION_TIMEOUT);
825 WifiSettings::GetInstance().SaveLinkedInfo(linkedInfo);
826 staCallback.OnStaConnChanged(OperateResState::CONNECT_CONNECTING_TIMEOUT, linkedInfo);
827 staCallback.OnStaConnChanged(OperateResState::DISCONNECT_DISCONNECTED, linkedInfo);
828 }
829
DealConnectionEvent(InternalMessage * msg)830 void StaStateMachine::DealConnectionEvent(InternalMessage *msg)
831 {
832 if (msg == nullptr) {
833 WIFI_LOGE("DealConnectionEvent, msg is nullptr.\n");
834 return;
835 }
836
837 WIFI_LOGI("enter DealConnectionEvent");
838 WifiSettings::GetInstance().SetDeviceState(targetNetworkId, (int)WifiDeviceConfigStatus::ENABLED, false);
839 WifiSettings::GetInstance().SyncDeviceConfig();
840 /* Stop clearing the Wpa_blocklist. */
841 StopTimer(static_cast<int>(WPA_BLOCK_LIST_CLEAR_EVENT));
842 StopTimer(static_cast<int>(CMD_NETWORK_CONNECT_TIMEOUT));
843 ConnectToNetworkProcess(msg);
844 StartTimer(static_cast<int>(CMD_SIGNAL_POLL), 0);
845
846 if (wpsState != SetupMethod::INVALID) {
847 SyncAllDeviceConfigs();
848 wpsState = SetupMethod::INVALID;
849 }
850 #ifndef OHOS_ARCH_LITE
851 if (NetSupplierInfo != nullptr) {
852 NetSupplierInfo->isAvailable_ = true;
853 NetSupplierInfo->isRoaming_ = isRoam;
854 WIFI_LOGI("On connect update net supplier info\n");
855 WifiNetAgent::GetInstance().OnStaMachineUpdateNetSupplierInfo(NetSupplierInfo);
856 }
857 #endif
858 /* Callback result to InterfaceService. */
859 staCallback.OnStaConnChanged(OperateResState::CONNECT_OBTAINING_IP, linkedInfo);
860
861 /* The current state of StaStateMachine transfers to GetIpState. */
862 SwitchState(pGetIpState);
863 WifiSettings::GetInstance().SetUserLastSelectedNetworkId(INVALID_NETWORK_ID);
864 }
865
DealDisconnectEvent(InternalMessage * msg)866 void StaStateMachine::DealDisconnectEvent(InternalMessage *msg)
867 {
868 LOGI("Enter DealDisconnectEvent.\n");
869 if (msg == nullptr) {
870 WIFI_LOGE("msg is null\n");
871 }
872 if (wpsState != SetupMethod::INVALID) {
873 WIFI_LOGE("wpsState is INVALID\n");
874 return;
875 }
876 #ifndef OHOS_ARCH_LITE
877 if (NetSupplierInfo != nullptr) {
878 NetSupplierInfo->isAvailable_ = false;
879 WIFI_LOGI("On disconnect update net supplier info\n");
880 WifiNetAgent::GetInstance().OnStaMachineUpdateNetSupplierInfo(NetSupplierInfo);
881 }
882 #endif
883 StopTimer(static_cast<int>(CMD_SIGNAL_POLL));
884 StopTimer(static_cast<int>(CMD_START_NETCHECK));
885 pNetcheck->StopNetCheckThread();
886 if (currentTpType == IPTYPE_IPV4) {
887 pDhcpService->StopDhcpClient(IF_NAME, false);
888 } else {
889 pDhcpService->StopDhcpClient(IF_NAME, true);
890 }
891 getIpSucNum = 0;
892 getIpFailNum = 0;
893 isRoam = false;
894
895 IpInfo ipInfo;
896 WifiSettings::GetInstance().SaveIpInfo(ipInfo);
897 #ifdef OHOS_ARCH_LITE
898 IfConfig::GetInstance().FlushIpAddr(IF_NAME, IPTYPE_IPV4);
899 #endif
900 /* Initialize connection information. */
901 InitWifiLinkedInfo();
902 if (lastLinkedInfo.detailedState == DetailedState::CONNECTING) {
903 linkedInfo.networkId = lastLinkedInfo.networkId;
904 linkedInfo.ssid = lastLinkedInfo.ssid;
905 linkedInfo.connState = ConnState::CONNECTING;
906 linkedInfo.detailedState = DetailedState::CONNECTING;
907 WifiSettings::GetInstance().SaveLinkedInfo(linkedInfo);
908 } else {
909 WifiSettings::GetInstance().SaveLinkedInfo(linkedInfo);
910 }
911 /* Callback result to InterfaceService. */
912 staCallback.OnStaConnChanged(OperateResState::DISCONNECT_DISCONNECTED, linkedInfo);
913 SwitchState(pSeparatedState);
914 return;
915 }
916
DealWpaLinkFailEvent(InternalMessage * msg)917 void StaStateMachine::DealWpaLinkFailEvent(InternalMessage *msg)
918 {
919 LOGW("enter DealWpaLinkFailEvent.\n");
920 if (msg == nullptr) {
921 LOGE("msg is null.\n");
922 return;
923 }
924 StopTimer(static_cast<int>(CMD_NETWORK_CONNECT_TIMEOUT));
925 InitWifiLinkedInfo();
926 WifiSettings::GetInstance().SaveLinkedInfo(linkedInfo);
927 if (msg->GetMessageName() == WIFI_SVR_CMD_STA_WPA_PASSWD_WRONG_EVENT) {
928 SaveLinkstate(ConnState::DISCONNECTED, DetailedState::PASSWORD_ERROR);
929 staCallback.OnStaConnChanged(OperateResState::CONNECT_PASSWORD_WRONG, linkedInfo);
930 } else if (msg->GetMessageName() == WIFI_SVR_CMD_STA_WPA_FULL_CONNECT_EVENT) {
931 DisableNetwork(targetNetworkId);
932 SaveLinkstate(ConnState::DISCONNECTED, DetailedState::CONNECTION_FULL);
933 staCallback.OnStaConnChanged(OperateResState::CONNECT_CONNECTION_FULL, linkedInfo);
934 staCallback.OnStaConnChanged(OperateResState::DISCONNECT_DISCONNECTED, linkedInfo);
935 } else if (msg->GetMessageName() == WIFI_SVR_CMD_STA_WPA_ASSOC_REJECT_EVENT) {
936 DisableNetwork(targetNetworkId);
937 SaveLinkstate(ConnState::DISCONNECTED, DetailedState::CONNECTION_REJECT);
938 staCallback.OnStaConnChanged(OperateResState::CONNECT_CONNECTION_REJECT, linkedInfo);
939 staCallback.OnStaConnChanged(OperateResState::DISCONNECT_DISCONNECTED, linkedInfo);
940 }
941 }
942
DealReConnectCmd(InternalMessage * msg)943 void StaStateMachine::DealReConnectCmd(InternalMessage *msg)
944 {
945 LOGI("enter DealReConnectCmd.\n");
946 if (msg == nullptr) {
947 WIFI_LOGE("msg is null\n");
948 }
949
950 if (linkedInfo.connState == ConnState::CONNECTED) {
951 WIFI_LOGE("Network is already connected, ignore the re-connect command!\n");
952 return;
953 }
954
955 if (WifiStaHalInterface::GetInstance().Reconnect() == WIFI_IDL_OPT_OK) {
956 WIFI_LOGI("StaStateMachine ReConnect successfully!");
957 /* Callback result to InterfaceService */
958 staCallback.OnStaConnChanged(OperateResState::CONNECT_CONNECTING, linkedInfo);
959 StopTimer(static_cast<int>(CMD_NETWORK_CONNECT_TIMEOUT));
960 StartTimer(static_cast<int>(CMD_NETWORK_CONNECT_TIMEOUT), STA_NETWORK_CONNECTTING_DELAY);
961 } else {
962 WIFI_LOGE("ReConnect failed!");
963 }
964 }
965
DealReassociateCmd(InternalMessage * msg)966 void StaStateMachine::DealReassociateCmd(InternalMessage *msg)
967 {
968 LOGI("enter DealReassociateCmd.\n");
969 if (msg == nullptr) {
970 WIFI_LOGE("msg is null\n");
971 }
972
973 if (WifiStaHalInterface::GetInstance().Reassociate() == WIFI_IDL_OPT_OK) {
974 /* Callback result to InterfaceService */
975 staCallback.OnStaConnChanged(OperateResState::CONNECT_ASSOCIATING, linkedInfo);
976 WIFI_LOGD("StaStateMachine ReAssociate successfully!");
977 StopTimer(static_cast<int>(CMD_NETWORK_CONNECT_TIMEOUT));
978 StartTimer(static_cast<int>(CMD_NETWORK_CONNECT_TIMEOUT), STA_NETWORK_CONNECTTING_DELAY);
979 } else {
980 WIFI_LOGE("ReAssociate failed!");
981 }
982 }
983
DealStartWpsCmd(InternalMessage * msg)984 void StaStateMachine::DealStartWpsCmd(InternalMessage *msg)
985 {
986 WIFI_LOGI("enter DealStartWpsCmd\n");
987 if (msg == nullptr) {
988 return;
989 }
990
991 if (WifiStaHalInterface::GetInstance().ClearDeviceConfig() != WIFI_IDL_OPT_OK) {
992 LOGE("ClearDeviceConfig() failed!");
993 return;
994 }
995
996 StartWpsMode(msg);
997 if ((wpsState == SetupMethod::DISPLAY) || (wpsState == SetupMethod::KEYPAD)) {
998 WIFI_LOGW("Clear WPA block list every ten second!");
999 SendMessage(WPA_BLOCK_LIST_CLEAR_EVENT);
1000 }
1001 }
1002
StartWpsMode(InternalMessage * msg)1003 void StaStateMachine::StartWpsMode(InternalMessage *msg)
1004 {
1005 if (msg == nullptr) {
1006 return;
1007 }
1008 /*
1009 * Make judgement to wps configuration information: the function will exit if
1010 * the result is fail, then else continue to chose the Wps starting mode. The
1011 * current state of StaStateMachine transfers to WpsState after Wps code start
1012 * successfully.
1013 */
1014 WifiIdlWpsConfig wpsParam;
1015 WpsConfig wpsConfig;
1016 wpsConfig.setup = static_cast<SetupMethod>(msg->GetParam1());
1017 wpsConfig.pin = msg->GetStringFromMessage();
1018 wpsConfig.bssid = msg->GetStringFromMessage();
1019 if (wpsConfig.bssid.length() == 0 || wpsConfig.bssid == PBC_ANY_BSSID) {
1020 wpsParam.anyFlag = 1;
1021 wpsParam.bssid = PBC_ANY_BSSID;
1022 } else {
1023 wpsParam.anyFlag = 0;
1024 wpsParam.bssid = wpsConfig.bssid;
1025 }
1026 wpsParam.multiAp = MULTI_AP;
1027 WIFI_LOGI("wpsConfig setup = %{public}d", wpsConfig.setup);
1028 WIFI_LOGI("wpsParam.AnyFlag = %{public}d, wpsParam.mulitAp = %{public}d, wpsParam.bssid = %{public}s",
1029 wpsParam.anyFlag,
1030 wpsParam.multiAp,
1031 MacAnonymize(wpsParam.bssid).c_str());
1032
1033 if (wpsConfig.setup == SetupMethod::PBC) {
1034 if (WifiStaHalInterface::GetInstance().StartWpsPbcMode(wpsParam) == WIFI_IDL_OPT_OK) {
1035 wpsState = wpsConfig.setup;
1036 WIFI_LOGD("StartWpsPbcMode() succeed!");
1037 /* Callback result to InterfaceService. */
1038 staCallback.OnWpsChanged(WpsStartState::START_PBC_SUCCEED, pinCode);
1039 SwitchState(pWpsState);
1040 } else {
1041 LOGE("StartWpsPbcMode() failed!");
1042 staCallback.OnWpsChanged(WpsStartState::START_PBC_FAILED, pinCode);
1043 }
1044 } else if (wpsConfig.setup == SetupMethod::DISPLAY) {
1045 if (WifiStaHalInterface::GetInstance().StartWpsPinMode(wpsParam, pinCode) == WIFI_IDL_OPT_OK) {
1046 wpsState = wpsConfig.setup;
1047 /* Callback result to InterfaceService. */
1048 staCallback.OnWpsChanged(WpsStartState::START_PIN_SUCCEED, pinCode);
1049 WIFI_LOGD("StartWpsPinMode() succeed! pincode: %d", pinCode);
1050 SwitchState(pWpsState);
1051 } else {
1052 WIFI_LOGE("StartWpsPinMode() failed!");
1053 staCallback.OnWpsChanged(WpsStartState::START_PIN_FAILED, pinCode);
1054 }
1055 } else if (wpsConfig.setup == SetupMethod::KEYPAD) {
1056 if (WifiStaHalInterface::GetInstance().StartWpsPinMode(wpsParam, pinCode) == WIFI_IDL_OPT_OK) {
1057 wpsState = wpsConfig.setup;
1058 /* Callback result to InterfaceService. */
1059 staCallback.OnWpsChanged(WpsStartState::START_AP_PIN_SUCCEED, pinCode);
1060 SwitchState(pWpsState);
1061 } else {
1062 LOGE("StartWpsPinMode() failed.");
1063 staCallback.OnWpsChanged(WpsStartState::START_AP_PIN_FAILED, pinCode);
1064 }
1065 } else {
1066 LOGE("Start Wps failed!");
1067 staCallback.OnWpsChanged(WpsStartState::START_WPS_FAILED, pinCode);
1068 }
1069 }
1070
DealWpaBlockListClearEvent(InternalMessage * msg)1071 void StaStateMachine::DealWpaBlockListClearEvent(InternalMessage *msg)
1072 {
1073 if (msg != nullptr) {
1074 WIFI_LOGE("enter DealWpaBlockListClearEvent\n");
1075 }
1076 if (WifiStaHalInterface::GetInstance().WpaBlocklistClear() != WIFI_IDL_OPT_OK) {
1077 WIFI_LOGE("Clearing the Wpa_blocklist failed\n");
1078 }
1079 StartTimer(static_cast<int>(WPA_BLOCK_LIST_CLEAR_EVENT), BLOCK_LIST_CLEAR_TIMER);
1080 WIFI_LOGI("Clearing the Wpa_blocklist.\n");
1081 }
1082
DealWpsConnectTimeOutEvent(InternalMessage * msg)1083 void StaStateMachine::DealWpsConnectTimeOutEvent(InternalMessage *msg)
1084 {
1085 WIFI_LOGW("enter DealWpsConnectTimeOutEvent\n");
1086 if (msg == nullptr) {
1087 WIFI_LOGE("msg is nullptr!\n");
1088 return;
1089 }
1090
1091 DealCancelWpsCmd(msg);
1092
1093 /* Callback InterfaceService that WPS time out. */
1094 staCallback.OnWpsChanged(WpsStartState::WPS_TIME_OUT, pinCode);
1095 SwitchState(pSeparatedState);
1096 }
1097
DealCancelWpsCmd(InternalMessage * msg)1098 void StaStateMachine::DealCancelWpsCmd(InternalMessage *msg)
1099 {
1100 if (msg == nullptr) {
1101 WIFI_LOGE("msg is null\n");
1102 }
1103
1104 StopTimer(static_cast<int>(WPA_BLOCK_LIST_CLEAR_EVENT));
1105 isWpsConnect = IsWpsConnected::WPS_INVALID;
1106 if (WifiStaHalInterface::GetInstance().StopWps() == WIFI_IDL_OPT_OK) {
1107 WIFI_LOGI("CancelWps succeed!");
1108 /* Callback result to InterfaceService that stop Wps connection successfully. */
1109 if (wpsState == SetupMethod::PBC) {
1110 staCallback.OnWpsChanged(WpsStartState::STOP_PBC_SUCCEED, pinCode);
1111 } else if (wpsState == SetupMethod::DISPLAY) {
1112 staCallback.OnWpsChanged(WpsStartState::STOP_PIN_SUCCEED, pinCode);
1113 } else if (wpsState == SetupMethod::KEYPAD) {
1114 staCallback.OnWpsChanged(WpsStartState::STOP_AP_PIN_SUCCEED, pinCode);
1115 }
1116 if (wpsState != SetupMethod::INVALID) {
1117 wpsState = SetupMethod::INVALID;
1118 SyncAllDeviceConfigs();
1119
1120 if (WifiStaHalInterface::GetInstance().EnableNetwork(lastNetworkId) == WIFI_IDL_OPT_OK) {
1121 WIFI_LOGI("EnableNetwork success! networkId is %{public}d", lastNetworkId);
1122 if (WifiStaHalInterface::GetInstance().SaveDeviceConfig() != WIFI_IDL_OPT_OK) {
1123 WIFI_LOGW("SaveDeviceConfig failed!");
1124 } else {
1125 WIFI_LOGI("SaveDeviceConfig success!");
1126 }
1127 } else {
1128 WIFI_LOGE("EnableNetwork failed");
1129 }
1130 }
1131 } else {
1132 WIFI_LOGE("CancelWps failed!");
1133 if (wpsState == SetupMethod::PBC) {
1134 staCallback.OnWpsChanged(WpsStartState::STOP_PBC_FAILED, pinCode);
1135 } else if (wpsState == SetupMethod::DISPLAY) {
1136 staCallback.OnWpsChanged(WpsStartState::STOP_PIN_FAILED, pinCode);
1137 } else if (wpsState == SetupMethod::KEYPAD) {
1138 staCallback.OnWpsChanged(WpsStartState::STOP_AP_PIN_FAILED, pinCode);
1139 }
1140 }
1141 SwitchState(pSeparatedState);
1142 }
1143
DealStartRoamCmd(InternalMessage * msg)1144 void StaStateMachine::DealStartRoamCmd(InternalMessage *msg)
1145 {
1146 if (msg == nullptr) {
1147 return;
1148 }
1149
1150 WIFI_LOGI("enter DealStartRoamCmd\n");
1151 std::string bssid = msg->GetStringFromMessage();
1152 /* GetDeviceConfig from Configuration center. */
1153 WifiDeviceConfig network;
1154 WifiSettings::GetInstance().GetDeviceConfig(linkedInfo.networkId, network);
1155
1156 /* Setting the network. */
1157 WifiIdlDeviceConfig idlConfig;
1158 idlConfig.networkId = linkedInfo.networkId;
1159 idlConfig.ssid = linkedInfo.ssid;
1160 idlConfig.bssid = bssid;
1161 idlConfig.psk = network.preSharedKey;
1162 idlConfig.keyMgmt = network.keyMgmt;
1163 idlConfig.priority = network.priority;
1164 idlConfig.scanSsid = network.hiddenSSID ? 1 : 0;
1165 idlConfig.eap = network.wifiEapConfig.eap;
1166 idlConfig.identity = network.wifiEapConfig.identity;
1167 idlConfig.password = network.wifiEapConfig.password;
1168 idlConfig.clientCert = network.wifiEapConfig.clientCert;
1169 idlConfig.privateKey = network.wifiEapConfig.privateKey;
1170 idlConfig.phase2Method = static_cast<int>(network.wifiEapConfig.phase2Method);
1171
1172 if (WifiStaHalInterface::GetInstance().SetDeviceConfig(linkedInfo.networkId, idlConfig) != WIFI_IDL_OPT_OK) {
1173 WIFI_LOGE("DealStartRoamCmd SetDeviceConfig() failed!");
1174 return;
1175 }
1176 WIFI_LOGD("DealStartRoamCmd SetDeviceConfig() succeed!");
1177
1178 /* Save to Configuration center. */
1179 network.bssid = bssid;
1180 WifiSettings::GetInstance().AddDeviceConfig(network);
1181 WifiSettings::GetInstance().SyncDeviceConfig();
1182
1183 /* Save linkedinfo */
1184 linkedInfo.bssid = bssid;
1185 WifiSettings::GetInstance().SaveLinkedInfo(linkedInfo);
1186
1187 if (WifiStaHalInterface::GetInstance().Reassociate() != WIFI_IDL_OPT_OK) {
1188 WIFI_LOGE("START_ROAM-ReAssociate() failed!");
1189 }
1190 WIFI_LOGI("START_ROAM-ReAssociate() succeeded!");
1191 /* Start roaming */
1192 SwitchState(pApRoamingState);
1193 }
1194
StartConnectToNetwork(int networkId)1195 ErrCode StaStateMachine::StartConnectToNetwork(int networkId)
1196 {
1197 targetNetworkId = networkId;
1198 SetRandomMac(targetNetworkId);
1199 if (WifiStaHalInterface::GetInstance().EnableNetwork(targetNetworkId) != WIFI_IDL_OPT_OK) {
1200 LOGE("EnableNetwork() failed!");
1201 return WIFI_OPT_FAILED;
1202 }
1203
1204 if (WifiStaHalInterface::GetInstance().Connect(targetNetworkId) != WIFI_IDL_OPT_OK) {
1205 LOGE("Connect failed!");
1206 staCallback.OnStaConnChanged(OperateResState::CONNECT_SELECT_NETWORK_FAILED, linkedInfo);
1207 return WIFI_OPT_FAILED;
1208 }
1209
1210 if (WifiStaHalInterface::GetInstance().SaveDeviceConfig() != WIFI_IDL_OPT_OK) {
1211 /* OHOS's wpa don't support save command, so don't judge as failure */
1212 LOGE("SaveDeviceConfig() failed!");
1213 }
1214
1215 StopTimer(static_cast<int>(CMD_NETWORK_CONNECT_TIMEOUT));
1216 StartTimer(static_cast<int>(CMD_NETWORK_CONNECT_TIMEOUT), STA_NETWORK_CONNECTTING_DELAY);
1217 return WIFI_OPT_SUCCESS;
1218 }
1219
MacAddressGenerate(std::string & strMac)1220 void StaStateMachine::MacAddressGenerate(std::string &strMac)
1221 {
1222 LOGI("enter MacAddressGenerate\n");
1223 constexpr int arraySize = 4;
1224 constexpr int macBitSize = 12;
1225 constexpr int firstBit = 1;
1226 constexpr int lastBit = 11;
1227 constexpr int two = 2;
1228 constexpr int hexBase = 16;
1229 constexpr int octBase = 8;
1230 int ret = 0;
1231 char strMacTmp[arraySize] = {0};
1232 srand(static_cast<unsigned int>(time(nullptr)));
1233 for (int i = 0; i < macBitSize; i++) {
1234 if (i != firstBit) {
1235 ret = sprintf_s(strMacTmp, arraySize, "%x", rand() % hexBase);
1236 } else {
1237 ret = sprintf_s(strMacTmp, arraySize, "%x", two * (rand() % octBase));
1238 }
1239 if (ret == -1) {
1240 LOGE("StaStateMachine::MacAddressGenerate failed, sprintf_s return -1!\n");
1241 }
1242 strMac += strMacTmp;
1243 if ((i % two) != 0 && (i != lastBit)) {
1244 strMac.append(":");
1245 }
1246 }
1247 }
1248
ComparedKeymgmt(const std::string scanInfoKeymgmt,const std::string deviceKeymgmt)1249 bool StaStateMachine::ComparedKeymgmt(const std::string scanInfoKeymgmt, const std::string deviceKeymgmt)
1250 {
1251 if (deviceKeymgmt == "WPA-PSK") {
1252 return scanInfoKeymgmt.find("PSK") != std::string::npos;
1253 } else if (deviceKeymgmt == "WPA-EAP") {
1254 return scanInfoKeymgmt.find("EAP") != std::string::npos;
1255 } else if (deviceKeymgmt == "SAE") {
1256 return scanInfoKeymgmt.find("SAE") != std::string::npos;
1257 } else if (deviceKeymgmt == "NONE") {
1258 return (scanInfoKeymgmt.find("PSK") == std::string::npos) &&
1259 (scanInfoKeymgmt.find("EAP") == std::string::npos) && (scanInfoKeymgmt.find("SAE") == std::string::npos);
1260 } else {
1261 return false;
1262 }
1263 }
1264
SetRandomMac(int networkId)1265 bool StaStateMachine::SetRandomMac(int networkId)
1266 {
1267 LOGI("enter SetRandomMac.\n");
1268 WifiDeviceConfig deviceConfig;
1269 if (WifiSettings::GetInstance().GetDeviceConfig(networkId, deviceConfig) != 0) {
1270 LOGE("SetRandomMac : GetDeviceConfig failed!\n");
1271 return false;
1272 }
1273 std::string lastMac;
1274 std::string currentMac;
1275 if (deviceConfig.wifiPrivacySetting == WifiPrivacyConfig::DEVICEMAC) {
1276 } else {
1277 WifiStoreRandomMac randomMacInfo;
1278 std::vector<WifiScanInfo> scanInfoList;
1279 WifiSettings::GetInstance().GetScanInfoList(scanInfoList);
1280 for (auto scanInfo : scanInfoList) {
1281 if ((deviceConfig.ssid == scanInfo.ssid) &&
1282 (ComparedKeymgmt(scanInfo.capabilities, deviceConfig.keyMgmt))) {
1283 randomMacInfo.ssid = scanInfo.ssid;
1284 randomMacInfo.keyMgmt = deviceConfig.keyMgmt;
1285 randomMacInfo.peerBssid = scanInfo.bssid;
1286 break;
1287 }
1288 }
1289 if (randomMacInfo.ssid.empty()) {
1290 LOGE("scanInfo has no target wifi!\n");
1291 return false;
1292 }
1293
1294 /* Sets the MAC address of WifiSettings. */
1295 MacAddressGenerate(randomMacInfo.randomMac);
1296 WifiSettings::GetInstance().AddRandomMac(randomMacInfo);
1297 currentMac = randomMacInfo.randomMac;
1298 }
1299
1300 if ((WifiStaHalInterface::GetInstance().GetStaDeviceMacAddress(lastMac)) != WIFI_IDL_OPT_OK) {
1301 LOGE("GetStaDeviceMacAddress failed!");
1302 return false;
1303 }
1304
1305 if (MacAddress::IsValidMac(currentMac.c_str())) {
1306 LOGI("Check MacAddress successfully.\n");
1307 if (lastMac != currentMac) {
1308 if (WifiStaHalInterface::GetInstance().SetConnectMacAddr(currentMac) != WIFI_IDL_OPT_OK) {
1309 LOGE("set Mac [%s] failed.\n", currentMac.c_str());
1310 return false;
1311 }
1312 }
1313 WifiSettings::GetInstance().SetMacAddress(currentMac);
1314 deviceConfig.macAddress = currentMac;
1315 WifiSettings::GetInstance().AddDeviceConfig(deviceConfig);
1316 WifiSettings::GetInstance().SyncDeviceConfig();
1317 } else {
1318 LOGE("Check MacAddress error.\n");
1319 return false;
1320 }
1321 return true;
1322 }
1323
StartRoamToNetwork(std::string bssid)1324 void StaStateMachine::StartRoamToNetwork(std::string bssid)
1325 {
1326 InternalMessage *msg = CreateMessage();
1327 if (msg == nullptr) {
1328 return;
1329 }
1330
1331 msg->SetMessageName(WIFI_SVR_COM_STA_START_ROAM);
1332 msg->AddStringMessageBody(bssid);
1333 SendMessage(msg);
1334 }
1335
IsRoaming(void)1336 bool StaStateMachine::IsRoaming(void)
1337 {
1338 return isRoam;
1339 }
1340
OnNetworkConnectionEvent(int networkId,std::string bssid)1341 void StaStateMachine::OnNetworkConnectionEvent(int networkId, std::string bssid)
1342 {
1343 InternalMessage *msg = CreateMessage();
1344 if (msg == nullptr) {
1345 LOGE("msg is nullptr.\n");
1346 return;
1347 }
1348
1349 msg->SetMessageName(WIFI_SVR_CMD_STA_NETWORK_CONNECTION_EVENT);
1350 msg->SetParam1(networkId);
1351 msg->AddStringMessageBody(bssid);
1352 SendMessage(msg);
1353 }
1354
OnBssidChangedEvent(std::string reason,std::string bssid)1355 void StaStateMachine::OnBssidChangedEvent(std::string reason, std::string bssid)
1356 {
1357 InternalMessage *msg = CreateMessage();
1358 if (msg == nullptr) {
1359 LOGE("msg is nullptr.\n");
1360 return;
1361 }
1362
1363 msg->SetMessageName(WIFI_SVR_CMD_STA_BSSID_CHANGED_EVENT);
1364 msg->AddStringMessageBody(reason);
1365 msg->AddStringMessageBody(bssid);
1366 SendMessage(msg);
1367 }
1368
OnDhcpResultNotifyEvent(bool result)1369 void StaStateMachine::OnDhcpResultNotifyEvent(bool result)
1370 {
1371 InternalMessage *msg = CreateMessage();
1372 if (msg == nullptr) {
1373 LOGE("msg is nullptr.\n");
1374 return;
1375 }
1376
1377 msg->SetMessageName(WIFI_SVR_CMD_STA_DHCP_RESULT_NOTIFY_EVENT);
1378 msg->SetParam1(result);
1379 SendMessage(msg);
1380 }
1381
1382 /* --------------------------- state machine Separating State ------------------------------ */
SeparatingState()1383 StaStateMachine::SeparatingState::SeparatingState() : State("SeparatingState")
1384 {}
1385
~SeparatingState()1386 StaStateMachine::SeparatingState::~SeparatingState()
1387 {}
1388
GoInState()1389 void StaStateMachine::SeparatingState::GoInState()
1390 {
1391 WIFI_LOGI("SeparatingState GoInState function.");
1392 return;
1393 }
1394
GoOutState()1395 void StaStateMachine::SeparatingState::GoOutState()
1396 {
1397 WIFI_LOGI("SeparatingState GoOutState function.");
1398 }
1399
ExecuteStateMsg(InternalMessage * msg)1400 bool StaStateMachine::SeparatingState::ExecuteStateMsg(InternalMessage *msg)
1401 {
1402 if (msg == nullptr) {
1403 return false;
1404 }
1405
1406 bool ret = NOT_EXECUTED;
1407 WIFI_LOGI("SeparatingState-msgCode=%{public}d not handled.\n", msg->GetMessageName());
1408 return ret;
1409 }
1410
1411 /* --------------------------- state machine Disconnected State ------------------------------ */
SeparatedState(StaStateMachine * staStateMachine)1412 StaStateMachine::SeparatedState::SeparatedState(StaStateMachine *staStateMachine)
1413 : State("SeparatedState"), pStaStateMachine(staStateMachine)
1414 {}
1415
~SeparatedState()1416 StaStateMachine::SeparatedState::~SeparatedState()
1417 {}
1418
GoInState()1419 void StaStateMachine::SeparatedState::GoInState()
1420 {
1421 WIFI_LOGI("SeparatedState GoInState function.");
1422 return;
1423 }
1424
GoOutState()1425 void StaStateMachine::SeparatedState::GoOutState()
1426 {
1427 WIFI_LOGI("SeparatedState GoOutState function.");
1428 return;
1429 }
1430
ExecuteStateMsg(InternalMessage * msg)1431 bool StaStateMachine::SeparatedState::ExecuteStateMsg(InternalMessage *msg)
1432 {
1433 if (msg == nullptr) {
1434 return false;
1435 }
1436
1437 WIFI_LOGI("SeparatedState-msgCode=%{public}d received.\n", msg->GetMessageName());
1438 bool ret = NOT_EXECUTED;
1439 switch (msg->GetMessageName()) {
1440 case WIFI_SVR_CMD_STA_NETWORK_DISCONNECTION_EVENT:
1441 break;
1442
1443 case WIFI_SVR_CMD_STA_ENABLE_WIFI: {
1444 ret = EXECUTED;
1445 WIFI_LOGE("Wifi has already started! start Wifi failed!");
1446 /* Callback result to InterfaceService. */
1447 pStaStateMachine->staCallback.OnStaOpenRes(OperateResState::OPEN_WIFI_OVERRIDE_OPEN_FAILED);
1448 break;
1449 }
1450
1451 default:
1452 break;
1453 }
1454
1455 return ret;
1456 }
1457
1458 /* --------------------------- state machine ApConnected State ------------------------------ */
ApLinkedState(StaStateMachine * staStateMachine)1459 StaStateMachine::ApLinkedState::ApLinkedState(StaStateMachine *staStateMachine)
1460 : State("ApLinkedState"), pStaStateMachine(staStateMachine)
1461 {}
1462
~ApLinkedState()1463 StaStateMachine::ApLinkedState::~ApLinkedState()
1464 {}
1465
GoInState()1466 void StaStateMachine::ApLinkedState::GoInState()
1467 {
1468 WIFI_LOGI("ApLinkedState GoInState function.");
1469 return;
1470 }
1471
GoOutState()1472 void StaStateMachine::ApLinkedState::GoOutState()
1473 {
1474 WIFI_LOGI("ApLinkedState GoOutState function.");
1475 return;
1476 }
1477
ExecuteStateMsg(InternalMessage * msg)1478 bool StaStateMachine::ApLinkedState::ExecuteStateMsg(InternalMessage *msg)
1479 {
1480 if (msg == nullptr) {
1481 return false;
1482 }
1483
1484 WIFI_LOGI("ApLinkedState-msgCode=%{public}d received.\n", msg->GetMessageName());
1485 bool ret = NOT_EXECUTED;
1486 switch (msg->GetMessageName()) {
1487 /* The current state of StaStateMachine transfers to SeparatingState when
1488 * receive the Separating message.
1489 */
1490 case WIFI_SVR_CMD_STA_DISCONNECT: {
1491 ret = EXECUTED;
1492 pStaStateMachine->DisConnectProcess();
1493 break;
1494 }
1495 case WIFI_SVR_CMD_STA_NETWORK_CONNECTION_EVENT: {
1496 ret = EXECUTED;
1497 pStaStateMachine->StopTimer(static_cast<int>(WPA_BLOCK_LIST_CLEAR_EVENT));
1498 WIFI_LOGI("Stop clearing wpa block list");
1499 /* Save linkedinfo */
1500 pStaStateMachine->linkedInfo.networkId = msg->GetParam1();
1501 pStaStateMachine->linkedInfo.bssid = msg->GetStringFromMessage();
1502 WifiSettings::GetInstance().SaveLinkedInfo(pStaStateMachine->linkedInfo);
1503
1504 break;
1505 }
1506 default:
1507 break;
1508 }
1509 return ret;
1510 }
1511
DisConnectProcess()1512 void StaStateMachine::DisConnectProcess()
1513 {
1514 WIFI_LOGI("Enter DisConnectProcess!");
1515 staCallback.OnStaConnChanged(OperateResState::DISCONNECT_DISCONNECTING, linkedInfo);
1516 if (WifiStaHalInterface::GetInstance().Disconnect() == WIFI_IDL_OPT_OK) {
1517 WIFI_LOGI("Disconnect() succeed!");
1518 #ifndef OHOS_ARCH_LITE
1519 if (NetSupplierInfo != nullptr) {
1520 NetSupplierInfo->isAvailable_ = false;
1521 WIFI_LOGI("Disconnect process update netsupplierinfo");
1522 WifiNetAgent::GetInstance().OnStaMachineUpdateNetSupplierInfo(NetSupplierInfo);
1523 }
1524 #endif
1525 WIFI_LOGI("Disconnect update wifi status");
1526 /* Save connection information to WifiSettings. */
1527 SaveLinkstate(ConnState::DISCONNECTED, DetailedState::DISCONNECTED);
1528 DisableNetwork(linkedInfo.networkId);
1529
1530 getIpSucNum = 0;
1531 /* The current state of StaStateMachine transfers to SeparatedState. */
1532 SwitchState(pSeparatedState);
1533 } else {
1534 SaveLinkstate(ConnState::DISCONNECTING, DetailedState::FAILED);
1535 staCallback.OnStaConnChanged(OperateResState::DISCONNECT_DISCONNECT_FAILED, linkedInfo);
1536 WIFI_LOGE("Disconnect() failed!");
1537 }
1538 }
1539
1540 /* --------------------------- state machine Wps State ------------------------------ */
StaWpsState(StaStateMachine * staStateMachine)1541 StaStateMachine::StaWpsState::StaWpsState(StaStateMachine *staStateMachine)
1542 : State("StaWpsState"), pStaStateMachine(staStateMachine)
1543 {}
1544
~StaWpsState()1545 StaStateMachine::StaWpsState::~StaWpsState()
1546 {}
1547
GoInState()1548 void StaStateMachine::StaWpsState::GoInState()
1549 {
1550 WIFI_LOGI("WpsState GoInState function.");
1551 return;
1552 }
1553
GoOutState()1554 void StaStateMachine::StaWpsState::GoOutState()
1555 {
1556 WIFI_LOGI("WpsState GoOutState function.");
1557 }
1558
ExecuteStateMsg(InternalMessage * msg)1559 bool StaStateMachine::StaWpsState::ExecuteStateMsg(InternalMessage *msg)
1560 {
1561 if (msg == nullptr) {
1562 return false;
1563 }
1564
1565 bool ret = NOT_EXECUTED;
1566 switch (msg->GetMessageName()) {
1567 case WIFI_SVR_CMD_STA_WPS_START_EVENT: {
1568 /* Wps starts successfully and Wait until the connection is complete. */
1569 break;
1570 }
1571 case WIFI_SVR_CMD_STA_NETWORK_CONNECTION_EVENT: {
1572 ret = EXECUTED;
1573 /* Stop clearing the Wpa_blocklist. */
1574 pStaStateMachine->StopTimer(static_cast<int>(WPA_BLOCK_LIST_CLEAR_EVENT));
1575
1576 WIFI_LOGI("WPS mode connect to a network!");
1577 pStaStateMachine->ConnectToNetworkProcess(msg);
1578 pStaStateMachine->SyncAllDeviceConfigs();
1579 /* Callback result to InterfaceService. */
1580 pStaStateMachine->SaveLinkstate(ConnState::CONNECTING, DetailedState::OBTAINING_IPADDR);
1581 pStaStateMachine->staCallback.OnStaConnChanged(OperateResState::CONNECT_OBTAINING_IP,
1582 pStaStateMachine->linkedInfo);
1583 pStaStateMachine->SwitchState(pStaStateMachine->pGetIpState);
1584 break;
1585 }
1586 case WIFI_SVR_CMD_STA_STARTWPS: {
1587 ret = EXECUTED;
1588 auto setup = static_cast<SetupMethod>(msg->GetParam1());
1589 /* Callback InterfaceService that wps has started successfully. */
1590 WIFI_LOGE("WPS has already started, start wps failed!");
1591 if (setup == SetupMethod::PBC) {
1592 pStaStateMachine->staCallback.OnWpsChanged(WpsStartState::PBC_STARTED_ALREADY,
1593 pStaStateMachine->pinCode);
1594 } else if ((setup == SetupMethod::DISPLAY) || (setup == SetupMethod::KEYPAD)) {
1595 pStaStateMachine->staCallback.OnWpsChanged(WpsStartState::PIN_STARTED_ALREADY,
1596 pStaStateMachine->pinCode);
1597 }
1598 break;
1599 }
1600 case WIFI_SVR_CMD_STA_WPS_OVERLAP_EVENT: {
1601 ret = EXECUTED;
1602 WIFI_LOGI("Wps PBC Overlap!");
1603 /* Callback InterfaceService that PBC is conflicting. */
1604 pStaStateMachine->staCallback.OnWpsChanged(WpsStartState::START_PBC_FAILED_OVERLAP,
1605 pStaStateMachine->pinCode);
1606 pStaStateMachine->SwitchState(pStaStateMachine->pSeparatedState);
1607 break;
1608 }
1609 case WIFI_SVR_CMD_STA_CANCELWPS: {
1610 ret = EXECUTED;
1611 pStaStateMachine->DealCancelWpsCmd(msg);
1612 break;
1613 }
1614 default:
1615 break;
1616 }
1617 return ret;
1618 }
1619
SyncAllDeviceConfigs()1620 void StaStateMachine::SyncAllDeviceConfigs()
1621 {
1622 std::vector<WifiDeviceConfig> result;
1623 WifiIdlDeviceConfig idlConfig;
1624 if (WifiSettings::GetInstance().GetDeviceConfig(result) != -1) {
1625 for (std::vector<WifiDeviceConfig>::iterator it = result.begin(); it != result.end(); ++it) {
1626 if (isWpsConnect == IsWpsConnected::WPS_CONNECTED && it->networkId == 0) {
1627 continue;
1628 }
1629 if (WifiStaHalInterface::GetInstance().GetNextNetworkId(it->networkId) == WIFI_IDL_OPT_OK) {
1630 WIFI_LOGI("GetNextNetworkId succeed");
1631 idlConfig.networkId = it->networkId;
1632 idlConfig.ssid = it->ssid;
1633 idlConfig.psk = it->preSharedKey;
1634 idlConfig.keyMgmt = it->keyMgmt;
1635 idlConfig.priority = it->priority;
1636 idlConfig.scanSsid = it->hiddenSSID ? 1 : 0;
1637 idlConfig.eap = it->wifiEapConfig.eap;
1638 idlConfig.identity = it->wifiEapConfig.identity;
1639 idlConfig.password = it->wifiEapConfig.password;
1640 idlConfig.clientCert = it->wifiEapConfig.clientCert;
1641 idlConfig.privateKey = it->wifiEapConfig.privateKey;
1642 idlConfig.phase2Method = static_cast<int>(it->wifiEapConfig.phase2Method);
1643 if (WifiStaHalInterface::GetInstance().SetDeviceConfig(it->networkId, idlConfig) != WIFI_IDL_OPT_OK) {
1644 WIFI_LOGE("SetDeviceConfig failed!");
1645 }
1646 WIFI_LOGD("SetDeviceConfig succeed!");
1647 } else {
1648 WIFI_LOGE("GetNextNetworkId failed!");
1649 }
1650 WIFI_LOGD("networkId = %{public}d", it->networkId);
1651 WifiStaHalInterface::GetInstance().SaveDeviceConfig();
1652 }
1653 WIFI_LOGD("Synchronizing network information!");
1654 } else {
1655 WIFI_LOGE("The Device config in WifiSettings is empty!");
1656 }
1657 }
1658
1659 /* --------------------------- state machine GetIp State ------------------------------ */
GetIpState(StaStateMachine * staStateMachine)1660 StaStateMachine::GetIpState::GetIpState(StaStateMachine *staStateMachine)
1661 : State("GetIpState"), pStaStateMachine(staStateMachine)
1662 {}
1663
~GetIpState()1664 StaStateMachine::GetIpState::~GetIpState()
1665 {}
1666
GoInState()1667 void StaStateMachine::GetIpState::GoInState()
1668 {
1669 WIFI_LOGI("GetIpState GoInState function.");
1670 #ifdef WIFI_DHCP_DISABLED
1671 SaveLinkstate(ConnState::CONNECTED, DetailedState::WORKING);
1672 staCallback.OnStaConnChanged(OperateResState::CONNECT_NETWORK_ENABLED, linkedInfo);
1673 SwitchState(pLinkedState);
1674 return;
1675 #endif
1676 pStaStateMachine->getIpSucNum = 0;
1677 WifiDeviceConfig config;
1678 AssignIpMethod assignMethod = AssignIpMethod::DHCP;
1679 int ret = WifiSettings::GetInstance().GetDeviceConfig(pStaStateMachine->linkedInfo.networkId, config);
1680 if (ret == 0) {
1681 assignMethod = config.wifiIpConfig.assignMethod;
1682 }
1683
1684 if (config.wifiProxyconfig.configureMethod == ConfigureProxyMethod::MANUALCONFIGUE) {
1685 std::string hostName = config.wifiProxyconfig.manualProxyConfig.serverHostName;
1686 std::string noProxys = config.wifiProxyconfig.manualProxyConfig.exclusionObjectList;
1687 std::string port = std::to_string(config.wifiProxyconfig.manualProxyConfig.serverPort);
1688 if (!hostName.empty()) {
1689 IfConfig::GetInstance().SetProxy(true, hostName, port, noProxys, "");
1690 }
1691 }
1692
1693 if (assignMethod == AssignIpMethod::STATIC) {
1694 pStaStateMachine->currentTpType = config.wifiIpConfig.staticIpAddress.ipAddress.address.family;
1695 if (!pStaStateMachine->ConfigStaticIpAddress(config.wifiIpConfig.staticIpAddress)) {
1696 if (pStaStateMachine->staCallback.OnStaConnChanged != nullptr) {
1697 pStaStateMachine->staCallback.OnStaConnChanged(
1698 OperateResState::CONNECT_NETWORK_DISABLED, pStaStateMachine->linkedInfo);
1699 }
1700 pStaStateMachine->DisConnectProcess();
1701 LOGE("ConfigstaticIpAddress failed!\n");
1702 }
1703 } else {
1704 int dhcpRet = 0;
1705 DhcpServiceInfo dhcpInfo;
1706 pStaStateMachine->pDhcpService->GetDhcpInfo(IF_NAME, dhcpInfo);
1707 LOGI("GetIpState get dhcp result, isRoam=%{public}d, clientRunStatus=%{public}d.",
1708 pStaStateMachine->isRoam, dhcpInfo.clientRunStatus);
1709 pStaStateMachine->currentTpType = static_cast<int>(WifiSettings::GetInstance().GetDhcpIpType());
1710 if (pStaStateMachine->currentTpType == IPTYPE_IPV6) {
1711 dhcpRet = pStaStateMachine->pDhcpService->StartDhcpClient(IF_NAME, true);
1712 } else {
1713 dhcpRet = pStaStateMachine->pDhcpService->StartDhcpClient(IF_NAME, false);
1714 }
1715 if ((dhcpRet != 0) || (pStaStateMachine->pDhcpService->GetDhcpResult(
1716 IF_NAME, pStaStateMachine->pDhcpResultNotify, DHCP_TIME) != 0)) {
1717 LOGE(" Dhcp connection failed.\n");
1718 pStaStateMachine->SaveLinkstate(ConnState::DISCONNECTED, DetailedState::OBTAINING_IPADDR_FAIL);
1719 pStaStateMachine->staCallback.OnStaConnChanged(
1720 OperateResState::CONNECT_OBTAINING_IP_FAILED, pStaStateMachine->linkedInfo);
1721 if (!pStaStateMachine->isRoam) {
1722 pStaStateMachine->DisConnectProcess();
1723 }
1724 }
1725 }
1726 return;
1727 }
1728
GoOutState()1729 void StaStateMachine::GetIpState::GoOutState()
1730 {
1731 WIFI_LOGI("GetIpState GoOutState function.");
1732 }
1733
ExecuteStateMsg(InternalMessage * msg)1734 bool StaStateMachine::GetIpState::ExecuteStateMsg(InternalMessage *msg)
1735 {
1736 if (msg == nullptr) {
1737 return false;
1738 }
1739
1740 bool ret = NOT_EXECUTED;
1741 bool result = false;
1742 WIFI_LOGI("GetIpState-msgCode=%{public}d received.\n", msg->GetMessageName());
1743 switch (msg->GetMessageName()) {
1744 case WIFI_SVR_CMD_STA_DHCP_RESULT_NOTIFY_EVENT: {
1745 ret = EXECUTED;
1746 result = msg->GetParam1();
1747 WIFI_LOGI("GetIpState, get ip result:%{public}d.\n", result);
1748 pStaStateMachine->SwitchState(pStaStateMachine->pLinkedState);
1749 break;
1750 }
1751 default:
1752 break;
1753 }
1754
1755 return ret;
1756 }
1757
1758 /* --- state machine GetIp State functions ----- */
ConfigStaticIpAddress(StaticIpAddress & staticIpAddress)1759 bool StaStateMachine::ConfigStaticIpAddress(StaticIpAddress &staticIpAddress)
1760 {
1761 WIFI_LOGI("Enter StaStateMachine::SetDhcpResultFromStatic.");
1762 DhcpResult result;
1763 switch (currentTpType) {
1764 case IPTYPE_IPV4: {
1765 result.iptype = IPTYPE_IPV4;
1766 result.strYourCli = staticIpAddress.ipAddress.address.GetIpv4Address();
1767 result.strRouter1 = staticIpAddress.gateway.GetIpv4Address();
1768 result.strSubnet = staticIpAddress.GetIpv4Mask();
1769 result.strDns1 = staticIpAddress.dnsServer1.GetIpv4Address();
1770 result.strDns2 = staticIpAddress.dnsServer2.GetIpv4Address();
1771 pDhcpResultNotify->OnSuccess(1, IF_NAME, result);
1772 break;
1773 }
1774 case IPTYPE_IPV6: {
1775 result.iptype = IPTYPE_IPV6;
1776 result.strYourCli = staticIpAddress.ipAddress.address.GetIpv6Address();
1777 result.strRouter1 = staticIpAddress.gateway.GetIpv6Address();
1778 result.strSubnet = staticIpAddress.GetIpv6Mask();
1779 result.strDns1 = staticIpAddress.dnsServer1.GetIpv6Address();
1780 result.strDns2 = staticIpAddress.dnsServer2.GetIpv6Address();
1781 pDhcpResultNotify->OnSuccess(1, IF_NAME, result);
1782 break;
1783 }
1784 case IPTYPE_MIX: {
1785 result.iptype = IPTYPE_IPV4;
1786 result.strYourCli = staticIpAddress.ipAddress.address.GetIpv4Address();
1787 result.strRouter1 = staticIpAddress.gateway.GetIpv4Address();
1788 result.strSubnet = staticIpAddress.GetIpv4Mask();
1789 result.strDns1 = staticIpAddress.dnsServer1.GetIpv4Address();
1790 result.strDns2 = staticIpAddress.dnsServer2.GetIpv4Address();
1791 pDhcpResultNotify->OnSuccess(1, IF_NAME, result);
1792
1793 result.iptype = IPTYPE_IPV6;
1794 result.strYourCli = staticIpAddress.ipAddress.address.GetIpv6Address();
1795 result.strRouter1 = staticIpAddress.gateway.GetIpv6Address();
1796 result.strSubnet = staticIpAddress.GetIpv6Mask();
1797 result.strDns1 = staticIpAddress.dnsServer1.GetIpv6Address();
1798 result.strDns2 = staticIpAddress.dnsServer2.GetIpv6Address();
1799 pDhcpResultNotify->OnSuccess(1, IF_NAME, result);
1800 break;
1801 }
1802
1803 default:
1804 WIFI_LOGE("Invalid currentTpType: %{public}d", currentTpType);
1805 return false;
1806 }
1807 return true;
1808 }
1809
HandleNetCheckResult(StaNetState netState,const std::string portalUrl)1810 void StaStateMachine::HandleNetCheckResult(StaNetState netState, const std::string portalUrl)
1811 {
1812 WIFI_LOGI("Enter HandleNetCheckResult, netState:%{public}d.", netState);
1813 if (linkedInfo.connState != ConnState::CONNECTED) {
1814 WIFI_LOGE("connState is NOT in connected state, connState:%{public}d\n", linkedInfo.connState);
1815 return;
1816 }
1817
1818 if (netState == StaNetState::NETWORK_STATE_WORKING) {
1819 WIFI_LOGI("HandleNetCheckResult network state is working\n");
1820 /* Save connection information to WifiSettings. */
1821 SaveLinkstate(ConnState::CONNECTED, DetailedState::WORKING);
1822 staCallback.OnStaConnChanged(OperateResState::CONNECT_NETWORK_ENABLED, linkedInfo);
1823 } else if (netState == StaNetState::NETWORK_CHECK_PORTAL) {
1824 linkedInfo.portalUrl = portalUrl;
1825 SaveLinkstate(ConnState::CONNECTED, DetailedState::CAPTIVE_PORTAL_CHECK);
1826 staCallback.OnStaConnChanged(OperateResState::CONNECT_CHECK_PORTAL, linkedInfo);
1827 } else {
1828 WIFI_LOGI("HandleNetCheckResult network state is notworking.\n");
1829 SaveLinkstate(ConnState::CONNECTED, DetailedState::NOTWORKING);
1830 staCallback.OnStaConnChanged(OperateResState::CONNECT_NETWORK_DISABLED, linkedInfo);
1831 }
1832 }
1833
1834 /* --------------------------- state machine Connected State ------------------------------ */
LinkedState(StaStateMachine * staStateMachine)1835 StaStateMachine::LinkedState::LinkedState(StaStateMachine *staStateMachine)
1836 : State("LinkedState"), pStaStateMachine(staStateMachine)
1837 {}
1838
~LinkedState()1839 StaStateMachine::LinkedState::~LinkedState()
1840 {}
1841
GoInState()1842 void StaStateMachine::LinkedState::GoInState()
1843 {
1844 WIFI_LOGI("LinkedState GoInState function.");
1845
1846 return;
1847 }
1848
GoOutState()1849 void StaStateMachine::LinkedState::GoOutState()
1850 {
1851 WIFI_LOGI("LinkedState GoOutState function.");
1852 }
1853
ExecuteStateMsg(InternalMessage * msg)1854 bool StaStateMachine::LinkedState::ExecuteStateMsg(InternalMessage *msg)
1855 {
1856 if (msg == nullptr) {
1857 WIFI_LOGI("msg is nullptr.");
1858 return false;
1859 }
1860
1861 WIFI_LOGI("LinkedState, reveived msgCode=%{public}d msg.\n", msg->GetMessageName());
1862 bool ret = NOT_EXECUTED;
1863 switch (msg->GetMessageName()) {
1864 case WIFI_SVR_CMD_STA_BSSID_CHANGED_EVENT: {
1865 ret = EXECUTED;
1866 std::string reason = msg->GetStringFromMessage();
1867 std::string bssid = msg->GetStringFromMessage();
1868 WIFI_LOGI("reveived bssid changed event, reason:%{public}s,bssid:%{public}s.\n",
1869 reason.c_str(), MacAnonymize(bssid).c_str());
1870 if (strcmp(reason.c_str(), "ASSOC_COMPLETE") != 0) {
1871 WIFI_LOGE("Bssid change not for ASSOC_COMPLETE, do nothing.");
1872 return false;
1873 }
1874 if (WifiStaHalInterface::GetInstance().SetWpsBssid(pStaStateMachine->linkedInfo.networkId,
1875 bssid) != WIFI_IDL_OPT_OK) {
1876 WIFI_LOGE("SetWpsBssid return fail.");
1877 return false;
1878 }
1879 pStaStateMachine->isRoam = true;
1880 /* The current state of StaStateMachine transfers to pApRoamingState. */
1881 pStaStateMachine->SwitchState(pStaStateMachine->pApRoamingState);
1882 break;
1883 }
1884 default:
1885 WIFI_LOGE("NOT handle this event!");
1886 break;
1887 }
1888
1889 return ret;
1890 }
1891
1892 /* --------------------------- state machine Roaming State ------------------------------ */
ApRoamingState(StaStateMachine * staStateMachine)1893 StaStateMachine::ApRoamingState::ApRoamingState(StaStateMachine *staStateMachine)
1894 : State("ApRoamingState"), pStaStateMachine(staStateMachine)
1895 {}
1896
~ApRoamingState()1897 StaStateMachine::ApRoamingState::~ApRoamingState()
1898 {}
1899
GoInState()1900 void StaStateMachine::ApRoamingState::GoInState()
1901 {
1902 WIFI_LOGI("ApRoamingState GoInState function.");
1903 }
1904
GoOutState()1905 void StaStateMachine::ApRoamingState::GoOutState()
1906 {
1907 WIFI_LOGI("ApRoamingState GoOutState function.");
1908 }
1909
ExecuteStateMsg(InternalMessage * msg)1910 bool StaStateMachine::ApRoamingState::ExecuteStateMsg(InternalMessage *msg)
1911 {
1912 if (msg == nullptr) {
1913 return false;
1914 }
1915
1916 WIFI_LOGI("ApRoamingState, reveived msgCode=%{public}d msg.", msg->GetMessageName());
1917 bool ret = NOT_EXECUTED;
1918 switch (msg->GetMessageName()) {
1919 case WIFI_SVR_CMD_STA_NETWORK_CONNECTION_EVENT: {
1920 WIFI_LOGI("ApRoamingState, receive WIFI_SVR_CMD_STA_NETWORK_CONNECTION_EVENT event.");
1921 ret = EXECUTED;
1922 pStaStateMachine->isRoam = true;
1923 pStaStateMachine->StopTimer(static_cast<int>(CMD_NETWORK_CONNECT_TIMEOUT));
1924 pStaStateMachine->ConnectToNetworkProcess(msg);
1925 /* Notify result to InterfaceService. */
1926 pStaStateMachine->staCallback.OnStaConnChanged(OperateResState::CONNECT_ASSOCIATED,
1927 pStaStateMachine->linkedInfo);
1928 pStaStateMachine->staCallback.OnStaConnChanged(OperateResState::CONNECT_OBTAINING_IP,
1929 pStaStateMachine->linkedInfo);
1930
1931 /* The current state of StaStateMachine transfers to GetIpState. */
1932 pStaStateMachine->SwitchState(pStaStateMachine->pGetIpState);
1933 break;
1934 }
1935 default:
1936 WIFI_LOGI("ApRoamingState-msgCode=%d not handled.", msg->GetMessageName());
1937 break;
1938 }
1939
1940 return ret;
1941 }
1942
ConnectToNetworkProcess(InternalMessage * msg)1943 void StaStateMachine::ConnectToNetworkProcess(InternalMessage *msg)
1944 {
1945 if (msg == nullptr) {
1946 return;
1947 }
1948
1949 lastNetworkId = msg->GetParam1();
1950 std::string bssid = msg->GetStringFromMessage();
1951 WIFI_LOGI("ConnectToNetworkProcess, Receive msg: lastNetworkId=%{public}d, bssid=%{public}s",
1952 lastNetworkId, MacAnonymize(bssid).c_str());
1953 WifiDeviceConfig deviceConfig;
1954 int result = WifiSettings::GetInstance().GetDeviceConfig(lastNetworkId, deviceConfig);
1955 WIFI_LOGI("Device config networkId = %{public}d", deviceConfig.networkId);
1956
1957 if (result == 0 && deviceConfig.bssid == bssid) {
1958 LOGI("Device Configuration already exists.");
1959 } else {
1960 deviceConfig.bssid = bssid;
1961 if ((wpsState == SetupMethod::DISPLAY) || (wpsState == SetupMethod::PBC) || (wpsState == SetupMethod::KEYPAD)) {
1962 /* Save connection information. */
1963 WifiIdlGetDeviceConfig config;
1964 config.networkId = lastNetworkId;
1965 config.param = "ssid";
1966 if (WifiStaHalInterface::GetInstance().GetDeviceConfig(config) != WIFI_IDL_OPT_OK) {
1967 LOGE("GetDeviceConfig failed!");
1968 }
1969
1970 deviceConfig.networkId = lastNetworkId;
1971 deviceConfig.bssid = bssid;
1972 deviceConfig.ssid = config.value;
1973 /* Remove the double quotation marks at the head and tail. */
1974 deviceConfig.ssid.erase(0, 1);
1975 deviceConfig.ssid.erase(deviceConfig.ssid.length() - 1, 1);
1976 WifiSettings::GetInstance().AddWpsDeviceConfig(deviceConfig);
1977 isWpsConnect = IsWpsConnected::WPS_CONNECTED;
1978 } else {
1979 WifiSettings::GetInstance().AddDeviceConfig(deviceConfig);
1980 }
1981 WifiSettings::GetInstance().SyncDeviceConfig();
1982 WIFI_LOGD("Device ssid = %s", SsidAnonymize(deviceConfig.ssid).c_str());
1983 }
1984
1985 std::string macAddr;
1986 WifiSettings::GetInstance().GetMacAddress(macAddr);
1987 linkedInfo.networkId = lastNetworkId;
1988 linkedInfo.bssid = bssid;
1989 linkedInfo.ssid = deviceConfig.ssid;
1990 linkedInfo.macAddress = macAddr;
1991 linkedInfo.ifHiddenSSID = deviceConfig.hiddenSSID;
1992 lastLinkedInfo.bssid = bssid;
1993 lastLinkedInfo.macAddress = deviceConfig.macAddress;
1994 lastLinkedInfo.ifHiddenSSID = deviceConfig.hiddenSSID;
1995 SetWifiLinkedInfo(lastNetworkId);
1996 SaveLinkstate(ConnState::CONNECTING, DetailedState::OBTAINING_IPADDR);
1997 }
1998
SetWifiLinkedInfo(int networkId)1999 void StaStateMachine::SetWifiLinkedInfo(int networkId)
2000 {
2001 WIFI_LOGI("SetWifiLinkedInfo, linkedInfo.networkId=%{public}d, lastLinkedInfo.networkId=%{public}d",
2002 linkedInfo.networkId, lastLinkedInfo.networkId);
2003 if (linkedInfo.networkId == INVALID_NETWORK_ID) {
2004 if (lastLinkedInfo.networkId != INVALID_NETWORK_ID) {
2005 /* Update connection information according to the last connecting information. */
2006 linkedInfo.networkId = lastLinkedInfo.networkId;
2007 linkedInfo.ssid = lastLinkedInfo.ssid;
2008 linkedInfo.bssid = lastLinkedInfo.bssid;
2009 linkedInfo.macAddress = lastLinkedInfo.macAddress;
2010 linkedInfo.rssi = lastLinkedInfo.rssi;
2011 linkedInfo.band = lastLinkedInfo.band;
2012 linkedInfo.frequency = lastLinkedInfo.frequency;
2013 linkedInfo.linkSpeed = lastLinkedInfo.linkSpeed;
2014 linkedInfo.ipAddress = lastLinkedInfo.ipAddress;
2015 linkedInfo.connState = lastLinkedInfo.connState;
2016 linkedInfo.ifHiddenSSID = lastLinkedInfo.ifHiddenSSID;
2017 linkedInfo.rxLinkSpeed = lastLinkedInfo.rxLinkSpeed;
2018 linkedInfo.txLinkSpeed = lastLinkedInfo.txLinkSpeed;
2019 linkedInfo.chload = lastLinkedInfo.chload;
2020 linkedInfo.snr = lastLinkedInfo.snr;
2021 linkedInfo.isDataRestricted = lastLinkedInfo.isDataRestricted;
2022 linkedInfo.portalUrl = lastLinkedInfo.portalUrl;
2023 linkedInfo.detailedState = lastLinkedInfo.detailedState;
2024 } else if (networkId != INVALID_NETWORK_ID) {
2025 linkedInfo.networkId = networkId;
2026 WifiDeviceConfig config;
2027 int ret = WifiSettings::GetInstance().GetDeviceConfig(networkId, config);
2028 if (ret == 0) {
2029 /* Update connection information according to configuration. */
2030 linkedInfo.networkId = config.networkId;
2031 linkedInfo.ssid = config.ssid;
2032 linkedInfo.bssid = config.bssid;
2033 linkedInfo.band = config.band;
2034 linkedInfo.connState = ConnState::CONNECTING;
2035 linkedInfo.ifHiddenSSID = config.hiddenSSID;
2036 linkedInfo.detailedState = DetailedState::OBTAINING_IPADDR;
2037
2038 lastLinkedInfo.networkId = config.networkId;
2039 lastLinkedInfo.ssid = config.ssid;
2040 lastLinkedInfo.bssid = config.bssid;
2041 lastLinkedInfo.band = config.band;
2042 lastLinkedInfo.connState = ConnState::CONNECTING;
2043 lastLinkedInfo.ifHiddenSSID = config.hiddenSSID;
2044 lastLinkedInfo.detailedState = DetailedState::OBTAINING_IPADDR;
2045 }
2046 }
2047 }
2048 }
2049
DealNetworkCheck(InternalMessage * msg)2050 void StaStateMachine::DealNetworkCheck(InternalMessage *msg)
2051 {
2052 LOGI("enter DealNetworkCheck.\n");
2053 if (msg == nullptr) {
2054 LOGE("InternalMessage msg is null.");
2055 return;
2056 }
2057
2058 if (pNetcheck == nullptr) {
2059 LOGE("pNetcheck is null.");
2060 return;
2061 }
2062 pNetcheck->SignalNetCheckThread();
2063 }
2064
2065 /* ------------------ state machine dhcp callback function ----------------- */
2066
DhcpResultNotify(StaStateMachine * staStateMachine)2067 StaStateMachine::DhcpResultNotify::DhcpResultNotify(StaStateMachine *staStateMachine)
2068 {
2069 pStaStateMachine = staStateMachine;
2070 }
2071
~DhcpResultNotify()2072 StaStateMachine::DhcpResultNotify::~DhcpResultNotify()
2073 {}
2074
OnSuccess(int status,const std::string & ifname,DhcpResult & result)2075 void StaStateMachine::DhcpResultNotify::OnSuccess(int status, const std::string &ifname, DhcpResult &result)
2076 {
2077 LOGI("Enter Sta DhcpResultNotify::OnSuccess. ifname=[%{public}s] status=[%{public}d]\n",
2078 ifname.c_str(), status);
2079
2080 if ((pStaStateMachine->linkedInfo.detailedState == DetailedState::DISCONNECTING) ||
2081 (pStaStateMachine->linkedInfo.detailedState == DetailedState::DISCONNECTED)) {
2082 return;
2083 }
2084 WIFI_LOGI("iptype=%{public}d, ip=%{public}s, gateway=%{public}s, \
2085 subnet=%{public}s, serverAddress=%{public}s, leaseDuration=%{public}d.",
2086 result.iptype,
2087 IpAnonymize(result.strYourCli).c_str(),
2088 IpAnonymize(result.strRouter1).c_str(),
2089 IpAnonymize(result.strSubnet).c_str(),
2090 IpAnonymize(result.strServer).c_str(),
2091 result.uLeaseTime);
2092 WIFI_LOGI("strDns1=%{public}s, strDns2=%{public}s", IpAnonymize(result.strDns1).c_str(),
2093 IpAnonymize(result.strDns2).c_str());
2094
2095 IpInfo ipInfo;
2096 WifiSettings::GetInstance().GetIpInfo(ipInfo);
2097 if (!((IpTools::ConvertIpv4Address(result.strYourCli) == ipInfo.ipAddress) &&
2098 (IpTools::ConvertIpv4Address(result.strRouter1) == ipInfo.gateway))) {
2099 result.strDns2 = WifiSettings::GetInstance().GetStrDnsBak();
2100 if (result.iptype == 0) {
2101 ipInfo.ipAddress = IpTools::ConvertIpv4Address(result.strYourCli);
2102 ipInfo.gateway = IpTools::ConvertIpv4Address(result.strRouter1);
2103 ipInfo.netmask = IpTools::ConvertIpv4Address(result.strSubnet);
2104 ipInfo.primaryDns = IpTools::ConvertIpv4Address(result.strDns1);
2105 ipInfo.secondDns = IpTools::ConvertIpv4Address(result.strDns2);
2106 ipInfo.serverIp = IpTools::ConvertIpv4Address(result.strServer);
2107 ipInfo.leaseDuration = result.uLeaseTime;
2108 WifiSettings::GetInstance().SaveIpInfo(ipInfo);
2109 pStaStateMachine->linkedInfo.ipAddress = IpTools::ConvertIpv4Address(result.strYourCli);
2110 pStaStateMachine->linkedInfo.isDataRestricted =
2111 (result.strVendor.find("ANDROID_METERED") == std::string::npos) ? 0 : 1;
2112 WifiSettings::GetInstance().SaveLinkedInfo(pStaStateMachine->linkedInfo);
2113 #ifndef OHOS_ARCH_LITE
2114 WIFI_LOGI("Update NetLink info, strYourCli=%{public}s, strSubnet=%{public}s, \
2115 strRouter1=%{public}s, strDns1=%{public}s, strDns2=%{public}s",
2116 IpAnonymize(result.strYourCli).c_str(), IpAnonymize(result.strSubnet).c_str(),
2117 IpAnonymize(result.strRouter1).c_str(), IpAnonymize(result.strDns1).c_str(),
2118 IpAnonymize(result.strDns2).c_str());
2119 WIFI_LOGI("On dhcp success update net linke info");
2120 WifiNetAgent::GetInstance().OnStaMachineUpdateNetLinkInfo(result.strYourCli, result.strSubnet,
2121 result.strRouter1, result.strDns1, result.strDns2);
2122 #endif
2123 }
2124 #ifdef OHOS_ARCH_LITE
2125 IfConfig::GetInstance().SetIfDnsAndRoute(result, result.iptype);
2126 #endif
2127 }
2128
2129 WIFI_LOGI("DhcpResultNotify::OnSuccess, getIpSucNum=%{public}d, isRoam=%{public}d",
2130 pStaStateMachine->getIpSucNum, pStaStateMachine->isRoam);
2131 pStaStateMachine->OnDhcpResultNotifyEvent(true);
2132 if (pStaStateMachine->getIpSucNum == 0 || pStaStateMachine->isRoam) {
2133 pStaStateMachine->SaveLinkstate(ConnState::CONNECTED, DetailedState::CONNECTED);
2134 pStaStateMachine->staCallback.OnStaConnChanged(
2135 OperateResState::CONNECT_AP_CONNECTED, pStaStateMachine->linkedInfo);
2136 /* Delay to wait for the network adapter information to take effect. */
2137 constexpr int NETCHECK_DELAY_TIME = 2000; // 2000 ms
2138 pStaStateMachine->StartTimer(static_cast<int>(CMD_START_NETCHECK), NETCHECK_DELAY_TIME);
2139 }
2140 pStaStateMachine->getIpSucNum++;
2141
2142 WIFI_LOGI("DhcpResultNotify::OnSuccess, stop dhcp client");
2143 if (pStaStateMachine->pDhcpService != nullptr) {
2144 if (pStaStateMachine->currentTpType == IPTYPE_IPV6) {
2145 pStaStateMachine->pDhcpService->StopDhcpClient(IF_NAME, true);
2146 } else {
2147 pStaStateMachine->pDhcpService->StopDhcpClient(IF_NAME, false);
2148 }
2149 }
2150 return;
2151 }
2152
OnFailed(int status,const std::string & ifname,const std::string & reason)2153 void StaStateMachine::DhcpResultNotify::OnFailed(int status, const std::string &ifname, const std::string &reason)
2154 {
2155 LOGI("Enter DhcpResultNotify::OnFailed. ifname=[%s] status=[%d], reason = [%s], detailedState = [%d]\n",
2156 ifname.c_str(), status, reason.c_str(), static_cast<int>(pStaStateMachine->linkedInfo.detailedState));
2157 if ((pStaStateMachine->linkedInfo.detailedState == DetailedState::DISCONNECTING) ||
2158 (pStaStateMachine->linkedInfo.detailedState == DetailedState::DISCONNECTED)) {
2159 return;
2160 }
2161
2162 LOGI("currentTpType: %{public}d, getIpSucNum: %{public}d, getIpFailNum: %{public}d, isRoam: %{public}d",
2163 pStaStateMachine->currentTpType, pStaStateMachine->getIpSucNum,
2164 pStaStateMachine->getIpFailNum, pStaStateMachine->isRoam);
2165
2166 if (pStaStateMachine->getIpFailNum == 0) {
2167 pStaStateMachine->staCallback.OnStaConnChanged(OperateResState::CONNECT_OBTAINING_IP_FAILED,
2168 pStaStateMachine->linkedInfo);
2169 pStaStateMachine->DisConnectProcess();
2170 pStaStateMachine->SaveLinkstate(ConnState::DISCONNECTED, DetailedState::OBTAINING_IPADDR_FAIL);
2171 pStaStateMachine->staCallback.OnStaConnChanged(OperateResState::DISCONNECT_DISCONNECTED,
2172 pStaStateMachine->linkedInfo);
2173 }
2174 pStaStateMachine->getIpFailNum++;
2175 }
2176
OnSerExitNotify(const std::string & ifname)2177 void StaStateMachine::DhcpResultNotify::OnSerExitNotify(const std::string &ifname)
2178 {
2179 LOGI("Enter DhcpResultNotify::OnSerExitNotify. ifname = [%s]\n", ifname.c_str());
2180 }
2181
2182 /* ------------------ state machine Comment function ----------------- */
SaveLinkstate(ConnState state,DetailedState detailState)2183 void StaStateMachine::SaveLinkstate(ConnState state, DetailedState detailState)
2184 {
2185 linkedInfo.connState = state;
2186 linkedInfo.detailedState = detailState;
2187 lastLinkedInfo.connState = state;
2188 lastLinkedInfo.detailedState = detailState;
2189 WifiSettings::GetInstance().SaveLinkedInfo(linkedInfo);
2190 }
2191
GetLinkedInfo(WifiLinkedInfo & linkedInfo)2192 int StaStateMachine::GetLinkedInfo(WifiLinkedInfo& linkedInfo)
2193 {
2194 return WifiSettings::GetInstance().GetLinkedInfo(linkedInfo);
2195 }
2196
DisableNetwork(int networkId)2197 ErrCode StaStateMachine::DisableNetwork(int networkId)
2198 {
2199 if (WifiStaHalInterface::GetInstance().DisableNetwork(networkId) != WIFI_IDL_OPT_OK) {
2200 LOGE("DisableNetwork() failed, networkId=%d.", networkId);
2201 return WIFI_OPT_FAILED;
2202 }
2203
2204 if (WifiStaHalInterface::GetInstance().SaveDeviceConfig() != WIFI_IDL_OPT_OK) {
2205 LOGE("DisableNetwork-SaveDeviceConfig() failed!");
2206 return WIFI_OPT_FAILED;
2207 }
2208 LOGI("DisableNetwork-SaveDeviceConfig() succeed!");
2209 return WIFI_OPT_SUCCESS;
2210 }
2211
SetOperationalMode(int mode)2212 void StaStateMachine::SetOperationalMode(int mode)
2213 {
2214 SendMessage(WIFI_SVR_CMD_STA_OPERATIONAL_MODE, mode, 0);
2215 }
2216
2217 #ifndef OHOS_ARCH_LITE
SubscribeSystemAbilityChanged(void)2218 void StaStateMachine::SubscribeSystemAbilityChanged(void)
2219 {
2220 auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
2221 statusChangeListener_ = new (std::nothrow) SystemAbilityStatusChangeListener(*this);
2222 if (samgrProxy == nullptr || statusChangeListener_ == nullptr) {
2223 LOGE("samgrProxy or statusChangeListener_ is nullptr");
2224 return;
2225 }
2226 int32_t ret = samgrProxy->SubscribeSystemAbility(COMM_NET_CONN_MANAGER_SYS_ABILITY_ID, statusChangeListener_);
2227 LOGI("SubscribeSystemAbility COMM_NET_CONN_MANAGER_SYS_ABILITY_ID result:%{public}d", ret);
2228 }
2229
OnNetManagerRestart(void)2230 void StaStateMachine::OnNetManagerRestart(void)
2231 {
2232 LOGI("OnNetManagerRestart()");
2233 int state = WifiSettings::GetInstance().GetWifiState();
2234 if (state != static_cast<int>(WifiState::ENABLED)) {
2235 return;
2236 }
2237 WifiNetAgent::GetInstance().OnStaMachineNetManagerRestart(NetSupplierInfo, staCallback);
2238 }
2239
ReUpdateNetSupplierInfo(sptr<NetManagerStandard::NetSupplierInfo> supplierInfo)2240 void StaStateMachine::ReUpdateNetSupplierInfo(sptr<NetManagerStandard::NetSupplierInfo> supplierInfo)
2241 {
2242 LOGI("ReUpdateNetSupplierInfo()");
2243 WifiLinkedInfo linkedInfo;
2244 WifiSettings::GetInstance().GetLinkedInfo(linkedInfo);
2245 if ((linkedInfo.detailedState == DetailedState::NOTWORKING) && (linkedInfo.connState == ConnState::CONNECTED)) {
2246 if (supplierInfo != nullptr) {
2247 TimeStats timeStats("Call UpdateNetSupplierInfo");
2248 WifiNetAgent::GetInstance().UpdateNetSupplierInfo(supplierInfo);
2249 }
2250 }
2251 }
2252
ReUpdateNetLinkInfo(void)2253 void StaStateMachine::ReUpdateNetLinkInfo(void)
2254 {
2255 LOGI("ReUpdateNetLinkInfo()");
2256 WifiLinkedInfo linkedInfo;
2257 WifiSettings::GetInstance().GetLinkedInfo(linkedInfo);
2258 if ((linkedInfo.detailedState == DetailedState::NOTWORKING) && (linkedInfo.connState == ConnState::CONNECTED)) {
2259 IpInfo wifiIpInfo;
2260 WifiSettings::GetInstance().GetIpInfo(wifiIpInfo);
2261 std::string ipAddress = IpTools::ConvertIpv4Address(wifiIpInfo.ipAddress);
2262 std::string gateway = IpTools::ConvertIpv4Address(wifiIpInfo.gateway);
2263 std::string netmask = IpTools::ConvertIpv4Address(wifiIpInfo.netmask);
2264 std::string primaryDns = IpTools::ConvertIpv4Address(wifiIpInfo.primaryDns);
2265 std::string secondDns = IpTools::ConvertIpv4Address(wifiIpInfo.secondDns);
2266 WifiNetAgent::GetInstance().UpdateNetLinkInfo(ipAddress, netmask, gateway, primaryDns, secondDns);
2267 }
2268 }
2269
SystemAbilityStatusChangeListener(StaStateMachine & stateMachine)2270 StaStateMachine::SystemAbilityStatusChangeListener::SystemAbilityStatusChangeListener(StaStateMachine &stateMachine)
2271 : stateMachine_(stateMachine){};
2272
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)2273 void StaStateMachine::SystemAbilityStatusChangeListener::OnAddSystemAbility(int32_t systemAbilityId,
2274 const std::string &deviceId)
2275 {
2276 LOGI("OnAddSystemAbility() systemAbilityId:%{public}d", systemAbilityId);
2277 if (systemAbilityId == COMM_NET_CONN_MANAGER_SYS_ABILITY_ID) {
2278 if (!hasSARemoved_) {
2279 return;
2280 }
2281 hasSARemoved_ = false;
2282 stateMachine_.OnNetManagerRestart();
2283 }
2284 }
2285
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)2286 void StaStateMachine::SystemAbilityStatusChangeListener::OnRemoveSystemAbility(int32_t systemAbilityId,
2287 const std::string &deviceId)
2288 {
2289 LOGI("OnRemoveSystemAbility() systemAbilityId:%{public}d", systemAbilityId);
2290 if (systemAbilityId == COMM_NET_CONN_MANAGER_SYS_ABILITY_ID) {
2291 hasSARemoved_ = true;
2292 }
2293 }
2294 #endif // OHOS_ARCH_LITE
2295 } // namespace Wifi
2296 } // namespace OHOS
2297