1 /*
2 * Copyright (c) 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 "networkshare_main_statemachine.h"
17
18 #include "netmgr_ext_log_wrapper.h"
19 #include "netsys_controller.h"
20 #include "networkshare_constants.h"
21 #include "networkshare_sub_statemachine.h"
22 #include "networkshare_tracker.h"
23
24 namespace OHOS {
25 namespace NetManagerStandard {
26 namespace {
27 constexpr const char *ERROR_MSG_TRUNON = "Turn on Ip Forward failed";
28 constexpr const char *ERROR_MSG_TRUNOFF = "Turn off Ip Forward failed";
29 constexpr const char *ERROR_MSG_ENABLE_FORWARD = "Enable Forward failed";
30 constexpr const char *ERROR_MSG_DISABLE_FORWARD = "Disable Forward failed";
31 constexpr const char *FAKE_DOWNSTREAM_IFACENAME = "";
32 constexpr const char *EMPTY_UPSTREAM_IFACENAME = "";
33 }
34
NetworkShareMainStateMachine(std::shared_ptr<NetworkShareUpstreamMonitor> & networkmonitor)35 NetworkShareMainStateMachine::NetworkShareMainStateMachine(std::shared_ptr<NetworkShareUpstreamMonitor> &networkmonitor)
36 : netshareRequester_("netsharing_requester"), networkMonitor_(networkmonitor)
37 {
38 MainSmStateTable temp;
39 temp.event_ = EVENT_IFACE_SM_STATE_ACTIVE;
40 temp.curState_ = MAINSTATE_INIT;
41 temp.func_ = &NetworkShareMainStateMachine::HandleInitInterfaceStateActive;
42 temp.nextState_ = MAINSTATE_ALIVE;
43 stateTable_.push_back(temp);
44
45 temp.event_ = EVENT_IFACE_SM_STATE_INACTIVE;
46 temp.curState_ = MAINSTATE_INIT;
47 temp.func_ = &NetworkShareMainStateMachine::HandleInitInterfaceStateInactive;
48 temp.nextState_ = NO_NEXT_STATE;
49 stateTable_.push_back(temp);
50
51 temp.event_ = EVENT_IFACE_SM_STATE_ACTIVE;
52 temp.curState_ = MAINSTATE_ALIVE;
53 temp.func_ = &NetworkShareMainStateMachine::HandleAliveInterfaceStateActive;
54 temp.nextState_ = NO_NEXT_STATE;
55 stateTable_.push_back(temp);
56
57 temp.event_ = EVENT_IFACE_SM_STATE_INACTIVE;
58 temp.curState_ = MAINSTATE_ALIVE;
59 temp.func_ = &NetworkShareMainStateMachine::HandleAliveInterfaceStateInactive;
60 temp.nextState_ = NO_NEXT_STATE;
61 stateTable_.push_back(temp);
62
63 temp.event_ = EVENT_UPSTREAM_CALLBACK;
64 temp.curState_ = MAINSTATE_ALIVE;
65 temp.func_ = &NetworkShareMainStateMachine::HandleAliveUpstreamMonitorCallback;
66 temp.nextState_ = NO_NEXT_STATE;
67 stateTable_.push_back(temp);
68
69 temp.event_ = EVENT_IFACE_SM_STATE_INACTIVE;
70 temp.curState_ = MAINSTATE_ERROR;
71 temp.func_ = &NetworkShareMainStateMachine::HandleErrorInterfaceStateInactive;
72 temp.nextState_ = NO_NEXT_STATE;
73 stateTable_.push_back(temp);
74
75 temp.event_ = CMD_CLEAR_ERROR;
76 temp.curState_ = MAINSTATE_ERROR;
77 temp.func_ = &NetworkShareMainStateMachine::HandleErrorClear;
78 temp.nextState_ = MAINSTATE_INIT;
79 stateTable_.push_back(temp);
80 }
81
MainSmStateSwitch(int newState)82 void NetworkShareMainStateMachine::MainSmStateSwitch(int newState)
83 {
84 int oldState = curState_;
85 curState_ = newState;
86 NETMGR_EXT_LOG_I("MainSmStateSwitch from[%{public}d] to[%{public}d].", oldState, newState);
87
88 if (oldState == MAINSTATE_INIT) {
89 InitStateExit();
90 } else if (oldState == MAINSTATE_ALIVE) {
91 AliveStateExit();
92 } else if (oldState == MAINSTATE_ERROR) {
93 ErrorStateExit();
94 } else {
95 NETMGR_EXT_LOG_E("MainSmStateSwitch oldState is unknow type value.");
96 }
97
98 if (newState == MAINSTATE_INIT) {
99 InitStateEnter();
100 } else if (newState == MAINSTATE_ALIVE) {
101 AliveStateEnter();
102 } else if (newState == MAINSTATE_ERROR) {
103 ErrorStateEnter();
104 } else {
105 NETMGR_EXT_LOG_E("MainSmStateSwitch newState is unknow type value.");
106 }
107 }
108
GetEventMutex()109 ffrt::recursive_mutex &NetworkShareMainStateMachine::GetEventMutex()
110 {
111 return mutex_;
112 }
113
MainSmEventHandle(int eventId,const std::any & messageObj)114 void NetworkShareMainStateMachine::MainSmEventHandle(int eventId, const std::any &messageObj)
115 {
116 std::lock_guard<ffrt::recursive_mutex> lock(mutex_);
117 int nextState = NO_NEXT_STATE;
118 int (NetworkShareMainStateMachine::*eventActionFun)(const std::any &messageObj) = nullptr;
119 for (const auto &iter : stateTable_) {
120 if ((eventId == iter.event_) && (curState_ == iter.curState_)) {
121 eventActionFun = iter.func_;
122 nextState = iter.nextState_;
123 break;
124 }
125 }
126 if (eventActionFun == nullptr) {
127 NETMGR_EXT_LOG_W("currentstate[%{public}d] eventId[%{public}d] is not matched.", curState_, eventId);
128 return;
129 }
130 (this->*eventActionFun)(messageObj);
131 if (nextState >= MAINSTATE_INIT && nextState < MAINSTATE_MAX) {
132 MainSmStateSwitch(nextState);
133 }
134
135 NETMGR_EXT_LOG_I("MainSm eventId[%{public}d], handle successful.", eventId);
136 }
137
InitStateEnter()138 void NetworkShareMainStateMachine::InitStateEnter()
139 {
140 NETMGR_EXT_LOG_I("Enter Init state");
141 }
142
InitStateExit()143 void NetworkShareMainStateMachine::InitStateExit()
144 {
145 NETMGR_EXT_LOG_I("Exit Init state");
146 }
147
AliveStateEnter()148 void NetworkShareMainStateMachine::AliveStateEnter()
149 {
150 NETMGR_EXT_LOG_I("Enter Alive State");
151 if (!(TurnOnMainShareSettings())) {
152 NETMGR_EXT_LOG_E("Enter Alive State TurnOnMainShareSettings error.");
153 return;
154 }
155 if (NetworkShareTracker::GetInstance().UpstreamWanted()) {
156 ChooseUpstreamNetwork();
157 }
158 }
159
AliveStateExit()160 void NetworkShareMainStateMachine::AliveStateExit()
161 {
162 NETMGR_EXT_LOG_I("Exit Alive state");
163 NetworkShareTracker::GetInstance().NotifyDownstreamsHasNewUpstreamIface(nullptr);
164 }
165
ErrorStateEnter()166 void NetworkShareMainStateMachine::ErrorStateEnter()
167 {
168 NETMGR_EXT_LOG_I("Enter Error state, error[%{public}d].", errorType_);
169 for_each(subMachineList_.begin(), subMachineList_.end(),
170 [this](std::shared_ptr<NetworkShareSubStateMachine> subsm) {
171 if (subsm != nullptr) {
172 NETMGR_EXT_LOG_I("NOTIFY TO SUB SM [%{public}s] EVENT[%{public}d].",
173 subsm->GetInterfaceName().c_str(), errorType_);
174 subsm->SubSmEventHandle(errorType_, 0);
175 }
176 });
177 }
178
ErrorStateExit() const179 void NetworkShareMainStateMachine::ErrorStateExit() const
180 {
181 NETMGR_EXT_LOG_I("Exit Error state, error[%{public}d].", errorType_);
182 }
183
HandleInitInterfaceStateActive(const std::any & messageObj)184 int NetworkShareMainStateMachine::HandleInitInterfaceStateActive(const std::any &messageObj)
185 {
186 const MessageIfaceActive &temp = std::any_cast<const MessageIfaceActive &>(messageObj);
187 std::vector<std::shared_ptr<NetworkShareSubStateMachine>>::iterator iter =
188 find(subMachineList_.begin(), subMachineList_.end(), temp.subsm_);
189 if (iter == subMachineList_.end()) {
190 NETMGR_EXT_LOG_I("add new subSm.");
191 subMachineList_.push_back(temp.subsm_);
192 }
193
194 NetworkShareTracker::GetInstance().ModifySharedSubStateMachineList(true, temp.subsm_);
195 return NETMANAGER_EXT_SUCCESS;
196 }
197
HandleInitInterfaceStateInactive(const std::any & messageObj)198 int NetworkShareMainStateMachine::HandleInitInterfaceStateInactive(const std::any &messageObj)
199 {
200 return EraseSharedSubSM(messageObj);
201 }
202
HandleAliveInterfaceStateActive(const std::any & messageObj)203 int NetworkShareMainStateMachine::HandleAliveInterfaceStateActive(const std::any &messageObj)
204 {
205 const MessageIfaceActive &temp = std::any_cast<const MessageIfaceActive &>(messageObj);
206 std::vector<std::shared_ptr<NetworkShareSubStateMachine>>::iterator iter =
207 find(subMachineList_.begin(), subMachineList_.end(), temp.subsm_);
208 if (iter == subMachineList_.end()) {
209 NETMGR_EXT_LOG_I("add new subSm.");
210 subMachineList_.push_back(temp.subsm_);
211 }
212
213 NetworkShareTracker::GetInstance().ModifySharedSubStateMachineList(true, temp.subsm_);
214 if (temp.subsm_ != nullptr) {
215 std::shared_ptr<UpstreamNetworkInfo> upstreamInfo = nullptr;
216 NetworkShareTracker::GetInstance().GetUpstreamInfo(upstreamInfo);
217 NETMGR_EXT_LOG_I("NOTIFY TO SUB SM [%{public}s] CMD_NETSHARE_CONNECTION_CHANGED.",
218 temp.subsm_->GetInterfaceName().c_str());
219 temp.subsm_->SubSmEventHandle(CMD_NETSHARE_CONNECTION_CHANGED, upstreamInfo);
220 }
221 return NETMANAGER_EXT_SUCCESS;
222 }
223
HandleAliveInterfaceStateInactive(const std::any & messageObj)224 int NetworkShareMainStateMachine::HandleAliveInterfaceStateInactive(const std::any &messageObj)
225 {
226 int ret = EraseSharedSubSM(messageObj);
227 if (ret != NETMANAGER_EXT_SUCCESS) {
228 return ret;
229 }
230 if (subMachineList_.size() == 0) {
231 DisableForward();
232 TurnOffMainShareSettings();
233 }
234 return NETMANAGER_EXT_SUCCESS;
235 }
236
EraseSharedSubSM(const std::any & messageObj)237 int NetworkShareMainStateMachine::EraseSharedSubSM(const std::any &messageObj)
238 {
239 const MessageIfaceActive &temp = std::any_cast<const MessageIfaceActive &>(messageObj);
240 if (temp.subsm_ == nullptr) {
241 NETMGR_EXT_LOG_E("subsm[%{public}d] is null.", temp.value_);
242 return NETMANAGER_EXT_ERR_LOCAL_PTR_NULL;
243 }
244 subMachineList_.erase(
245 remove_if(subMachineList_.begin(), subMachineList_.end(),
246 [temp](std::shared_ptr<NetworkShareSubStateMachine> sm) { return sm == temp.subsm_; }),
247 subMachineList_.end());
248
249 NetworkShareTracker::GetInstance().ModifySharedSubStateMachineList(false, temp.subsm_);
250 return NETMANAGER_EXT_SUCCESS;
251 }
252
ChooseUpstreamNetwork()253 void NetworkShareMainStateMachine::ChooseUpstreamNetwork()
254 {
255 sptr<NetHandle> pNetHandle = new (std::nothrow) NetHandle();
256 sptr<NetAllCapabilities> pNetCapabilities = new (std::nothrow) NetAllCapabilities();
257 sptr<NetLinkInfo> pNetLinkInfo = new (std::nothrow) NetLinkInfo();
258 std::shared_ptr<UpstreamNetworkInfo> netInfoPtr =
259 std::make_shared<UpstreamNetworkInfo>(pNetHandle, pNetCapabilities, pNetLinkInfo);
260 if (networkMonitor_ != nullptr && networkMonitor_->GetCurrentGoodUpstream(netInfoPtr)) {
261 upstreamIfaceName_ = netInfoPtr->netLinkPro_->ifaceName_;
262 int32_t result = NetsysController::GetInstance().EnableNat(FAKE_DOWNSTREAM_IFACENAME, upstreamIfaceName_);
263 if (result != NETSYS_SUCCESS) {
264 NetworkShareHisysEvent::GetInstance().SendFaultEvent(
265 NetworkShareEventOperator::OPERATION_CONFIG_FORWARD, NetworkShareEventErrorType::ERROR_CONFIG_FORWARD,
266 ERROR_MSG_ENABLE_FORWARD, NetworkShareEventType::SETUP_EVENT);
267 NETMGR_EXT_LOG_E("Main StateMachine enable NAT newIface[%{public}s] error[%{public}d].",
268 upstreamIfaceName_.c_str(), result);
269 }
270 NetworkShareTracker::GetInstance().SetUpstreamNetHandle(netInfoPtr);
271 }
272 }
273
HandleAliveUpstreamMonitorCallback(const std::any & messageObj)274 int NetworkShareMainStateMachine::HandleAliveUpstreamMonitorCallback(const std::any &messageObj)
275 {
276 if (!NetworkShareTracker::GetInstance().UpstreamWanted()) {
277 NETMGR_EXT_LOG_W("don't need handle upstream callback.");
278 return NETMANAGER_EXT_SUCCESS;
279 }
280 const MessageUpstreamInfo &temp = std::any_cast<const MessageUpstreamInfo &>(messageObj);
281 switch (temp.cmd_) {
282 case EVENT_UPSTREAM_CALLBACK_ON_LINKPROPERTIES: {
283 ChooseUpstreamNetwork();
284 break;
285 }
286 case EVENT_UPSTREAM_CALLBACK_ON_LOST: {
287 DisableForward();
288 break;
289 }
290 case EVENT_UPSTREAM_CALLBACK_ON_CAPABILITIES: {
291 break;
292 }
293 case EVENT_UPSTREAM_CALLBACK_DEFAULT_SWITCHED: {
294 DisableForward();
295 ChooseUpstreamNetwork();
296 break;
297 }
298 default:
299 break;
300 }
301 return NETMANAGER_EXT_SUCCESS;
302 }
303
HandleErrorInterfaceStateInactive(const std::any & messageObj)304 int NetworkShareMainStateMachine::HandleErrorInterfaceStateInactive(const std::any &messageObj)
305 {
306 const MessageIfaceActive &temp = std::any_cast<const MessageIfaceActive &>(messageObj);
307 if (temp.subsm_ == nullptr) {
308 NETMGR_EXT_LOG_E("mode[%{public}d] subsm is null.", temp.value_);
309 return NETMANAGER_EXT_ERR_LOCAL_PTR_NULL;
310 }
311 NETMGR_EXT_LOG_I("NOTIFY TO SUB SM [%{public}s] EVENT[%{public}d].", temp.subsm_->GetInterfaceName().c_str(),
312 errorType_);
313 temp.subsm_->SubSmEventHandle(errorType_, 0);
314 return NETMANAGER_EXT_SUCCESS;
315 }
316
HandleErrorClear(const std::any & messageObj)317 int NetworkShareMainStateMachine::HandleErrorClear(const std::any &messageObj)
318 {
319 (void)messageObj;
320 errorType_ = NETWORKSHARING_SHARING_NO_ERROR;
321 return NETMANAGER_EXT_SUCCESS;
322 }
323
SwitcheToErrorState(int32_t errType)324 void NetworkShareMainStateMachine::SwitcheToErrorState(int32_t errType)
325 {
326 NETMGR_EXT_LOG_W("SwitcheToErrorState errType[%{public}d].", errType);
327 errorType_ = errType;
328 MainSmStateSwitch(MAINSTATE_ERROR);
329 }
330
TurnOnMainShareSettings()331 bool NetworkShareMainStateMachine::TurnOnMainShareSettings()
332 {
333 if (hasSetForward_) {
334 return true;
335 }
336 int32_t result = NetsysController::GetInstance().IpEnableForwarding(netshareRequester_);
337 if (result != NETSYS_SUCCESS) {
338 NetworkShareHisysEvent::GetInstance().SendFaultEvent(NetworkShareEventOperator::OPERATION_TURNON_IP_FORWARD,
339 NetworkShareEventErrorType::ERROR_TURNON_IP_FORWARD,
340 ERROR_MSG_TRUNON, NetworkShareEventType::SETUP_EVENT);
341 NETMGR_EXT_LOG_E("ipfwdEnableForwarding is error, switch error State.");
342 errorType_ = CMD_IP_FORWARDING_ENABLE_ERROR;
343 MainSmStateSwitch(MAINSTATE_ERROR);
344 return false;
345 }
346 hasSetForward_ = true;
347 NETMGR_EXT_LOG_I("turn on main ip forward successful.");
348 return true;
349 }
350
TurnOffMainShareSettings()351 bool NetworkShareMainStateMachine::TurnOffMainShareSettings()
352 {
353 int32_t result = NetsysController::GetInstance().IpDisableForwarding(netshareRequester_);
354 if (result != NETSYS_SUCCESS) {
355 NetworkShareHisysEvent::GetInstance().SendFaultEvent(NetworkShareEventOperator::OPERATION_TURNOFF_IP_FORWARD,
356 NetworkShareEventErrorType::ERROR_TURNOFF_IP_FORWARD,
357 ERROR_MSG_TRUNOFF, NetworkShareEventType::CANCEL_EVENT);
358 NETMGR_EXT_LOG_E("IpfwdDisableForwarding is error, switch to error State.");
359 errorType_ = CMD_IP_FORWARDING_DISABLE_ERROR;
360 MainSmStateSwitch(MAINSTATE_ERROR);
361 return false;
362 }
363 NETMGR_EXT_LOG_I("turn off main ip forward successful, switch to init state.");
364 MainSmStateSwitch(MAINSTATE_INIT);
365 hasSetForward_ = false;
366 return true;
367 }
368
DisableForward()369 void NetworkShareMainStateMachine::DisableForward()
370 {
371 NetworkShareTracker::GetInstance().SetUpstreamNetHandle(nullptr);
372 int32_t result = NetsysController::GetInstance().DisableNat(FAKE_DOWNSTREAM_IFACENAME, upstreamIfaceName_);
373 if (result != NETSYS_SUCCESS) {
374 NetworkShareHisysEvent::GetInstance().SendFaultEvent(
375 NetworkShareEventOperator::OPERATION_CONFIG_FORWARD, NetworkShareEventErrorType::ERROR_CONFIG_FORWARD,
376 ERROR_MSG_DISABLE_FORWARD, NetworkShareEventType::SETUP_EVENT);
377 NETMGR_EXT_LOG_E("MainSM disable NAT newIface[%{public}s] in Lost Network error[%{public}d].",
378 upstreamIfaceName_.c_str(), result);
379 }
380 upstreamIfaceName_ = EMPTY_UPSTREAM_IFACENAME;
381 }
382 } // namespace NetManagerStandard
383 } // namespace OHOS
384