1*bb8a927bSDirk Helbig /* 2*bb8a927bSDirk Helbig * Copyright (C) 2024 BlueKitchen GmbH 3*bb8a927bSDirk Helbig * 4*bb8a927bSDirk Helbig * Redistribution and use in source and binary forms, with or without 5*bb8a927bSDirk Helbig * modification, are permitted provided that the following conditions 6*bb8a927bSDirk Helbig * are met: 7*bb8a927bSDirk Helbig * 8*bb8a927bSDirk Helbig * 1. Redistributions of source code must retain the above copyright 9*bb8a927bSDirk Helbig * notice, this list of conditions and the following disclaimer. 10*bb8a927bSDirk Helbig * 2. Redistributions in binary form must reproduce the above copyright 11*bb8a927bSDirk Helbig * notice, this list of conditions and the following disclaimer in the 12*bb8a927bSDirk Helbig * documentation and/or other materials provided with the distribution. 13*bb8a927bSDirk Helbig * 3. Neither the name of the copyright holders nor the names of 14*bb8a927bSDirk Helbig * contributors may be used to endorse or promote products derived 15*bb8a927bSDirk Helbig * from this software without specific prior written permission. 16*bb8a927bSDirk Helbig * 4. Any redistribution, use, or modification is done solely for 17*bb8a927bSDirk Helbig * personal benefit and not for any commercial purpose or for 18*bb8a927bSDirk Helbig * monetary gain. 19*bb8a927bSDirk Helbig * 20*bb8a927bSDirk Helbig * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 21*bb8a927bSDirk Helbig * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22*bb8a927bSDirk Helbig * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23*bb8a927bSDirk Helbig * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN 24*bb8a927bSDirk Helbig * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25*bb8a927bSDirk Helbig * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26*bb8a927bSDirk Helbig * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 27*bb8a927bSDirk Helbig * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28*bb8a927bSDirk Helbig * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29*bb8a927bSDirk Helbig * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 30*bb8a927bSDirk Helbig * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31*bb8a927bSDirk Helbig * SUCH DAMAGE. 32*bb8a927bSDirk Helbig * 33*bb8a927bSDirk Helbig * Please inquire about commercial licensing options at 34*bb8a927bSDirk Helbig * [email protected] 35*bb8a927bSDirk Helbig * 36*bb8a927bSDirk Helbig */ 37*bb8a927bSDirk Helbig 38*bb8a927bSDirk Helbig /** 39*bb8a927bSDirk Helbig * @title Finite State Machine (FSM) 40*bb8a927bSDirk Helbig * 41*bb8a927bSDirk Helbig */ 42*bb8a927bSDirk Helbig 43*bb8a927bSDirk Helbig #ifndef BTSTACK_FSM_H 44*bb8a927bSDirk Helbig #define BTSTACK_FSM_H 45*bb8a927bSDirk Helbig 46*bb8a927bSDirk Helbig #if defined __cplusplus 47*bb8a927bSDirk Helbig extern "C" { 48*bb8a927bSDirk Helbig #endif 49*bb8a927bSDirk Helbig 50*bb8a927bSDirk Helbig #include <stdint.h> 51*bb8a927bSDirk Helbig 52*bb8a927bSDirk Helbig typedef uint16_t btstack_fsm_signal_t; 53*bb8a927bSDirk Helbig enum btstack_fsm_reserved_signals_e { 54*bb8a927bSDirk Helbig BTSTACK_FSM_EMPTY_SIG, 55*bb8a927bSDirk Helbig BTSTACK_FSM_INIT_SIG, 56*bb8a927bSDirk Helbig BTSTACK_FSM_ENTRY_SIG, 57*bb8a927bSDirk Helbig BTSTACK_FSM_EXIT_SIG, 58*bb8a927bSDirk Helbig BTSTACK_FSM_USER_SIG 59*bb8a927bSDirk Helbig }; 60*bb8a927bSDirk Helbig 61*bb8a927bSDirk Helbig typedef struct { 62*bb8a927bSDirk Helbig btstack_fsm_signal_t sig; 63*bb8a927bSDirk Helbig } btstack_fsm_event_t; 64*bb8a927bSDirk Helbig 65*bb8a927bSDirk Helbig typedef struct btstack_fsm_s btstack_fsm_t; 66*bb8a927bSDirk Helbig 67*bb8a927bSDirk Helbig typedef enum { 68*bb8a927bSDirk Helbig BTSTACK_FSM_TRAN_STATUS, 69*bb8a927bSDirk Helbig BTSTACK_FSM_SUPER_STATUS, 70*bb8a927bSDirk Helbig BTSTACK_FSM_HANDLED_STATUS, 71*bb8a927bSDirk Helbig BTSTACK_FSM_UNHANDLED_STATUS, 72*bb8a927bSDirk Helbig BTSTACK_FSM_IGNORED_STATUS 73*bb8a927bSDirk Helbig } btstack_fsm_state_t; 74*bb8a927bSDirk Helbig 75*bb8a927bSDirk Helbig typedef btstack_fsm_state_t (*btstack_fsm_state_handler_t)(btstack_fsm_t * const me, btstack_fsm_event_t const * const e); 76*bb8a927bSDirk Helbig 77*bb8a927bSDirk Helbig struct btstack_fsm_s { 78*bb8a927bSDirk Helbig btstack_fsm_state_handler_t state; 79*bb8a927bSDirk Helbig }; 80*bb8a927bSDirk Helbig 81*bb8a927bSDirk Helbig /* API_START */ 82*bb8a927bSDirk Helbig 83*bb8a927bSDirk Helbig /* 84*bb8a927bSDirk Helbig * @brief Request the transition from the current state to the given new state 85*bb8a927bSDirk Helbig * @param me the current state machine 86*bb8a927bSDirk Helbig * @param target the new state to transit to 87*bb8a927bSDirk Helbig * @result transition status 88*bb8a927bSDirk Helbig */ 89*bb8a927bSDirk Helbig btstack_fsm_state_t btstack_fsm_transit(btstack_fsm_t * const me, btstack_fsm_state_handler_t target); 90*bb8a927bSDirk Helbig 91*bb8a927bSDirk Helbig /* 92*bb8a927bSDirk Helbig * @brief Constructs a new state hierarchical machine machine, with storage for maximum hierarchy depth. 93*bb8a927bSDirk Helbig * @param me the current state machine 94*bb8a927bSDirk Helbig * @param initial the initial state 95*bb8a927bSDirk Helbig */ 96*bb8a927bSDirk Helbig void btstack_fsm_constructor(btstack_fsm_t * const me, btstack_fsm_state_handler_t initial); 97*bb8a927bSDirk Helbig 98*bb8a927bSDirk Helbig /* 99*bb8a927bSDirk Helbig * @brief Takes the initial transition of the state machine and sending it a BTSTACK_HSM_INIT_SIG 100*bb8a927bSDirk Helbig * @param me the current state machine 101*bb8a927bSDirk Helbig * @param e event 102*bb8a927bSDirk Helbig */ 103*bb8a927bSDirk Helbig void btstack_fsm_init(btstack_fsm_t * const me, btstack_fsm_event_t const * const e); 104*bb8a927bSDirk Helbig 105*bb8a927bSDirk Helbig /* 106*bb8a927bSDirk Helbig * @brief Dispatches the given event to the state machine, if a transition is requested, leave the old states and enter the new on. 107*bb8a927bSDirk Helbig * Handling entering/exiting all states on the way. 108*bb8a927bSDirk Helbig * @param me the current state machine 109*bb8a927bSDirk Helbig * @param e event 110*bb8a927bSDirk Helbig */ 111*bb8a927bSDirk Helbig btstack_fsm_state_t btstack_fsm_dispatch(btstack_fsm_t * const me, btstack_fsm_event_t const * const e); 112*bb8a927bSDirk Helbig 113*bb8a927bSDirk Helbig /* 114*bb8a927bSDirk Helbig * @brief Dispatches the given event to the state machine until it was handled. 115*bb8a927bSDirk Helbig * @param me the current state machine 116*bb8a927bSDirk Helbig * @param e event 117*bb8a927bSDirk Helbig */ 118*bb8a927bSDirk Helbig void btstack_fsm_dispatch_until(btstack_fsm_t * const me, btstack_fsm_event_t const * const e); 119*bb8a927bSDirk Helbig 120*bb8a927bSDirk Helbig /* API_END */ 121*bb8a927bSDirk Helbig 122*bb8a927bSDirk Helbig #if defined __cplusplus 123*bb8a927bSDirk Helbig } 124*bb8a927bSDirk Helbig #endif 125*bb8a927bSDirk Helbig 126*bb8a927bSDirk Helbig #endif 127*bb8a927bSDirk Helbig 128