From 53c392a006c434900c7307c1b95ffe3d7f9aed52 Mon Sep 17 00:00:00 2001 From: Neels Hofmeyr Date: Mon, 10 Feb 2020 11:44:34 +0100 Subject: wip Change-Id: I16e229992c00e161d7596e35cc6e6212e564e9fe --- contrib/new_fsm.py | 123 +++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 87 insertions(+), 36 deletions(-) diff --git a/contrib/new_fsm.py b/contrib/new_fsm.py index e584150c..3abc24c3 100755 --- a/contrib/new_fsm.py +++ b/contrib/new_fsm.py @@ -14,6 +14,7 @@ class State: s.events = as_tuple(events) s.out_states = as_tuple(out_states) s.onenter = onenter + def __eq__(s, name): return s.name == name @@ -27,10 +28,10 @@ class Event: class FSM: def NAME(s, name): - return '_'.join((s.prefix, name)).upper() + return '_'.join((s.fsm_name, name)).upper() def name(s, name): - return '_'.join((s.prefix, name)).lower() + return '_'.join((s.fsm_name, name)).lower() def state_const(s, name): return s.NAME('ST_' + name) @@ -38,16 +39,24 @@ class FSM: def event_const(s, name): return s.NAME('EV_' + name) - def __init__(s, prefix, priv, states, head=''): + def __init__(s, fsm_name, priv, states, head=''): s.head = head - s.prefix = prefix + s.fsm_name = fsm_name s.priv = priv s.states = states + first = True for state in s.states: state.const = s.state_const(state.name) out_state_class_insts = [] + if first: + # allow initial transition to self to activate timeout + state.out_states = [state.name] + list(state.out_states) + first = False + for out_state in state.out_states: + if out_state in out_state_class_insts: + continue out_state_class_insts.append(s.states[s.states.index(out_state)]) state.out_states = out_state_class_insts @@ -70,29 +79,48 @@ class FSM: {{head}} #include #include +#include -enum {{prefix}}_fsm_state { +enum {{fsm_name}}_fsm_state { {% for state in states %} {{state.const}}, {% endfor -%} }; -enum {{prefix}}_fsm_event { +enum {{fsm_name}}_fsm_event { {% for event in events %} {{event.const}}, {% endfor -%} }; -static const struct value_string {{prefix}}_fsm_event_names[] = { +static const struct value_string {{fsm_name}}_fsm_event_names[] = { {% for event in events %} OSMO_VALUE_STRING({{event.const}}), {% endfor %} {} }; -static struct osmo_fsm {{prefix}}_fsm; +static struct osmo_fsm {{fsm_name}}_fsm; + +struct osmo_tdef {{fsm_name}}_tdefs[] = { +// FIXME +{% for state in states %} { .T={{(-loop.index)}}, .default_val=5, .desc="{{fsm_name}} {{state.name}} timeout" }, +{% endfor %} {} +}; + +static const struct osmo_tdef_state_timeout {{fsm_name}}_fsm_timeouts[32] = { +// FIXME +{% for state in states %} [{{state.const}}] = { .T={{(-loop.index)}} }, +{% endfor -%} +}; + +#define {{fsm_name}}_fsm_state_chg(state) \\ + osmo_tdef_fsm_inst_state_chg(fi, state, \\ + {{fsm_name}}_fsm_timeouts, \\ + {{fsm_name}}_tdefs, \\ + 5) -struct {{priv}} *{{prefix}}_alloc(struct osmo_fsm_inst *parent_fi, uint32_t parent_event_term) +struct {{priv}} *{{fsm_name}}_alloc(struct osmo_fsm_inst *parent_fi, uint32_t parent_event_term) { struct {{priv}} *{{priv}}; - struct osmo_fsm_inst *fi = osmo_fsm_inst_alloc_child(&{{prefix}}_fsm, parent_fi, parent_event_term); + struct osmo_fsm_inst *fi = osmo_fsm_inst_alloc_child(&{{fsm_name}}_fsm, parent_fi, parent_event_term); OSMO_ASSERT(fi); {{priv}} = talloc(fi, struct {{priv}}); @@ -102,41 +130,43 @@ struct {{priv}} *{{prefix}}_alloc(struct osmo_fsm_inst *parent_fi, uint32_t pare .fi = fi, }; - return {{priv}}; -} + /* Do a state change to activate timeout */ + osmo_fsm_inst_state_chg(fi, {{states[0].const}}); -static int {{prefix}}_fsm_timer_cb(struct osmo_fsm_inst *fi) -{ - //struct {{priv}} *{{priv}} = fi->priv; - /* Return 1 to terminate FSM instance, 0 to keep running */ - return 1; + return {{priv}}; } {% for state in states %} {%- if state.onenter %} -void {{prefix}}_{{state.name}}_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) +static void {{fsm_name}}_{{state.name}}_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) { //struct {{priv}} *{{priv}} = fi->priv; // FIXME } {% endif %} -static void {{prefix}}_{{state.name}}_action(struct osmo_fsm_inst *fi, uint32_t event, void *data) +static void {{fsm_name}}_{{state.name}}_action(struct osmo_fsm_inst *fi, uint32_t event, void *data) { //struct {{priv}} *{{priv}} = fi->priv; switch (event) { - {% for event in state.events %} +{% for event in state.events %} case {{event.const}}: // FIXME break; - {% endfor %} +{% endfor %} default: OSMO_ASSERT(false); } } + +static int {{fsm_name}}_{{state.name}}_timeout(struct osmo_fsm_inst *fi) +{ + /* Return 1 to terminate FSM instance, 0 to keep running */ + return 1; +} {% endfor %} #define S(x) (1 << (x)) -static const struct osmo_fsm_state {{prefix}}_fsm_states[] = { +static const struct osmo_fsm_state {{fsm_name}}_fsm_states[] = { {% for state in states %} [{{state.const}}] = { .name = "{{state.name}}", .in_event_mask = 0 @@ -145,32 +175,53 @@ static const struct osmo_fsm_state {{prefix}}_fsm_states[] = { .out_state_mask = 0 {% for out_state in state.out_states %} | S({{out_state.const}}) {% endfor %} ,{% if state.onenter %} - .onenter = {{prefix}}_{{state.name}}_onenter,{% endif %} - .action = {{prefix}}_{{state.name}}_action, + .onenter = {{fsm_name}}_{{state.name}}_onenter,{% endif %} + .action = {{fsm_name}}_{{state.name}}_action, }, {% endfor -%} }; -static struct osmo_fsm {{prefix}}_fsm = { - .name = "{{prefix}}", - .states = {{prefix}}_fsm_states, - .num_states = ARRAY_SIZE({{prefix}}_fsm_states), +static int {{fsm_name}}_fsm_timer_cb(struct osmo_fsm_inst *fi) +{ + //struct {{priv}} *{{priv}} = fi->priv; + switch (fi->state) { +{% for state in states %} + case {{state.const}}: + return {{fsm_name}}_{{state.name}}_timeout(fi); +{% endfor %} + default: + /* Return 1 to terminate FSM instance, 0 to keep running */ + return 1; + } +} + +static void {{fsm_name}}_fsm_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause) +{ + //struct {{priv}} *{{priv}} = fi->priv; + // FIXME +} + +static struct osmo_fsm {{fsm_name}}_fsm = { + .name = "{{fsm_name}}", + .states = {{fsm_name}}_fsm_states, + .num_states = ARRAY_SIZE({{fsm_name}}_fsm_states), .log_subsys = DLGLOBAL, // FIXME - .event_names = {{prefix}}_fsm_event_names, - .timer_cb = {{prefix}}_fsm_timer_cb, + .event_names = {{fsm_name}}_fsm_event_names, + .timer_cb = {{fsm_name}}_fsm_timer_cb, + .cleanup = {{fsm_name}}_fsm_cleanup, }; -static __attribute__((constructor)) void {{prefix}}_fsm_register(void) +static __attribute__((constructor)) void {{fsm_name}}_fsm_register(void) { - OSMO_ASSERT(osmo_fsm_register(&{{prefix}}_fsm) == 0); + OSMO_ASSERT(osmo_fsm_register(&{{fsm_name}}_fsm) == 0); } ''') return template.render(**vars(s)) fsm = FSM(head='#include ', - prefix = 'proxy_mm', - priv = 'proxy_subscr', + fsm_name = 'proxy_mm', + priv = 'proxy_mm', states = ( State('ready', ('subscr_invalid', 'rx_gsup_lu', 'rx_gsup_sai', ), @@ -200,8 +251,8 @@ all_home_events = ('home_hlr_resolved', 'check_tuples','confirm_lu',) all_home_states = ('wait_home_hlr_resolved', 'wait_update_location_result', 'wait_send_auth_info_result', 'idle', 'clear',) fsm = FSM(head='#include ', - prefix = 'proxy_to_home', - priv = 'proxy_subscr', + fsm_name = 'proxy_to_home', + priv = 'proxy_mm', states = [State(state, all_home_events, all_home_states) for state in all_home_states], ) with open('proxy_to_home.c', 'w') as f: -- cgit v1.2.3