16d49e1aeSJan Lentfer /*
26d49e1aeSJan Lentfer  * wpa_supplicant/hostapd - State machine definitions
36d49e1aeSJan Lentfer  * Copyright (c) 2002-2005, Jouni Malinen <j@w1.fi>
46d49e1aeSJan Lentfer  *
5*3ff40c12SJohn Marino  * This software may be distributed under the terms of the BSD license.
6*3ff40c12SJohn Marino  * See README for more details.
76d49e1aeSJan Lentfer  *
86d49e1aeSJan Lentfer  * This file includes a set of pre-processor macros that can be used to
96d49e1aeSJan Lentfer  * implement a state machine. In addition to including this header file, each
106d49e1aeSJan Lentfer  * file implementing a state machine must define STATE_MACHINE_DATA to be the
116d49e1aeSJan Lentfer  * data structure including state variables (enum machine_state,
126d49e1aeSJan Lentfer  * Boolean changed), and STATE_MACHINE_DEBUG_PREFIX to be a string that is used
136d49e1aeSJan Lentfer  * as a prefix for all debug messages. If SM_ENTRY_MA macro is used to define
146d49e1aeSJan Lentfer  * a group of state machines with shared data structure, STATE_MACHINE_ADDR
156d49e1aeSJan Lentfer  * needs to be defined to point to the MAC address used in debug output.
166d49e1aeSJan Lentfer  * SM_ENTRY_M macro can be used to define similar group of state machines
176d49e1aeSJan Lentfer  * without this additional debug info.
186d49e1aeSJan Lentfer  */
196d49e1aeSJan Lentfer 
206d49e1aeSJan Lentfer #ifndef STATE_MACHINE_H
216d49e1aeSJan Lentfer #define STATE_MACHINE_H
226d49e1aeSJan Lentfer 
236d49e1aeSJan Lentfer /**
246d49e1aeSJan Lentfer  * SM_STATE - Declaration of a state machine function
256d49e1aeSJan Lentfer  * @machine: State machine name
266d49e1aeSJan Lentfer  * @state: State machine state
276d49e1aeSJan Lentfer  *
286d49e1aeSJan Lentfer  * This macro is used to declare a state machine function. It is used in place
296d49e1aeSJan Lentfer  * of a C function definition to declare functions to be run when the state is
306d49e1aeSJan Lentfer  * entered by calling SM_ENTER or SM_ENTER_GLOBAL.
316d49e1aeSJan Lentfer  */
326d49e1aeSJan Lentfer #define SM_STATE(machine, state) \
336d49e1aeSJan Lentfer static void sm_ ## machine ## _ ## state ## _Enter(STATE_MACHINE_DATA *sm, \
346d49e1aeSJan Lentfer 	int global)
356d49e1aeSJan Lentfer 
366d49e1aeSJan Lentfer /**
376d49e1aeSJan Lentfer  * SM_ENTRY - State machine function entry point
386d49e1aeSJan Lentfer  * @machine: State machine name
396d49e1aeSJan Lentfer  * @state: State machine state
406d49e1aeSJan Lentfer  *
416d49e1aeSJan Lentfer  * This macro is used inside each state machine function declared with
426d49e1aeSJan Lentfer  * SM_STATE. SM_ENTRY should be in the beginning of the function body, but
436d49e1aeSJan Lentfer  * after declaration of possible local variables. This macro prints debug
446d49e1aeSJan Lentfer  * information about state transition and update the state machine state.
456d49e1aeSJan Lentfer  */
466d49e1aeSJan Lentfer #define SM_ENTRY(machine, state) \
476d49e1aeSJan Lentfer if (!global || sm->machine ## _state != machine ## _ ## state) { \
486d49e1aeSJan Lentfer 	sm->changed = TRUE; \
496d49e1aeSJan Lentfer 	wpa_printf(MSG_DEBUG, STATE_MACHINE_DEBUG_PREFIX ": " #machine \
506d49e1aeSJan Lentfer 		   " entering state " #state); \
516d49e1aeSJan Lentfer } \
526d49e1aeSJan Lentfer sm->machine ## _state = machine ## _ ## state;
536d49e1aeSJan Lentfer 
546d49e1aeSJan Lentfer /**
556d49e1aeSJan Lentfer  * SM_ENTRY_M - State machine function entry point for state machine group
566d49e1aeSJan Lentfer  * @machine: State machine name
576d49e1aeSJan Lentfer  * @_state: State machine state
586d49e1aeSJan Lentfer  * @data: State variable prefix (full variable: prefix_state)
596d49e1aeSJan Lentfer  *
606d49e1aeSJan Lentfer  * This macro is like SM_ENTRY, but for state machine groups that use a shared
616d49e1aeSJan Lentfer  * data structure for more than one state machine. Both machine and prefix
626d49e1aeSJan Lentfer  * parameters are set to "sub-state machine" name. prefix is used to allow more
636d49e1aeSJan Lentfer  * than one state variable to be stored in the same data structure.
646d49e1aeSJan Lentfer  */
656d49e1aeSJan Lentfer #define SM_ENTRY_M(machine, _state, data) \
666d49e1aeSJan Lentfer if (!global || sm->data ## _ ## state != machine ## _ ## _state) { \
676d49e1aeSJan Lentfer 	sm->changed = TRUE; \
686d49e1aeSJan Lentfer 	wpa_printf(MSG_DEBUG, STATE_MACHINE_DEBUG_PREFIX ": " \
696d49e1aeSJan Lentfer 		   #machine " entering state " #_state); \
706d49e1aeSJan Lentfer } \
716d49e1aeSJan Lentfer sm->data ## _ ## state = machine ## _ ## _state;
726d49e1aeSJan Lentfer 
736d49e1aeSJan Lentfer /**
746d49e1aeSJan Lentfer  * SM_ENTRY_MA - State machine function entry point for state machine group
756d49e1aeSJan Lentfer  * @machine: State machine name
766d49e1aeSJan Lentfer  * @_state: State machine state
776d49e1aeSJan Lentfer  * @data: State variable prefix (full variable: prefix_state)
786d49e1aeSJan Lentfer  *
796d49e1aeSJan Lentfer  * This macro is like SM_ENTRY_M, but a MAC address is included in debug
806d49e1aeSJan Lentfer  * output. STATE_MACHINE_ADDR has to be defined to point to the MAC address to
816d49e1aeSJan Lentfer  * be included in debug.
826d49e1aeSJan Lentfer  */
836d49e1aeSJan Lentfer #define SM_ENTRY_MA(machine, _state, data) \
846d49e1aeSJan Lentfer if (!global || sm->data ## _ ## state != machine ## _ ## _state) { \
856d49e1aeSJan Lentfer 	sm->changed = TRUE; \
866d49e1aeSJan Lentfer 	wpa_printf(MSG_DEBUG, STATE_MACHINE_DEBUG_PREFIX ": " MACSTR " " \
876d49e1aeSJan Lentfer 		   #machine " entering state " #_state, \
886d49e1aeSJan Lentfer 		   MAC2STR(STATE_MACHINE_ADDR)); \
896d49e1aeSJan Lentfer } \
906d49e1aeSJan Lentfer sm->data ## _ ## state = machine ## _ ## _state;
916d49e1aeSJan Lentfer 
926d49e1aeSJan Lentfer /**
936d49e1aeSJan Lentfer  * SM_ENTER - Enter a new state machine state
946d49e1aeSJan Lentfer  * @machine: State machine name
956d49e1aeSJan Lentfer  * @state: State machine state
966d49e1aeSJan Lentfer  *
976d49e1aeSJan Lentfer  * This macro expands to a function call to a state machine function defined
986d49e1aeSJan Lentfer  * with SM_STATE macro. SM_ENTER is used in a state machine step function to
996d49e1aeSJan Lentfer  * move the state machine to a new state.
1006d49e1aeSJan Lentfer  */
1016d49e1aeSJan Lentfer #define SM_ENTER(machine, state) \
1026d49e1aeSJan Lentfer sm_ ## machine ## _ ## state ## _Enter(sm, 0)
1036d49e1aeSJan Lentfer 
1046d49e1aeSJan Lentfer /**
1056d49e1aeSJan Lentfer  * SM_ENTER_GLOBAL - Enter a new state machine state based on global rule
1066d49e1aeSJan Lentfer  * @machine: State machine name
1076d49e1aeSJan Lentfer  * @state: State machine state
1086d49e1aeSJan Lentfer  *
1096d49e1aeSJan Lentfer  * This macro is like SM_ENTER, but this is used when entering a new state
1106d49e1aeSJan Lentfer  * based on a global (not specific to any particular state) rule. A separate
1116d49e1aeSJan Lentfer  * macro is used to avoid unwanted debug message floods when the same global
1126d49e1aeSJan Lentfer  * rule is forcing a state machine to remain in on state.
1136d49e1aeSJan Lentfer  */
1146d49e1aeSJan Lentfer #define SM_ENTER_GLOBAL(machine, state) \
1156d49e1aeSJan Lentfer sm_ ## machine ## _ ## state ## _Enter(sm, 1)
1166d49e1aeSJan Lentfer 
1176d49e1aeSJan Lentfer /**
1186d49e1aeSJan Lentfer  * SM_STEP - Declaration of a state machine step function
1196d49e1aeSJan Lentfer  * @machine: State machine name
1206d49e1aeSJan Lentfer  *
1216d49e1aeSJan Lentfer  * This macro is used to declare a state machine step function. It is used in
1226d49e1aeSJan Lentfer  * place of a C function definition to declare a function that is used to move
1236d49e1aeSJan Lentfer  * state machine to a new state based on state variables. This function uses
1246d49e1aeSJan Lentfer  * SM_ENTER and SM_ENTER_GLOBAL macros to enter new state.
1256d49e1aeSJan Lentfer  */
1266d49e1aeSJan Lentfer #define SM_STEP(machine) \
1276d49e1aeSJan Lentfer static void sm_ ## machine ## _Step(STATE_MACHINE_DATA *sm)
1286d49e1aeSJan Lentfer 
1296d49e1aeSJan Lentfer /**
1306d49e1aeSJan Lentfer  * SM_STEP_RUN - Call the state machine step function
1316d49e1aeSJan Lentfer  * @machine: State machine name
1326d49e1aeSJan Lentfer  *
1336d49e1aeSJan Lentfer  * This macro expands to a function call to a state machine step function
1346d49e1aeSJan Lentfer  * defined with SM_STEP macro.
1356d49e1aeSJan Lentfer  */
1366d49e1aeSJan Lentfer #define SM_STEP_RUN(machine) sm_ ## machine ## _Step(sm)
1376d49e1aeSJan Lentfer 
1386d49e1aeSJan Lentfer #endif /* STATE_MACHINE_H */
139