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 "wifi_controller_state_machine.h"
17 #include "wifi_controller_define.h"
18 #include "wifi_manager.h"
19 #include "wifi_config_center.h"
20 #include "wifi_msg.h"
21 #include "wifi_system_timer.h"
22 #include "wifi_hisysevent.h"
23 #ifdef HAS_BATTERY_MANAGER_PART
24 #include "battery_srv_client.h"
25 #endif
26 #ifdef HDI_CHIP_INTERFACE_SUPPORT
27 #include "hal_device_manage.h"
28 #endif
29 #ifndef OHOS_ARCH_LITE
30 #include "wifi_internal_event_dispatcher.h"
31 #else
32 #include "wifi_internal_event_dispatcher_lite.h"
33 #endif
34 
35 namespace OHOS {
36 namespace Wifi {
37 DEFINE_WIFILOG_LABEL("WifiControllerMachine");
38 int WifiControllerMachine::mWifiStartFailCount{0};
39 
WifiControllerMachine()40 WifiControllerMachine::WifiControllerMachine()
41     : StateMachine("WifiControllerMachine"),
42 #ifndef HDI_CHIP_INTERFACE_SUPPORT
43       mApidStopWifi(0),
44 #endif
45       pEnableState(nullptr),
46       pDisableState(nullptr),
47       pDefaultState(nullptr)
48 {}
49 
~WifiControllerMachine()50 WifiControllerMachine::~WifiControllerMachine()
51 {
52     WIFI_LOGI("WifiControllerMachine::~WifiControllerMachine");
53     StopHandlerThread();
54     ParsePointer(pEnableState);
55     ParsePointer(pDisableState);
56     ParsePointer(pDefaultState);
57 }
58 
59 /* --------------------------Initialization functions--------------------------*/
InitWifiControllerMachine()60 ErrCode WifiControllerMachine::InitWifiControllerMachine()
61 {
62     WIFI_LOGI("Enter WifiControllerMachine::InitWifiControllerMachine.\n");
63     if (!InitialStateMachine("WifiControllerMachine")) {
64         WIFI_LOGE("Initial StateMachine failed.\n");
65         return WIFI_OPT_FAILED;
66     }
67 
68     if (InitWifiStates() == WIFI_OPT_FAILED) {
69         return WIFI_OPT_FAILED;
70     }
71     BuildStateTree();
72     SetFirstState(pDisableState);
73     StartStateMachine();
74     return WIFI_OPT_SUCCESS;
75 }
76 
BuildStateTree()77 void WifiControllerMachine::BuildStateTree()
78 {
79     StatePlus(pDefaultState, nullptr);
80     StatePlus(pEnableState, pDefaultState);
81     StatePlus(pDisableState, pDefaultState);
82 }
83 
InitWifiStates()84 ErrCode WifiControllerMachine::InitWifiStates()
85 {
86     int tmpErrNumber;
87 
88     WIFI_LOGE("Enter InitWifiStates.\n");
89     pDefaultState = new (std::nothrow) DefaultState(this);
90     tmpErrNumber = JudgmentEmpty(pDefaultState);
91     pEnableState = new (std::nothrow) EnableState(this);
92     tmpErrNumber += JudgmentEmpty(pEnableState);
93     pDisableState = new (std::nothrow) DisableState(this);
94     tmpErrNumber += JudgmentEmpty(pDisableState);
95     if (tmpErrNumber != 0) {
96         WIFI_LOGE("InitWifiStates some one state is null\n");
97         return WIFI_OPT_FAILED;
98     }
99     return WIFI_OPT_SUCCESS;
100 }
101 
DisableState(WifiControllerMachine * wifiControllerMachine)102 WifiControllerMachine::DisableState::DisableState(WifiControllerMachine *wifiControllerMachine)
103     : State("DisableState"), pWifiControllerMachine(wifiControllerMachine)
104 {}
105 
~DisableState()106 WifiControllerMachine::DisableState::~DisableState()
107 {}
108 
GoInState()109 void WifiControllerMachine::DisableState::GoInState()
110 {
111     WIFI_LOGE("DisableState GoInState function.");
112 }
113 
GoOutState()114 void WifiControllerMachine::DisableState::GoOutState()
115 {
116     WIFI_LOGE("DisableState GoOutState function.");
117 }
118 
ExecuteStateMsg(InternalMessagePtr msg)119 bool WifiControllerMachine::DisableState::ExecuteStateMsg(InternalMessagePtr msg)
120 {
121     if (msg == nullptr) {
122         return false;
123     }
124     WIFI_LOGE("DisableState-msgCode=%{public}d is received.\n", msg->GetMessageName());
125     switch (msg->GetMessageName()) {
126 #ifdef FEATURE_AP_SUPPORT
127         case CMD_SOFTAP_TOGGLED:
128             if (msg->GetParam1()) {
129                 int id = msg->GetParam2();
130                 pWifiControllerMachine->MakeSoftapManager(SoftApManager::Role::ROLE_SOFTAP, id);
131                 pWifiControllerMachine->StartTimer(CMD_AP_START_TIME, SOFT_AP_TIME_OUT);
132                 pWifiControllerMachine->SwitchState(pWifiControllerMachine->pEnableState);
133             }
134             break;
135 #endif
136         case CMD_WIFI_TOGGLED:
137         case CMD_SCAN_ALWAYS_MODE_CHANGED:
138             if (!pWifiControllerMachine->ShouldEnableWifi(msg->GetParam2())) {
139                 WIFI_LOGW("keep disable, shouldn't enabled wifi.");
140                 break;
141             }
142             if (msg->GetParam2() == INSTID_WLAN1) {
143                 pWifiControllerMachine->MakeMultiStaManager(MultiStaManager::Role::ROLE_STA_WIFI_2, msg->GetParam2());
144                 pWifiControllerMachine->SwitchState(pWifiControllerMachine->pEnableState);
145             } else if (msg->GetParam2() == INSTID_WLAN0) {
146                 ConcreteManagerRole roleStaWifi1 = pWifiControllerMachine->GetWifiRole();
147                 if (roleStaWifi1 == ConcreteManagerRole::ROLE_UNKNOW) {
148                     WIFI_LOGE("Get unknow wifi role, break");
149                     break;
150                 }
151                 pWifiControllerMachine->MakeConcreteManager(roleStaWifi1, msg->GetParam2());
152                 pWifiControllerMachine->SwitchState(pWifiControllerMachine->pEnableState);
153             }
154             break;
155         case CMD_AIRPLANE_TOGGLED:
156             if (msg->GetParam1()) {
157                 pWifiControllerMachine->HandleAirplaneOpen();
158             } else {
159                 pWifiControllerMachine->HandleAirplaneClose();
160             }
161             break;
162         default:
163             return false;
164     }
165     return true;
166 }
167 
EnableState(WifiControllerMachine * wifiControllerMachine)168 WifiControllerMachine::EnableState::EnableState(WifiControllerMachine *wifiControllerMachine)
169     : State("EnableState"), pWifiControllerMachine(wifiControllerMachine)
170 {}
171 
~EnableState()172 WifiControllerMachine::EnableState::~EnableState()
173 {}
174 
GoInState()175 void WifiControllerMachine::EnableState::GoInState()
176 {
177     WIFI_LOGE("EnableState GoInState function.");
178 }
179 
GoOutState()180 void WifiControllerMachine::EnableState::GoOutState()
181 {
182     WIFI_LOGE("EnableState GoOutState function.");
183 }
184 
ExecuteStateMsg(InternalMessagePtr msg)185 bool WifiControllerMachine::EnableState::ExecuteStateMsg(InternalMessagePtr msg)
186 {
187     if (msg == nullptr) {
188         return false;
189     }
190     WIFI_LOGE("EnableState-msgCode=%{public}d is received.\n", msg->GetMessageName());
191 #ifdef FEATURE_AP_SUPPORT
192     HandleApMsg(msg);
193 #endif
194     switch (msg->GetMessageName()) {
195         case CMD_WIFI_TOGGLED:
196         case CMD_SCAN_ALWAYS_MODE_CHANGED:
197             pWifiControllerMachine->StopTimer(CMD_OPEN_WIFI_RETRY);
198             HandleWifiToggleChangeInEnabledState(msg);
199             break;
200         case CMD_STA_START_FAILURE:
201             msg->GetParam1() == INSTID_WLAN0 ?
202                 HandleStaStartFailure(INSTID_WLAN0) : pWifiControllerMachine->RemoveMultiStaManager(INSTID_WLAN1);
203             break;
204         case CMD_CONCRETE_STOPPED:
205             pWifiControllerMachine->HandleConcreteStop(INSTID_WLAN0);
206             break;
207         case CMD_MULTI_STA_STOPPED:
208             pWifiControllerMachine->RemoveMultiStaManager(INSTID_WLAN1);
209             break;
210         case CMD_AIRPLANE_TOGGLED:
211             if (msg->GetParam1()) {
212                 pWifiControllerMachine->HandleAirplaneOpen();
213             } else {
214                 pWifiControllerMachine->HandleAirplaneClose();
215             }
216             break;
217         case CMD_OPEN_WIFI_RETRY:
218             pWifiControllerMachine->SendMessage(CMD_WIFI_TOGGLED, 1, 0);
219             break;
220         case CMD_STA_REMOVED:
221             INSTID_WLAN0 == msg->GetParam2() ? HandleStaRemoved(msg) : HandleWifi2Removed(msg);
222             break;
223         case CMD_CONCRETECLIENT_REMOVED:
224             HandleConcreteClientRemoved(msg);
225             break;
226         case CMD_AP_REMOVED:
227 #ifdef FEATURE_AP_SUPPORT
228             HandleApRemoved(msg);
229 #endif
230             break;
231         default:
232             return false;
233     }
234     return true;
235 }
236 
237 #ifdef FEATURE_AP_SUPPORT
HandleApMsg(InternalMessagePtr msg)238 bool WifiControllerMachine::EnableState::HandleApMsg(InternalMessagePtr msg)
239 {
240     switch (msg->GetMessageName()) {
241         case CMD_SOFTAP_TOGGLED:
242             HandleSoftapToggleChangeInEnabledState(msg);
243             break;
244         case CMD_AP_STOPPED:
245             HandleApStop(msg);
246             break;
247         case CMD_AP_START_FAILURE:
248             HandleAPServiceStartFail(msg->GetParam1());
249             HandleApStop(msg);
250             break;
251         case CMD_AP_START:
252             pWifiControllerMachine->StopTimer(CMD_AP_START_TIME);
253             HandleApStart(msg->GetParam1());
254             break;
255         case CMD_AP_START_TIME:
256             WriteSoftApOpenAndCloseFailedEvent(static_cast<int>(SoftApperateType::OPEN_SOFT_AP_FAILED), "TIME_OUT");
257             break;
258         case CMD_AP_STOP_TIME:
259             WriteSoftApOpenAndCloseFailedEvent(static_cast<int>(SoftApperateType::CLOSE_SOFT_AP_FAILED), "TIME_OUT");
260             break;
261         default:
262             return false;
263     }
264     return true;
265 }
266 #endif
267 
DefaultState(WifiControllerMachine * wifiControllerMachine)268 WifiControllerMachine::DefaultState::DefaultState(WifiControllerMachine *wifiControllerMachine)
269     : State("DefaultState"), pWifiControllerMachine(wifiControllerMachine)
270 {}
271 
~DefaultState()272 WifiControllerMachine::DefaultState::~DefaultState()
273 {}
274 
GoInState()275 void WifiControllerMachine::DefaultState::GoInState()
276 {
277     WIFI_LOGE("DefaultState GoInState function.");
278 }
279 
GoOutState()280 void WifiControllerMachine::DefaultState::GoOutState()
281 {
282     WIFI_LOGE("DefaultState GoOutState function.");
283 }
284 
ExecuteStateMsg(InternalMessagePtr msg)285 bool WifiControllerMachine::DefaultState::ExecuteStateMsg(InternalMessagePtr msg)
286 {
287     if (msg == nullptr || pWifiControllerMachine == nullptr) {
288         return false;
289     }
290     WIFI_LOGE("DefaultState-msgCode=%{public}d is received.\n", msg->GetMessageName());
291     switch (msg->GetMessageName()) {
292         case CMD_WIFI_TOGGLED_TIMEOUT:
293             WifiManager::GetInstance().GetWifiTogglerManager()->OnWifiToggledTimeOut();
294             break;
295         case CMD_SEMI_WIFI_TOGGLED_TIMEOUT:
296             WifiManager::GetInstance().GetWifiTogglerManager()->OnSemiWifiToggledTimeOut();
297             break;
298         default:
299             return false;
300     }
301     return true;
302 }
303 
HandleAirplaneOpen()304 void WifiControllerMachine::HandleAirplaneOpen()
305 {
306     WIFI_LOGI("airplane open set softap false");
307     this->StopTimer(CMD_WIFI_TOGGLED_TIMEOUT);
308     this->StopTimer(CMD_SEMI_WIFI_TOGGLED_TIMEOUT);
309 #ifdef FEATURE_AP_SUPPORT
310     WifiConfigCenter::GetInstance().SetSoftapToggledState(false);
311     StopAllSoftapManagers();
312 #endif
313     if (!WifiSettings::GetInstance().GetWifiFlagOnAirplaneMode() || !ShouldEnableWifi(INSTID_WLAN0)) {
314         StopAllMultiStaManagers();
315         StopAllConcreteManagers();
316     }
317 }
318 
HandleAirplaneClose()319 void WifiControllerMachine::HandleAirplaneClose()
320 {
321     WIFI_LOGI("HandleAirplaneClose in");
322 #ifndef OHOS_ARCH_LITE
323     WifiManager::GetInstance().GetWifiEventSubscriberManager()->GetWifiAllowSemiActiveByDatashare();
324 #endif
325     if (!ShouldEnableWifi(INSTID_WLAN0) || WifiConfigCenter::GetInstance().GetWifiStopState()) {
326         return;
327     }
328 #ifdef FEATURE_AP_SUPPORT
329 #ifndef HDI_CHIP_INTERFACE_SUPPORT
330     if (!WifiConfigCenter::GetInstance().GetCoexSupport() && HasAnySoftApManager()) {
331         WIFI_LOGE("HandleAirplaneClose, has softap in runing return.");
332         return;
333     }
334 #endif
335 #endif
336     ConcreteManagerRole role = GetWifiRole();
337     if (role == ConcreteManagerRole::ROLE_UNKNOW) {
338         WIFI_LOGE("Get unknow wifi role in HandleAirplaneClose.");
339         return;
340     }
341     if (role == ConcreteManagerRole::ROLE_CLIENT_MIX_SEMI_ACTIVE ||
342         role == ConcreteManagerRole::ROLE_CLIENT_STA_SEMI_ACTIVE) {
343         WifiManager::GetInstance().GetWifiTogglerManager()->StartSemiWifiToggledTimer();
344     }
345     if (!HasAnyConcreteManager()) {
346         MakeConcreteManager(role, 0);
347         SwitchState(pEnableState);
348     } else {
349         SwitchRole(role);
350     }
351 }
352 
353 #ifdef FEATURE_AP_SUPPORT
SoftApIdExist(int id)354 bool WifiControllerMachine::SoftApIdExist(int id)
355 {
356     if (!HasAnySoftApManager()) {
357         return false;
358     }
359     std::unique_lock<std::mutex> lock(softapManagerMutex);
360     for (auto iter = softapManagers.begin(); iter != softapManagers.end(); ++iter) {
361         if ((*iter)->mid == id) {
362             WIFI_LOGI("Softap id %{public}d exist.", id);
363             return true;
364         }
365     }
366     return false;
367 }
368 
GetSoftApManager(int id)369 SoftApManager *WifiControllerMachine::GetSoftApManager(int id)
370 {
371     if (!HasAnySoftApManager()) {
372         return nullptr;
373     }
374 
375     std::unique_lock<std::mutex> lock(softapManagerMutex);
376     for (auto iter = softapManagers.begin(); iter != softapManagers.end(); ++iter) {
377         if ((*iter)->mid == id) {
378             WIFI_LOGI("Get softap manager id %{public}d.", id);
379             return *iter;
380         }
381     }
382     return nullptr;
383 }
384 #endif
385 
ConcreteIdExist(int id)386 bool WifiControllerMachine::ConcreteIdExist(int id)
387 {
388     if (!HasAnyConcreteManager()) {
389         return false;
390     }
391     std::unique_lock<std::mutex> lock(concreteManagerMutex);
392     for (auto iter = concreteManagers.begin(); iter != concreteManagers.end(); ++iter) {
393         if ((*iter)->mid == id) {
394             WIFI_LOGI("concreteManagers is match");
395             return true;
396         }
397     }
398     return false;
399 }
400 
IsWifi2IdExist(int id)401 bool WifiControllerMachine::IsWifi2IdExist(int id)
402 {
403     if (!HasAnyMultiStaManager()) {
404         return false;
405     }
406     std::unique_lock<std::mutex> lock(multiStaManagerMutex);
407     for (auto iter = multiStaManagers.begin(); iter != multiStaManagers.end(); ++iter) {
408         if ((*iter)->mid == id) {
409             WIFI_LOGI("multiStaManagers is match");
410             return true;
411         }
412     }
413     return false;
414 }
415 
HasAnyConcreteManager()416 bool WifiControllerMachine::HasAnyConcreteManager()
417 {
418     std::unique_lock<std::mutex> lock(concreteManagerMutex);
419     if (concreteManagers.empty()) {
420         WIFI_LOGE("Enter HasAnyConcreteManager is empty");
421         return false;
422     }
423     return true;
424 }
425 
HasAnyMultiStaManager()426 bool WifiControllerMachine::HasAnyMultiStaManager()
427 {
428     std::unique_lock<std::mutex> lock(multiStaManagerMutex);
429     if (multiStaManagers.empty()) {
430         WIFI_LOGE("Enter HasAnyMultiStaManager is empty");
431         return false;
432     }
433     return true;
434 }
435 
436 #ifdef FEATURE_AP_SUPPORT
HasAnySoftApManager()437 bool WifiControllerMachine::HasAnySoftApManager()
438 {
439     std::unique_lock<std::mutex> lock(softapManagerMutex);
440     if (softapManagers.empty()) {
441         WIFI_LOGI("Softap managers is empty");
442         return false;
443     }
444     WIFI_LOGI("Has softap manager");
445     return true;
446 }
447 #endif
448 
HasAnyManager()449 bool WifiControllerMachine::HasAnyManager()
450 {
451     if (!HasAnyConcreteManager() && !HasAnyMultiStaManager()
452 #ifdef FEATURE_AP_SUPPORT
453         && !HasAnySoftApManager()
454 #endif
455     ) {
456         return false;
457     }
458     return true;
459 }
460 
MakeConcreteManager(ConcreteManagerRole role,int id)461 void WifiControllerMachine::MakeConcreteManager(ConcreteManagerRole role, int id)
462 {
463     WIFI_LOGE("Enter MakeConcreteManager");
464     ConcreteClientModeManager *clientmode = new (std::nothrow) ConcreteClientModeManager(role, id);
465     clientmode->RegisterCallback(WifiManager::GetInstance().GetWifiTogglerManager()->GetConcreteCallback());
466     clientmode->InitConcreteManager();
467     std::unique_lock<std::mutex> lock(concreteManagerMutex);
468     concreteManagers.push_back(clientmode);
469 }
470 
MakeMultiStaManager(MultiStaManager::Role role,int instId)471 void WifiControllerMachine::MakeMultiStaManager(MultiStaManager::Role role, int instId)
472 {
473     WIFI_LOGI("Enter MakeMultiStaManager");
474     MultiStaManager *multiStaMode = new (std::nothrow) MultiStaManager(role, instId);
475     if (multiStaMode == nullptr) {
476         WIFI_LOGE("new multiStaMode failed");
477         return;
478     }
479     multiStaMode->RegisterCallback(WifiManager::GetInstance().GetWifiTogglerManager()->GetMultiStaCallback());
480     multiStaMode->InitMultiStaManager();
481     std::unique_lock<std::mutex> lock(multiStaManagerMutex);
482     multiStaManagers.push_back(multiStaMode);
483 }
484 
485 #ifdef FEATURE_AP_SUPPORT
MakeSoftapManager(SoftApManager::Role role,int id)486 void WifiControllerMachine::MakeSoftapManager(SoftApManager::Role role, int id)
487 {
488     WIFI_LOGE("Enter MakeSoftapManager");
489     SoftApManager *softapmode = new (std::nothrow) SoftApManager(role, id);
490     softapmode->RegisterCallback(WifiManager::GetInstance().GetWifiTogglerManager()->GetSoftApCallback());
491     softapmode->InitSoftapManager();
492     std::unique_lock<std::mutex> lock(softapManagerMutex);
493     softapManagers.push_back(softapmode);
494 }
495 
ShouldEnableSoftap()496 bool WifiControllerMachine::ShouldEnableSoftap()
497 {
498     bool toggledState = WifiConfigCenter::GetInstance().GetSoftapToggledState();
499     WIFI_LOGI("Softap toggled state is %{public}d", toggledState);
500     return toggledState;
501 }
502 #endif
503 
ShouldDisableWifi(InternalMessagePtr msg)504 bool WifiControllerMachine::ShouldDisableWifi(InternalMessagePtr msg)
505 {
506     auto currState = WifiConfigCenter::GetInstance().GetWifiDetailState(msg->GetParam2());
507     if (WifiConfigCenter::GetInstance().GetWifiToggledEnable() == WIFI_STATE_SEMI_ENABLED &&
508         (currState == WifiDetailState::STATE_ACTIVATED || currState == WifiDetailState::STATE_ACTIVATING) &&
509         msg->GetMessageName() == CMD_WIFI_TOGGLED && ConcreteIdExist(msg->GetParam2())) {
510         WIFI_LOGI("Should disable wifi");
511         WifiEventCallbackMsg cbMsg;
512         cbMsg.msgCode = WIFI_CBK_MSG_SEMI_STATE_CHANGE;
513         cbMsg.id = msg->GetParam2();
514         cbMsg.msgData = static_cast<int>(WifiDetailState::STATE_INACTIVE);
515         WifiInternalEventDispatcher::GetInstance().AddBroadCastMsg(cbMsg);
516         return true;
517     }
518     return !ShouldEnableWifi(msg->GetParam2());
519 }
520 
ShouldEnableWifi(int id)521 bool WifiControllerMachine::ShouldEnableWifi(int id)
522 {
523     WIFI_LOGI("Enter ShouldEnableWifi");
524     if (id == INSTID_WLAN1) {
525         return WifiConfigCenter::GetInstance().GetWifiToggledEnable(INSTID_WLAN0) == WIFI_STATE_ENABLED;
526     }
527 #ifndef OHOS_ARCH_LITE
528     if (WifiManager::GetInstance().GetWifiEventSubscriberManager()->IsMdmForbidden()) {
529         return false;
530     }
531 #endif
532     if (WifiConfigCenter::GetInstance().GetWifiToggledEnable(id) != WIFI_STATE_DISABLED || IsScanOnlyEnable()) {
533         WIFI_LOGI("Should start wifi or scanonly.");
534         return true;
535     }
536 
537     WIFI_LOGI("no need to start Wifi or scanonly");
538     return false;
539 }
540 
GetWifiRole()541 ConcreteManagerRole WifiControllerMachine::GetWifiRole()
542 {
543     if (IsWifiEnable()) {
544         return ConcreteManagerRole::ROLE_CLIENT_STA;
545     } else if (IsSemiWifiEnable() && IsScanOnlyEnable()) {
546         return ConcreteManagerRole::ROLE_CLIENT_MIX_SEMI_ACTIVE;
547     } else if (IsSemiWifiEnable()) {
548         return ConcreteManagerRole::ROLE_CLIENT_STA_SEMI_ACTIVE;
549     } else if (IsScanOnlyEnable()) {
550         return ConcreteManagerRole::ROLE_CLIENT_SCAN_ONLY;
551     } else {
552         return ConcreteManagerRole::ROLE_UNKNOW;
553     }
554 }
555 
IsWifiEnable(int id)556 bool WifiControllerMachine::IsWifiEnable(int id)
557 {
558     return WifiConfigCenter::GetInstance().GetWifiToggledEnable(id) == WIFI_STATE_ENABLED;
559 }
560 
IsSemiWifiEnable()561 bool WifiControllerMachine::IsSemiWifiEnable()
562 {
563     return WifiConfigCenter::GetInstance().GetWifiToggledEnable() == WIFI_STATE_SEMI_ENABLED;
564 }
565 
IsScanOnlyEnable()566 bool WifiControllerMachine::IsScanOnlyEnable()
567 {
568     if (WifiConfigCenter::GetInstance().CheckScanOnlyAvailable()) {
569         WIFI_LOGI("scanonly available is true");
570 #ifndef OHOS_ARCH_LITE
571         if (WifiManager::GetInstance().GetWifiEventSubscriberManager()->GetLocationModeByDatashare()) {
572             WIFI_LOGI("location mode is 1");
573             return true;
574         } else {
575             WIFI_LOGI("No need to StartScanOnly");
576             return false;
577         }
578 #endif
579         return true;
580     }
581     WIFI_LOGI("No need to StartScanOnly");
582     return false;
583 }
584 
StopAllConcreteManagers()585 void WifiControllerMachine::StopAllConcreteManagers()
586 {
587     WIFI_LOGI("Enter StopAllConcreteManagers.");
588     if (!HasAnyConcreteManager()) {
589         return;
590     }
591     std::unique_lock<std::mutex> lock(concreteManagerMutex);
592     for (auto iter = concreteManagers.begin(); iter != concreteManagers.end(); ++iter) {
593         WIFI_LOGD("Enter StopAllConcreteManagers. mid = %{public}d", (*iter)->mid);
594         (*iter)->GetConcreteMachine()->SendMessage(CONCRETE_CMD_STOP);
595     }
596 }
597 
StopConcreteManager(int id)598 void WifiControllerMachine::StopConcreteManager(int id)
599 {
600     if (!HasAnyConcreteManager()) {
601         return;
602     }
603 
604     std::unique_lock<std::mutex> lock(concreteManagerMutex);
605     for (auto iter = concreteManagers.begin(); iter != concreteManagers.end(); ++iter) {
606         if ((*iter)->mid == id) {
607             (*iter)->GetConcreteMachine()->SendMessage(CONCRETE_CMD_STOP);
608             return;
609         }
610     }
611     return;
612 }
613 
StopMultiStaManager(int id)614 void WifiControllerMachine::StopMultiStaManager(int id)
615 {
616     WIFI_LOGI("Enter StopMultiStaManager, id = %{public}d", id);
617     if (!HasAnyMultiStaManager()) {
618         return;
619     }
620     std::unique_lock<std::mutex> lock(multiStaManagerMutex);
621     for (auto iter = multiStaManagers.begin(); iter != multiStaManagers.end(); ++iter) {
622         if ((*iter)->mid == id) {
623             (*iter)->GetMultiStaMachine()->SendMessage(MULTI_STA_CMD_STOP);
624             return;
625         }
626     }
627 }
628 
StopAllMultiStaManagers()629 void WifiControllerMachine::StopAllMultiStaManagers()
630 {
631     WIFI_LOGI("Enter StopAllMultiStaManagers");
632     if (!HasAnyMultiStaManager()) {
633         return;
634     }
635     std::unique_lock<std::mutex> lock(multiStaManagerMutex);
636     for (auto iter = multiStaManagers.begin(); iter != multiStaManagers.end(); ++iter) {
637         (*iter)->GetMultiStaMachine()->SendMessage(MULTI_STA_CMD_STOP);
638     }
639 }
640 
641 #ifdef FEATURE_AP_SUPPORT
StopSoftapManager(int id)642 void WifiControllerMachine::StopSoftapManager(int id)
643 {
644     if (!HasAnySoftApManager()) {
645         return;
646     }
647     std::unique_lock<std::mutex> lock(softapManagerMutex);
648     for (auto iter = softapManagers.begin(); iter != softapManagers.end(); ++iter) {
649         if ((*iter)->mid == id) {
650             (*iter)->GetSoftapMachine()->SendMessage(SOFTAP_CMD_STOP);
651             return;
652         }
653     }
654 }
655 
StopAllSoftapManagers()656 void WifiControllerMachine::StopAllSoftapManagers()
657 {
658     if (!HasAnySoftApManager()) {
659         WIFI_LOGE("Not found AnySoftApManager.");
660         return;
661     }
662     std::unique_lock<std::mutex> lock(softapManagerMutex);
663     for (auto iter = softapManagers.begin(); iter != softapManagers.end(); ++iter) {
664         (*iter)->GetSoftapMachine()->SendMessage(SOFTAP_CMD_STOP);
665     }
666 }
667 #endif
668 
RemoveConcreteManager(int id)669 void WifiControllerMachine::RemoveConcreteManager(int id)
670 {
671     ConcreteClientModeManager *concreteManager = nullptr;
672 
673     if (!HasAnyConcreteManager()) {
674         return;
675     }
676     {
677         std::unique_lock<std::mutex> lock(concreteManagerMutex);
678         for (auto iter = concreteManagers.begin(); iter != concreteManagers.end(); ++iter) {
679             if ((*iter)->mid == id) {
680                 concreteManager = *iter;
681                 concreteManagers.erase(iter);
682                 break;
683             }
684         }
685     }
686     if (concreteManager != nullptr) {
687         delete concreteManager;
688     }
689 }
690 
RemoveMultiStaManager(int id)691 void WifiControllerMachine::RemoveMultiStaManager(int id)
692 {
693     MultiStaManager *multiStaMgr = nullptr;
694 
695     if (!HasAnyMultiStaManager()) {
696         return;
697     }
698     {
699         std::unique_lock<std::mutex> lock(multiStaManagerMutex);
700         for (auto iter = multiStaManagers.begin(); iter != multiStaManagers.end(); ++iter) {
701             if ((*iter)->mid == id) {
702                 multiStaMgr = *iter;
703                 multiStaManagers.erase(iter);
704                 break;
705             }
706         }
707     }
708     if (multiStaMgr != nullptr) {
709         delete multiStaMgr;
710         multiStaMgr = nullptr;
711     }
712 }
713 
714 #ifdef FEATURE_AP_SUPPORT
RmoveSoftapManager(int id)715 void WifiControllerMachine::RmoveSoftapManager(int id)
716 {
717     SoftApManager *softapManager = nullptr;
718 
719     if (!HasAnySoftApManager()) {
720         return;
721     }
722     std::unique_lock<std::mutex> lock(softapManagerMutex);
723     for (auto iter = softapManagers.begin(); iter != softapManagers.end(); ++iter) {
724         if ((*iter)->mid == id) {
725             softapManager = *iter;
726             softapManagers.erase(iter);
727             break;
728         }
729     }
730     if (softapManager != nullptr) {
731         delete softapManager;
732     }
733 }
734 #endif
735 
HandleStaClose(int id)736 void WifiControllerMachine::HandleStaClose(int id)
737 {
738     std::unique_lock<std::mutex> lock(concreteManagerMutex);
739     if (concreteManagers.empty()) {
740         return;
741     }
742     for (auto iter = concreteManagers.begin(); iter != concreteManagers.end(); ++iter) {
743         if ((*iter)->mid == id) {
744             (*iter)->GetConcreteMachine()->SendMessage(CONCRETE_CMD_STA_STOP);
745             break;
746         }
747     }
748 }
749 
HandleWifi2Close(int id)750 void WifiControllerMachine::HandleWifi2Close(int id)
751 {
752     std::unique_lock<std::mutex> lock(multiStaManagerMutex);
753     if (multiStaManagers.empty()) {
754         return;
755     }
756     for (auto iter = multiStaManagers.begin(); iter != multiStaManagers.end(); ++iter) {
757         if ((*iter)->mid == id) {
758             (*iter)->GetMultiStaMachine()->SendMessage(MULTI_STA_CMD_STOPPED);
759             break;
760         }
761     }
762 }
763 
SwitchRole(ConcreteManagerRole role)764 void WifiControllerMachine::SwitchRole(ConcreteManagerRole role)
765 {
766     std::unique_lock<std::mutex> lock(concreteManagerMutex);
767     for (auto iter = concreteManagers.begin(); iter != concreteManagers.end(); ++iter) {
768         (*iter)->SetRole(role);
769     }
770 }
771 
HandleWifiToggleChangeInEnabledState(InternalMessagePtr msg)772 void WifiControllerMachine::EnableState::HandleWifiToggleChangeInEnabledState(InternalMessagePtr msg)
773 {
774     if (msg->GetParam2() == INSTID_WLAN1 && msg->GetParam1() == 0) {
775         WIFI_LOGI("Toggle disable wlan1.");
776         pWifiControllerMachine->StopMultiStaManager(INSTID_WLAN1);
777         return;
778     }
779     if (msg->GetParam2() == INSTID_WLAN1 && WifiConfigCenter::GetInstance().GetPersistWifiState(INSTID_WLAN0)
780         == WIFI_STATE_ENABLED && msg->GetParam1() == 1) {
781         pWifiControllerMachine->MakeMultiStaManager(MultiStaManager::Role::ROLE_STA_WIFI_2, msg->GetParam2());
782         return;
783     }
784 
785     ConcreteManagerRole presentRole;
786     if (pWifiControllerMachine->ShouldDisableWifi(msg)) {
787         pWifiControllerMachine->StopAllMultiStaManagers();
788         pWifiControllerMachine->StopAllConcreteManagers();
789         return;
790     }
791     if (pWifiControllerMachine->ConcreteIdExist(msg->GetParam2())) {
792         if (WifiConfigCenter::GetInstance().GetWifiStopState()) {
793             return;
794         }
795         presentRole = pWifiControllerMachine->GetWifiRole();
796         if (presentRole == ConcreteManagerRole::ROLE_UNKNOW) {
797             WIFI_LOGE("Get unknow wifi role in enablestate.");
798             return;
799         }
800         if (presentRole != ConcreteManagerRole::ROLE_CLIENT_STA) {
801             pWifiControllerMachine->StopMultiStaManager(INSTID_WLAN1);
802         }
803         pWifiControllerMachine->SwitchRole(presentRole);
804         return;
805     }
806     WifiConfigCenter::GetInstance().SetWifiStopState(false);
807 #ifdef FEATURE_AP_SUPPORT
808 #ifndef HDI_CHIP_INTERFACE_SUPPORT
809     if (!WifiConfigCenter::GetInstance().GetCoexSupport() &&
810         pWifiControllerMachine->HasAnySoftApManager()) {
811         pWifiControllerMachine->StopAllSoftapManagers();
812         return;
813     }
814 #endif
815 #endif
816     presentRole = pWifiControllerMachine->GetWifiRole();
817     if (presentRole == ConcreteManagerRole::ROLE_UNKNOW) {
818         WIFI_LOGE("Get unknow wifi role  in EnableState.");
819         return;
820     }
821     pWifiControllerMachine->MakeConcreteManager(presentRole, msg->GetParam2());
822     return;
823 }
824 
825 #ifdef FEATURE_AP_SUPPORT
HandleSoftapToggleChangeInEnabledState(InternalMessagePtr msg)826 void WifiControllerMachine::EnableState::HandleSoftapToggleChangeInEnabledState(InternalMessagePtr msg)
827 {
828     int id = msg->GetParam2();
829     WIFI_LOGI("handleSoftapToggleChangeInEnabledState");
830     if (msg->GetParam1() == 1) {
831 #ifndef HDI_CHIP_INTERFACE_SUPPORT
832         if (!WifiConfigCenter::GetInstance().GetCoexSupport() &&
833             pWifiControllerMachine->HasAnyConcreteManager()) {
834             pWifiControllerMachine->StopAllMultiStaManagers();
835             pWifiControllerMachine->StopAllConcreteManagers();
836             pWifiControllerMachine->mApidStopWifi = id;
837             return;
838         }
839 #endif
840         if (!pWifiControllerMachine->SoftApIdExist(id)) {
841             pWifiControllerMachine->MakeSoftapManager(SoftApManager::Role::ROLE_SOFTAP, id);
842             return;
843         }
844     }
845 #ifndef HDI_CHIP_INTERFACE_SUPPORT
846     if (!WifiConfigCenter::GetInstance().GetCoexSupport() &&
847         pWifiControllerMachine->ShouldEnableWifi(INSTID_WLAN0) &&
848         !WifiConfigCenter::GetInstance().GetWifiStopState() &&
849         pWifiControllerMachine->HasAnyConcreteManager()) {
850         ConcreteManagerRole role = pWifiControllerMachine->GetWifiRole();
851         if (role != ConcreteManagerRole::ROLE_UNKNOW) {
852             pWifiControllerMachine->SwitchRole(role);
853         }
854     }
855 #endif
856     WifiOprMidState apState = WifiConfigCenter::GetInstance().GetApMidState(id);
857     if (apState == WifiOprMidState::CLOSING || apState == WifiOprMidState::OPENING) {
858         WIFI_LOGI("Current ap state is %{public}d, return", apState);
859         return;
860     }
861     if (pWifiControllerMachine->SoftApIdExist(id)) {
862         pWifiControllerMachine->StopSoftapManager(id);
863         pWifiControllerMachine->StartTimer(CMD_AP_STOP_TIME, SOFT_AP_TIME_OUT);
864         return;
865     }
866 }
867 #endif
868 
HandleStaStartFailure(int id)869 void WifiControllerMachine::EnableState::HandleStaStartFailure(int id)
870 {
871     WIFI_LOGE("HandleStaStartFailure");
872     pWifiControllerMachine->RemoveConcreteManager(id);
873     mWifiStartFailCount++;
874     if (pWifiControllerMachine->ShouldEnableWifi(id) && mWifiStartFailCount < WIFI_OPEN_RETRY_MAX_COUNT) {
875         pWifiControllerMachine->StartTimer(CMD_OPEN_WIFI_RETRY, WIFI_OPEN_RETRY_TIMEOUT);
876     }
877 }
878 
HandleStaRemoved(InternalMessagePtr msg)879 void WifiControllerMachine::EnableState::HandleStaRemoved(InternalMessagePtr msg)
880 {
881     {
882         std::unique_lock<std::mutex> lock(pWifiControllerMachine->concreteManagerMutex);
883         for (auto iter = pWifiControllerMachine->concreteManagers.begin();
884             iter != pWifiControllerMachine->concreteManagers.end(); ++iter) {
885             if ((*iter)->mid == msg->GetParam2() && msg->GetParam1() >= 0) {
886                 (*iter)->GetConcreteMachine()->SendMessage(CONCRETE_CMD_STA_REMOVED);
887             }
888         }
889     }
890     pWifiControllerMachine->StopAllMultiStaManagers();
891     pWifiControllerMachine->StopConcreteManager(msg->GetParam2());
892 }
893 
HandleWifi2Removed(InternalMessagePtr msg)894 void WifiControllerMachine::EnableState::HandleWifi2Removed(InternalMessagePtr msg)
895 {
896     pWifiControllerMachine->StopMultiStaManager(msg->GetParam2());
897 }
898 
HandleConcreteClientRemoved(InternalMessagePtr msg)899 void WifiControllerMachine::EnableState::HandleConcreteClientRemoved(InternalMessagePtr msg)
900 {
901     int id = msg->GetParam1();
902     pWifiControllerMachine->RemoveConcreteManager(id);
903     if (!(pWifiControllerMachine->HasAnyManager())) {
904         pWifiControllerMachine->SwitchState(pWifiControllerMachine->pDisableState);
905     }
906 }
907 
HandleAPServiceStartFail(int id)908 void WifiControllerMachine::EnableState::HandleAPServiceStartFail(int id)
909 {
910     WIFI_LOGE("Ap start fail, set softap toggled false");
911     WifiConfigCenter::GetInstance().SetSoftapToggledState(false);
912 }
913 
ClearWifiStartFailCount()914 void WifiControllerMachine::ClearWifiStartFailCount()
915 {
916     WIFI_LOGD("Clear wifi start fail count");
917     mWifiStartFailCount = 0;
918 }
919 
HandleStaStart(int id)920 void WifiControllerMachine::HandleStaStart(int id)
921 {
922     mWifiStartFailCount = 0;
923     this->StopTimer(CMD_WIFI_TOGGLED_TIMEOUT);
924     this->StopTimer(CMD_OPEN_WIFI_RETRY);
925     std::unique_lock<std::mutex> lock(concreteManagerMutex);
926     for (auto iter = concreteManagers.begin(); iter != concreteManagers.end(); ++iter) {
927         (*iter)->GetConcreteMachine()->SendMessage(CONCRETE_CMD_STA_START);
928     }
929 }
930 
HandleWifi2Start(int id)931 void WifiControllerMachine::HandleWifi2Start(int id)
932 {
933     std::unique_lock<std::mutex> lock(multiStaManagerMutex);
934     for (auto iter = multiStaManagers.begin(); iter != multiStaManagers.end(); ++iter) {
935         (*iter)->GetMultiStaMachine()->SendMessage(MULTI_STA_CMD_STARTED);
936     }
937 }
938 
HandleStaSemiActive(int id)939 void WifiControllerMachine::HandleStaSemiActive(int id)
940 {
941     mWifiStartFailCount = 0;
942     this->StopTimer(CMD_SEMI_WIFI_TOGGLED_TIMEOUT);
943     this->StopTimer(CMD_OPEN_WIFI_RETRY);
944     std::unique_lock<std::mutex> lock(concreteManagerMutex);
945     for (auto iter = concreteManagers.begin(); iter != concreteManagers.end(); ++iter) {
946         (*iter)->GetConcreteMachine()->SendMessage(CONCRETE_CMD_STA_SEMI_ACTIVE);
947     }
948 }
949 
950 #ifdef FEATURE_AP_SUPPORT
HandleApStart(int id)951 void WifiControllerMachine::EnableState::HandleApStart(int id)
952 {
953     if (!pWifiControllerMachine->ShouldEnableSoftap()) {
954         pWifiControllerMachine->StopSoftapManager(id);
955         return;
956     }
957     pWifiControllerMachine->StartSoftapCloseTimer();
958 }
959 
HandleApRemoved(InternalMessagePtr msg)960 void WifiControllerMachine::EnableState::HandleApRemoved(InternalMessagePtr msg)
961 {
962     pWifiControllerMachine->StopSoftapManager(msg->GetParam2());
963     SoftApManager *softap = pWifiControllerMachine->GetSoftApManager(msg->GetParam2());
964     if (softap != nullptr) {
965         softap->SetRole(SoftApManager::Role::ROLE_HAS_REMOVED);
966     }
967 }
968 
HandleApStop(InternalMessagePtr msg)969 void WifiControllerMachine::EnableState::HandleApStop(InternalMessagePtr msg)
970 {
971     pWifiControllerMachine->StopTimer(CMD_AP_STOP_TIME);
972     pWifiControllerMachine->StopSoftapCloseTimer();
973     pWifiControllerMachine->HandleSoftapStop(msg->GetParam1());
974 }
975 #endif
976 
HandleConcreteStop(int id)977 void WifiControllerMachine::HandleConcreteStop(int id)
978 {
979     WIFI_LOGD("WifiControllerMachine HandleConcreteStop id = %{public}d", id);
980     RemoveConcreteManager(id);
981 #ifndef HDI_CHIP_INTERFACE_SUPPORT
982     if (!WifiConfigCenter::GetInstance().GetCoexSupport()) {
983 #ifdef FEATURE_AP_SUPPORT
984         int airplanstate = WifiConfigCenter::GetInstance().GetAirplaneModeState();
985         if (ShouldEnableSoftap() && airplanstate != MODE_STATE_OPEN &&
986             !SoftApIdExist(mApidStopWifi)) {
987             MakeSoftapManager(SoftApManager::Role::ROLE_SOFTAP, mApidStopWifi);
988             return;
989         }
990 #endif
991         if (!WifiManager::GetInstance().GetWifiTogglerManager()->HasAnyApRuning()) {
992             if (ShouldEnableWifi(id)) {
993                 ConcreteManagerRole presentRole = GetWifiRole();
994                 MakeConcreteManager(presentRole, 0);
995                 return;
996             }
997         }
998     } else {
999 #endif
1000         if (ShouldEnableWifi(id)) {
1001             ConcreteManagerRole presentRole = GetWifiRole();
1002             MakeConcreteManager(presentRole, 0);
1003             return;
1004         }
1005 #ifndef HDI_CHIP_INTERFACE_SUPPORT
1006     }
1007 #endif
1008     if (!(HasAnyManager())) {
1009         SwitchState(pDisableState);
1010     }
1011 }
1012 
1013 #ifdef FEATURE_AP_SUPPORT
HandleSoftapStop(int id)1014 void WifiControllerMachine::HandleSoftapStop(int id)
1015 {
1016     ConcreteManagerRole role;
1017     SoftApManager *softap = GetSoftApManager(id);
1018     if (softap != nullptr && softap->GetRole() == SoftApManager::Role::ROLE_HAS_REMOVED) {
1019         RmoveSoftapManager(id);
1020         if (!HasAnyManager()) {
1021             SwitchState(pDisableState);
1022         }
1023         return;
1024     }
1025 
1026     RmoveSoftapManager(id);
1027     if (ShouldEnableSoftap() && !SoftApIdExist(0)) {
1028         MakeSoftapManager(SoftApManager::Role::ROLE_SOFTAP, 0);
1029         return;
1030     }
1031     if (HasAnyManager()) {
1032         return;
1033     }
1034     if (ShouldEnableWifi(INSTID_WLAN0) && !WifiConfigCenter::GetInstance().GetWifiStopState()) {
1035         role = GetWifiRole();
1036         if (role == ConcreteManagerRole::ROLE_UNKNOW) {
1037             WIFI_LOGE("Get unknow wifi role in HandleSoftapStop.");
1038             return;
1039         }
1040         MakeConcreteManager(role, 0);
1041     } else {
1042         SwitchState(pDisableState);
1043     }
1044 }
1045 
AlarmStopSoftap()1046 static void AlarmStopSoftap()
1047 {
1048     WifiManager::GetInstance().GetWifiTogglerManager()->SoftapToggled(0, 0);
1049 }
1050 
StartSoftapCloseTimer()1051 void WifiControllerMachine::StartSoftapCloseTimer()
1052 {
1053     WIFI_LOGI("enter softapCloseTimer");
1054     int mTimeoutDelay = WifiConfigCenter::GetInstance().GetHotspotIdleTimeout();
1055     if (stopSoftapTimerId_ != 0) {
1056         return;
1057     }
1058 #ifdef HAS_BATTERY_MANAGER_PART
1059     auto &batterySrvClient = PowerMgr::BatterySrvClient::GetInstance();
1060     auto batteryPluggedType = batterySrvClient.GetPluggedType();
1061     if (batteryPluggedType == PowerMgr::BatteryPluggedType::PLUGGED_TYPE_USB) {
1062         WIFI_LOGI("usb connect do not start timer");
1063         return;
1064     }
1065 #endif
1066     std::shared_ptr<WifiSysTimer> wifiSysTimer = std::make_shared<WifiSysTimer>(false, 0, false, false);
1067     wifiSysTimer->SetCallbackInfo(AlarmStopSoftap);
1068     stopSoftapTimerId_ = MiscServices::TimeServiceClient::GetInstance()->CreateTimer(wifiSysTimer);
1069     int64_t currentTime = MiscServices::TimeServiceClient::GetInstance()->GetBootTimeMs();
1070     MiscServices::TimeServiceClient::GetInstance()->StartTimer(stopSoftapTimerId_, currentTime + mTimeoutDelay);
1071 }
1072 
StopSoftapCloseTimer()1073 void WifiControllerMachine::StopSoftapCloseTimer()
1074 {
1075     WIFI_LOGI("enter StopSoftapCloseTimer");
1076     if (stopSoftapTimerId_ == 0) {
1077         return;
1078     }
1079     MiscServices::TimeServiceClient::GetInstance()->StopTimer(stopSoftapTimerId_);
1080     MiscServices::TimeServiceClient::GetInstance()->DestroyTimer(stopSoftapTimerId_);
1081     stopSoftapTimerId_ = 0;
1082 }
1083 #endif
1084 
ShutdownWifi(bool shutDownAp)1085 void WifiControllerMachine::ShutdownWifi(bool shutDownAp)
1086 {
1087     WIFI_LOGI("shutdownWifi.");
1088     if (shutDownAp) {
1089 #ifdef FEATURE_AP_SUPPORT
1090     WifiConfigCenter::GetInstance().SetSoftapToggledState(false);
1091     StopAllSoftapManagers();
1092 #endif
1093     }
1094     StopAllMultiStaManagers();
1095     StopAllConcreteManagers();
1096 }
1097 } // namespace Wifi
1098 } // namespace OHOS
1099