1 /*
2 * Copyright (C) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <cinttypes>
17 #include "state_machine.h"
18 #include "wifi_log.h"
19
20 #undef LOG_TAG
21 #define LOG_TAG "OHWIFI_STATE_MACHINE"
22
23 namespace OHOS {
24 namespace Wifi {
25 static const int SM_INIT_CMD = -2;
StateMachine(const std::string & name)26 StateMachine::StateMachine(const std::string &name) : pStateMachineHandler(nullptr), mStateName(name)
27 {}
28
~StateMachine()29 StateMachine::~StateMachine()
30 {
31 LOGD("StateMachine::~StateMachine");
32 if (pStateMachineHandler != nullptr) {
33 delete pStateMachineHandler;
34 pStateMachineHandler = nullptr;
35 }
36 }
37
InitialStateMachine(const std::string & name)38 bool StateMachine::InitialStateMachine(const std::string &name)
39 {
40 LOGI("InitialStateMachine\n");
41 pStateMachineHandler = new (std::nothrow) StateMachineHandler(this);
42 if (pStateMachineHandler == nullptr) {
43 LOGE("pStateMachineHandler alloc failed.\n");
44 return false;
45 }
46
47 if (!pStateMachineHandler->InitialSmHandler(name)) {
48 LOGE("InitialStateMachineHandler failed.\n");
49 return false;
50 }
51
52 return true;
53 }
54
StartStateMachine()55 void StateMachine::StartStateMachine()
56 {
57 if (pStateMachineHandler == nullptr) {
58 LOGE("StartStateMachine failed, pStateMachineHandler is nullptr!");
59 return;
60 }
61
62 pStateMachineHandler->BuildTreeComplete();
63 return;
64 }
65
SetHandler(StateMachineHandler * handler)66 void StateMachine::SetHandler(StateMachineHandler *handler)
67 {
68 pStateMachineHandler = handler;
69 }
70
NotExecutedMessage(const InternalMessagePtr msg)71 void StateMachine::NotExecutedMessage(const InternalMessagePtr msg)
72 {
73 if (msg == nullptr) {
74 return;
75 }
76 LOGD("msg not handled msg:%{public}d", msg->GetMessageName());
77 }
78
StatePlus(State * state,State * upper)79 void StateMachine::StatePlus(State *state, State *upper)
80 {
81 if (pStateMachineHandler == nullptr) {
82 LOGE("StatePlus failed, pStateMachineHandler is nullptr!");
83 return;
84 }
85
86 pStateMachineHandler->StatePlus(state, upper);
87 }
88
StateDelete(State * state)89 void StateMachine::StateDelete(State *state)
90 {
91 if (pStateMachineHandler == nullptr) {
92 LOGE("StateDelete failed, pStateMachineHandler is nullptr!");
93 return;
94 }
95
96 pStateMachineHandler->StateDelete(state);
97 }
98
SetFirstState(State * firstState)99 void StateMachine::SetFirstState(State *firstState)
100 {
101 if (pStateMachineHandler == nullptr) {
102 LOGE("SetFirstState failed, pStateMachineHandler is nullptr!");
103 return;
104 }
105
106 pStateMachineHandler->SetFirstState(firstState);
107 }
108
SwitchState(State * targetState)109 void StateMachine::SwitchState(State *targetState)
110 {
111 if (pStateMachineHandler == nullptr) {
112 LOGE("SwitchState failed, pStateMachineHandler is nullptr!");
113 return;
114 }
115
116 pStateMachineHandler->SwitchState(targetState);
117 }
118
DelayMessage(const InternalMessagePtr msg)119 void StateMachine::DelayMessage(const InternalMessagePtr msg)
120 {
121 if (pStateMachineHandler == nullptr) {
122 LOGE("DelayMessage failed, pStateMachineHandler is nullptr!");
123 return;
124 }
125
126 pStateMachineHandler->DelayMessage(msg);
127 }
128
StopHandlerThread()129 void StateMachine::StopHandlerThread()
130 {
131 if (pStateMachineHandler == nullptr) {
132 LOGE("StopHandlerThread failed, pStateMachineHandler is nullptr!");
133 return;
134 }
135 pStateMachineHandler->StopHandlerThread();
136 }
137
CreateMessage()138 InternalMessagePtr StateMachine::CreateMessage()
139 {
140 return MessageManage::GetInstance().CreateMessage();
141 }
142
CreateMessage(const InternalMessagePtr orig)143 InternalMessagePtr StateMachine::CreateMessage(const InternalMessagePtr orig)
144 {
145 if (orig == nullptr) {
146 return nullptr;
147 }
148 return MessageManage::GetInstance().CreateMessage(orig);
149 }
150
CreateMessage(int msgName)151 InternalMessagePtr StateMachine::CreateMessage(int msgName)
152 {
153 return MessageManage::GetInstance().CreateMessage(msgName);
154 }
155
CreateMessage(int msgName,int param1)156 InternalMessagePtr StateMachine::CreateMessage(int msgName, int param1)
157 {
158 return MessageManage::GetInstance().CreateMessage(msgName, param1, 0);
159 }
160
CreateMessage(int msgName,int param1,int param2)161 InternalMessagePtr StateMachine::CreateMessage(int msgName, int param1, int param2)
162 {
163 return MessageManage::GetInstance().CreateMessage(msgName, param1, param2);
164 }
165
CreateMessage(int msgName,const std::any & messageObj)166 InternalMessagePtr StateMachine::CreateMessage(int msgName, const std::any &messageObj)
167 {
168 return MessageManage::GetInstance().CreateMessage(msgName, messageObj);
169 }
170
CreateMessage(int msgName,int param1,int param2,const std::any & messageObj)171 InternalMessagePtr StateMachine::CreateMessage(int msgName, int param1, int param2, const std::any &messageObj)
172 {
173 return MessageManage::GetInstance().CreateMessage(msgName, param1, param2, messageObj);
174 }
175
SendMessage(int msgName)176 void StateMachine::SendMessage(int msgName)
177 {
178 pStateMachineHandler->SendMessage(CreateMessage(msgName));
179 return;
180 }
181
SendMessage(int msgName,int param1)182 void StateMachine::SendMessage(int msgName, int param1)
183 {
184 pStateMachineHandler->SendMessage(CreateMessage(msgName, param1));
185 return;
186 }
187
SendMessage(int msgName,int param1,int param2)188 void StateMachine::SendMessage(int msgName, int param1, int param2)
189 {
190 pStateMachineHandler->SendMessage(CreateMessage(msgName, param1, param2));
191 return;
192 }
193
SendMessage(InternalMessagePtr msg)194 void StateMachine::SendMessage(InternalMessagePtr msg)
195 {
196 if (msg == nullptr) {
197 return;
198 }
199 if (pStateMachineHandler != nullptr) {
200 pStateMachineHandler->SendMessage(msg);
201 }
202 return;
203 }
204
SendMessage(int msgName,const std::any & messageObj)205 void StateMachine::SendMessage(int msgName, const std::any &messageObj)
206 {
207 pStateMachineHandler->SendMessage(CreateMessage(msgName, messageObj));
208 return;
209 }
210
SendMessage(int msgName,int param1,int param2,const std::any & messageObj)211 void StateMachine::SendMessage(int msgName, int param1, int param2, const std::any &messageObj)
212 {
213 pStateMachineHandler->SendMessage(CreateMessage(msgName, param1, param2, messageObj));
214 return;
215 }
216
MessageExecutedLater(int msgName,int64_t delayTimeMs)217 void StateMachine::MessageExecutedLater(int msgName, int64_t delayTimeMs)
218 {
219 pStateMachineHandler->MessageExecutedLater(CreateMessage(msgName), delayTimeMs);
220 return;
221 }
222
MessageExecutedLater(int msgName,int param1,int64_t delayTimeMs)223 void StateMachine::MessageExecutedLater(int msgName, int param1, int64_t delayTimeMs)
224 {
225 pStateMachineHandler->MessageExecutedLater(CreateMessage(msgName, param1), delayTimeMs);
226 return;
227 }
228
MessageExecutedLater(int msgName,int param1,int param2,int64_t delayTimeMs)229 void StateMachine::MessageExecutedLater(int msgName, int param1, int param2, int64_t delayTimeMs)
230 {
231 pStateMachineHandler->MessageExecutedLater(CreateMessage(msgName, param1, param2), delayTimeMs);
232 return;
233 }
234
MessageExecutedLater(InternalMessagePtr msg,int64_t delayTimeMs)235 void StateMachine::MessageExecutedLater(InternalMessagePtr msg, int64_t delayTimeMs)
236 {
237 pStateMachineHandler->MessageExecutedLater(msg, delayTimeMs);
238 return;
239 }
240
MessageExecutedLater(int msgName,const std::any & messageObj,int64_t delayTimeMs)241 void StateMachine::MessageExecutedLater(int msgName, const std::any &messageObj, int64_t delayTimeMs)
242 {
243 pStateMachineHandler->MessageExecutedLater(CreateMessage(msgName, messageObj), delayTimeMs);
244 return;
245 }
246
MessageExecutedLater(int msgName,int param1,int param2,const std::any & messageObj,int64_t delayTimeMs)247 void StateMachine::MessageExecutedLater(
248 int msgName, int param1, int param2, const std::any &messageObj, int64_t delayTimeMs)
249 {
250 pStateMachineHandler->MessageExecutedLater(CreateMessage(msgName, param1, param2, messageObj), delayTimeMs);
251 return;
252 }
253
SendMessageAtFrontOfQueue(int msgName,int param1)254 void StateMachine::SendMessageAtFrontOfQueue(int msgName, int param1)
255 {
256 pStateMachineHandler->PlaceMessageTopOfQueue(CreateMessage(msgName, param1));
257 return;
258 }
259
StartTimer(int timerName,int64_t interval)260 void StateMachine::StartTimer(int timerName, int64_t interval)
261 {
262 LOGD("Enter StartTimer, timerName is %{public}d, interval is %" PRId64 ".", timerName, interval);
263 MessageExecutedLater(timerName, interval);
264 return;
265 }
266
StopTimer(int timerName)267 void StateMachine::StopTimer(int timerName)
268 {
269 LOGD("Enter StopTimer, timerName is %{public}d.", timerName);
270 if (pStateMachineHandler != nullptr) {
271 pStateMachineHandler->DeleteMessageFromQueue(timerName);
272 }
273 return;
274 }
275
GetCurStateName()276 std::string StateMachine::GetCurStateName()
277 {
278 LOGD("GetCurStateName");
279 if (pStateMachineHandler == nullptr) {
280 LOGE("GetCurStateName failed, pStateMachineHandler is nullptr!");
281 return "";
282 }
283 return pStateMachineHandler->GetCurStateName();
284 }
285
StateMachineHandler(StateMachine * pStateMgr)286 StateMachineHandler::StateMachineHandler(StateMachine *pStateMgr)
287 {
288 mStateInfoMap.clear();
289 mStateVector.clear();
290 mStateVectorTopIndex = -1;
291 mSequenceStateVector.clear();
292 mSequenceStateVectorCount = 0;
293 mDelayedMessages.clear();
294 pStateMachine = pStateMgr;
295 pFirstState = nullptr;
296 pTargetState = nullptr;
297 mQuitFlag = false;
298 mBuildCompleteFlag = false;
299 mSwitchingStateFlag = false;
300 pCurrentMsg = nullptr;
301 }
302
~StateMachineHandler()303 StateMachineHandler::~StateMachineHandler()
304 {
305 LOGI("~StateMachineHandler");
306 StopHandlerThread();
307 ReleaseDelayedMessages();
308 ClearWhenQuit();
309 return;
310 }
311
InitialSmHandler(const std::string & name)312 bool StateMachineHandler::InitialSmHandler(const std::string &name)
313 {
314 if (!InitialHandler(name)) {
315 LOGE("InitialHandler failed.");
316 return false;
317 }
318 return true;
319 }
320
StatePlus(State * state,State * upper)321 StateInfo *StateMachineHandler::StatePlus(State *state, State *upper)
322 {
323 LOGD("Enter StateMachineHandler::StatePlus function.");
324
325 StateInfo *upperStateInfo = nullptr;
326 StateInfoMap::iterator it = mStateInfoMap.begin();
327 if (upper != nullptr) {
328 it = mStateInfoMap.find(upper->GetStateName());
329 if (it != mStateInfoMap.end()) {
330 upperStateInfo = it->second;
331 }
332 if (upperStateInfo == nullptr) {
333 LOGD("upperStateInfo is null, add upper first. upper->GetStateName():%{public}s",
334 upper->GetStateName().c_str());
335 /* Recursively add our upper as it's not been added yet. */
336 StatePlus(upper, nullptr);
337 } else {
338 LOGD("upperStateInfo is not null, go on.");
339 }
340 }
341
342 StateInfo *stateInfo = nullptr;
343 it = mStateInfoMap.find(state->GetStateName());
344 if (it != mStateInfoMap.end()) {
345 stateInfo = it->second;
346 }
347 if (stateInfo == nullptr) {
348 stateInfo = new (std::nothrow) StateInfo();
349 if (stateInfo == nullptr) {
350 LOGE("failed to new StateInfo!");
351 return nullptr;
352 }
353 mStateInfoMap.insert(StateInfoMap::value_type(state->GetStateName(), stateInfo));
354 }
355
356 /* Validate that we aren't adding the same state in two different hierarchies. */
357 if (stateInfo->upperStateInfo != nullptr && stateInfo->upperStateInfo != upperStateInfo) {
358 LOGE("The same state cannot be added to two different hierarchies!");
359 }
360
361 stateInfo->state = state;
362 stateInfo->upperStateInfo = upperStateInfo;
363 stateInfo->active = false;
364
365 LOGD("successfully added a new state!");
366
367 return stateInfo;
368 }
369
StateDelete(State * state)370 void StateMachineHandler::StateDelete(State *state)
371 {
372 StateInfoMap::iterator it = mStateInfoMap.find(state->GetStateName());
373 StateInfo *stateInfo = nullptr;
374 if (it != mStateInfoMap.end()) {
375 stateInfo = it->second;
376 }
377 if (stateInfo == nullptr || stateInfo->active) {
378 return;
379 }
380
381 it = mStateInfoMap.begin();
382 while (it != mStateInfoMap.end()) {
383 if (it->second->upperStateInfo == stateInfo) {
384 return;
385 }
386 ++it;
387 }
388
389 it = mStateInfoMap.find(state->GetStateName());
390 if (it != mStateInfoMap.end()) {
391 delete it->second;
392 it->second = nullptr;
393 mStateInfoMap.erase(it);
394 }
395 }
396
SetFirstState(State * firstState)397 void StateMachineHandler::SetFirstState(State *firstState)
398 {
399 pFirstState = firstState;
400 }
401
BuildTreeComplete()402 void StateMachineHandler::BuildTreeComplete()
403 {
404 /* Determines the maximum depth of the state hierarchy. */
405 int maxDepth = 0;
406 StateInfoMap::iterator it = mStateInfoMap.begin();
407 while (it != mStateInfoMap.end()) {
408 int depth = 0;
409 StateInfo *tempStateInfo = it->second;
410 while (tempStateInfo != nullptr) {
411 depth++;
412 tempStateInfo = tempStateInfo->upperStateInfo;
413 }
414
415 if (maxDepth < depth) {
416 maxDepth = depth;
417 }
418
419 ++it;
420 }
421
422 LOGD("StateMachineHandler::BuildTreeComplete, maxDepth:%{public}d", maxDepth);
423 mStateVector.resize(maxDepth);
424 mSequenceStateVector.resize(maxDepth);
425 BuildStateInitVector();
426 MessageExecutedAtTime(pStateMachine->CreateMessage(SM_INIT_CMD), 0);
427 return;
428 }
429
BuildStateInitVector()430 void StateMachineHandler::BuildStateInitVector()
431 {
432 LOGD("StateMachineHandler::BuildStateInitVector");
433
434 if (pFirstState == nullptr) {
435 LOGE("StateMachineHandler::BuildStateInitVector please set initial state first!");
436 return;
437 }
438
439 StateInfoMap::iterator it = mStateInfoMap.find(pFirstState->GetStateName());
440 StateInfo *startStateInfo = nullptr;
441 if (it != mStateInfoMap.end()) {
442 startStateInfo = it->second;
443 }
444
445 for (mSequenceStateVectorCount = 0; startStateInfo != nullptr; mSequenceStateVectorCount++) {
446 mSequenceStateVector[mSequenceStateVectorCount] = startStateInfo;
447 startStateInfo = startStateInfo->upperStateInfo;
448 }
449
450 /* Clearing the StateVector. */
451 mStateVectorTopIndex = -1;
452 MoveSequenceToStateVector();
453 }
454
BuildSequenceStateVector(State * targetState)455 StateInfo *StateMachineHandler::BuildSequenceStateVector(State *targetState)
456 {
457 mSequenceStateVectorCount = 0;
458 StateInfoMap::iterator it = mStateInfoMap.find(targetState->GetStateName());
459 StateInfo *curStateInfo = nullptr;
460 if (it != mStateInfoMap.end()) {
461 curStateInfo = it->second;
462 }
463
464 if (curStateInfo == nullptr) {
465 return nullptr;
466 }
467
468 do {
469 mSequenceStateVector[mSequenceStateVectorCount++] = curStateInfo;
470 curStateInfo = curStateInfo->upperStateInfo;
471 } while ((curStateInfo != nullptr) && (!curStateInfo->active));
472
473 return curStateInfo;
474 }
475
PlaceDelayedMsgQueueTop()476 void StateMachineHandler::PlaceDelayedMsgQueueTop()
477 {
478 LOGD("Enter StateMachineHandler::PlaceDelayedMsgQueueTop.");
479 if (mDelayedMessages.size() == 0) {
480 return;
481 }
482 for (int i = mDelayedMessages.size() - 1; i >= 0; i--) {
483 InternalMessagePtr curMsg = mDelayedMessages[i];
484 if (curMsg == nullptr) {
485 LOGE("StateMachineHandler::PlaceDelayedMsgQueueTop: curMsg is null.");
486 continue;
487 }
488 PlaceMessageTopOfQueue(curMsg);
489 }
490 mDelayedMessages.clear();
491
492 return;
493 }
494
ReleaseDelayedMessages()495 void StateMachineHandler::ReleaseDelayedMessages()
496 {
497 if (mDelayedMessages.size() == 0) {
498 return;
499 }
500 for (int i = mDelayedMessages.size() - 1; i >= 0; i--) {
501 InternalMessagePtr curMsg = mDelayedMessages[i];
502 if (curMsg != nullptr) {
503 curMsg = nullptr;
504 }
505 }
506 mDelayedMessages.clear();
507
508 return;
509 }
510
MoveSequenceToStateVector()511 int StateMachineHandler::MoveSequenceToStateVector()
512 {
513 LOGD("StateMachineHandler::MoveSequenceToStateVector mSequenceStateVectorCount:%{public}d",
514 mSequenceStateVectorCount);
515
516 int newIndex = mStateVectorTopIndex + 1;
517 int i = mSequenceStateVectorCount - 1;
518 int j = newIndex;
519 while (i >= 0) {
520 mStateVector[j] = mSequenceStateVector[i];
521 j += 1;
522 i -= 1;
523 }
524
525 mStateVectorTopIndex = j - 1;
526 return newIndex;
527 }
528
SwitchState(State * targetState)529 void StateMachineHandler::SwitchState(State *targetState)
530 {
531 if (targetState == nullptr) {
532 LOGE("targetState is null.");
533 return;
534 }
535 LOGE("SwitchState, Switch to targetState: %{public}s.", targetState->GetStateName().c_str());
536 pTargetState = static_cast<State *>(targetState);
537 }
538
ClearWhenQuit()539 void StateMachineHandler::ClearWhenQuit()
540 {
541 pStateMachine->SetHandler(nullptr);
542 pStateMachine = nullptr;
543 pCurrentMsg = nullptr;
544 mStateVector.clear();
545 mSequenceStateVector.clear();
546 mDelayedMessages.clear();
547 pFirstState = nullptr;
548 pTargetState = nullptr;
549 mQuitFlag = true;
550
551 StateInfoMap::iterator it = mStateInfoMap.begin();
552 while (it != mStateInfoMap.end()) {
553 delete it->second;
554 it->second = nullptr;
555 it = mStateInfoMap.erase(it);
556 }
557 mStateInfoMap.clear();
558 }
559
PerformSwitchState(State * msgProcessedState,InternalMessagePtr msg)560 void StateMachineHandler::PerformSwitchState(State *msgProcessedState, InternalMessagePtr msg)
561 {
562 if (msgProcessedState == nullptr || msg == nullptr) {
563 LOGE("pointer is null.");
564 }
565
566 State *targetState = pTargetState;
567 if (targetState != nullptr) {
568 if (pFirstState != nullptr) {
569 LOGD("StateMachineHandler::PerformSwitchState, Switch %{public}s -->> %{public}s",
570 pFirstState->GetStateName().c_str(), targetState->GetStateName().c_str());
571 }
572 while (true) {
573 StateInfo *commonStateInfo = BuildSequenceStateVector(targetState);
574 mSwitchingStateFlag = true;
575 CallTreeStateExits(commonStateInfo);
576
577 int stateListEnteringIndex = MoveSequenceToStateVector();
578 CallTreeStateEnters(stateListEnteringIndex);
579
580 PlaceDelayedMsgQueueTop();
581
582 if (targetState != pTargetState) {
583 targetState = pTargetState;
584 } else {
585 break;
586 }
587 }
588 pTargetState = nullptr;
589 }
590
591 return;
592 }
593
ExecuteMessage(InternalMessagePtr msg)594 void StateMachineHandler::ExecuteMessage(InternalMessagePtr msg)
595 {
596 if (msg == nullptr) {
597 return;
598 }
599 if (!mQuitFlag) {
600 if (pStateMachine != nullptr && msg->GetMessageName() != SM_INIT_CMD) {
601 }
602
603 pCurrentMsg = msg;
604
605 State *msgProcessedState = nullptr;
606 if (mBuildCompleteFlag) {
607 LOGD("StateMachineHandler::ExecuteMessage ExecuteTreeStateMsg!");
608 msgProcessedState = ExecuteTreeStateMsg(msg);
609 } else if (!mBuildCompleteFlag && msg->GetMessageName() == SM_INIT_CMD) {
610 LOGD("StateMachineHandler::ExecuteMessage msg: SM_INIT_CMD");
611 mBuildCompleteFlag = true;
612 CallTreeStateEnters(0);
613 } else {
614 LOGE("The start method not called!");
615 }
616
617 if (pStateMachine != nullptr) {
618 PerformSwitchState(msgProcessedState, msg);
619 } else {
620 LOGE("pointer is null.");
621 }
622
623 if (pStateMachine != nullptr && msg->GetMessageName() != SM_INIT_CMD) {
624 }
625 }
626
627 return;
628 }
629
DelayMessage(const InternalMessagePtr msg)630 void StateMachineHandler::DelayMessage(const InternalMessagePtr msg)
631 {
632 LOGD("Enter StateMachineHandler::DelayMessage.");
633 if (msg == nullptr) {
634 return;
635 }
636
637 InternalMessagePtr newMsg = pStateMachine->CreateMessage(msg);
638 if (newMsg == nullptr) {
639 LOGE("StateMachineHandler::DelayMessage: newMsg is null.");
640 return;
641 }
642 mDelayedMessages.push_back(newMsg);
643 return;
644 }
645
ExecuteTreeStateMsg(InternalMessagePtr msg)646 State *StateMachineHandler::ExecuteTreeStateMsg(InternalMessagePtr msg)
647 {
648 LOGD("StateMachineHandler::ExecuteTreeStateMsg mStateVectorTopIndex:%{public}d", mStateVectorTopIndex);
649 if (msg == nullptr) {
650 LOGE("ExecuteTreeStateMsg, msg is nullptr.");
651 return nullptr;
652 }
653
654 StateInfo *curStateInfo = mStateVector[mStateVectorTopIndex];
655 if (curStateInfo == nullptr) {
656 LOGE("ExecuteTreeStateMsg, curStateInfo is nullptr.");
657 return nullptr;
658 }
659
660 if (curStateInfo->state) {
661 LOGD("ExecuteTreeStateMsg, State machine: %{public}s execute Cmd:%{public}d",
662 curStateInfo->state->GetStateName().c_str(), msg->GetMessageName());
663 }
664
665 while (curStateInfo->state && (!curStateInfo->state->ExecuteStateMsg(msg))) {
666 curStateInfo = curStateInfo->upperStateInfo;
667
668 if (curStateInfo == nullptr) {
669 pStateMachine->NotExecutedMessage(msg);
670 break;
671 }
672 }
673
674 return (curStateInfo != nullptr) ? curStateInfo->state : nullptr;
675 }
676
CallTreeStateExits(StateInfo * commonStateInfo)677 void StateMachineHandler::CallTreeStateExits(StateInfo *commonStateInfo)
678 {
679 while ((mStateVectorTopIndex >= 0) && (mStateVector[mStateVectorTopIndex] != commonStateInfo)) {
680 if (mStateVector[mStateVectorTopIndex] != nullptr) {
681 State *curState = mStateVector[mStateVectorTopIndex]->state;
682 if (curState != nullptr) {
683 curState->GoOutState();
684 }
685 mStateVector[mStateVectorTopIndex]->active = false;
686 }
687 mStateVectorTopIndex -= 1;
688 }
689 }
690
CallTreeStateEnters(int index)691 void StateMachineHandler::CallTreeStateEnters(int index)
692 {
693 for (int i = index; i <= mStateVectorTopIndex; i++) {
694 if (index == mStateVectorTopIndex) {
695 /* Last enter state for transition. */
696 mSwitchingStateFlag = false;
697 }
698 LOGD("StateMachineHandler::CallTreeStateEnters mStateVectorTopIndex:%{public}d, i: %{public}d",
699 mStateVectorTopIndex,
700 i);
701 if (mStateVector[i] != nullptr && mStateVector[i]->state != nullptr) {
702 mStateVector[i]->state->GoInState();
703 mStateVector[i]->active = true;
704 }
705 }
706 /* ensure flag set to false if no methods called. */
707 mSwitchingStateFlag = false;
708 }
709
GetCurStateName()710 std::string StateMachineHandler::GetCurStateName()
711 {
712 StateInfo *curStateInfo = mStateVector[mStateVectorTopIndex];
713 if (curStateInfo == nullptr) {
714 LOGE("StateInfo is null.");
715 return "";
716 }
717 return curStateInfo->state->GetStateName();
718 }
719 } // namespace Wifi
720 } // namespace OHOS
721