1 /*
2  * Copyright (C) 2021 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 #ifndef OHOS_STA_MACHINE_H
17 #define OHOS_STA_MACHINE_H
18 
19 #include <map>
20 #include <string>
21 #include <vector>
22 #include "handler.h"
23 #include "message_queue.h"
24 #include "state.h"
25 
26 namespace OHOS {
27 namespace Wifi {
28 #define CMD_SET_OPERATIONAL_MODE 1
29 /* Message Processed */
30 static const bool EXECUTED = true;
31 /* The message is not processed. */
32 static const bool NOT_EXECUTED = false;
33 
34 class StateMachineHandler;
35 class StateMachine {
36 public:
37     /**
38      * @Description : StateMachine Initialization Function
39      *
40      * @return true :success, false : failed.
41      */
42     bool InitialStateMachine(const std::string &name = "RunHandleThread");
43 
44     /**
45      * @Description : Start StateMachine.
46      *
47      */
48     void StartStateMachine();
49 
50     /**
51      * @Description : Set Handler.
52      *
53      * @param handler - StateMachineHandler instance.[in]
54      */
55     void SetHandler(StateMachineHandler *handler);
56 
57     /**
58      * @Description : The Message is not handled.
59      *
60      * @param msg - Message object.[in]
61      */
62     void NotExecutedMessage(const InternalMessagePtr msg);
63 
64     /**
65      * @Description Stop Handler Thread.
66      *
67      */
68     void StopHandlerThread();
69 
70     /**
71      * @Description : Start the timer.
72      *
73      * @param timerName - Timer Name.[in]
74      * @param interval - Timer duration, in milliseconds.[in]
75      */
76     virtual void StartTimer(int timerName, int64_t interval);
77 
78     /**
79      * @Description : Stop the timer.
80      *
81      * @param timerName - Timer Name.[in]
82      */
83     virtual void StopTimer(int timerName);
84 
85     /**
86      * @Description : Construct internal messages.
87      *
88      * @return InternalMessagePtr : Pointer to the constructed internal message.
89      */
90     InternalMessagePtr CreateMessage();
91 
92     /**
93      * @Description : Construct an information message based on
94      * the original message.
95      *
96      * @param orig - Original message.[in]
97      * @return InternalMessagePtr : Pointer to the constructed internal message.
98      */
99     InternalMessagePtr CreateMessage(const InternalMessagePtr orig);
100 
101     /**
102      * @Description : Construct internal messages.
103      *
104      * @param msgName - Message Name.[in]
105      * @return InternalMessagePtr : Pointer to the constructed internal message.
106      */
107     InternalMessagePtr CreateMessage(int msgName);
108 
109     /**
110      * @Description : Construct internal messages.
111      *
112      * @param msgName - Message Name.[in]
113      * @param param1 - Message parameters.[in]
114      * @return InternalMessagePtr : Pointer to the constructed internal message.
115      */
116     InternalMessagePtr CreateMessage(int msgName, int param1);
117 
118     /**
119      * @Description : Construct internal messages.
120      *
121      * @param msgName - Message Name.[in]
122      * @param param1 - Message parameters.[in]
123      * @param param2 - Message parameters.[in]
124      * @return InternalMessagePtr : Pointer to the constructed internal message.
125      */
126     InternalMessagePtr CreateMessage(int msgName, int param1, int param2);
127 
128     /**
129      * @Description : Construct internal messages.
130      *
131      * @param msgName - Message Name.[in]
132      * @param messageObj - User-defined data
133      * @return InternalMessagePtr : Pointer to the constructed internal message.
134      */
135     InternalMessagePtr CreateMessage(int msgName, const std::any &messageObj);
136 
137     /**
138      * @Description : Constructs internal messages.
139      *
140      * @param msgName - Message name.[in]
141      * @param param1 - First Message parameter.[in]
142      * @param param2 - Second Message parameter.[in]
143      * @param messageObj - User-defined data
144      * @return InternalMessagePtr : Pointer to the constructed internal message.
145      */
146     InternalMessagePtr CreateMessage(int msgName, int param1, int param2, const std::any &messageObj);
147 
148     /**
149      * @Description : Constructs internal messages and places the
150      * messages in the message queue of the state machine.
151      *
152      * @param msgName - Message name.[in]
153      */
154     virtual void SendMessage(int msgName);
155 
156     /**
157      * @Description : Constructs internal messages and places the messages
158      * in the message queue of the state machine.
159      *
160      * @param msgName - Message name.[in]
161      * @param param1 - Message parameter.[in]
162      */
163     virtual void SendMessage(int msgName, int param1);
164 
165     /**
166      * @Description : Constructs internal messages and places the messages
167      * in the message queue of the state machine.
168      *
169      * @param msgName - Message name.[in]
170      * @param param1 - Message parameter.[in]
171      * @param param2 - Message parameter.[in]
172      */
173     virtual void SendMessage(int msgName, int param1, int param2);
174 
175     /**
176      * @Description : Puts messages into the message queue of the state machine.
177      *
178      * @param msg - Message to be sent.[in]
179      */
180     virtual void SendMessage(InternalMessagePtr msg);
181 
182     /**
183      * @Description : Puts messages into the message queue of the state machine.
184      *
185      * @param msgName - Message Name.[in]
186      * @param messageObj -  User-defined data
187      */
188     virtual void SendMessage(int msgName, const std::any &messageObj);
189 
190     /**
191      * @Description : Puts messages into the message queue of the state machine.
192      *
193      * @param msgName - Message Name.[in]
194      * @param param1 - Message parameters.[in]
195      * @param param2 - Message parameters.[in]
196      * @param messageObj - User-defined data
197      */
198     virtual void SendMessage(int msgName, int param1, int param2, const std::any &messageObj);
199 
200     /**
201      * @Description  Constructs internal messages and places them in the
202      * message queue of the state machine. The messages are processed
203      * after the specified delay time.
204      *
205      * @param msgName - Message Name.[in]
206      * @param delayTimeMs - Delay time, in milliseconds.[in]
207      */
208     void MessageExecutedLater(int msgName, int64_t delayTimeMs);
209 
210     /**
211      * @Description : Constructs internal messages and places them in the
212      * message queue of the state machine. The messages are processed
213      * after the specified delay time.
214      *
215      * @param msgName - Message Name.[in]
216      * @param param1 - Message parameters.[in]
217      * @param delayTimeMs - Delay time, in milliseconds.[in]
218      */
219     void MessageExecutedLater(int msgName, int param1, int64_t delayTimeMs);
220 
221     /**
222      * @Description : Constructs internal messages and places them in the
223      * message queue of the state machine. The messages are processed
224      * after the specified delay time.
225      *
226      * @param msgName - Message Name.[in]
227      * @param param1 - Message parameters.[in]
228      * @param param2 - Message parameters.[in]
229      * @param delayTimeMs - Delay time, in milliseconds.[in]
230      */
231     void MessageExecutedLater(int msgName, int param1, int param2, int64_t delayTimeMs);
232 
233     /**
234      * @Description : Constructs internal messages and places them in the
235      * message queue of the state machine. The messages are processed
236      * after the specified delay time.
237      *
238      * @param msg - Message to be sent.[in]
239      * @param delayTimeMs - Delay time, in milliseconds.[in]
240      */
241     void MessageExecutedLater(InternalMessagePtr msg, int64_t delayTimeMs);
242 
243     /**
244      * @Description : Constructs internal messages and places them in the
245      * message queue of the state machine. The messages are processed
246      * after the specified delay time.
247      *
248      * @param msgName - Message Name.[in]
249      * @param messageObj -User-defined data
250      * @param delayTimeMs - Delay time, in milliseconds.[in]
251      */
252     void MessageExecutedLater(int msgName, const std::any &messageObj, int64_t delayTimeMs);
253 
254     /**
255      * @Description : Constructs internal messages and places them in the
256      * message queue of the state machine. The messages are processed
257      * after the specified delay time.
258      *
259      * @param msgName - Message Name.[in]
260      * @param param1 - Message parameters.[in]
261      * @param param2 - Message parameters.[in]
262      * @param messageObj - User-defined data
263      * @param delayTimeMs - Delay time, in milliseconds.[in]
264      */
265     void MessageExecutedLater(int msgName, int param1, int param2, const std::any &messageObj, int64_t delayTimeMs);
266 
267     /**
268      * @Description : Constructs internal messages and places them in the
269      * front of message queue of the state machine.
270      *
271      * @param msgName - Message Name.[in]
272      * @param param1 - Message parameters.[in]
273      */
274     void SendMessageAtFrontOfQueue(int msgName, int param1);
275 
276     /**
277      * @Description : get current state name.
278      */
279     std::string GetCurStateName();
280 
281 protected:
282     /**
283      * @Description : Construct a new State Machine:: State Machine object.
284      *
285      * @param name - State name.[in]
286      */
287     explicit StateMachine(const std::string &name);
288 
289     /**
290      * @Description : Destroy the State Machine:: State Machine object.
291      *
292      */
293     virtual ~StateMachine();
294 
295     /**
296      * @Description : Add state.
297      *
298      * @param state - state.[in]
299      * @param upper - upper state.[in]
300      */
301     void StatePlus(State *state, State *upper);
302 
303     /**
304      * @Description : Remove state.
305      *
306      * @param state - state.[in]
307      */
308     void StateDelete(State *state);
309 
310     /**
311      * @Description : Set first state.
312      *
313      * @param firstState - First state.[in]
314      */
315     void SetFirstState(State *firstState);
316 
317     /**
318      * @Description : Transition to orther state.
319      *
320      * @param targetState - state.[in]
321      */
322     void SwitchState(State *targetState);
323 
324     /**
325      * @Description : Delay Message.
326      *
327      * @param msg - Message object.[in]
328      */
329     void DelayMessage(const InternalMessagePtr msg);
330 
331 private:
332     StateMachineHandler *pStateMachineHandler;
333     std::string mStateName;
334 };
335 
336 typedef struct StateInfo {
337     State *state;
338     StateInfo *upperStateInfo;
339     bool active;
340 } StateInfo;
341 
342 class StateMachineHandler : public Handler {
343 public:
344     using StateInfoMap = std::map<std::string, StateInfo *>;
345     using StateVector = std::vector<StateInfo *>;
346     using DelayedMessage = std::vector<InternalMessagePtr >;
347 
348     /**
349      * @Description : Construct a new state machine Handler:: StateMachine Handler object.
350      *
351      * @param pStateMgr - Handler pointer.[in]
352      */
353     explicit StateMachineHandler(StateMachine *pStateMgr);
354 
355     /**
356      * @Description : Destroy the StateMachine Handler:: StateMachine Handler object.
357      *
358      */
359     ~StateMachineHandler();
360 
361     /**
362      * @Description : StateMachineHandler Initialization Function.
363      *
364      * @return true : success, false : failed.
365      */
366     bool InitialSmHandler(const std::string &name);
367 
368     /**
369      * @Description : Add a new state.
370      *
371      * @param state - State to be added.[in]
372      * @param upper - upper of state.[in]
373      * @return StateInfo*
374      */
375     StateInfo *StatePlus(State *state, State *upper);
376 
377     /**
378      * @Description : Delete a state.
379      *
380      * @param state - State to be deleted.[in]
381      */
382     void StateDelete(State *state);
383 
384     /**
385      * @Description : Sets the Initialization State.
386      *
387      * @param firstState - Initialization State.[in]
388      */
389     void SetFirstState(State *firstState);
390 
391     /**
392      * @Description : State transition function.
393      *
394      * @param targetState - Destination State.[in]
395      */
396     void SwitchState(State *targetState);
397 
398     /**
399      * @Description : Delay Message Processing Function.
400      *
401      * @param msg - Message body pointer.[in]
402      */
403     void DelayMessage(const InternalMessagePtr msg);
404 
405     /**
406      * @Description : The state machine is constructed.
407      *
408      */
409     void BuildTreeComplete();
410 
411     /**
412      * @Description : get current state name.
413      */
414     std::string GetCurStateName();
415 
416 private:
417     /**
418      * @Description : Sets the initial state sequence.
419      *
420      */
421     void BuildStateInitVector();
422 
423     /**
424      * @Description : Writes the inactive upper states of targetState
425      * and targetState to the sequenceStateVector list.
426      *
427      * @param targetState - Target State Machine.[in]
428      * @return StateInfo*
429      */
430     StateInfo *BuildSequenceStateVector(State *targetState);
431 
432     /**
433      * @Description : Move Delayed Message At Front Of Queue.
434      *
435      */
436     void PlaceDelayedMsgQueueTop();
437 
438     /**
439      * @Description : Release all messages in delayed Messages.
440      *
441      */
442     void ReleaseDelayedMessages();
443 
444     /**
445      * @Description : Fill the status in the sequential status
446      * list in reverse order.
447      *
448      * @return int
449      */
450     int MoveSequenceToStateVector();
451 
452     /**
453      * @Description : Invoke the ExecuteStateMsg interface of the current state
454      * to process messages sent to the state machine. The entry/exit of the
455      * state machine is also called, and the delayed messagei s put back
456      * into queue when transitioning to a new state.
457      *
458      * @param msg - Messages.[in]
459      */
460     void ExecuteMessage(InternalMessagePtr msg) override;
461 
462     /**
463      * @Description : Clean up After Quitting.
464      *
465      */
466     void ClearWhenQuit();
467 
468     /**
469      * @Description : Performing Status Transitions.
470      *
471      * @param msgProcessedState - Message processing status.[in]
472      * @param msg - Messages.[in]
473      */
474     void PerformSwitchState(State *msgProcessedState, InternalMessagePtr msg);
475 
476     /**
477      * @Description : Process messages. If the current state does not process it,
478      * the upper state processing is called, and so on. If all upper states
479      * are not processed, invoke the NotExecutedMessage method of the state machine.
480      *
481      * @param msg - Message body pointer.[in]
482      * @return State*
483      */
484     State *ExecuteTreeStateMsg(InternalMessagePtr msg);
485 
486     /**
487      * @Description : Invoke GoOutState() for each state from the first
488      * state in the list to the public upper state.
489      *
490      * @param commonStateInfo - common upper state machine.[in]
491      */
492     void CallTreeStateExits(StateInfo *commonStateInfo);
493 
494     /**
495      * @Description : Call the GoInState method from the start state
496      * index to the top of the state stack.
497      *
498      * @param index - Start state index of the
499      *                                 state machine list.
500      */
501     void CallTreeStateEnters(int index);
502 
503 private:
504     /* All state mappings of the state machine */
505     StateInfoMap mStateInfoMap;
506     /* From child state to upper state list */
507     StateVector mStateVector;
508     /* Top index of mStateVector */
509     int mStateVectorTopIndex;
510     /* From upper state to child state list */
511     StateVector mSequenceStateVector;
512     /* Top of mSequenceStateVector */
513     int mSequenceStateVectorCount;
514     /* Delayed Message Queue */
515     DelayedMessage mDelayedMessages;
516     /* State machine instance */
517     StateMachine *pStateMachine;
518     /* Initial state */
519     State *pFirstState;
520     /* Target Status */
521     State *pTargetState;
522     /* StateMachine exit or not */
523     bool mQuitFlag;
524     /* Whether the state machine has been built */
525     bool mBuildCompleteFlag;
526     /*
527      * All State exit/enter calls are true before the
528      * last enter call in the target state.
529      */
530     bool mSwitchingStateFlag;
531     /* Current Message */
532     InternalMessagePtr pCurrentMsg;
533 };
534 }  // namespace Wifi
535 }  // namespace OHOS
536 #endif
537