supplicant_backend_fsm.c
Go to the documentation of this file.
1 /**
2  * @file supplicant_backend_fsm.c
3  * @brief Supplicant backend state machine
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2022-2024 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneEAP Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.4.0
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL SUPPLICANT_TRACE_LEVEL
33 
34 //Dependencies
35 #include "supplicant/supplicant.h"
40 #include "eap/eap_debug.h"
41 #include "debug.h"
42 
43 //Check TCP/IP stack configuration
44 #if (SUPPLICANT_SUPPORT == ENABLED)
45 
46 //Supplicant backend states
48 {
57 };
58 
59 
60 /**
61  * @brief Supplicant backend state machine initialization
62  * @param[in] context Pointer to the 802.1X supplicant context
63  **/
64 
66 {
67  //Enter initial state
69 }
70 
71 
72 /**
73  * @brief Supplicant backend state machine implementation
74  * @param[in] context Pointer to the 802.1X supplicant context
75  **/
76 
78 {
79  //A global transition can occur from any of the possible states
80  if(context->initialize || context->suppAbort)
81  {
82  //When the condition associated with a global transition is met, it
83  //supersedes all other exit conditions
85  }
86  else
87  {
88  //All exit conditions for the state are evaluated continuously until one
89  //of the conditions is met (refer to IEEE Std 802.1X-2004, section 8.2.1)
90  switch(context->suppBackendState)
91  {
92  //INITIALIZE state?
94  //Unconditional transition (UCT) to IDLE state
96  break;
97 
98  //IDLE state?
100  //Evaluate conditions for the current state
101  if(context->eapFail && context->suppStart)
102  {
103  //Switch to the FAIL state
105  }
106  else if(context->eapolEap && context->suppStart)
107  {
108  //Switch to the REQUEST state
110  }
111  else if(context->eapSuccess && context->suppStart)
112  {
113  //Switch to the SUCCESS state
115  }
116  else
117  {
118  //Just for sanity
119  }
120 
121  break;
122 
123  //REQUEST state?
125  //Evaluate conditions for the current state
126  if(context->eapFail)
127  {
128  //Switch to the FAIL state
130  }
131  else if(context->eapNoResp)
132  {
133  //Switch to the RECEIVE state
135  }
136  else if(context->eapResp)
137  {
138  //Switch to the RESPONSE state
140  }
141  else if(context->eapSuccess)
142  {
143  //Switch to the SUCCESS state
145  }
146  else
147  {
148  //Just for sanity
149  }
150 
151  break;
152 
153  //RESPONSE state?
155  //Unconditional transition (UCT) to RECEIVE state
157  break;
158 
159  //RECEIVE state?
161  //Evaluate conditions for the current state
162  if(context->eapolEap)
163  {
164  //Switch to the REQUEST state
166  }
167  else if(context->eapFail)
168  {
169  //Switch to the FAIL state
171  }
172  else if(context->authWhile == 0)
173  {
174  //Switch to the TIMEOUT state
176  }
177  else if(context->eapSuccess)
178  {
179  //Switch to the SUCCESS state
181  }
182  else
183  {
184  //Just for sanity
185  }
186 
187  break;
188 
189  //FAIL state?
191  //Unconditional transition (UCT) to IDLE state
193  break;
194 
195  //TIMEOUT state?
197  //Unconditional transition (UCT) to IDLE state
199  break;
200 
201  //SUCCESS state?
203  //Unconditional transition (UCT) to IDLE state
205  break;
206 
207  //Invalid state?
208  default:
209  //Just for sanity
210  supplicantFsmError(context);
211  break;
212  }
213  }
214 }
215 
216 
217 /**
218  * @brief Update supplicant backend state
219  * @param[in] context Pointer to the 802.1X supplicant context
220  * @param[in] newState New state to switch to
221  **/
222 
224  SupplicantBackendState newState)
225 {
226  SupplicantBackendState oldState;
227 
228  //Retrieve current state
229  oldState = context->suppBackendState;
230 
231  //Any state change?
232  if(newState != oldState)
233  {
234  //Dump the state transition
235  TRACE_DEBUG("Supplicant Backend state machine %s -> %s\r\n",
240  }
241 
242  //Switch to the new state
243  context->suppBackendState = newState;
244 
245  //On entry to a state, the procedures defined for the state are executed
246  //exactly once (refer to IEEE Std 802.1X-2004, section 8.2.1)
247  switch(newState)
248  {
249  //INITIALIZE state?
251  //System initialization
252  supplicantAbortSupp(context);
253  context->suppAbort = FALSE;
254  //Errata
255  context->eapReq = FALSE;
256  break;
257 
258  //IDLE state?
260  //The state machine is waiting for the supplicant state machine to signal
261  //the start of a new authentication session
262  context->suppStart = FALSE;
263  break;
264 
265  //REQUEST state?
267  //The state machine has received an EAP request from the authenticator,
268  //and invokes EAP to perform whatever processing is needed in order to
269  //acquire the information that will form the response
270  context->authWhile = 0;
271  context->eapReq = TRUE;
272  supplicantGetSuppRsp(context);
273  break;
274 
275  //RESPONSE state?
277  //The appropriate EAP response constructed by EAP is transmitted to the
278  //authenticator
279  supplicantTxSuppRsp(context);
280  context->eapResp = FALSE;
281  break;
282 
283  //RECEIVE state?
285  //The supplicant is waiting for the next EAP request from the
286  //authenticator
287  context->authWhile = context->authPeriod;
288  context->eapolEap = FALSE;
289  context->eapNoResp = FALSE;
290  break;
291 
292  //FAIL state?
294  //The authentication session has terminated unsuccessfully
295  context->suppFail = TRUE;
296  //Errata
297  context->eapolEap = FALSE;
298  break;
299 
300  //TIMEOUT state?
302  //The authentication session has terminated due to a timeout
303  context->suppTimeout = TRUE;
304  break;
305 
306  //SUCCESS state?
308  //The authentication session has terminated successfully
309  context->keyRun = TRUE;
310  context->suppSuccess = TRUE;
311  //Errata
312  context->eapolEap = FALSE;
313  break;
314 
315  //Invalid state?
316  default:
317  //Just for sanity
318  break;
319  }
320 
321  //Any state change?
322  if(newState != oldState)
323  {
324  //Any registered callback?
325  if(context->backendStateChangeCallback != NULL)
326  {
327  //Invoke user callback function
328  context->backendStateChangeCallback(context, newState);
329  }
330  }
331 
332  //Check whether the port is enabled
333  if(!context->initialize && context->portEnabled)
334  {
335  //The supplicant backend state machine is busy
336  context->busy = TRUE;
337  }
338 }
339 
340 #endif
Debugging facilities.
#define TRACE_DEBUG(...)
Definition: debug.h:107
const char_t * eapGetParamName(uint_t value, const EapParamName *paramList, size_t paramListLen)
Convert a parameter to string representation.
Definition: eap_debug.c:219
Data logging functions for debugging purpose (EAP)
#define arraysize(a)
Definition: os_port.h:71
#define TRUE
Definition: os_port.h:50
#define FALSE
Definition: os_port.h:46
Parameter value/name binding.
Definition: eap_debug.h:50
802.1X supplicant
#define SupplicantContext
Definition: supplicant.h:36
const EapParamName supplicantBackendStates[]
void supplicantBackendChangeState(SupplicantContext *context, SupplicantBackendState newState)
Update supplicant backend state.
void supplicantBackendInitFsm(SupplicantContext *context)
Supplicant backend state machine initialization.
void supplicantBackendFsm(SupplicantContext *context)
Supplicant backend state machine implementation.
Supplicant backend state machine.
SupplicantBackendState
Supplicant backend states.
@ SUPPLICANT_BACKEND_STATE_TIMEOUT
@ SUPPLICANT_BACKEND_STATE_REQUEST
@ SUPPLICANT_BACKEND_STATE_RESPONSE
@ SUPPLICANT_BACKEND_STATE_SUCCESS
@ SUPPLICANT_BACKEND_STATE_RECEIVE
@ SUPPLICANT_BACKEND_STATE_INITIALIZE
@ SUPPLICANT_BACKEND_STATE_FAIL
@ SUPPLICANT_BACKEND_STATE_IDLE
void supplicantFsmError(SupplicantContext *context)
Supplicant state machine error handler.
Supplicant state machine.
Helper functions for 802.1X supplicant.
void supplicantTxSuppRsp(SupplicantContext *context)
Transmit an EAPOL-Packet packet (8.2.12.1.3 c)
void supplicantAbortSupp(SupplicantContext *context)
Release any system resources (8.2.12.1.3 a)
void supplicantGetSuppRsp(SupplicantContext *context)
Get the information required in order to respond to the EAP request (8.2.12.1.3 b)
Supplicant state machine procedures.