1189251Ssam/*
2189251Ssam * wpa_supplicant/hostapd - State machine definitions
3189251Ssam * Copyright (c) 2002-2005, Jouni Malinen <j@w1.fi>
4189251Ssam *
5252726Srpaulo * This software may be distributed under the terms of the BSD license.
6252726Srpaulo * See README for more details.
7189251Ssam *
8189251Ssam * This file includes a set of pre-processor macros that can be used to
9189251Ssam * implement a state machine. In addition to including this header file, each
10189251Ssam * file implementing a state machine must define STATE_MACHINE_DATA to be the
11189251Ssam * data structure including state variables (enum machine_state,
12189251Ssam * Boolean changed), and STATE_MACHINE_DEBUG_PREFIX to be a string that is used
13189251Ssam * as a prefix for all debug messages. If SM_ENTRY_MA macro is used to define
14189251Ssam * a group of state machines with shared data structure, STATE_MACHINE_ADDR
15189251Ssam * needs to be defined to point to the MAC address used in debug output.
16189251Ssam * SM_ENTRY_M macro can be used to define similar group of state machines
17189251Ssam * without this additional debug info.
18189251Ssam */
19189251Ssam
20189251Ssam#ifndef STATE_MACHINE_H
21189251Ssam#define STATE_MACHINE_H
22189251Ssam
23189251Ssam/**
24189251Ssam * SM_STATE - Declaration of a state machine function
25189251Ssam * @machine: State machine name
26189251Ssam * @state: State machine state
27189251Ssam *
28189251Ssam * This macro is used to declare a state machine function. It is used in place
29189251Ssam * of a C function definition to declare functions to be run when the state is
30189251Ssam * entered by calling SM_ENTER or SM_ENTER_GLOBAL.
31189251Ssam */
32189251Ssam#define SM_STATE(machine, state) \
33189251Ssamstatic void sm_ ## machine ## _ ## state ## _Enter(STATE_MACHINE_DATA *sm, \
34189251Ssam	int global)
35189251Ssam
36189251Ssam/**
37189251Ssam * SM_ENTRY - State machine function entry point
38189251Ssam * @machine: State machine name
39189251Ssam * @state: State machine state
40189251Ssam *
41189251Ssam * This macro is used inside each state machine function declared with
42189251Ssam * SM_STATE. SM_ENTRY should be in the beginning of the function body, but
43189251Ssam * after declaration of possible local variables. This macro prints debug
44189251Ssam * information about state transition and update the state machine state.
45189251Ssam */
46189251Ssam#define SM_ENTRY(machine, state) \
47189251Ssamif (!global || sm->machine ## _state != machine ## _ ## state) { \
48189251Ssam	sm->changed = TRUE; \
49189251Ssam	wpa_printf(MSG_DEBUG, STATE_MACHINE_DEBUG_PREFIX ": " #machine \
50189251Ssam		   " entering state " #state); \
51189251Ssam} \
52189251Ssamsm->machine ## _state = machine ## _ ## state;
53189251Ssam
54189251Ssam/**
55189251Ssam * SM_ENTRY_M - State machine function entry point for state machine group
56189251Ssam * @machine: State machine name
57189251Ssam * @_state: State machine state
58189251Ssam * @data: State variable prefix (full variable: prefix_state)
59189251Ssam *
60189251Ssam * This macro is like SM_ENTRY, but for state machine groups that use a shared
61189251Ssam * data structure for more than one state machine. Both machine and prefix
62189251Ssam * parameters are set to "sub-state machine" name. prefix is used to allow more
63189251Ssam * than one state variable to be stored in the same data structure.
64189251Ssam */
65189251Ssam#define SM_ENTRY_M(machine, _state, data) \
66189251Ssamif (!global || sm->data ## _ ## state != machine ## _ ## _state) { \
67189251Ssam	sm->changed = TRUE; \
68189251Ssam	wpa_printf(MSG_DEBUG, STATE_MACHINE_DEBUG_PREFIX ": " \
69189251Ssam		   #machine " entering state " #_state); \
70189251Ssam} \
71189251Ssamsm->data ## _ ## state = machine ## _ ## _state;
72189251Ssam
73189251Ssam/**
74189251Ssam * SM_ENTRY_MA - State machine function entry point for state machine group
75189251Ssam * @machine: State machine name
76189251Ssam * @_state: State machine state
77189251Ssam * @data: State variable prefix (full variable: prefix_state)
78189251Ssam *
79189251Ssam * This macro is like SM_ENTRY_M, but a MAC address is included in debug
80189251Ssam * output. STATE_MACHINE_ADDR has to be defined to point to the MAC address to
81189251Ssam * be included in debug.
82189251Ssam */
83189251Ssam#define SM_ENTRY_MA(machine, _state, data) \
84189251Ssamif (!global || sm->data ## _ ## state != machine ## _ ## _state) { \
85189251Ssam	sm->changed = TRUE; \
86189251Ssam	wpa_printf(MSG_DEBUG, STATE_MACHINE_DEBUG_PREFIX ": " MACSTR " " \
87189251Ssam		   #machine " entering state " #_state, \
88189251Ssam		   MAC2STR(STATE_MACHINE_ADDR)); \
89189251Ssam} \
90189251Ssamsm->data ## _ ## state = machine ## _ ## _state;
91189251Ssam
92189251Ssam/**
93189251Ssam * SM_ENTER - Enter a new state machine state
94189251Ssam * @machine: State machine name
95189251Ssam * @state: State machine state
96189251Ssam *
97189251Ssam * This macro expands to a function call to a state machine function defined
98189251Ssam * with SM_STATE macro. SM_ENTER is used in a state machine step function to
99189251Ssam * move the state machine to a new state.
100189251Ssam */
101189251Ssam#define SM_ENTER(machine, state) \
102189251Ssamsm_ ## machine ## _ ## state ## _Enter(sm, 0)
103189251Ssam
104189251Ssam/**
105189251Ssam * SM_ENTER_GLOBAL - Enter a new state machine state based on global rule
106189251Ssam * @machine: State machine name
107189251Ssam * @state: State machine state
108189251Ssam *
109189251Ssam * This macro is like SM_ENTER, but this is used when entering a new state
110189251Ssam * based on a global (not specific to any particular state) rule. A separate
111189251Ssam * macro is used to avoid unwanted debug message floods when the same global
112189251Ssam * rule is forcing a state machine to remain in on state.
113189251Ssam */
114189251Ssam#define SM_ENTER_GLOBAL(machine, state) \
115189251Ssamsm_ ## machine ## _ ## state ## _Enter(sm, 1)
116189251Ssam
117189251Ssam/**
118189251Ssam * SM_STEP - Declaration of a state machine step function
119189251Ssam * @machine: State machine name
120189251Ssam *
121189251Ssam * This macro is used to declare a state machine step function. It is used in
122189251Ssam * place of a C function definition to declare a function that is used to move
123189251Ssam * state machine to a new state based on state variables. This function uses
124189251Ssam * SM_ENTER and SM_ENTER_GLOBAL macros to enter new state.
125189251Ssam */
126189251Ssam#define SM_STEP(machine) \
127189251Ssamstatic void sm_ ## machine ## _Step(STATE_MACHINE_DATA *sm)
128189251Ssam
129189251Ssam/**
130189251Ssam * SM_STEP_RUN - Call the state machine step function
131189251Ssam * @machine: State machine name
132189251Ssam *
133189251Ssam * This macro expands to a function call to a state machine step function
134189251Ssam * defined with SM_STEP macro.
135189251Ssam */
136189251Ssam#define SM_STEP_RUN(machine) sm_ ## machine ## _Step(sm)
137189251Ssam
138189251Ssam#endif /* STATE_MACHINE_H */
139