1 /*
2  * Copyright (C) 2021-2024 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 "multi_sta_state_machine.h"
17 #include "wifi_manager.h"
18 #include "wifi_service_manager.h"
19 #include "wifi_config_center.h"
20 #include "wifi_chip_hal_interface.h"
21 #include "wifi_internal_event_dispatcher.h"
22 #include "wifi_settings.h"
23 #include "wifi_common_event_helper.h"
24 #include "wifi_service_scheduler.h"
25 #include "i_ap_service.h"
26 #ifdef HDI_CHIP_INTERFACE_SUPPORT
27 #include "hal_device_manage.h"
28 #endif
29 
30 namespace OHOS {
31 namespace Wifi {
32 DEFINE_WIFILOG_LABEL("MultiStaStateMachine");
33 int MultiStaStateMachine::mid{0};
34 
MultiStaStateMachine()35 MultiStaStateMachine::MultiStaStateMachine()
36     : StateMachine("MultiStaStateMachine"), pDefaultState(nullptr), pIdleState(nullptr), pStartedState(nullptr)
37 {}
38 
~MultiStaStateMachine()39 MultiStaStateMachine::~MultiStaStateMachine()
40 {
41     WIFI_LOGE("MultiStaStateMachine::~MultiStaStateMachine");
42     StopHandlerThread();
43     ParsePointer(pDefaultState);
44     ParsePointer(pIdleState);
45     ParsePointer(pStartedState);
46 #ifdef HDI_CHIP_INTERFACE_SUPPORT
47     if (!ifaceName.empty()) {
48         WIFI_LOGW("~MultiStaStateMachine ifaceName: %{public}s,instId:%{public}d",
49             ifaceName.c_str(), mid);
50         DelayedSingleton<HalDeviceManager>::GetInstance()->RemoveStaIface(ifaceName);
51         ifaceName.clear();
52         WifiServiceScheduler::GetInstance().ClearStaIfaceNameMap(mid);
53         WifiConfigCenter::GetInstance().SetStaIfaceName("", mid);
54     }
55 #endif
56 }
57 
58 /* --------------------------Initialization functions--------------------------*/
InitMultiStaStateMachine()59 ErrCode MultiStaStateMachine::InitMultiStaStateMachine()
60 {
61     WIFI_LOGI("Enter MultiStaStateMachine::InitMultiStaStateMachine.\n");
62     if (!InitialStateMachine("MultiStaStateMachine")) {
63         WIFI_LOGE("Initial StateMachine failed.\n");
64         return WIFI_OPT_FAILED;
65     }
66 
67     if (InitMultiStaStates() == WIFI_OPT_FAILED) {
68         return WIFI_OPT_FAILED;
69     }
70     BuildStateTree();
71     SetFirstState(pIdleState);
72     StartStateMachine();
73     return WIFI_OPT_SUCCESS;
74 }
75 
BuildStateTree()76 void MultiStaStateMachine::BuildStateTree()
77 {
78     StatePlus(pDefaultState, nullptr);
79     StatePlus(pIdleState, pDefaultState);
80     StatePlus(pStartedState, pDefaultState);
81 }
82 
InitMultiStaStates()83 ErrCode MultiStaStateMachine::InitMultiStaStates()
84 {
85     int tmpErrNumber;
86 
87     WIFI_LOGE("Enter MultiStaStateMachine\n");
88     pDefaultState = new (std::nothrow) DefaultState(this);
89     tmpErrNumber = JudgmentEmpty(pDefaultState);
90     pIdleState = new (std::nothrow) IdleState(this);
91     tmpErrNumber += JudgmentEmpty(pIdleState);
92     pStartedState = new (std::nothrow) StartedState(this);
93     tmpErrNumber += JudgmentEmpty(pStartedState);
94     if (tmpErrNumber != 0) {
95         WIFI_LOGE("InitMultiStaStates some one state is null\n");
96         return WIFI_OPT_FAILED;
97     }
98     return WIFI_OPT_SUCCESS;
99 }
100 
RegisterCallback(const MultiStaModeCallback & callbacks)101 ErrCode MultiStaStateMachine::RegisterCallback(const MultiStaModeCallback &callbacks)
102 {
103     mcb = callbacks;
104     return WIFI_OPT_SUCCESS;
105 }
106 
DefaultState(MultiStaStateMachine * multiStaStateMachine)107 MultiStaStateMachine::DefaultState::DefaultState(MultiStaStateMachine *multiStaStateMachine)
108     : State("DefaultState"), pMultiStaStateMachine(multiStaStateMachine)
109 {}
110 
~DefaultState()111 MultiStaStateMachine::DefaultState::~DefaultState()
112 {}
113 
GoInState()114 void MultiStaStateMachine::DefaultState::GoInState()
115 {
116     WIFI_LOGE("DefaultState GoInState function.\n");
117 }
118 
GoOutState()119 void MultiStaStateMachine::DefaultState::GoOutState()
120 {
121     WIFI_LOGE("DefaultState GoOutState function.\n");
122 }
123 
ExecuteStateMsg(InternalMessagePtr msg)124 bool MultiStaStateMachine::DefaultState::ExecuteStateMsg(InternalMessagePtr msg)
125 {
126     if (msg == nullptr || pMultiStaStateMachine == nullptr) {
127         return false;
128     }
129     WIFI_LOGE("DefaultState-msgCode=%{public}d is received.\n", msg->GetMessageName());
130     return true;
131 }
132 
IdleState(MultiStaStateMachine * multiStaStateMachine)133 MultiStaStateMachine::IdleState::IdleState(MultiStaStateMachine *multiStaStateMachine)
134     : State("IdleState"), pMultiStaStateMachine(multiStaStateMachine)
135 {}
136 
~IdleState()137 MultiStaStateMachine::IdleState::~IdleState()
138 {}
139 
GoInState()140 void MultiStaStateMachine::IdleState::GoInState()
141 {
142     WIFI_LOGE("IdleState GoInState function.\n");
143 }
144 
GoOutState()145 void MultiStaStateMachine::IdleState::GoOutState()
146 {
147     WIFI_LOGE("IdleState GoOutState function.\n");
148 }
149 
ExecuteStateMsg(InternalMessagePtr msg)150 bool MultiStaStateMachine::IdleState::ExecuteStateMsg(InternalMessagePtr msg)
151 {
152     if (msg == nullptr) {
153         return false;
154     }
155     WIFI_LOGI("IdleState-msgCode=%{public}d is received.\n", msg->GetMessageName());
156     switch (msg->GetMessageName()) {
157         case MULTI_STA_CMD_START:
158             HandleStartInIdleState(msg);
159             break;
160         case MULTI_STA_CMD_STARTED:
161             pMultiStaStateMachine->SwitchState(pMultiStaStateMachine->pStartedState);
162             break;
163         default:
164             break;
165     }
166     return true;
167 }
168 
HandleStartInIdleState(InternalMessagePtr msg)169 void MultiStaStateMachine::IdleState::HandleStartInIdleState(InternalMessagePtr msg)
170 {
171     mid = msg->GetParam2();
172     ErrCode ret = WifiServiceScheduler::GetInstance().AutoStartWifi2Service(mid, pMultiStaStateMachine->ifaceName);
173     if (ret != WIFI_OPT_SUCCESS) {
174         WIFI_LOGE("IdelState start wifi2 fail.\n");
175         pMultiStaStateMachine->mcb.onStartFailure(mid);
176         return;
177     }
178 }
179 
StartedState(MultiStaStateMachine * multiStaStateMachine)180 MultiStaStateMachine::StartedState::StartedState(MultiStaStateMachine *multiStaStateMachine)
181     : State("StartedState"), pMultiStaStateMachine(multiStaStateMachine)
182 {}
183 
~StartedState()184 MultiStaStateMachine::StartedState::~StartedState()
185 {}
186 
GoInState()187 void MultiStaStateMachine::StartedState::GoInState()
188 {
189     WIFI_LOGE("StartedState GoInState function.\n");
190 }
191 
GoOutState()192 void MultiStaStateMachine::StartedState::GoOutState()
193 {
194     WIFI_LOGE("StartedState GoOutState function.\n");
195 }
196 
ExecuteStateMsg(InternalMessagePtr msg)197 bool MultiStaStateMachine::StartedState::ExecuteStateMsg(InternalMessagePtr msg)
198 {
199     if (msg == nullptr) {
200         return false;
201     }
202     WIFI_LOGE("StartedState-msgCode=%{public}d is received.\n", msg->GetMessageName());
203     ErrCode ret = WIFI_OPT_FAILED;
204     switch (msg->GetMessageName()) {
205         case MULTI_STA_CMD_STOP:
206             ret = WifiServiceScheduler::GetInstance().AutoStopWifi2Service(mid);
207             if (ret != WIFI_OPT_SUCCESS) {
208                 WIFI_LOGE("AutoStopWifi2Service fail.\n");
209             }
210             pMultiStaStateMachine->mcb.onStopped(mid);
211             break;
212         default:
213             break;
214     }
215     return true;
216 }
217 
218 } // namespace Wifi
219 } // namespace OHOS