/* * (C) 2021-2022 by sysmocom - s.f.m.c. GmbH * All Rights Reserved. * * Author: Neels Janosch Hofmeyr * * SPDX-License-Identifier: GPL-2.0+ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #include #include #include enum up_peer_fsm_state { UP_PEER_ST_NOT_ASSOCIATED, UP_PEER_ST_ASSOCIATED, UP_PEER_ST_GRACEFUL_RELEASE, }; static const struct value_string up_peer_fsm_event_names[] = { OSMO_VALUE_STRING(UP_PEER_EV_RX_ASSOC_SETUP_REQ), OSMO_VALUE_STRING(UP_PEER_EV_RX_ASSOC_UPD_REQ), OSMO_VALUE_STRING(UP_PEER_EV_RX_SESSION_EST_REQ), OSMO_VALUE_STRING(UP_PEER_EV_HEARTBEAT_FAILURE), {} }; static struct osmo_fsm up_peer_fsm; static const struct osmo_tdef_state_timeout up_peer_fsm_timeouts[32] = { [UP_PEER_ST_GRACEFUL_RELEASE] = { .T = -21 }, }; /* Transition to a state, using the T timer defined in up_peer_fsm_timeouts. * Assumes local variable fi exists. */ #define up_peer_fsm_state_chg(state) \ osmo_tdef_fsm_inst_state_chg(fi, state, \ up_peer_fsm_timeouts, \ g_upf_tdefs, \ 5) struct up_peer *up_peer_alloc(struct osmo_fsm_inst *parent_fi, uint32_t parent_event_term) { struct up_peer *up_peer; struct osmo_fsm_inst *fi = osmo_fsm_inst_alloc_child(&up_peer_fsm, parent_fi, parent_event_term); OSMO_ASSERT(fi); up_peer = talloc(fi, struct up_peer); OSMO_ASSERT(up_peer); fi->priv = up_peer; *up_peer = (struct up_peer){ .fi = fi, }; return up_peer; } static int up_peer_fsm_timer_cb(struct osmo_fsm_inst *fi) { //struct up_peer *up_peer = fi->priv; /* Return 1 to terminate FSM instance, 0 to keep running */ return 1; } static void up_peer_not_associated_action(struct osmo_fsm_inst *fi, uint32_t event, void *data) { //struct up_peer *up_peer = fi->priv; switch (event) { case UP_PEER_EV_RX_ASSOC_SETUP_REQ: // FIXME break; default: OSMO_ASSERT(false); } } static void up_peer_associated_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) { //struct up_peer *up_peer = fi->priv; // FIXME } static void up_peer_associated_action(struct osmo_fsm_inst *fi, uint32_t event, void *data) { //struct up_peer *up_peer = fi->priv; switch (event) { case UP_PEER_EV_RX_ASSOC_UPD_REQ: // FIXME break; case UP_PEER_EV_RX_SESSION_EST_REQ: // FIXME break; case UP_PEER_EV_HEARTBEAT_FAILURE: // FIXME break; default: OSMO_ASSERT(false); } } static void up_peer_graceful_release_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) { //struct up_peer *up_peer = fi->priv; // FIXME } static void up_peer_graceful_release_action(struct osmo_fsm_inst *fi, uint32_t event, void *data) { //struct up_peer *up_peer = fi->priv; switch (event) { case UP_PEER_EV_HEARTBEAT_FAILURE: // FIXME break; default: OSMO_ASSERT(false); } } #define S(x) (1 << (x)) static const struct osmo_fsm_state up_peer_fsm_states[] = { [UP_PEER_ST_NOT_ASSOCIATED] = { .name = "not_associated", .in_event_mask = 0 | S(UP_PEER_EV_RX_ASSOC_SETUP_REQ) , .out_state_mask = 0 | S(UP_PEER_ST_ASSOCIATED) , .action = up_peer_not_associated_action, }, [UP_PEER_ST_ASSOCIATED] = { .name = "associated", .in_event_mask = 0 | S(UP_PEER_EV_RX_ASSOC_UPD_REQ) | S(UP_PEER_EV_RX_SESSION_EST_REQ) | S(UP_PEER_EV_HEARTBEAT_FAILURE) , .out_state_mask = 0 | S(UP_PEER_ST_GRACEFUL_RELEASE) , .onenter = up_peer_associated_onenter, .action = up_peer_associated_action, }, [UP_PEER_ST_GRACEFUL_RELEASE] = { .name = "graceful_release", .in_event_mask = 0 | S(UP_PEER_EV_HEARTBEAT_FAILURE) , .out_state_mask = 0 , .onenter = up_peer_graceful_release_onenter, .action = up_peer_graceful_release_action, }, }; static struct osmo_fsm up_peer_fsm = { .name = "up_peer", .states = up_peer_fsm_states, .num_states = ARRAY_SIZE(up_peer_fsm_states), .log_subsys = DSESSION, .event_names = up_peer_fsm_event_names, .timer_cb = up_peer_fsm_timer_cb, }; static __attribute__((constructor)) void up_peer_fsm_register(void) { OSMO_ASSERT(osmo_fsm_register(&up_peer_fsm) == 0); }