1 /*
2 * Copyright (C) 2021-2023 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 "concrete_manager_state_machine.h"
17 #include "wifi_controller_define.h"
18 #include "wifi_manager.h"
19 #include "wifi_config_center.h"
20 #include "wifi_internal_msg.h"
21 #include "wifi_sta_hal_interface.h"
22 #include "wifi_common_event_helper.h"
23 #include "wifi_service_scheduler.h"
24 #ifndef OHOS_ARCH_LITE
25 #include "wifi_country_code_manager.h"
26 #include "wifi_common_util.h"
27 #include "app_network_speed_limit_service.h"
28 #include "wifi_internal_event_dispatcher.h"
29 #else
30 #include "wifi_internal_event_dispatcher_lite.h"
31 #endif
32 #ifdef HDI_CHIP_INTERFACE_SUPPORT
33 #include "hal_device_manage.h"
34 #endif
35
36 namespace OHOS {
37 namespace Wifi {
38 DEFINE_WIFILOG_LABEL("ConcreteMangerMachine");
39 int ConcreteMangerMachine::mTargetRole{static_cast<int>(ConcreteManagerRole::ROLE_UNKNOW)};
40 using TimeOutCallback = std::function<void()>;
41 int ConcreteMangerMachine::mid{0};
42 std::string ConcreteMangerMachine::ifaceName{""};
43
ConcreteMangerMachine()44 ConcreteMangerMachine::ConcreteMangerMachine()
45 : StateMachine("ConcreteMangerMachine"), pDefaultState(nullptr), pIdleState(nullptr), pConnectState(nullptr),
46 pScanonlyState(nullptr), pSemiActiveState(nullptr)
47 {}
48
~ConcreteMangerMachine()49 ConcreteMangerMachine::~ConcreteMangerMachine()
50 {
51 WIFI_LOGE("~ConcreteMangerMachine");
52 StopHandlerThread();
53 ParsePointer(pDefaultState);
54 ParsePointer(pIdleState);
55 ParsePointer(pConnectState);
56 ParsePointer(pScanonlyState);
57 ParsePointer(pSemiActiveState);
58 WIFI_LOGE("set wifi stoping state is false");
59 WifiConfigCenter::GetInstance().SetWifiStopState(false);
60 #ifdef HDI_CHIP_INTERFACE_SUPPORT
61 if (!ifaceName.empty()) {
62 WIFI_LOGW("destroy ConcreteMangerMachine RemoveStaIface ifaceName:%{public}s, instId:%{public}d",
63 ifaceName.c_str(), mid);
64 DelayedSingleton<HalDeviceManager>::GetInstance()->RemoveStaIface(ifaceName);
65 ifaceName.clear();
66 WifiServiceScheduler::GetInstance().ClearStaIfaceNameMap(mid);
67 WifiConfigCenter::GetInstance().SetStaIfaceName("", mid);
68 }
69 #endif
70 }
71
72 /* --------------------------Initialization functions--------------------------*/
InitConcreteMangerMachine()73 ErrCode ConcreteMangerMachine::InitConcreteMangerMachine()
74 {
75 WIFI_LOGE("Enter InitConcreteMangerMachine.\n");
76 if (!InitialStateMachine("ConcreteManagerMachine")) {
77 WIFI_LOGE("Initial StateMachine failed.\n");
78 return WIFI_OPT_FAILED;
79 }
80 WifiConfigCenter::GetInstance().SetWifiStopState(false);
81 if (InitConcreteMangerStates() == WIFI_OPT_FAILED) {
82 return WIFI_OPT_FAILED;
83 }
84 BuildStateTree();
85 SetFirstState(pIdleState);
86 StartStateMachine();
87 return WIFI_OPT_SUCCESS;
88 }
89
BuildStateTree()90 void ConcreteMangerMachine::BuildStateTree()
91 {
92 StatePlus(pDefaultState, nullptr);
93 StatePlus(pIdleState, pDefaultState);
94 StatePlus(pConnectState, pDefaultState);
95 StatePlus(pScanonlyState, pDefaultState);
96 StatePlus(pSemiActiveState, pDefaultState);
97 }
98
InitConcreteMangerStates()99 ErrCode ConcreteMangerMachine::InitConcreteMangerStates()
100 {
101 int tmpErrNumber;
102
103 WIFI_LOGE("Enter InitConcreteMangerStates.\n");
104 pDefaultState = new (std::nothrow) DefaultState(this);
105 tmpErrNumber = JudgmentEmpty(pDefaultState);
106 pIdleState = new (std::nothrow) IdleState(this);
107 tmpErrNumber += JudgmentEmpty(pIdleState);
108 pConnectState = new (std::nothrow) ConnectState(this);
109 tmpErrNumber += JudgmentEmpty(pConnectState);
110 pScanonlyState = new (std::nothrow) ScanonlyState(this);
111 tmpErrNumber += JudgmentEmpty(pScanonlyState);
112 pSemiActiveState = new (std::nothrow) SemiActiveState(this);
113 tmpErrNumber += JudgmentEmpty(pSemiActiveState);
114 if (tmpErrNumber != 0) {
115 WIFI_LOGE("InitConcreteMangerStates some one state is null\n");
116 return WIFI_OPT_FAILED;
117 }
118 return WIFI_OPT_SUCCESS;
119 }
120
RegisterCallback(ConcreteModeCallback & callback)121 void ConcreteMangerMachine::RegisterCallback(ConcreteModeCallback &callback)
122 {
123 mcb = callback;
124 }
125
SetTargetRole(ConcreteManagerRole role)126 void ConcreteMangerMachine::SetTargetRole(ConcreteManagerRole role)
127 {
128 WIFI_LOGI("SetTargetRole:%{public}d", static_cast<int>(role));
129 mTargetRole = static_cast<int>(role);
130 }
131
DefaultState(ConcreteMangerMachine * concreteMangerMachine)132 ConcreteMangerMachine::DefaultState::DefaultState(ConcreteMangerMachine *concreteMangerMachine)
133 : State("DefaultState"), pConcreteMangerMachine(concreteMangerMachine)
134 {}
135
~DefaultState()136 ConcreteMangerMachine::DefaultState::~DefaultState()
137 {}
138
GoInState()139 void ConcreteMangerMachine::DefaultState::GoInState()
140 {
141 WIFI_LOGE("DefaultState GoInState function.\n");
142 }
143
GoOutState()144 void ConcreteMangerMachine::DefaultState::GoOutState()
145 {
146 WIFI_LOGE("DefaultState GoOutState function.\n");
147 }
148
ExecuteStateMsg(InternalMessagePtr msg)149 bool ConcreteMangerMachine::DefaultState::ExecuteStateMsg(InternalMessagePtr msg)
150 {
151 if (msg == nullptr || pConcreteMangerMachine == nullptr) {
152 return false;
153 }
154 WIFI_LOGE("DefaultState-msgCode=%{public}d is received.\n", msg->GetMessageName());
155 switch (msg->GetMessageName()) {
156 case CONCRETE_CMD_STOP:
157 pConcreteMangerMachine->CheckAndContinueToStopWifi(msg);
158 break;
159 case CONCRETE_CMD_STA_STOP:
160 pConcreteMangerMachine->HandleStaStop();
161 break;
162 default:
163 break;
164 }
165 return true;
166 }
167
IdleState(ConcreteMangerMachine * concreteMangerMachine)168 ConcreteMangerMachine::IdleState::IdleState(ConcreteMangerMachine *concreteMangerMachine)
169 : State("IdleState"), pConcreteMangerMachine(concreteMangerMachine)
170 {}
171
~IdleState()172 ConcreteMangerMachine::IdleState::~IdleState()
173 {}
174
GoInState()175 void ConcreteMangerMachine::IdleState::GoInState()
176 {
177 WIFI_LOGE("IdleState GoInState function.\n");
178 }
179
GoOutState()180 void ConcreteMangerMachine::IdleState::GoOutState()
181 {
182 WIFI_LOGE("IdleState GoOutState function.\n");
183 }
184
ExecuteStateMsg(InternalMessagePtr msg)185 bool ConcreteMangerMachine::IdleState::ExecuteStateMsg(InternalMessagePtr msg) __attribute__((no_sanitize("cfi")))
186 {
187 if (msg == nullptr) {
188 return false;
189 }
190 WIFI_LOGE("IdleState-msgCode=%{public}d is received.\n", msg->GetMessageName());
191 if (pConcreteMangerMachine->HandleCommonMessage(msg)) {
192 return true;
193 }
194 switch (msg->GetMessageName()) {
195 case CONCRETE_CMD_START:
196 HandleStartInIdleState(msg);
197 break;
198 case CONCRETE_CMD_SWITCH_TO_CONNECT_MODE:
199 HandleSwitchToConnectMode(msg);
200 break;
201 case CONCRETE_CMD_SWITCH_TO_SCAN_ONLY_MODE:
202 HandleSwitchToScanOnlyMode(msg);
203 break;
204 case CONCRETE_CMD_SWITCH_TO_SEMI_ACTIVE_MODE:
205 HandleSwitchToSemiActiveMode(msg);
206 break;
207 default:
208 break;
209 }
210 return true;
211 }
212
HandleSwitchToConnectMode(InternalMessagePtr msg)213 void ConcreteMangerMachine::IdleState::HandleSwitchToConnectMode(InternalMessagePtr msg)
214 {
215 ErrCode ret = WifiServiceScheduler::GetInstance().AutoStartStaService(mid, ifaceName);
216 if (ret != WIFI_OPT_SUCCESS) {
217 WifiConfigCenter::GetInstance().SetWifiStopState(true);
218 pConcreteMangerMachine->mcb.onStartFailure(mid);
219 return;
220 }
221 pConcreteMangerMachine->SwitchState(pConcreteMangerMachine->pConnectState);
222 }
223
HandleSwitchToScanOnlyMode(InternalMessagePtr msg)224 void ConcreteMangerMachine::IdleState::HandleSwitchToScanOnlyMode(InternalMessagePtr msg)
225 {
226 ErrCode ret = WifiServiceScheduler::GetInstance().AutoStartScanOnly(mid, ifaceName);
227 if (ret != WIFI_OPT_SUCCESS) {
228 WifiConfigCenter::GetInstance().SetWifiStopState(true);
229 pConcreteMangerMachine->mcb.onStartFailure(mid);
230 return;
231 }
232 pConcreteMangerMachine->SwitchState(pConcreteMangerMachine->pScanonlyState);
233 }
234
HandleSwitchToSemiActiveMode(InternalMessagePtr msg)235 void ConcreteMangerMachine::IdleState::HandleSwitchToSemiActiveMode(InternalMessagePtr msg)
236 {
237 ErrCode ret = WifiServiceScheduler::GetInstance().AutoStartSemiStaService(mid, ifaceName);
238 if (ret != WIFI_OPT_SUCCESS) {
239 WifiConfigCenter::GetInstance().SetWifiStopState(true);
240 pConcreteMangerMachine->mcb.onStartFailure(mid);
241 return;
242 }
243 pConcreteMangerMachine->SwitchState(pConcreteMangerMachine->pSemiActiveState);
244 }
245
HandleStartInIdleState(InternalMessagePtr msg)246 void ConcreteMangerMachine::IdleState::HandleStartInIdleState(InternalMessagePtr msg)
247 {
248 mid = msg->GetParam1();
249 WIFI_LOGI("HandleStartInIdleState targetRole:%{public}d mid:%{public}d", mTargetRole, mid);
250 ErrCode res = WifiServiceScheduler::GetInstance().AutoStartScanOnly(mid, ifaceName);
251 if (res != WIFI_OPT_SUCCESS) {
252 WifiConfigCenter::GetInstance().SetWifiStopState(true);
253 pConcreteMangerMachine->mcb.onStartFailure(mid);
254 return;
255 }
256 if (mTargetRole == static_cast<int>(ConcreteManagerRole::ROLE_CLIENT_STA)) {
257 ErrCode ret = WifiServiceScheduler::GetInstance().AutoStartStaService(mid, ifaceName);
258 if (ret != WIFI_OPT_SUCCESS) {
259 WifiConfigCenter::GetInstance().SetWifiStopState(true);
260 pConcreteMangerMachine->mcb.onStartFailure(mid);
261 return;
262 }
263 pConcreteMangerMachine->SwitchState(pConcreteMangerMachine->pConnectState);
264 } else if (mTargetRole == static_cast<int>(ConcreteManagerRole::ROLE_CLIENT_SCAN_ONLY)) {
265 WIFI_LOGI("HandleStartInIdleState, current role is %{public}d, start scan only success.", mTargetRole);
266 pConcreteMangerMachine->SwitchState(pConcreteMangerMachine->pScanonlyState);
267 } else if (mTargetRole == static_cast<int>(ConcreteManagerRole::ROLE_CLIENT_MIX_SEMI_ACTIVE) ||
268 mTargetRole == static_cast<int>(ConcreteManagerRole::ROLE_CLIENT_STA_SEMI_ACTIVE)) {
269 ErrCode ret = WifiServiceScheduler::GetInstance().AutoStartSemiStaService(mid, ifaceName);
270 if (ret != WIFI_OPT_SUCCESS) {
271 WifiConfigCenter::GetInstance().SetWifiStopState(true);
272 pConcreteMangerMachine->mcb.onStartFailure(mid);
273 return;
274 }
275 pConcreteMangerMachine->SwitchState(pConcreteMangerMachine->pSemiActiveState);
276 } else {
277 WIFI_LOGE("idlestate start role is error");
278 }
279 }
280
ConnectState(ConcreteMangerMachine * concreteMangerMachine)281 ConcreteMangerMachine::ConnectState::ConnectState(ConcreteMangerMachine *concreteMangerMachine)
282 : State("ConnectState"), pConcreteMangerMachine(concreteMangerMachine)
283 {}
284
~ConnectState()285 ConcreteMangerMachine::ConnectState::~ConnectState()
286 {}
287
GoInState()288 void ConcreteMangerMachine::ConnectState::GoInState()
289 {
290 WIFI_LOGE("ConnectState GoInState function.\n");
291 }
292
GoOutState()293 void ConcreteMangerMachine::ConnectState::GoOutState()
294 {
295 WIFI_LOGE("ConnectState GoOutState function.\n");
296 }
297
ExecuteStateMsg(InternalMessagePtr msg)298 bool ConcreteMangerMachine::ConnectState::ExecuteStateMsg(InternalMessagePtr msg)
299 {
300 if (msg == nullptr) {
301 return false;
302 }
303 WIFI_LOGE("ConnectState-msgCode=%{public}d is received.\n", msg->GetMessageName());
304 if (pConcreteMangerMachine->HandleCommonMessage(msg)) {
305 return true;
306 }
307 switch (msg->GetMessageName()) {
308 case CONCRETE_CMD_SWITCH_TO_SCAN_ONLY_MODE:
309 SwitchScanOnlyInConnectState();
310 break;
311 case CONCRETE_CMD_SWITCH_TO_SEMI_ACTIVE_MODE:
312 SwitchSemiActiveInConnectState();
313 break;
314 default:
315 break;
316 }
317 return true;
318 }
319
SwitchScanOnlyInConnectState()320 void ConcreteMangerMachine::ConnectState::SwitchScanOnlyInConnectState()
321 {
322 ErrCode ret = WifiServiceScheduler::GetInstance().AutoStopStaService(mid);
323 if (ret != WIFI_OPT_SUCCESS) {
324 WIFI_LOGE("stop sta failed ret =%{public}d \n", ret);
325 }
326 }
327
SwitchSemiActiveInConnectState()328 void ConcreteMangerMachine::ConnectState::SwitchSemiActiveInConnectState()
329 {
330 ErrCode ret = pConcreteMangerMachine->SwitchSemiFromEnable();
331 if (ret != WIFI_OPT_SUCCESS) {
332 WIFI_LOGE("switch semi wifi failed ret = %{public}d \n", ret);
333 }
334 }
335
ScanonlyState(ConcreteMangerMachine * concreteMangerMachine)336 ConcreteMangerMachine::ScanonlyState::ScanonlyState(ConcreteMangerMachine *concreteMangerMachine)
337 : State("ScanonlyState"), pConcreteMangerMachine(concreteMangerMachine)
338 {}
339
~ScanonlyState()340 ConcreteMangerMachine::ScanonlyState::~ScanonlyState()
341 {}
342
GoInState()343 void ConcreteMangerMachine::ScanonlyState::GoInState()
344 {
345 WIFI_LOGE("ScanonlyState GoInState function.\n");
346 }
347
GoOutState()348 void ConcreteMangerMachine::ScanonlyState::GoOutState()
349 {
350 WIFI_LOGE("ScanonlyState GoOutState function.\n");
351 }
352
ExecuteStateMsg(InternalMessagePtr msg)353 bool ConcreteMangerMachine::ScanonlyState::ExecuteStateMsg(InternalMessagePtr msg)
354 {
355 if (msg == nullptr) {
356 return false;
357 }
358 WIFI_LOGE("ScanonlyState-msgCode=%{public}d is received.\n", msg->GetMessageName());
359 if (pConcreteMangerMachine->HandleCommonMessage(msg)) {
360 return true;
361 }
362 switch (msg->GetMessageName()) {
363 case CONCRETE_CMD_SWITCH_TO_CONNECT_MODE:
364 SwitchConnectInScanOnlyState();
365 break;
366 case CONCRETE_CMD_SWITCH_TO_SEMI_ACTIVE_MODE:
367 SwitchSemiActiveInScanOnlyState();
368 break;
369 default:
370 break;
371 }
372 return true;
373 }
374
SwitchConnectInScanOnlyState()375 void ConcreteMangerMachine::ScanonlyState::SwitchConnectInScanOnlyState()
376 {
377 ErrCode ret = WifiServiceScheduler::GetInstance().AutoStartStaService(mid, ifaceName);
378 if (ret != WIFI_OPT_SUCCESS) {
379 pConcreteMangerMachine->mcb.onStartFailure(mid);
380 return;
381 }
382 pConcreteMangerMachine->SwitchState(pConcreteMangerMachine->pConnectState);
383 }
384
SwitchSemiActiveInScanOnlyState()385 void ConcreteMangerMachine::ScanonlyState::SwitchSemiActiveInScanOnlyState()
386 {
387 ErrCode ret = WifiServiceScheduler::GetInstance().AutoStartSemiStaService(mid, ifaceName);
388 if (ret != WIFI_OPT_SUCCESS) {
389 pConcreteMangerMachine->mcb.onStartFailure(mid);
390 return;
391 }
392 pConcreteMangerMachine->SwitchState(pConcreteMangerMachine->pSemiActiveState);
393 }
394
SemiActiveState(ConcreteMangerMachine * concreteMangerMachine)395 ConcreteMangerMachine::SemiActiveState::SemiActiveState(ConcreteMangerMachine *concreteMangerMachine)
396 : State("SemiActiveState"), pConcreteMangerMachine(concreteMangerMachine)
397 {}
398
~SemiActiveState()399 ConcreteMangerMachine::SemiActiveState::~SemiActiveState()
400 {}
401
GoInState()402 void ConcreteMangerMachine::SemiActiveState::GoInState()
403 {
404 WIFI_LOGI("SemiActiveState GoInState function.\n");
405 }
406
GoOutState()407 void ConcreteMangerMachine::SemiActiveState::GoOutState()
408 {
409 WIFI_LOGI("SemiActiveState GoOutState function.\n");
410 }
411
ExecuteStateMsg(InternalMessagePtr msg)412 bool ConcreteMangerMachine::SemiActiveState::ExecuteStateMsg(InternalMessagePtr msg)
413 {
414 if (msg == nullptr) {
415 return false;
416 }
417 WIFI_LOGI("SemiActiveState-msgCode=%{public}d is received.\n", msg->GetMessageName());
418 if (pConcreteMangerMachine->HandleCommonMessage(msg)) {
419 return true;
420 }
421 switch (msg->GetMessageName()) {
422 case CONCRETE_CMD_SWITCH_TO_CONNECT_MODE:
423 SwitchConnectInSemiActiveState();
424 break;
425 case CONCRETE_CMD_SWITCH_TO_SCAN_ONLY_MODE:
426 SwitchScanOnlyInSemiActiveState();
427 break;
428 case CONCRETE_CMD_SWITCH_TO_SEMI_ACTIVE_MODE:
429 if (pConcreteMangerMachine->mTargetRole ==
430 static_cast<int>(ConcreteManagerRole::ROLE_CLIENT_STA_SEMI_ACTIVE)) {
431 WIFI_LOGI("switch ROLE_CLIENT_STA_SEMI_ACTIVE");
432 WifiManager::GetInstance().GetWifiScanManager()->CheckAndStopScanService(mid);
433 } else {
434 WIFI_LOGI("switch ROLE_CLIENT_MIX_SEMI_ACTIVE");
435 WifiServiceScheduler::GetInstance().AutoStartScanOnly(mid, ifaceName);
436 }
437 WifiManager::GetInstance().GetWifiTogglerManager()->StopSemiWifiToggledTimer();
438 break;
439 default:
440 break;
441 }
442 return true;
443 }
444
SwitchConnectInSemiActiveState()445 void ConcreteMangerMachine::SemiActiveState::SwitchConnectInSemiActiveState()
446 {
447 WifiServiceScheduler::GetInstance().AutoStartScanOnly(mid, ifaceName);
448 ErrCode ret = pConcreteMangerMachine->SwitchEnableFromSemi();
449 if (ret != WIFI_OPT_SUCCESS) {
450 WIFI_LOGE("SemiActiveState SwitchEnableFromSemi failed");
451 pConcreteMangerMachine->mcb.onStartFailure(mid);
452 return;
453 }
454 pConcreteMangerMachine->SwitchState(pConcreteMangerMachine->pConnectState);
455 }
456
SwitchScanOnlyInSemiActiveState()457 void ConcreteMangerMachine::SemiActiveState::SwitchScanOnlyInSemiActiveState()
458 {
459 WIFI_LOGI("SwitchScanOnlyInSemiActiveState");
460 ErrCode ret = WifiServiceScheduler::GetInstance().AutoStopStaService(mid);
461 if (ret != WIFI_OPT_SUCCESS) {
462 WIFI_LOGE("Stop sta failed ret = %{public}d", ret);
463 }
464 }
465
HandleCommonMessage(InternalMessagePtr msg)466 bool ConcreteMangerMachine::HandleCommonMessage(InternalMessagePtr msg)
467 {
468 switch (msg->GetMessageName()) {
469 case CONCRETE_CMD_STA_STOP:
470 HandleStaStop();
471 return true;
472 case CONCRETE_CMD_STA_START:
473 HandleStaStart();
474 return true;
475 case CONCRETE_CMD_STOP:
476 DelayMessage(msg);
477 SwitchState(pDefaultState);
478 return true;
479 case CONCRETE_CMD_STA_SEMI_ACTIVE:
480 HandleStaSemiActive();
481 return true;
482 case CONCRETE_CMD_STA_REMOVED:
483 ClearIfaceName();
484 return true;
485 default:
486 return false;
487 }
488 }
489
HandleStaStop()490 void ConcreteMangerMachine::HandleStaStop()
491 {
492 if (WifiConfigCenter::GetInstance().GetWifiStopState()) {
493 WIFI_LOGE("Sta stoped remove manager.");
494 ErrCode ret = WifiServiceScheduler::GetInstance().AutoStopScanOnly(mid, true);
495 if (ret != WIFI_OPT_SUCCESS) {
496 WIFI_LOGE("Stop scanonly failed ret = %{public}d", ret);
497 }
498 return ReportClose();
499 }
500 if (mTargetRole == static_cast<int>(ConcreteManagerRole::ROLE_CLIENT_SCAN_ONLY)) {
501 #ifdef HDI_CHIP_INTERFACE_SUPPORT
502 DelayedSingleton<HalDeviceManager>::GetInstance()->SetNetworkUpDown(
503 WifiConfigCenter::GetInstance().GetStaIfaceName(), true);
504 #endif
505 SwitchState(pScanonlyState);
506 } else if (mTargetRole == static_cast<int>(ConcreteManagerRole::ROLE_CLIENT_STA)) {
507 ErrCode ret = WifiServiceScheduler::GetInstance().AutoStartStaService(mid, ifaceName);
508 if (ret != WIFI_OPT_SUCCESS) {
509 mcb.onStartFailure(mid);
510 return;
511 }
512 SwitchState(pConnectState);
513 } else if (mTargetRole == static_cast<int>(ConcreteManagerRole::ROLE_CLIENT_MIX_SEMI_ACTIVE) ||
514 mTargetRole == static_cast<int>(ConcreteManagerRole::ROLE_CLIENT_STA_SEMI_ACTIVE)) {
515 ErrCode ret = WifiServiceScheduler::GetInstance().AutoStartSemiStaService(mid, ifaceName);
516 if (ret != WIFI_OPT_SUCCESS) {
517 mcb.onStartFailure(mid);
518 return;
519 }
520 SwitchState(pSemiActiveState);
521 } else {
522 WIFI_LOGE("Now targetrole is unknow, stop concrete.");
523 ErrCode ret = WifiServiceScheduler::GetInstance().AutoStopScanOnly(mid, true);
524 if (ret != WIFI_OPT_SUCCESS) {
525 WIFI_LOGE("Stop scanonly failed ret = %{public}d", ret);
526 }
527 return ReportClose();
528 }
529 }
530
ReportClose()531 void ConcreteMangerMachine::ReportClose()
532 {
533 #ifdef HDI_CHIP_INTERFACE_SUPPORT
534 if (!ifaceName.empty()) {
535 mcb.onStopped(mid);
536 } else {
537 mcb.onRemoved(mid);
538 }
539 #else
540 mcb.onStopped(mid);
541 #endif
542 }
543
HandleStaStart()544 void ConcreteMangerMachine::HandleStaStart()
545 {
546 ErrCode ret;
547
548 if (mTargetRole == static_cast<int>(ConcreteManagerRole::ROLE_CLIENT_SCAN_ONLY)) {
549 ret = WifiServiceScheduler::GetInstance().AutoStopStaService(mid);
550 if (ret != WIFI_OPT_SUCCESS) {
551 WIFI_LOGE("Stop sta failed ret = %{public}d", ret);
552 }
553 } else if (mTargetRole == static_cast<int>(ConcreteManagerRole::ROLE_CLIENT_STA)) {
554 SwitchState(pConnectState);
555 } else if (mTargetRole == static_cast<int>(ConcreteManagerRole::ROLE_CLIENT_MIX_SEMI_ACTIVE) ||
556 mTargetRole == static_cast<int>(ConcreteManagerRole::ROLE_CLIENT_STA_SEMI_ACTIVE)) {
557 ret = SwitchSemiFromEnable();
558 if (ret != WIFI_OPT_SUCCESS) {
559 WIFI_LOGE("switch semi wifi failed ret = %{public}d", ret);
560 }
561 } else {
562 WIFI_LOGE("Now targetrole is unknow.");
563 ret = WifiServiceScheduler::GetInstance().AutoStopStaService(mid);
564 if (ret != WIFI_OPT_SUCCESS) {
565 WIFI_LOGE("Stop sta failed ret = %{public}d", ret);
566 }
567 }
568 }
569
HandleStaSemiActive()570 void ConcreteMangerMachine::HandleStaSemiActive()
571 {
572 ErrCode ret;
573
574 if (mTargetRole == static_cast<int>(ConcreteManagerRole::ROLE_CLIENT_STA)) {
575 ret = SwitchEnableFromSemi();
576 if (ret != WIFI_OPT_SUCCESS) {
577 WIFI_LOGE("switch enable failed ret = %{public}d", ret);
578 mcb.onStartFailure(mid);
579 return;
580 }
581 WifiServiceScheduler::GetInstance().AutoStartScanOnly(mid, ifaceName);
582 } else if (mTargetRole == static_cast<int>(ConcreteManagerRole::ROLE_CLIENT_SCAN_ONLY)) {
583 ret = WifiServiceScheduler::GetInstance().AutoStopStaService(mid);
584 if (ret != WIFI_OPT_SUCCESS) {
585 WIFI_LOGE("Stop sta failed ret = %{public}d", ret);
586 }
587 } else if (mTargetRole == static_cast<int>(ConcreteManagerRole::ROLE_CLIENT_MIX_SEMI_ACTIVE)) {
588 WifiManager::GetInstance().GetWifiScanManager()->CheckAndStartScanService(mid);
589 SwitchState(pSemiActiveState);
590 } else if (mTargetRole == static_cast<int>(ConcreteManagerRole::ROLE_CLIENT_STA_SEMI_ACTIVE)) {
591 WifiManager::GetInstance().GetWifiScanManager()->CheckAndStopScanService(mid);
592 SwitchState(pSemiActiveState);
593 } else {
594 WIFI_LOGE("Now targetrole is unknow.");
595 ret = WifiServiceScheduler::GetInstance().AutoStopStaService(mid);
596 if (ret != WIFI_OPT_SUCCESS) {
597 WIFI_LOGE("Stop sta failed ret = %{public}d", ret);
598 }
599 }
600 }
601
SwitchSemiFromEnable()602 ErrCode ConcreteMangerMachine::SwitchSemiFromEnable()
603 {
604 auto detailState = WifiConfigCenter::GetInstance().GetWifiDetailState(mid);
605 WIFI_LOGI("SwitchSemiFromEnable: current sta detailState:%{public}d", detailState);
606 if (detailState == WifiDetailState::STATE_SEMI_ACTIVE || detailState == WifiDetailState::STATE_SEMI_ACTIVATING) {
607 return WIFI_OPT_SUCCESS;
608 }
609 IStaService *pService = WifiServiceManager::GetInstance().GetStaServiceInst(mid);
610 if (pService == nullptr) {
611 WIFI_LOGE("SwitchSemiFromEnable, Instance get sta service is null!");
612 WifiConfigCenter::GetInstance().SetWifiMidState(WifiOprMidState::CLOSED, mid);
613 WifiServiceManager::GetInstance().UnloadService(WIFI_SERVICE_STA, mid);
614 #ifdef FEATURE_WIFI_PRO_SUPPORT
615 WifiServiceManager::GetInstance().UnloadService(WIFI_SERVICE_WIFIPRO, mid);
616 #endif
617 #ifdef FEATURE_SELF_CURE_SUPPORT
618 WifiServiceManager::GetInstance().UnloadService(WIFI_SERVICE_SELFCURE, mid);
619 #endif
620 return WIFI_OPT_FAILED;
621 }
622 WifiServiceScheduler::GetInstance().DispatchWifiSemiActiveRes(OperateResState::ENABLE_SEMI_WIFI_OPENING, mid);
623 ErrCode ret = pService->DisableStaService();
624 if (ret != static_cast<int>(WIFI_OPT_SUCCESS)) {
625 WIFI_LOGE("DisableStaService failed!");
626 return WIFI_OPT_FAILED;
627 }
628 WifiServiceScheduler::GetInstance().DispatchWifiSemiActiveRes(OperateResState::ENABLE_SEMI_WIFI_SUCCEED, mid);
629 auto &ins = WifiManager::GetInstance().GetWifiTogglerManager()->GetControllerMachine();
630 ins->HandleStaSemiActive(mid);
631 return WIFI_OPT_SUCCESS;
632 }
633
SwitchEnableFromSemi()634 ErrCode ConcreteMangerMachine::SwitchEnableFromSemi()
635 {
636 auto detailState = WifiConfigCenter::GetInstance().GetWifiDetailState(mid);
637 WIFI_LOGI("SwitchEnableFromSemi, current sta detailState:%{public}d", detailState);
638 if (detailState == WifiDetailState::STATE_ACTIVATED) {
639 auto &ins = WifiManager::GetInstance().GetWifiTogglerManager()->GetControllerMachine();
640 ins->HandleStaStart(mid);
641 return WIFI_OPT_SUCCESS;
642 }
643 WifiOprMidState staState = WifiConfigCenter::GetInstance().GetWifiMidState(mid);
644 if (!WifiConfigCenter::GetInstance().SetWifiMidState(staState, WifiOprMidState::OPENING, mid)) {
645 WIFI_LOGE("SwitchEnableFromSemi, set wifi mid state opening failed!");
646 return WIFI_OPT_FAILED;
647 }
648 ErrCode errCode = WIFI_OPT_FAILED;
649 IStaService *pService = WifiServiceManager::GetInstance().GetStaServiceInst(mid);
650 if (pService == nullptr) {
651 WIFI_LOGE("Get %{public}s service failed!", WIFI_SERVICE_STA);
652 return WIFI_OPT_FAILED;
653 }
654 WifiServiceScheduler::GetInstance().DispatchWifiOpenRes(OperateResState::OPEN_WIFI_OPENING, mid);
655 errCode = pService->EnableStaService();
656 if (errCode != WIFI_OPT_SUCCESS) {
657 WIFI_LOGE("Service enable sta failed ,ret %{public}d!", static_cast<int>(errCode));
658 return WIFI_OPT_FAILED;
659 }
660 WifiServiceScheduler::GetInstance().DispatchWifiOpenRes(OperateResState::OPEN_WIFI_SUCCEED, mid);
661 WifiManager::GetInstance().PushServiceCloseMsg(WifiCloseServiceCode::STA_MSG_OPENED, mid);
662 auto &ins = WifiManager::GetInstance().GetWifiTogglerManager()->GetControllerMachine();
663 ins->HandleStaStart(mid);
664 return WIFI_OPT_SUCCESS;
665 }
666
CheckAndContinueToStopWifi(InternalMessagePtr msg)667 void ConcreteMangerMachine::CheckAndContinueToStopWifi(InternalMessagePtr msg)
668 {
669 if (WifiConfigCenter::GetInstance().GetWifiStopState()) {
670 WIFI_LOGE("CheckAndContinueToStopWifi: wifi is stoping");
671 return;
672 }
673
674 mTargetRole = static_cast<int>(ConcreteManagerRole::ROLE_UNKNOW);
675 WifiOprMidState staState = WifiConfigCenter::GetInstance().GetWifiMidState(mid);
676 auto detailState = WifiConfigCenter::GetInstance().GetWifiDetailState(mid);
677 WIFI_LOGI("CheckAndContinueToStopWifi: current sta state: %{public}d detailState:%{public}d", staState,
678 detailState);
679 if (detailState != WifiDetailState::STATE_SEMI_ACTIVE && detailState != WifiDetailState::STATE_SEMI_ACTIVATING &&
680 (staState == WifiOprMidState::CLOSING || staState == WifiOprMidState::OPENING)) {
681 return;
682 }
683
684 WifiConfigCenter::GetInstance().SetWifiStopState(true);
685 WIFI_LOGI("Set WifiStopState is true.");
686 if (staState == WifiOprMidState::RUNNING || detailState == WifiDetailState::STATE_SEMI_ACTIVE ||
687 detailState == WifiDetailState::STATE_SEMI_ACTIVATING) {
688 ErrCode ret = WifiServiceScheduler::GetInstance().AutoStopStaService(mid);
689 if (ret != WIFI_OPT_SUCCESS) {
690 WIFI_LOGE("stop sta failed in timer ret = %{public}d", ret);
691 WifiConfigCenter::GetInstance().SetWifiStopState(false);
692 auto &ins = WifiManager::GetInstance().GetWifiTogglerManager()->GetControllerMachine();
693 ins->HandleStaClose(mid);
694 }
695 } else {
696 auto &ins = WifiManager::GetInstance().GetWifiTogglerManager()->GetControllerMachine();
697 ins->HandleStaClose(mid);
698 }
699 }
700
ClearIfaceName()701 void ConcreteMangerMachine::ClearIfaceName()
702 {
703 ifaceName.clear();
704 }
705 } // namespace Wifi
706 } // namespace OHOS
707