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 Hierarchical State Machine (HSM) 40*bb8a927bSDirk Helbig * 41*bb8a927bSDirk Helbig */ 42*bb8a927bSDirk Helbig 43*bb8a927bSDirk Helbig #ifndef BTSTACK_HSM_H 44*bb8a927bSDirk Helbig #define BTSTACK_HSM_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_hsm_signal_t; 53*bb8a927bSDirk Helbig enum btstack_hsm_reserved_signals_e { 54*bb8a927bSDirk Helbig BTSTACK_HSM_EMPTY_SIG, 55*bb8a927bSDirk Helbig BTSTACK_HSM_INIT_SIG, 56*bb8a927bSDirk Helbig BTSTACK_HSM_ENTRY_SIG, 57*bb8a927bSDirk Helbig BTSTACK_HSM_EXIT_SIG, 58*bb8a927bSDirk Helbig BTSTACK_HSM_USER_SIG 59*bb8a927bSDirk Helbig }; 60*bb8a927bSDirk Helbig 61*bb8a927bSDirk Helbig typedef struct { 62*bb8a927bSDirk Helbig btstack_hsm_signal_t sig; 63*bb8a927bSDirk Helbig } btstack_hsm_event_t; 64*bb8a927bSDirk Helbig typedef struct btstack_hsm_s btstack_hsm_t; 65*bb8a927bSDirk Helbig typedef enum { 66*bb8a927bSDirk Helbig BTSTACK_HSM_TRAN_STATUS, 67*bb8a927bSDirk Helbig BTSTACK_HSM_SUPER_STATUS, 68*bb8a927bSDirk Helbig BTSTACK_HSM_HANDLED_STATUS, 69*bb8a927bSDirk Helbig BTSTACK_HSM_UNHANDLED_STATUS, 70*bb8a927bSDirk Helbig BTSTACK_HSM_IGNORED_STATUS 71*bb8a927bSDirk Helbig } btstack_hsm_state_t; 72*bb8a927bSDirk Helbig 73*bb8a927bSDirk Helbig typedef btstack_hsm_state_t (*btstack_hsm_state_handler_t)(btstack_hsm_t * const me, btstack_hsm_event_t const * const e); 74*bb8a927bSDirk Helbig 75*bb8a927bSDirk Helbig struct btstack_hsm_s { 76*bb8a927bSDirk Helbig btstack_hsm_state_handler_t state; 77*bb8a927bSDirk Helbig btstack_hsm_state_handler_t temp; 78*bb8a927bSDirk Helbig btstack_hsm_state_handler_t *path; 79*bb8a927bSDirk Helbig int_fast8_t depth; 80*bb8a927bSDirk Helbig }; 81*bb8a927bSDirk Helbig 82*bb8a927bSDirk Helbig /* API_START */ 83*bb8a927bSDirk Helbig 84*bb8a927bSDirk Helbig /* 85*bb8a927bSDirk Helbig * @brief Request the transition from the current state to the given new state 86*bb8a927bSDirk Helbig * @param me the current state machine 87*bb8a927bSDirk Helbig * @param target the new state to transit to 88*bb8a927bSDirk Helbig * @result transition status 89*bb8a927bSDirk Helbig */ 90*bb8a927bSDirk Helbig btstack_hsm_state_t btstack_hsm_transit(btstack_hsm_t * const me, btstack_hsm_state_handler_t const target); 91*bb8a927bSDirk Helbig 92*bb8a927bSDirk Helbig /* 93*bb8a927bSDirk Helbig * @brief Specifies the upper state in a state hierarchy 94*bb8a927bSDirk Helbig * @param me the current state machine 95*bb8a927bSDirk Helbig * @param target the next parent state in the hierarchy 96*bb8a927bSDirk Helbig * @result transition status 97*bb8a927bSDirk Helbig */ 98*bb8a927bSDirk Helbig btstack_hsm_state_t btstack_hsm_super(btstack_hsm_t * const me, btstack_hsm_state_handler_t const target); 99*bb8a927bSDirk Helbig 100*bb8a927bSDirk Helbig /* 101*bb8a927bSDirk Helbig * @brief Placeholder state to mark the top most state in a state hierarchy, the root state. Ignores all events. 102*bb8a927bSDirk Helbig * @param me the current state machine 103*bb8a927bSDirk Helbig * @param e event 104*bb8a927bSDirk Helbig * @result ignored status 105*bb8a927bSDirk Helbig */ 106*bb8a927bSDirk Helbig btstack_hsm_state_t btstack_hsm_top(btstack_hsm_t * const me, btstack_hsm_event_t const * const e); 107*bb8a927bSDirk Helbig 108*bb8a927bSDirk Helbig /* 109*bb8a927bSDirk Helbig * @brief Constructs a new state hierarchical machine machine, with storage for maximum hierarchy depth. 110*bb8a927bSDirk Helbig * @param me the current state machine 111*bb8a927bSDirk Helbig * @param initial the initial state 112*bb8a927bSDirk Helbig * @param array of btstack_hsm_state_handler_t elements with the same number of elements as the maximum number of nested state machines. 113*bb8a927bSDirk Helbig * @param The number of nested state machines. 114*bb8a927bSDirk Helbig */ 115*bb8a927bSDirk Helbig void btstack_hsm_constructor(btstack_hsm_t * const me, btstack_hsm_state_handler_t initial, btstack_hsm_state_handler_t path[], int8_t depth); 116*bb8a927bSDirk Helbig 117*bb8a927bSDirk Helbig /* 118*bb8a927bSDirk Helbig * @brief Takes the initial transition of the state machine and sending it a BTSTACK_HSM_INIT_SIG 119*bb8a927bSDirk Helbig * @param me the current state machine 120*bb8a927bSDirk Helbig * @param e event 121*bb8a927bSDirk Helbig */ 122*bb8a927bSDirk Helbig void btstack_hsm_init(btstack_hsm_t * const me, btstack_hsm_event_t const * const e); 123*bb8a927bSDirk Helbig 124*bb8a927bSDirk Helbig /* 125*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. 126*bb8a927bSDirk Helbig * Honoring the hierarchy and handling entering/exiting all states on the way. 127*bb8a927bSDirk Helbig * @param me the current state machine 128*bb8a927bSDirk Helbig * @param e event 129*bb8a927bSDirk Helbig */ 130*bb8a927bSDirk Helbig btstack_hsm_state_t btstack_hsm_dispatch(btstack_hsm_t * const me, btstack_hsm_event_t const * const e); 131*bb8a927bSDirk Helbig 132*bb8a927bSDirk Helbig /* API_END */ 133*bb8a927bSDirk Helbig 134*bb8a927bSDirk Helbig #if defined __cplusplus 135*bb8a927bSDirk Helbig } 136*bb8a927bSDirk Helbig #endif 137*bb8a927bSDirk Helbig 138*bb8a927bSDirk Helbig #endif 139