• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "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