18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*
28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant/hostapd - State machine definitions
38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2002-2005, Jouni Malinen <j@w1.fi>
48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license.
6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details.
78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This file includes a set of pre-processor macros that can be used to
98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * implement a state machine. In addition to including this header file, each
108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * file implementing a state machine must define STATE_MACHINE_DATA to be the
118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * data structure including state variables (enum machine_state,
128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Boolean changed), and STATE_MACHINE_DEBUG_PREFIX to be a string that is used
138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * as a prefix for all debug messages. If SM_ENTRY_MA macro is used to define
148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * a group of state machines with shared data structure, STATE_MACHINE_ADDR
158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * needs to be defined to point to the MAC address used in debug output.
168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * SM_ENTRY_M macro can be used to define similar group of state machines
178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * without this additional debug info.
188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef STATE_MACHINE_H
218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define STATE_MACHINE_H
228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * SM_STATE - Declaration of a state machine function
258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @machine: State machine name
268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @state: State machine state
278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This macro is used to declare a state machine function. It is used in place
298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * of a C function definition to declare functions to be run when the state is
308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * entered by calling SM_ENTER or SM_ENTER_GLOBAL.
318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define SM_STATE(machine, state) \
338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void sm_ ## machine ## _ ## state ## _Enter(STATE_MACHINE_DATA *sm, \
348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int global)
358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * SM_ENTRY - State machine function entry point
388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @machine: State machine name
398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @state: State machine state
408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This macro is used inside each state machine function declared with
428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * SM_STATE. SM_ENTRY should be in the beginning of the function body, but
438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * after declaration of possible local variables. This macro prints debug
448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * information about state transition and update the state machine state.
458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define SM_ENTRY(machine, state) \
478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtif (!global || sm->machine ## _state != machine ## _ ## state) { \
488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	sm->changed = TRUE; \
498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, STATE_MACHINE_DEBUG_PREFIX ": " #machine \
508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   " entering state " #state); \
518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} \
528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtsm->machine ## _state = machine ## _ ## state;
538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * SM_ENTRY_M - State machine function entry point for state machine group
568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @machine: State machine name
578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @_state: State machine state
588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @data: State variable prefix (full variable: prefix_state)
598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This macro is like SM_ENTRY, but for state machine groups that use a shared
618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * data structure for more than one state machine. Both machine and prefix
628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * parameters are set to "sub-state machine" name. prefix is used to allow more
638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * than one state variable to be stored in the same data structure.
648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define SM_ENTRY_M(machine, _state, data) \
668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtif (!global || sm->data ## _ ## state != machine ## _ ## _state) { \
678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	sm->changed = TRUE; \
688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, STATE_MACHINE_DEBUG_PREFIX ": " \
698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   #machine " entering state " #_state); \
708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} \
718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtsm->data ## _ ## state = machine ## _ ## _state;
728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * SM_ENTRY_MA - State machine function entry point for state machine group
758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @machine: State machine name
768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @_state: State machine state
778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @data: State variable prefix (full variable: prefix_state)
788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This macro is like SM_ENTRY_M, but a MAC address is included in debug
808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * output. STATE_MACHINE_ADDR has to be defined to point to the MAC address to
818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * be included in debug.
828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define SM_ENTRY_MA(machine, _state, data) \
848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtif (!global || sm->data ## _ ## state != machine ## _ ## _state) { \
858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	sm->changed = TRUE; \
868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, STATE_MACHINE_DEBUG_PREFIX ": " MACSTR " " \
878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   #machine " entering state " #_state, \
888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   MAC2STR(STATE_MACHINE_ADDR)); \
898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} \
908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtsm->data ## _ ## state = machine ## _ ## _state;
918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * SM_ENTER - Enter a new state machine state
948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @machine: State machine name
958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @state: State machine state
968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This macro expands to a function call to a state machine function defined
988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * with SM_STATE macro. SM_ENTER is used in a state machine step function to
998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * move the state machine to a new state.
1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define SM_ENTER(machine, state) \
1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtsm_ ## machine ## _ ## state ## _Enter(sm, 0)
1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * SM_ENTER_GLOBAL - Enter a new state machine state based on global rule
1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @machine: State machine name
1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @state: State machine state
1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This macro is like SM_ENTER, but this is used when entering a new state
1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * based on a global (not specific to any particular state) rule. A separate
1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * macro is used to avoid unwanted debug message floods when the same global
1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * rule is forcing a state machine to remain in on state.
1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define SM_ENTER_GLOBAL(machine, state) \
1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtsm_ ## machine ## _ ## state ## _Enter(sm, 1)
1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * SM_STEP - Declaration of a state machine step function
1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @machine: State machine name
1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This macro is used to declare a state machine step function. It is used in
1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * place of a C function definition to declare a function that is used to move
1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * state machine to a new state based on state variables. This function uses
1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * SM_ENTER and SM_ENTER_GLOBAL macros to enter new state.
1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define SM_STEP(machine) \
1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void sm_ ## machine ## _Step(STATE_MACHINE_DATA *sm)
1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * SM_STEP_RUN - Call the state machine step function
1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @machine: State machine name
1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This macro expands to a function call to a state machine step function
1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * defined with SM_STEP macro.
1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define SM_STEP_RUN(machine) sm_ ## machine ## _Step(sm)
1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* STATE_MACHINE_H */
139