diff --git a/src/v5x_le_port_fsm.c b/src/v5x_le_port_fsm.c new file mode 100644 index 0000000..c2384e3 --- /dev/null +++ b/src/v5x_le_port_fsm.c @@ -0,0 +1,848 @@ +/* ITU-T G.964 Section 14.1.3.2.2 ISDN user port FSM - LE */ + +/***********************************************************************/ +/* internal data structures */ +/***********************************************************************/ + +#include +#include + +#include "v5x_internal.h" +#include "v5x_protocol.h" +#include "v5x_le_ctrl_fsm.h" +#include "v5x_le_management.h" +#include "logging.h" + +#define S(x) (1 << (x)) + +/***********************************************************************/ +/* state names, event names, primitives, ... */ +/***********************************************************************/ + +/* 14.1.3.2.2 ISDN user port FSM - LE(ISDN port) */ +enum v5x_le_isdn_port_state { + V5X_LE_UP_I_S_LE10_NOP_BLOCKED, /* LE1.0 */ + V5X_LE_UP_I_S_LE11_NOP_LOCAL_UNBLOCK, /* LE1.1 */ + V5X_LE_UP_I_S_LE12_NOP_REMOTE_UNBLOCK, /* LE1.2 */ + V5X_LE_UP_I_S_LE20_OP_OPERATIONAL_DEACTIVTED, /* LE2.0 */ + V5X_LE_UP_I_S_LE21_OP_ACTIVATION_INITIATED, /* LE2.1 */ + V5X_LE_UP_I_S_LE22_OP_ACCESS_ACTIVATED, /* LE2.2 */ +}; + +/* 14.2.3.2.2 PSTN user port FSM - LE(PSTN port) */ +enum v5x_le_pstn_port_state { + V5X_LE_UP_P_S_LE10_NOP_BLOCKED, /* LE1.0 */ + V5X_LE_UP_P_S_LE11_NOP_LOCAL_UNBLOCK, /* LE1.1 */ + V5X_LE_UP_P_S_LE12_NOP_REMOTE_UNBLOCK, /* LE1.2 */ + V5X_LE_UP_P_S_LE20_OPERATIONAL, /* LE2.0 */ +}; + +enum v5x_le_ctrl_port_fsm_event { + /* inbound function elements from AN (Table 34/G.964) */ + V5X_CUP_LE_FE102_ACTIV_INIT_USER_IND, + V5X_CUP_LE_FE103_DS_ACTIVATED_IND, + V5X_CUP_LE_FE104_ACCESS_ACTIVATED_IND, + V5X_CUP_LE_FE106_ACCESS_DEACTIVATED_IND, + V5X_CUP_LE_FE202_UNBLOCK, + V5X_CUP_LE_FE204_BLOCK_CMD, + V5X_CUP_LE_FE205_BLOCK_REQ, + V5X_CUP_LE_FE206_PREFORMANCE_GRADING_IND, + /* inbound primitives from Mgmt (Table 35/G.964) */ + V5X_CUP_LE_MPH_UBR_UNBLOCK_REQ, + V5X_CUP_LE_MPH_BI_BLOCK_CMD, + V5X_CUP_LE_MPH_AR_ACTIVATE_ACCESS_REQ, + V5X_CUP_LE_MPH_DR_DEACTIVATE_ACCESS_REQ, + V5X_CUP_LE_MPH_DB_BLOCK_DCHAN_REQ, + V5X_CUP_LE_MPH_DU_BLOCK_DCHAN_REQ, +}; + +static const struct value_string v5x_le_ctrl_port_fsm_event_names[] = { + { V5X_CUP_LE_FE102_ACTIV_INIT_USER_IND, "FE102 Activation by user indication" }, + { V5X_CUP_LE_FE103_DS_ACTIVATED_IND, "FE103 DS Activated indication" }, + { V5X_CUP_LE_FE104_ACCESS_ACTIVATED_IND, "FE104 Access activated indication" }, + { V5X_CUP_LE_FE106_ACCESS_DEACTIVATED_IND, "FE106 Access deactivated indication" }, + { V5X_CUP_LE_FE202_UNBLOCK, "FE202 Unblock request or ack" }, + { V5X_CUP_LE_FE204_BLOCK_CMD, "FE204 Block command" }, + { V5X_CUP_LE_FE205_BLOCK_REQ, "FE205 Block request" }, + { V5X_CUP_LE_FE206_PREFORMANCE_GRADING_IND, "FE206 Performance grading info" }, + { V5X_CUP_LE_MPH_UBR_UNBLOCK_REQ, "MPH-UBR Unblock request" }, + { V5X_CUP_LE_MPH_BI_BLOCK_CMD, "MPH-BI Block command" }, + { V5X_CUP_LE_MPH_AR_ACTIVATE_ACCESS_REQ, "MPH-AR Activate access" }, + { V5X_CUP_LE_MPH_DR_DEACTIVATE_ACCESS_REQ, "MPH-DR Deactivate access" }, + { V5X_CUP_LE_MPH_DB_BLOCK_DCHAN_REQ, "MPH-DB Block D-channel" }, + { V5X_CUP_LE_MPH_DU_BLOCK_DCHAN_REQ, "MPH-DU Unblock D-channel" }, + { 0, NULL } +}; + +/***********************************************************************/ +/* upper layer interface */ +/***********************************************************************/ + +static void v5x_mph_rcv(struct osmo_fsm_inst *fi, enum v5x_mph_prim prim, uint8_t perf_grading) +{ + struct v5x_user_port *v5up = fi->priv; + + v5x_mph_rcv_an(v5up, prim, perf_grading); +} + +void v5x_mph_snd(struct v5x_user_port *v5up, enum v5x_mph_prim prim) +{ + struct osmo_fsm_inst *fi = v5up->port_fi; + enum v5x_le_ctrl_port_fsm_event event; + + switch (prim) { + case MPH_UBR: + event = V5X_CUP_LE_MPH_UBR_UNBLOCK_REQ; + break; + case MPH_BI: + event = V5X_CUP_LE_MPH_BI_BLOCK_CMD; + break; + case MPH_AR: + event = V5X_CUP_LE_MPH_AR_ACTIVATE_ACCESS_REQ; + break; + case MPH_DR: + event = V5X_CUP_LE_MPH_DR_DEACTIVATE_ACCESS_REQ; + break; + case MPH_DB: + event = V5X_CUP_LE_MPH_DB_BLOCK_DCHAN_REQ; + break; + case MPH_DU: + event = V5X_CUP_LE_MPH_DU_BLOCK_DCHAN_REQ; + break; + default: + LOGP(DV5PORT, LOGL_NOTICE, "Got invalid prim %d at this protocol\n", prim); + return; + } + + /* send event to FSM */ + osmo_fsm_inst_dispatch(fi, event, NULL); +} + +/***********************************************************************/ +/* ISDN port state FSM */ +/***********************************************************************/ + +static void isdn_up_le10_blocked(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct v5x_user_port *v5up = fi->priv; + + switch (event) { + case V5X_CUP_LE_FE102_ACTIV_INIT_USER_IND: + case V5X_CUP_LE_FE103_DS_ACTIVATED_IND: + case V5X_CUP_LE_FE104_ACCESS_ACTIVATED_IND: + case V5X_CUP_LE_MPH_DR_DEACTIVATE_ACCESS_REQ: + case V5X_CUP_LE_FE106_ACCESS_DEACTIVATED_IND: + /* ignore */ + break; + case V5X_CUP_LE_MPH_UBR_UNBLOCK_REQ: + osmo_fsm_inst_state_chg(fi, V5X_LE_UP_I_S_LE11_NOP_LOCAL_UNBLOCK, 0, 0); + /* Send FE201 */ + v5x_le_ctrl_port_snd(v5up, V5X_CTRL_FE201_UNBLOCK); + break; + case V5X_CUP_LE_MPH_BI_BLOCK_CMD: + /* Send FE203 */ + v5x_le_ctrl_port_snd(v5up, V5X_CTRL_FE203_BLOCK); + break; + case V5X_CUP_LE_FE202_UNBLOCK: + osmo_fsm_inst_state_chg(fi, V5X_LE_UP_I_S_LE12_NOP_REMOTE_UNBLOCK, 0, 0); + /* Send MPU-UBR */ + v5x_mph_rcv(fi, MPH_UBR, 0); + break; + case V5X_CUP_LE_FE204_BLOCK_CMD: + case V5X_CUP_LE_FE205_BLOCK_REQ: + /* ignore */ + break; + default: + OSMO_ASSERT(0); + } + +} + +static void isdn_up_le11_local_unblock(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct v5x_user_port *v5up = fi->priv; + + switch (event) { + case V5X_CUP_LE_FE102_ACTIV_INIT_USER_IND: + osmo_fsm_inst_state_chg(fi, V5X_LE_UP_I_S_LE21_OP_ACTIVATION_INITIATED, 0, 0); + /* send MPG-AWI */ + v5x_mph_rcv(fi, MPH_AWI, 0); + break; + case V5X_CUP_LE_FE103_DS_ACTIVATED_IND: + /* ignore */ + break; + case V5X_CUP_LE_FE104_ACCESS_ACTIVATED_IND: + osmo_fsm_inst_state_chg(fi, V5X_LE_UP_I_S_LE22_OP_ACCESS_ACTIVATED, 0, 0); + /* send MPH-AI */ + v5x_mph_rcv(fi, MPH_AI, 0); + break; + case V5X_CUP_LE_MPH_DR_DEACTIVATE_ACCESS_REQ: + case V5X_CUP_LE_FE106_ACCESS_DEACTIVATED_IND: + /* ignore */ + break; + case V5X_CUP_LE_MPH_UBR_UNBLOCK_REQ: + /* send FE201 */ + v5x_le_ctrl_port_snd(v5up, V5X_CTRL_FE201_UNBLOCK); + break; + case V5X_CUP_LE_MPH_BI_BLOCK_CMD: + osmo_fsm_inst_state_chg(fi, V5X_LE_UP_I_S_LE10_NOP_BLOCKED, 0, 0); + /* send FE203 */ + v5x_le_ctrl_port_snd(v5up, V5X_CTRL_FE203_BLOCK); + break; + case V5X_CUP_LE_FE202_UNBLOCK: + osmo_fsm_inst_state_chg(fi, V5X_LE_UP_I_S_LE20_OP_OPERATIONAL_DEACTIVTED, 0, 0); + /* send MPH-UBI */ + v5x_mph_rcv(fi, MPH_UBI, 0); + break; + case V5X_CUP_LE_FE204_BLOCK_CMD: + osmo_fsm_inst_state_chg(fi, V5X_LE_UP_I_S_LE10_NOP_BLOCKED, 0, 0); + /* send MPH-BI */ + v5x_mph_rcv(fi, MPH_BI, 0); + break; + case V5X_CUP_LE_FE205_BLOCK_REQ: + /* ignore */ + break; + default: + OSMO_ASSERT(0); + } +} + +static void isdn_up_le12_remote_unblock(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct v5x_user_port *v5up = fi->priv; + + switch (event) { + case V5X_CUP_LE_FE103_DS_ACTIVATED_IND: + /* ignore */ + break; + case V5X_CUP_LE_MPH_DR_DEACTIVATE_ACCESS_REQ: + case V5X_CUP_LE_FE106_ACCESS_DEACTIVATED_IND: + /* ignore */ + break; + case V5X_CUP_LE_MPH_UBR_UNBLOCK_REQ: + osmo_fsm_inst_state_chg(fi, V5X_LE_UP_I_S_LE20_OP_OPERATIONAL_DEACTIVTED, 0, 0); + /* send FE201 */ + v5x_le_ctrl_port_snd(v5up, V5X_CTRL_FE201_UNBLOCK); + /* send MPH-UBI */ + v5x_mph_rcv(fi, MPH_UBI, 0); + break; + case V5X_CUP_LE_MPH_BI_BLOCK_CMD: + osmo_fsm_inst_state_chg(fi, V5X_LE_UP_I_S_LE10_NOP_BLOCKED, 0, 0); + /* send FE203 */ + v5x_le_ctrl_port_snd(v5up, V5X_CTRL_FE203_BLOCK); + break; + case V5X_CUP_LE_FE202_UNBLOCK: + /* send MPH-UBR */ + v5x_mph_rcv(fi, MPH_UBR, 0); + break; + case V5X_CUP_LE_FE204_BLOCK_CMD: + osmo_fsm_inst_state_chg(fi, V5X_LE_UP_I_S_LE10_NOP_BLOCKED, 0, 0); + /* send MPH-BI */ + v5x_mph_rcv(fi, MPH_BI, 0); + break; + case V5X_CUP_LE_FE205_BLOCK_REQ: + /* ignore */ + break; + default: + OSMO_ASSERT(0); + } +} + +/* LE 2.0 Operational deactivated */ +static void isdn_up_le20_op_deact(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct v5x_user_port *v5up = fi->priv; + + switch (event) { + case V5X_CUP_LE_MPH_AR_ACTIVATE_ACCESS_REQ: + osmo_fsm_inst_state_chg(fi, V5X_LE_UP_I_S_LE21_OP_ACTIVATION_INITIATED, 0, 0); + /* Send FE101 */ + v5x_le_ctrl_port_snd(v5up, V5X_CTRL_FE101_ACTIVATE_ACCESS); + break; + case V5X_CUP_LE_FE102_ACTIV_INIT_USER_IND: + osmo_fsm_inst_state_chg(fi, V5X_LE_UP_I_S_LE21_OP_ACTIVATION_INITIATED, 0, 0); + /* Send MPH-AWI */ + v5x_mph_rcv(fi, MPH_AWI, 0); + break; + case V5X_CUP_LE_FE103_DS_ACTIVATED_IND: + /* ignore */ + break; + case V5X_CUP_LE_FE104_ACCESS_ACTIVATED_IND: + osmo_fsm_inst_state_chg(fi, V5X_LE_UP_I_S_LE22_OP_ACCESS_ACTIVATED, 0, 0); + /* Send MPH-AI */ + v5x_mph_rcv(fi, MPH_AI, 0); + break; + case V5X_CUP_LE_MPH_DR_DEACTIVATE_ACCESS_REQ: + /* Send FE105 */ + v5x_le_ctrl_port_snd(v5up, V5X_CTRL_FE105_DEACTIVATE_ACCESS); + break; + case V5X_CUP_LE_FE106_ACCESS_DEACTIVATED_IND: + /* Send MPH-DI */ + v5x_mph_rcv(fi, MPH_DI, 0); + break; + case V5X_CUP_LE_MPH_UBR_UNBLOCK_REQ: + /* Send FE201 */ + v5x_le_ctrl_port_snd(v5up, V5X_CTRL_FE201_UNBLOCK); + break; + case V5X_CUP_LE_MPH_BI_BLOCK_CMD: + osmo_fsm_inst_state_chg(fi, V5X_LE_UP_I_S_LE10_NOP_BLOCKED, 0, 0); + /* Send FE203 */ + v5x_le_ctrl_port_snd(v5up, V5X_CTRL_FE203_BLOCK); + break; + case V5X_CUP_LE_FE202_UNBLOCK: + /* Send MPH-UBI */ + v5x_mph_rcv(fi, MPH_UBI, 0); + break; + case V5X_CUP_LE_FE204_BLOCK_CMD: + osmo_fsm_inst_state_chg(fi, V5X_LE_UP_I_S_LE10_NOP_BLOCKED, 0, 0); + /* Send MPH-BI */ + v5x_mph_rcv(fi, MPH_BI, 0); + break; + case V5X_CUP_LE_FE205_BLOCK_REQ: + /* Send MPH-BR */ + v5x_mph_rcv(fi, MPH_BR, 0); + break; + case V5X_CUP_LE_FE206_PREFORMANCE_GRADING_IND: + /* Send MPH-GI */ + v5x_mph_rcv(fi, MPH_GI, *(uint8_t *)data); + break; + default: + OSMO_ASSERT(0); + } +} + +/* LE 2.1 Access initiated */ +static void isdn_up_le21_op_act_init(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct v5x_user_port *v5up = fi->priv; + + switch (event) { + case V5X_CUP_LE_MPH_AR_ACTIVATE_ACCESS_REQ: + case V5X_CUP_LE_FE102_ACTIV_INIT_USER_IND: + /* ignore */ + break; + case V5X_CUP_LE_FE103_DS_ACTIVATED_IND: + /* Send MPH-DSAI */ + v5x_mph_rcv(fi, MPH_DSAI, 0); + break; + case V5X_CUP_LE_FE104_ACCESS_ACTIVATED_IND: + osmo_fsm_inst_state_chg(fi, V5X_LE_UP_I_S_LE22_OP_ACCESS_ACTIVATED, 0, 0); + /* Send MPH-AI */ + v5x_mph_rcv(fi, MPH_AI, 0); + break; + case V5X_CUP_LE_MPH_DR_DEACTIVATE_ACCESS_REQ: + osmo_fsm_inst_state_chg(fi, V5X_LE_UP_I_S_LE20_OP_OPERATIONAL_DEACTIVTED, 0, 0); + /* Send FE105 */ + v5x_le_ctrl_port_snd(v5up, V5X_CTRL_FE105_DEACTIVATE_ACCESS); + /* Send MPH-DI */ + v5x_mph_rcv(fi, MPH_DI, 0); + break; + case V5X_CUP_LE_FE106_ACCESS_DEACTIVATED_IND: + osmo_fsm_inst_state_chg(fi, V5X_LE_UP_I_S_LE20_OP_OPERATIONAL_DEACTIVTED, 0, 0); + /* Send MPH-DI */ + v5x_mph_rcv(fi, MPH_DI, 0); + break; + case V5X_CUP_LE_MPH_UBR_UNBLOCK_REQ: + /* Send FE201 */ + v5x_le_ctrl_port_snd(v5up, V5X_CTRL_FE201_UNBLOCK); + break; + case V5X_CUP_LE_MPH_BI_BLOCK_CMD: + osmo_fsm_inst_state_chg(fi, V5X_LE_UP_I_S_LE10_NOP_BLOCKED, 0, 0); + /* Send FE203 */ + v5x_le_ctrl_port_snd(v5up, V5X_CTRL_FE203_BLOCK); + break; + case V5X_CUP_LE_FE202_UNBLOCK: + /* Send MPH-UBI */ + v5x_mph_rcv(fi, MPH_UBI, 0); + break; + case V5X_CUP_LE_FE204_BLOCK_CMD: + osmo_fsm_inst_state_chg(fi, V5X_LE_UP_I_S_LE10_NOP_BLOCKED, 0, 0); + /* Send MPH-BI */ + v5x_mph_rcv(fi, MPH_BI, 0); + /* Send MPH-DI */ + v5x_mph_rcv(fi, MPH_DI, 0); + break; + case V5X_CUP_LE_FE205_BLOCK_REQ: + /* Send MPH-BR */ + v5x_mph_rcv(fi, MPH_BR, 0); + break; + case V5X_CUP_LE_FE206_PREFORMANCE_GRADING_IND: + /* Send MPH-GI */ + v5x_mph_rcv(fi, MPH_GI, *(uint8_t *)data); + break; + default: + OSMO_ASSERT(0); + } + +} + +/* LE 2.2 Access activated */ +static void isdn_up_le22_op_acc_act(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct v5x_user_port *v5up = fi->priv; + + switch (event) { + case V5X_CUP_LE_FE104_ACCESS_ACTIVATED_IND: + /* ignore */ + break; + case V5X_CUP_LE_MPH_DR_DEACTIVATE_ACCESS_REQ: + osmo_fsm_inst_state_chg(fi, V5X_LE_UP_I_S_LE20_OP_OPERATIONAL_DEACTIVTED, 0, 0); + /* Send FE105 */ + v5x_le_ctrl_port_snd(v5up, V5X_CTRL_FE105_DEACTIVATE_ACCESS); + /* Send MPH-DI */ + v5x_mph_rcv(fi, MPH_DI, 0); + break; + case V5X_CUP_LE_FE106_ACCESS_DEACTIVATED_IND: + osmo_fsm_inst_state_chg(fi, V5X_LE_UP_I_S_LE20_OP_OPERATIONAL_DEACTIVTED, 0, 0); + /* Send MPH-DI */ + v5x_mph_rcv(fi, MPH_DI, 0); + break; + case V5X_CUP_LE_MPH_UBR_UNBLOCK_REQ: + /* Send FE201 */ + v5x_le_ctrl_port_snd(v5up, V5X_CTRL_FE201_UNBLOCK); + /* Send MPH-AI */ + v5x_mph_rcv(fi, MPH_AI, 0); + break; + case V5X_CUP_LE_MPH_BI_BLOCK_CMD: + osmo_fsm_inst_state_chg(fi, V5X_LE_UP_I_S_LE10_NOP_BLOCKED, 0, 0); + /* Send FE203 */ + v5x_le_ctrl_port_snd(v5up, V5X_CTRL_FE203_BLOCK); + break; + case V5X_CUP_LE_FE202_UNBLOCK: + /* Send MPH-UBI */ + v5x_mph_rcv(fi, MPH_UBI, 0); + break; + case V5X_CUP_LE_FE204_BLOCK_CMD: + osmo_fsm_inst_state_chg(fi, V5X_LE_UP_I_S_LE10_NOP_BLOCKED, 0, 0); + /* Send MPH-BI */ + v5x_mph_rcv(fi, MPH_BI, 0); + /* Send MPH-DI */ + v5x_mph_rcv(fi, MPH_DI, 0); + break; + case V5X_CUP_LE_FE205_BLOCK_REQ: + /* Send MPH-BR */ + v5x_mph_rcv(fi, MPH_BR, 0); + break; + case V5X_CUP_LE_FE206_PREFORMANCE_GRADING_IND: + /* Send MPH-GI */ + v5x_mph_rcv(fi, MPH_GI, *(uint8_t *)data); + break; + case V5X_CUP_LE_MPH_DB_BLOCK_DCHAN_REQ: + /* Send FE207 */ + v5x_le_ctrl_port_snd(v5up, V5X_CTRL_FE207_D_CHANNEL_BLOCK); + break; + case V5X_CUP_LE_MPH_DU_BLOCK_DCHAN_REQ: + /* Send FE208 */ + v5x_le_ctrl_port_snd(v5up, V5X_CTRL_FE208_D_CHANNEL_UNBLOCK); + break; + default: + OSMO_ASSERT(0); + } +} + +/* Table 38/G.964 LE (ISDN port) FSM for ISDN basic access user ports */ +static const struct osmo_fsm_state v5x_le_ctrl_isdn_port_fsm_states[] = { + [V5X_LE_UP_I_S_LE10_NOP_BLOCKED] = { + .name = "LE1.0_BLOCKED", + .in_event_mask = S(V5X_CUP_LE_FE102_ACTIV_INIT_USER_IND) | + S(V5X_CUP_LE_FE103_DS_ACTIVATED_IND) | + S(V5X_CUP_LE_FE104_ACCESS_ACTIVATED_IND) | + S(V5X_CUP_LE_MPH_DR_DEACTIVATE_ACCESS_REQ) | + S(V5X_CUP_LE_FE106_ACCESS_DEACTIVATED_IND) | + S(V5X_CUP_LE_MPH_UBR_UNBLOCK_REQ) | + S(V5X_CUP_LE_MPH_BI_BLOCK_CMD) | + S(V5X_CUP_LE_FE202_UNBLOCK) | + S(V5X_CUP_LE_FE204_BLOCK_CMD) | + S(V5X_CUP_LE_FE205_BLOCK_REQ), + .out_state_mask = S(V5X_LE_UP_I_S_LE11_NOP_LOCAL_UNBLOCK) | + S(V5X_LE_UP_I_S_LE12_NOP_REMOTE_UNBLOCK), + .action = isdn_up_le10_blocked, + }, + [V5X_LE_UP_I_S_LE11_NOP_LOCAL_UNBLOCK] = { + .name = "LE1.1_LOCAL_UNBLOCK", + .in_event_mask = S(V5X_CUP_LE_FE102_ACTIV_INIT_USER_IND) | + S(V5X_CUP_LE_FE103_DS_ACTIVATED_IND) | + S(V5X_CUP_LE_FE104_ACCESS_ACTIVATED_IND) | + S(V5X_CUP_LE_MPH_DR_DEACTIVATE_ACCESS_REQ) | + S(V5X_CUP_LE_FE106_ACCESS_DEACTIVATED_IND) | + S(V5X_CUP_LE_MPH_UBR_UNBLOCK_REQ) | + S(V5X_CUP_LE_MPH_BI_BLOCK_CMD) | + S(V5X_CUP_LE_FE202_UNBLOCK) | + S(V5X_CUP_LE_FE204_BLOCK_CMD) | + S(V5X_CUP_LE_FE205_BLOCK_REQ), + .out_state_mask = S(V5X_LE_UP_I_S_LE21_OP_ACTIVATION_INITIATED) | + S(V5X_LE_UP_I_S_LE22_OP_ACCESS_ACTIVATED) | + S(V5X_LE_UP_I_S_LE10_NOP_BLOCKED) | + S(V5X_LE_UP_I_S_LE20_OP_OPERATIONAL_DEACTIVTED), + .action = isdn_up_le11_local_unblock, + }, + [V5X_LE_UP_I_S_LE12_NOP_REMOTE_UNBLOCK] = { + .name = "LE1.2_REMOTE_UNBLOCK", + .in_event_mask = S(V5X_CUP_LE_FE103_DS_ACTIVATED_IND) | + S(V5X_CUP_LE_MPH_DR_DEACTIVATE_ACCESS_REQ) | + S(V5X_CUP_LE_FE106_ACCESS_DEACTIVATED_IND) | + S(V5X_CUP_LE_MPH_UBR_UNBLOCK_REQ) | + S(V5X_CUP_LE_MPH_BI_BLOCK_CMD) | + S(V5X_CUP_LE_FE202_UNBLOCK) | + S(V5X_CUP_LE_FE204_BLOCK_CMD) | + S(V5X_CUP_LE_FE205_BLOCK_REQ), + .out_state_mask = S(V5X_LE_UP_I_S_LE20_OP_OPERATIONAL_DEACTIVTED) | + S(V5X_LE_UP_I_S_LE10_NOP_BLOCKED), + .action = isdn_up_le12_remote_unblock, + }, + [V5X_LE_UP_I_S_LE20_OP_OPERATIONAL_DEACTIVTED] = { + .name = "LE2.0_OPERATIONAL_DEACTIVATED", + .in_event_mask = S(V5X_CUP_LE_MPH_AR_ACTIVATE_ACCESS_REQ) | + S(V5X_CUP_LE_FE102_ACTIV_INIT_USER_IND) | + S(V5X_CUP_LE_FE103_DS_ACTIVATED_IND) | + S(V5X_CUP_LE_FE104_ACCESS_ACTIVATED_IND) | + S(V5X_CUP_LE_MPH_DR_DEACTIVATE_ACCESS_REQ) | + S(V5X_CUP_LE_FE106_ACCESS_DEACTIVATED_IND) | + S(V5X_CUP_LE_MPH_UBR_UNBLOCK_REQ) | + S(V5X_CUP_LE_MPH_BI_BLOCK_CMD) | + S(V5X_CUP_LE_FE202_UNBLOCK) | + S(V5X_CUP_LE_FE204_BLOCK_CMD) | + S(V5X_CUP_LE_FE205_BLOCK_REQ) | + S(V5X_CUP_LE_FE206_PREFORMANCE_GRADING_IND), + .out_state_mask = S(V5X_LE_UP_I_S_LE21_OP_ACTIVATION_INITIATED) | + S(V5X_LE_UP_I_S_LE22_OP_ACCESS_ACTIVATED) | + S(V5X_LE_UP_I_S_LE10_NOP_BLOCKED), + .action = isdn_up_le20_op_deact, + }, + [V5X_LE_UP_I_S_LE21_OP_ACTIVATION_INITIATED] = { + .name = "LE2.1_ACTIVATION_INITIATED", + .in_event_mask = S(V5X_CUP_LE_MPH_AR_ACTIVATE_ACCESS_REQ) | + S(V5X_CUP_LE_FE102_ACTIV_INIT_USER_IND) | + S(V5X_CUP_LE_FE103_DS_ACTIVATED_IND) | + S(V5X_CUP_LE_FE104_ACCESS_ACTIVATED_IND) | + S(V5X_CUP_LE_MPH_DR_DEACTIVATE_ACCESS_REQ) | + S(V5X_CUP_LE_FE106_ACCESS_DEACTIVATED_IND) | + S(V5X_CUP_LE_MPH_UBR_UNBLOCK_REQ) | + S(V5X_CUP_LE_MPH_BI_BLOCK_CMD) | + S(V5X_CUP_LE_FE202_UNBLOCK) | + S(V5X_CUP_LE_FE204_BLOCK_CMD) | + S(V5X_CUP_LE_FE205_BLOCK_REQ), + .out_state_mask = S(V5X_LE_UP_I_S_LE22_OP_ACCESS_ACTIVATED) | + S(V5X_LE_UP_I_S_LE20_OP_OPERATIONAL_DEACTIVTED) | + S(V5X_LE_UP_I_S_LE10_NOP_BLOCKED), + .action = isdn_up_le21_op_act_init, + }, + [V5X_LE_UP_I_S_LE22_OP_ACCESS_ACTIVATED] = { + .name = "LE2.2_ACCESS_ACTIVATED", + .in_event_mask = S(V5X_CUP_LE_FE104_ACCESS_ACTIVATED_IND) | + S(V5X_CUP_LE_MPH_DR_DEACTIVATE_ACCESS_REQ) | + S(V5X_CUP_LE_FE106_ACCESS_DEACTIVATED_IND) | + S(V5X_CUP_LE_MPH_UBR_UNBLOCK_REQ) | + S(V5X_CUP_LE_MPH_BI_BLOCK_CMD) | + S(V5X_CUP_LE_FE202_UNBLOCK) | + S(V5X_CUP_LE_FE204_BLOCK_CMD) | + S(V5X_CUP_LE_FE205_BLOCK_REQ) | + S(V5X_CUP_LE_FE206_PREFORMANCE_GRADING_IND) | + S(V5X_CUP_LE_MPH_DB_BLOCK_DCHAN_REQ) | + S(V5X_CUP_LE_MPH_DU_BLOCK_DCHAN_REQ), + .out_state_mask = S(V5X_LE_UP_I_S_LE20_OP_OPERATIONAL_DEACTIVTED) | + S(V5X_LE_UP_I_S_LE10_NOP_BLOCKED), + .action = isdn_up_le22_op_acc_act, + }, +}; + +struct osmo_fsm v5x_le_ctrl_isdn_port_fsm = { + .name = "V5X_CTRL_ISDN", + .states = v5x_le_ctrl_isdn_port_fsm_states, + .num_states = ARRAY_SIZE(v5x_le_ctrl_isdn_port_fsm_states), + .allstate_event_mask = 0, + .allstate_action = NULL, + .cleanup = NULL, + .log_subsys = DV5PORT, + .event_names = v5x_le_ctrl_port_fsm_event_names, +}; + +struct osmo_fsm_inst *v5x_le_port_isdn_create(struct v5x_user_port *v5up, uint16_t nr) +{ + struct osmo_fsm_inst *fi; + + OSMO_ASSERT(v5up); + + fi = osmo_fsm_inst_alloc(&v5x_le_ctrl_isdn_port_fsm, v5up, v5up, LOGL_DEBUG, NULL); + if (!fi) + return NULL; + osmo_fsm_inst_update_id_f(fi, "%d", nr); + + return fi; +} + +void v5x_le_port_isdn_rcv(struct v5x_user_port *v5up, uint8_t cfe, uint8_t perf_grading) +{ + enum v5x_le_ctrl_port_fsm_event event; + + switch (cfe) { + case V5X_CTRL_FE102_ACT_INIT_BY_USER: + event = V5X_CUP_LE_FE102_ACTIV_INIT_USER_IND; + break; + case V5X_CTRL_FE103_DS_ACTIVATED: + event = V5X_CUP_LE_FE103_DS_ACTIVATED_IND; + break; + case V5X_CTRL_FE104_ACCESS_ACTIVATED: + event = V5X_CUP_LE_FE104_ACCESS_ACTIVATED_IND; + break; + case V5X_CTRL_FE106_ACCESS_DEACTIVATED: + event = V5X_CUP_LE_FE106_ACCESS_DEACTIVATED_IND; + break; + case V5X_CTRL_FE201_UNBLOCK: // actually FE202 + event = V5X_CUP_LE_FE202_UNBLOCK; + break; + case V5X_CTRL_FE203_BLOCK: // actually FE204 + event = V5X_CUP_LE_FE204_BLOCK_CMD; + break; + case V5X_CTRL_FE205_BLOCK_REQ: + event = V5X_CUP_LE_FE205_BLOCK_REQ; + break; + case V5X_CTRL_FE206_PERFORMANCE_GRADING: + event = V5X_CUP_LE_FE206_PREFORMANCE_GRADING_IND; + break; + default: + LOGP(DV5PORT, LOGL_NOTICE, "Received cfe %d not valid at this protocol\n", cfe); + break; + } + + /* send event to FSM */ + osmo_fsm_inst_dispatch(v5up->port_fi, event, &perf_grading); +} + +/***********************************************************************/ +/* PSTN port state FSM */ +/***********************************************************************/ + +static void pstn_up_le10_blocked(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct v5x_user_port *v5up = fi->priv; + + switch (event) { + case V5X_CUP_LE_MPH_UBR_UNBLOCK_REQ: + osmo_fsm_inst_state_chg(fi, V5X_LE_UP_P_S_LE11_NOP_LOCAL_UNBLOCK, 0, 0); + /* Send FE201 */ + v5x_le_ctrl_port_snd(v5up, V5X_CTRL_FE201_UNBLOCK); + break; + case V5X_CUP_LE_MPH_BI_BLOCK_CMD: + /* Send FE203 */ + v5x_le_ctrl_port_snd(v5up, V5X_CTRL_FE203_BLOCK); + break; + case V5X_CUP_LE_FE202_UNBLOCK: + osmo_fsm_inst_state_chg(fi, V5X_LE_UP_P_S_LE12_NOP_REMOTE_UNBLOCK, 0, 0); + /* Send MPU-UBR */ + v5x_mph_rcv(fi, MPH_UBR, 0); + break; + case V5X_CUP_LE_FE204_BLOCK_CMD: + case V5X_CUP_LE_FE205_BLOCK_REQ: + /* ignore */ + break; + default: + OSMO_ASSERT(0); + } + +} + +static void pstn_up_le11_local_unblock(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct v5x_user_port *v5up = fi->priv; + + switch (event) { + case V5X_CUP_LE_MPH_UBR_UNBLOCK_REQ: + /* send FE201 */ + v5x_le_ctrl_port_snd(v5up, V5X_CTRL_FE201_UNBLOCK); + break; + case V5X_CUP_LE_MPH_BI_BLOCK_CMD: + osmo_fsm_inst_state_chg(fi, V5X_LE_UP_P_S_LE10_NOP_BLOCKED, 0, 0); + /* send FE203 */ + v5x_le_ctrl_port_snd(v5up, V5X_CTRL_FE203_BLOCK); + break; + case V5X_CUP_LE_FE202_UNBLOCK: + osmo_fsm_inst_state_chg(fi, V5X_LE_UP_P_S_LE20_OPERATIONAL, 0, 0); + /* send MPH-UBI */ + v5x_mph_rcv(fi, MPH_UBI, 0); + break; + case V5X_CUP_LE_FE204_BLOCK_CMD: + osmo_fsm_inst_state_chg(fi, V5X_LE_UP_P_S_LE10_NOP_BLOCKED, 0, 0); + /* send MPH-BI */ + v5x_mph_rcv(fi, MPH_BI, 0); + break; + case V5X_CUP_LE_FE205_BLOCK_REQ: + /* ignore */ + break; + default: + OSMO_ASSERT(0); + } +} + +static void pstn_up_le12_remote_unblock(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct v5x_user_port *v5up = fi->priv; + + switch (event) { + case V5X_CUP_LE_MPH_UBR_UNBLOCK_REQ: + osmo_fsm_inst_state_chg(fi, V5X_LE_UP_P_S_LE20_OPERATIONAL, 0, 0); + /* send FE201 */ + v5x_le_ctrl_port_snd(v5up, V5X_CTRL_FE201_UNBLOCK); + /* send MPH-UBI */ + v5x_mph_rcv(fi, MPH_UBI, 0); + break; + case V5X_CUP_LE_MPH_BI_BLOCK_CMD: + osmo_fsm_inst_state_chg(fi, V5X_LE_UP_P_S_LE10_NOP_BLOCKED, 0, 0); + /* send FE203 */ + v5x_le_ctrl_port_snd(v5up, V5X_CTRL_FE203_BLOCK); + break; + case V5X_CUP_LE_FE202_UNBLOCK: + /* send MPH-UBR */ + v5x_mph_rcv(fi, MPH_UBR, 0); + break; + case V5X_CUP_LE_FE204_BLOCK_CMD: + osmo_fsm_inst_state_chg(fi, V5X_LE_UP_P_S_LE10_NOP_BLOCKED, 0, 0); + /* send MPH-BI */ + v5x_mph_rcv(fi, MPH_BI, 0); + break; + case V5X_CUP_LE_FE205_BLOCK_REQ: + /* ignore */ + break; + default: + OSMO_ASSERT(0); + } +} + +/* LE 2.0 Operational deactivated */ +static void pstn_up_le20_operational(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct v5x_user_port *v5up = fi->priv; + + switch (event) { + case V5X_CUP_LE_MPH_UBR_UNBLOCK_REQ: + /* Send FE201 */ + v5x_le_ctrl_port_snd(v5up, V5X_CTRL_FE201_UNBLOCK); + break; + case V5X_CUP_LE_MPH_BI_BLOCK_CMD: + osmo_fsm_inst_state_chg(fi, V5X_LE_UP_P_S_LE10_NOP_BLOCKED, 0, 0); + /* Send FE203 */ + v5x_le_ctrl_port_snd(v5up, V5X_CTRL_FE203_BLOCK); + break; + case V5X_CUP_LE_FE202_UNBLOCK: + /* Send MPH-UBI */ + v5x_mph_rcv(fi, MPH_UBI, 0); + break; + case V5X_CUP_LE_FE204_BLOCK_CMD: + osmo_fsm_inst_state_chg(fi, V5X_LE_UP_P_S_LE10_NOP_BLOCKED, 0, 0); + /* Send MPH-BI */ + v5x_mph_rcv(fi, MPH_BI, 0); + break; + case V5X_CUP_LE_FE205_BLOCK_REQ: + /* Send MPH-BR */ + v5x_mph_rcv(fi, MPH_BR, 0); + break; + default: + OSMO_ASSERT(0); + } +} + +/* Table 43/G.964 LE (ISDN port) FSM for PSTN user ports */ +static const struct osmo_fsm_state v5x_le_ctrl_pstn_port_fsm_states[] = { + [V5X_LE_UP_P_S_LE10_NOP_BLOCKED] = { + .name = "LE1.0_BLOCKED", + .in_event_mask = S(V5X_CUP_LE_MPH_UBR_UNBLOCK_REQ) | + S(V5X_CUP_LE_MPH_BI_BLOCK_CMD) | + S(V5X_CUP_LE_FE202_UNBLOCK) | + S(V5X_CUP_LE_FE204_BLOCK_CMD) | + S(V5X_CUP_LE_FE205_BLOCK_REQ), + .out_state_mask = S(V5X_LE_UP_P_S_LE11_NOP_LOCAL_UNBLOCK) | + S(V5X_LE_UP_P_S_LE12_NOP_REMOTE_UNBLOCK), + .action = pstn_up_le10_blocked, + }, + [V5X_LE_UP_P_S_LE11_NOP_LOCAL_UNBLOCK] = { + .name = "LE1.1_LOCAL_UNBLOCK", + .in_event_mask = S(V5X_CUP_LE_MPH_UBR_UNBLOCK_REQ) | + S(V5X_CUP_LE_MPH_BI_BLOCK_CMD) | + S(V5X_CUP_LE_FE202_UNBLOCK) | + S(V5X_CUP_LE_FE204_BLOCK_CMD) | + S(V5X_CUP_LE_FE205_BLOCK_REQ), + .out_state_mask = S(V5X_LE_UP_P_S_LE10_NOP_BLOCKED) | + S(V5X_LE_UP_P_S_LE20_OPERATIONAL), + .action = pstn_up_le11_local_unblock, + }, + [V5X_LE_UP_P_S_LE12_NOP_REMOTE_UNBLOCK] = { + .name = "LE1.2_REMOTE_UNBLOCK", + .in_event_mask = S(V5X_CUP_LE_MPH_UBR_UNBLOCK_REQ) | + S(V5X_CUP_LE_MPH_BI_BLOCK_CMD) | + S(V5X_CUP_LE_FE202_UNBLOCK) | + S(V5X_CUP_LE_FE204_BLOCK_CMD) | + S(V5X_CUP_LE_FE205_BLOCK_REQ), + .out_state_mask = S(V5X_LE_UP_P_S_LE20_OPERATIONAL) | + S(V5X_LE_UP_P_S_LE10_NOP_BLOCKED), + .action = pstn_up_le12_remote_unblock, + }, + [V5X_LE_UP_P_S_LE20_OPERATIONAL] = { + .name = "LE2.0_OPERATIONAL", + .in_event_mask = S(V5X_CUP_LE_MPH_UBR_UNBLOCK_REQ) | + S(V5X_CUP_LE_MPH_BI_BLOCK_CMD) | + S(V5X_CUP_LE_FE202_UNBLOCK) | + S(V5X_CUP_LE_FE204_BLOCK_CMD) | + S(V5X_CUP_LE_FE205_BLOCK_REQ), + .out_state_mask = S(V5X_LE_UP_P_S_LE10_NOP_BLOCKED), + .action = pstn_up_le20_operational, + }, +}; + +struct osmo_fsm v5x_le_ctrl_pstn_port_fsm = { + .name = "V5X_CTRL_PSTN", + .states = v5x_le_ctrl_pstn_port_fsm_states, + .num_states = ARRAY_SIZE(v5x_le_ctrl_pstn_port_fsm_states), + .allstate_event_mask = 0, + .allstate_action = NULL, + .cleanup = NULL, + .log_subsys = DV5PORT, + .event_names = v5x_le_ctrl_port_fsm_event_names, +}; + +struct osmo_fsm_inst *v5x_le_port_pstn_create(struct v5x_user_port *v5up, uint16_t nr) +{ + struct osmo_fsm_inst *fi; + + OSMO_ASSERT(v5up); + + fi = osmo_fsm_inst_alloc(&v5x_le_ctrl_pstn_port_fsm, v5up, v5up, LOGL_DEBUG, NULL); + if (!fi) + return NULL; + osmo_fsm_inst_update_id_f(fi, "%d", nr); + + return fi; +} + +void v5x_le_port_pstn_rcv(struct v5x_user_port *v5up, uint8_t cfe) +{ + struct osmo_fsm_inst *fi = v5up->port_fi; + enum v5x_le_ctrl_port_fsm_event event; + + switch (cfe) { + case V5X_CTRL_FE201_UNBLOCK: // actually FE202 + event = V5X_CUP_LE_FE202_UNBLOCK; + break; + case V5X_CTRL_FE203_BLOCK: // actually FE204 + event = V5X_CUP_LE_FE204_BLOCK_CMD; + break; + case V5X_CTRL_FE205_BLOCK_REQ: + event = V5X_CUP_LE_FE205_BLOCK_REQ; + break; + default: + LOGP(DV5PORT, LOGL_NOTICE, "Received cfe %d not valid at this protocol\n", cfe); + } + + /* send event to FSM */ + osmo_fsm_inst_dispatch(fi, event, NULL); +} + +void v5x_le_port_init(void) +{ + int rc; + + rc = osmo_fsm_register(&v5x_le_ctrl_isdn_port_fsm); + OSMO_ASSERT(!rc); + rc = osmo_fsm_register(&v5x_le_ctrl_pstn_port_fsm); + OSMO_ASSERT(!rc); + LOGP(DV5PORT, LOGL_NOTICE, "Using V5x port control protocol\n"); +} diff --git a/src/v5x_le_port_fsm.h b/src/v5x_le_port_fsm.h new file mode 100644 index 0000000..c4005a3 --- /dev/null +++ b/src/v5x_le_port_fsm.h @@ -0,0 +1,9 @@ + +void v5x_mph_snd(struct v5x_user_port *v5up, enum v5x_mph_prim prim); + +struct osmo_fsm_inst *v5x_le_port_isdn_create(struct v5x_user_port *v5up, uint16_t nr); +void v5x_le_port_isdn_rcv(struct v5x_user_port *v5up, uint8_t cfe, uint8_t perf_grading); +struct osmo_fsm_inst *v5x_le_port_pstn_create(struct v5x_user_port *v5up, uint16_t nr); +void v5x_le_port_pstn_rcv(struct v5x_user_port *v5up, uint8_t cfe); + +void v5x_le_port_init(void); diff --git a/v52_le_user_port_fsm.c b/v52_le_user_port_fsm.c deleted file mode 100644 index be4bcdd..0000000 --- a/v52_le_user_port_fsm.c +++ /dev/null @@ -1,849 +0,0 @@ -/* ITU-T G.964 Section 14.1.3.2.2 ISDN user port FSM - LE */ - -/***********************************************************************/ -/* internal data structures */ -/***********************************************************************/ - -#include -#include - -#include "v5x_internal.h" -#include "v5x_protocol.h" -#include "v5x_l2_mgmt.h" -#include "v52_le_user_port_fsm.h" -#include "v51_le_ctrl.h" -#include "logging.h" - -#define S(x) (1 << (x)) - -/***********************************************************************/ -/* state names, event names, primitives, ... */ -/***********************************************************************/ - -/* 14.1.3.2.2 ISDN user port FSM - LE(ISDN port) */ -enum v51_le_isdn_port_state { - V51_LE_UP_I_S_LE10_NOP_BLOCKED, /* LE1.0 */ - V51_LE_UP_I_S_LE11_NOP_LOCAL_UNBLOCK, /* LE1.1 */ - V51_LE_UP_I_S_LE12_NOP_REMOTE_UNBLOCK, /* LE1.2 */ - V51_LE_UP_I_S_LE20_OP_OPERATIONAL_DEACTIVTED, /* LE2.0 */ - V51_LE_UP_I_S_LE21_OP_ACTIVATION_INITIATED, /* LE2.1 */ - V51_LE_UP_I_S_LE22_OP_ACCESS_ACTIVATED, /* LE2.2 */ -}; - -/* 14.2.3.2.2 PSTN user port FSM - LE(PSTN port) */ -enum v51_le_pstn_port_state { - V51_LE_UP_P_S_LE10_NOP_BLOCKED, /* LE1.0 */ - V51_LE_UP_P_S_LE11_NOP_LOCAL_UNBLOCK, /* LE1.1 */ - V51_LE_UP_P_S_LE12_NOP_REMOTE_UNBLOCK, /* LE1.2 */ - V51_LE_UP_P_S_LE20_OPERATIONAL, /* LE2.0 */ -}; - -enum v51_ctrl_le_port_fsm_event { - /* inbound function elements from AN (Table 34/G.964) */ - V51_CUP_LE_FE102_ACTIV_INIT_USER_IND, - V51_CUP_LE_FE103_DS_ACTIVATED_IND, - V51_CUP_LE_FE104_ACCESS_ACTIVATED_IND, - V51_CUP_LE_FE106_ACCESS_DEACTIVATED_IND, - V51_CUP_LE_FE202_UNBLOCK, - V51_CUP_LE_FE204_BLOCK_CMD, - V51_CUP_LE_FE205_BLOCK_REQ, - V51_CUP_LE_FE206_PREFORMANCE_GRADING_IND, - /* inbound primitives from Mgmt (Table 35/G.964) */ - V51_CUP_LE_MPH_UBR_UNBLOCK_REQ, - V51_CUP_LE_MPH_BI_BLOCK_CMD, - V51_CUP_LE_MPH_AR_ACTIVATE_ACCESS_REQ, - V51_CUP_LE_MPH_DR_DEACTIVATE_ACCESS_REQ, - V51_CUP_LE_MPH_DB_BLOCK_DCHAN_REQ, - V51_CUP_LE_MPH_DU_BLOCK_DCHAN_REQ, -}; - -static const struct value_string v51_ctrl_le_port_fsm_event_names[] = { - { V51_CUP_LE_FE102_ACTIV_INIT_USER_IND, "FE102 Activation by user indication" }, - { V51_CUP_LE_FE103_DS_ACTIVATED_IND, "FE103 DS Activated indication" }, - { V51_CUP_LE_FE104_ACCESS_ACTIVATED_IND, "FE104 Access activated indication" }, - { V51_CUP_LE_FE106_ACCESS_DEACTIVATED_IND, "FE106 Access deactivated indication" }, - { V51_CUP_LE_FE202_UNBLOCK, "FE202 Unblock request or ack" }, - { V51_CUP_LE_FE204_BLOCK_CMD, "FE204 Block command" }, - { V51_CUP_LE_FE205_BLOCK_REQ, "FE205 Block request" }, - { V51_CUP_LE_FE206_PREFORMANCE_GRADING_IND, "FE206 Performance grading info" }, - { V51_CUP_LE_MPH_UBR_UNBLOCK_REQ, "MPH-UBR Unblock request" }, - { V51_CUP_LE_MPH_BI_BLOCK_CMD, "MPH-BI Block command" }, - { V51_CUP_LE_MPH_AR_ACTIVATE_ACCESS_REQ, "MPH-AR Activate access" }, - { V51_CUP_LE_MPH_DR_DEACTIVATE_ACCESS_REQ, "MPH-DR Deactivate access" }, - { V51_CUP_LE_MPH_DB_BLOCK_DCHAN_REQ, "MPH-DB Block D-channel" }, - { V51_CUP_LE_MPH_DU_BLOCK_DCHAN_REQ, "MPH-DU Unblock D-channel" }, - { 0, NULL } -}; - -/***********************************************************************/ -/* upper layer interface */ -/***********************************************************************/ - -static void v51_mph_rcv(struct osmo_fsm_inst *fi, enum v5x_mph_prim prim, uint8_t perf_grading) -{ - struct v5x_user_port *v5up = fi->priv; - - v5x_mph_rcv_an(v5up, prim, perf_grading); -} - -void v51_mph_snd(struct v5x_user_port *v5up, enum v5x_mph_prim prim) -{ - struct osmo_fsm_inst *fi = v5up->port_fi; - enum v51_ctrl_le_port_fsm_event event; - - switch (prim) { - case MPH_UBR: - event = V51_CUP_LE_MPH_UBR_UNBLOCK_REQ; - break; - case MPH_BI: - event = V51_CUP_LE_MPH_BI_BLOCK_CMD; - break; - case MPH_AR: - event = V51_CUP_LE_MPH_AR_ACTIVATE_ACCESS_REQ; - break; - case MPH_DR: - event = V51_CUP_LE_MPH_DR_DEACTIVATE_ACCESS_REQ; - break; - case MPH_DB: - event = V51_CUP_LE_MPH_DB_BLOCK_DCHAN_REQ; - break; - case MPH_DU: - event = V51_CUP_LE_MPH_DU_BLOCK_DCHAN_REQ; - break; - default: - LOGP(DV5PORT, LOGL_NOTICE, "Got invalid prim %d at this protocol\n", prim); - return; - } - - /* send event to FSM */ - osmo_fsm_inst_dispatch(fi, event, NULL); -} - -/***********************************************************************/ -/* ISDN port state FSM */ -/***********************************************************************/ - -static void isdn_up_le10_blocked(struct osmo_fsm_inst *fi, uint32_t event, void *data) -{ - struct v5x_user_port *v5up = fi->priv; - - switch (event) { - case V51_CUP_LE_FE102_ACTIV_INIT_USER_IND: - case V51_CUP_LE_FE103_DS_ACTIVATED_IND: - case V51_CUP_LE_FE104_ACCESS_ACTIVATED_IND: - case V51_CUP_LE_MPH_DR_DEACTIVATE_ACCESS_REQ: - case V51_CUP_LE_FE106_ACCESS_DEACTIVATED_IND: - /* ignore */ - break; - case V51_CUP_LE_MPH_UBR_UNBLOCK_REQ: - osmo_fsm_inst_state_chg(fi, V51_LE_UP_I_S_LE11_NOP_LOCAL_UNBLOCK, 0, 0); - /* Send FE201 */ - v51_snd_ctrl_port(v5up, V51_CTRL_FE201_UNBLOCK); - break; - case V51_CUP_LE_MPH_BI_BLOCK_CMD: - /* Send FE203 */ - v51_snd_ctrl_port(v5up, V51_CTRL_FE203_BLOCK); - break; - case V51_CUP_LE_FE202_UNBLOCK: - osmo_fsm_inst_state_chg(fi, V51_LE_UP_I_S_LE12_NOP_REMOTE_UNBLOCK, 0, 0); - /* Send MPU-UBR */ - v51_mph_rcv(fi, MPH_UBR, 0); - break; - case V51_CUP_LE_FE204_BLOCK_CMD: - case V51_CUP_LE_FE205_BLOCK_REQ: - /* ignore */ - break; - default: - OSMO_ASSERT(0); - } - -} - -static void isdn_up_le11_local_unblock(struct osmo_fsm_inst *fi, uint32_t event, void *data) -{ - struct v5x_user_port *v5up = fi->priv; - - switch (event) { - case V51_CUP_LE_FE102_ACTIV_INIT_USER_IND: - osmo_fsm_inst_state_chg(fi, V51_LE_UP_I_S_LE21_OP_ACTIVATION_INITIATED, 0, 0); - /* send MPG-AWI */ - v51_mph_rcv(fi, MPH_AWI, 0); - break; - case V51_CUP_LE_FE103_DS_ACTIVATED_IND: - /* ignore */ - break; - case V51_CUP_LE_FE104_ACCESS_ACTIVATED_IND: - osmo_fsm_inst_state_chg(fi, V51_LE_UP_I_S_LE22_OP_ACCESS_ACTIVATED, 0, 0); - /* send MPH-AI */ - v51_mph_rcv(fi, MPH_AI, 0); - break; - case V51_CUP_LE_MPH_DR_DEACTIVATE_ACCESS_REQ: - case V51_CUP_LE_FE106_ACCESS_DEACTIVATED_IND: - /* ignore */ - break; - case V51_CUP_LE_MPH_UBR_UNBLOCK_REQ: - /* send FE201 */ - v51_snd_ctrl_port(v5up, V51_CTRL_FE201_UNBLOCK); - break; - case V51_CUP_LE_MPH_BI_BLOCK_CMD: - osmo_fsm_inst_state_chg(fi, V51_LE_UP_I_S_LE10_NOP_BLOCKED, 0, 0); - /* send FE203 */ - v51_snd_ctrl_port(v5up, V51_CTRL_FE203_BLOCK); - break; - case V51_CUP_LE_FE202_UNBLOCK: - osmo_fsm_inst_state_chg(fi, V51_LE_UP_I_S_LE20_OP_OPERATIONAL_DEACTIVTED, 0, 0); - /* send MPH-UBI */ - v51_mph_rcv(fi, MPH_UBI, 0); - break; - case V51_CUP_LE_FE204_BLOCK_CMD: - osmo_fsm_inst_state_chg(fi, V51_LE_UP_I_S_LE10_NOP_BLOCKED, 0, 0); - /* send MPH-BI */ - v51_mph_rcv(fi, MPH_BI, 0); - break; - case V51_CUP_LE_FE205_BLOCK_REQ: - /* ignore */ - break; - default: - OSMO_ASSERT(0); - } -} - -static void isdn_up_le12_remote_unblock(struct osmo_fsm_inst *fi, uint32_t event, void *data) -{ - struct v5x_user_port *v5up = fi->priv; - - switch (event) { - case V51_CUP_LE_FE103_DS_ACTIVATED_IND: - /* ignore */ - break; - case V51_CUP_LE_MPH_DR_DEACTIVATE_ACCESS_REQ: - case V51_CUP_LE_FE106_ACCESS_DEACTIVATED_IND: - /* ignore */ - break; - case V51_CUP_LE_MPH_UBR_UNBLOCK_REQ: - osmo_fsm_inst_state_chg(fi, V51_LE_UP_I_S_LE20_OP_OPERATIONAL_DEACTIVTED, 0, 0); - /* send FE201 */ - v51_snd_ctrl_port(v5up, V51_CTRL_FE201_UNBLOCK); - /* send MPH-UBI */ - v51_mph_rcv(fi, MPH_UBI, 0); - break; - case V51_CUP_LE_MPH_BI_BLOCK_CMD: - osmo_fsm_inst_state_chg(fi, V51_LE_UP_I_S_LE10_NOP_BLOCKED, 0, 0); - /* send FE203 */ - v51_snd_ctrl_port(v5up, V51_CTRL_FE203_BLOCK); - break; - case V51_CUP_LE_FE202_UNBLOCK: - /* send MPH-UBR */ - v51_mph_rcv(fi, MPH_UBR, 0); - break; - case V51_CUP_LE_FE204_BLOCK_CMD: - osmo_fsm_inst_state_chg(fi, V51_LE_UP_I_S_LE10_NOP_BLOCKED, 0, 0); - /* send MPH-BI */ - v51_mph_rcv(fi, MPH_BI, 0); - break; - case V51_CUP_LE_FE205_BLOCK_REQ: - /* ignore */ - break; - default: - OSMO_ASSERT(0); - } -} - -/* LE 2.0 Operational deactivated */ -static void isdn_up_le20_op_deact(struct osmo_fsm_inst *fi, uint32_t event, void *data) -{ - struct v5x_user_port *v5up = fi->priv; - - switch (event) { - case V51_CUP_LE_MPH_AR_ACTIVATE_ACCESS_REQ: - osmo_fsm_inst_state_chg(fi, V51_LE_UP_I_S_LE21_OP_ACTIVATION_INITIATED, 0, 0); - /* Send FE101 */ - v51_snd_ctrl_port(v5up, V51_CTRL_FE101_ACTIVATE_ACCESS); - break; - case V51_CUP_LE_FE102_ACTIV_INIT_USER_IND: - osmo_fsm_inst_state_chg(fi, V51_LE_UP_I_S_LE21_OP_ACTIVATION_INITIATED, 0, 0); - /* Send MPH-AWI */ - v51_mph_rcv(fi, MPH_AWI, 0); - break; - case V51_CUP_LE_FE103_DS_ACTIVATED_IND: - /* ignore */ - break; - case V51_CUP_LE_FE104_ACCESS_ACTIVATED_IND: - osmo_fsm_inst_state_chg(fi, V51_LE_UP_I_S_LE22_OP_ACCESS_ACTIVATED, 0, 0); - /* Send MPH-AI */ - v51_mph_rcv(fi, MPH_AI, 0); - break; - case V51_CUP_LE_MPH_DR_DEACTIVATE_ACCESS_REQ: - /* Send FE105 */ - v51_snd_ctrl_port(v5up, V51_CTRL_FE105_DEACTIVATE_ACCESS); - break; - case V51_CUP_LE_FE106_ACCESS_DEACTIVATED_IND: - /* Send MPH-DI */ - v51_mph_rcv(fi, MPH_DI, 0); - break; - case V51_CUP_LE_MPH_UBR_UNBLOCK_REQ: - /* Send FE201 */ - v51_snd_ctrl_port(v5up, V51_CTRL_FE201_UNBLOCK); - break; - case V51_CUP_LE_MPH_BI_BLOCK_CMD: - osmo_fsm_inst_state_chg(fi, V51_LE_UP_I_S_LE10_NOP_BLOCKED, 0, 0); - /* Send FE203 */ - v51_snd_ctrl_port(v5up, V51_CTRL_FE203_BLOCK); - break; - case V51_CUP_LE_FE202_UNBLOCK: - /* Send MPH-UBI */ - v51_mph_rcv(fi, MPH_UBI, 0); - break; - case V51_CUP_LE_FE204_BLOCK_CMD: - osmo_fsm_inst_state_chg(fi, V51_LE_UP_I_S_LE10_NOP_BLOCKED, 0, 0); - /* Send MPH-BI */ - v51_mph_rcv(fi, MPH_BI, 0); - break; - case V51_CUP_LE_FE205_BLOCK_REQ: - /* Send MPH-BR */ - v51_mph_rcv(fi, MPH_BR, 0); - break; - case V51_CUP_LE_FE206_PREFORMANCE_GRADING_IND: - /* Send MPH-GI */ - v51_mph_rcv(fi, MPH_GI, *(uint8_t *)data); - break; - default: - OSMO_ASSERT(0); - } -} - -/* LE 2.1 Access initiated */ -static void isdn_up_le21_op_act_init(struct osmo_fsm_inst *fi, uint32_t event, void *data) -{ - struct v5x_user_port *v5up = fi->priv; - - switch (event) { - case V51_CUP_LE_MPH_AR_ACTIVATE_ACCESS_REQ: - case V51_CUP_LE_FE102_ACTIV_INIT_USER_IND: - /* ignore */ - break; - case V51_CUP_LE_FE103_DS_ACTIVATED_IND: - /* Send MPH-DSAI */ - v51_mph_rcv(fi, MPH_DSAI, 0); - break; - case V51_CUP_LE_FE104_ACCESS_ACTIVATED_IND: - osmo_fsm_inst_state_chg(fi, V51_LE_UP_I_S_LE22_OP_ACCESS_ACTIVATED, 0, 0); - /* Send MPH-AI */ - v51_mph_rcv(fi, MPH_AI, 0); - break; - case V51_CUP_LE_MPH_DR_DEACTIVATE_ACCESS_REQ: - osmo_fsm_inst_state_chg(fi, V51_LE_UP_I_S_LE20_OP_OPERATIONAL_DEACTIVTED, 0, 0); - /* Send FE105 */ - v51_snd_ctrl_port(v5up, V51_CTRL_FE105_DEACTIVATE_ACCESS); - /* Send MPH-DI */ - v51_mph_rcv(fi, MPH_DI, 0); - break; - case V51_CUP_LE_FE106_ACCESS_DEACTIVATED_IND: - osmo_fsm_inst_state_chg(fi, V51_LE_UP_I_S_LE20_OP_OPERATIONAL_DEACTIVTED, 0, 0); - /* Send MPH-DI */ - v51_mph_rcv(fi, MPH_DI, 0); - break; - case V51_CUP_LE_MPH_UBR_UNBLOCK_REQ: - /* Send FE201 */ - v51_snd_ctrl_port(v5up, V51_CTRL_FE201_UNBLOCK); - break; - case V51_CUP_LE_MPH_BI_BLOCK_CMD: - osmo_fsm_inst_state_chg(fi, V51_LE_UP_I_S_LE10_NOP_BLOCKED, 0, 0); - /* Send FE203 */ - v51_snd_ctrl_port(v5up, V51_CTRL_FE203_BLOCK); - break; - case V51_CUP_LE_FE202_UNBLOCK: - /* Send MPH-UBI */ - v51_mph_rcv(fi, MPH_UBI, 0); - break; - case V51_CUP_LE_FE204_BLOCK_CMD: - osmo_fsm_inst_state_chg(fi, V51_LE_UP_I_S_LE10_NOP_BLOCKED, 0, 0); - /* Send MPH-BI */ - v51_mph_rcv(fi, MPH_BI, 0); - /* Send MPH-DI */ - v51_mph_rcv(fi, MPH_DI, 0); - break; - case V51_CUP_LE_FE205_BLOCK_REQ: - /* Send MPH-BR */ - v51_mph_rcv(fi, MPH_BR, 0); - break; - case V51_CUP_LE_FE206_PREFORMANCE_GRADING_IND: - /* Send MPH-GI */ - v51_mph_rcv(fi, MPH_GI, *(uint8_t *)data); - break; - default: - OSMO_ASSERT(0); - } - -} - -/* LE 2.2 Access activated */ -static void isdn_up_le22_op_acc_act(struct osmo_fsm_inst *fi, uint32_t event, void *data) -{ - struct v5x_user_port *v5up = fi->priv; - - switch (event) { - case V51_CUP_LE_FE104_ACCESS_ACTIVATED_IND: - /* ignore */ - break; - case V51_CUP_LE_MPH_DR_DEACTIVATE_ACCESS_REQ: - osmo_fsm_inst_state_chg(fi, V51_LE_UP_I_S_LE20_OP_OPERATIONAL_DEACTIVTED, 0, 0); - /* Send FE105 */ - v51_snd_ctrl_port(v5up, V51_CTRL_FE105_DEACTIVATE_ACCESS); - /* Send MPH-DI */ - v51_mph_rcv(fi, MPH_DI, 0); - break; - case V51_CUP_LE_FE106_ACCESS_DEACTIVATED_IND: - osmo_fsm_inst_state_chg(fi, V51_LE_UP_I_S_LE20_OP_OPERATIONAL_DEACTIVTED, 0, 0); - /* Send MPH-DI */ - v51_mph_rcv(fi, MPH_DI, 0); - break; - case V51_CUP_LE_MPH_UBR_UNBLOCK_REQ: - /* Send FE201 */ - v51_snd_ctrl_port(v5up, V51_CTRL_FE201_UNBLOCK); - /* Send MPH-AI */ - v51_mph_rcv(fi, MPH_AI, 0); - break; - case V51_CUP_LE_MPH_BI_BLOCK_CMD: - osmo_fsm_inst_state_chg(fi, V51_LE_UP_I_S_LE10_NOP_BLOCKED, 0, 0); - /* Send FE203 */ - v51_snd_ctrl_port(v5up, V51_CTRL_FE203_BLOCK); - break; - case V51_CUP_LE_FE202_UNBLOCK: - /* Send MPH-UBI */ - v51_mph_rcv(fi, MPH_UBI, 0); - break; - case V51_CUP_LE_FE204_BLOCK_CMD: - osmo_fsm_inst_state_chg(fi, V51_LE_UP_I_S_LE10_NOP_BLOCKED, 0, 0); - /* Send MPH-BI */ - v51_mph_rcv(fi, MPH_BI, 0); - /* Send MPH-DI */ - v51_mph_rcv(fi, MPH_DI, 0); - break; - case V51_CUP_LE_FE205_BLOCK_REQ: - /* Send MPH-BR */ - v51_mph_rcv(fi, MPH_BR, 0); - break; - case V51_CUP_LE_FE206_PREFORMANCE_GRADING_IND: - /* Send MPH-GI */ - v51_mph_rcv(fi, MPH_GI, *(uint8_t *)data); - break; - case V51_CUP_LE_MPH_DB_BLOCK_DCHAN_REQ: - /* Send FE207 */ - v51_snd_ctrl_port(v5up, V51_CTRL_FE207_D_CHANNEL_BLOCK); - break; - case V51_CUP_LE_MPH_DU_BLOCK_DCHAN_REQ: - /* Send FE208 */ - v51_snd_ctrl_port(v5up, V51_CTRL_FE208_D_CHANNEL_UNBLOCK); - break; - default: - OSMO_ASSERT(0); - } -} - -/* Table 38/G.964 LE (ISDN port) FSM for ISDN basic access user ports */ -static const struct osmo_fsm_state v51_ctrl_le_i_port_fsm_states[] = { - [V51_LE_UP_I_S_LE10_NOP_BLOCKED] = { - .name = "LE1.0_BLOCKED", - .in_event_mask = S(V51_CUP_LE_FE102_ACTIV_INIT_USER_IND) | - S(V51_CUP_LE_FE103_DS_ACTIVATED_IND) | - S(V51_CUP_LE_FE104_ACCESS_ACTIVATED_IND) | - S(V51_CUP_LE_MPH_DR_DEACTIVATE_ACCESS_REQ) | - S(V51_CUP_LE_FE106_ACCESS_DEACTIVATED_IND) | - S(V51_CUP_LE_MPH_UBR_UNBLOCK_REQ) | - S(V51_CUP_LE_MPH_BI_BLOCK_CMD) | - S(V51_CUP_LE_FE202_UNBLOCK) | - S(V51_CUP_LE_FE204_BLOCK_CMD) | - S(V51_CUP_LE_FE205_BLOCK_REQ), - .out_state_mask = S(V51_LE_UP_I_S_LE11_NOP_LOCAL_UNBLOCK) | - S(V51_LE_UP_I_S_LE12_NOP_REMOTE_UNBLOCK), - .action = isdn_up_le10_blocked, - }, - [V51_LE_UP_I_S_LE11_NOP_LOCAL_UNBLOCK] = { - .name = "LE1.1_LOCAL_UNBLOCK", - .in_event_mask = S(V51_CUP_LE_FE102_ACTIV_INIT_USER_IND) | - S(V51_CUP_LE_FE103_DS_ACTIVATED_IND) | - S(V51_CUP_LE_FE104_ACCESS_ACTIVATED_IND) | - S(V51_CUP_LE_MPH_DR_DEACTIVATE_ACCESS_REQ) | - S(V51_CUP_LE_FE106_ACCESS_DEACTIVATED_IND) | - S(V51_CUP_LE_MPH_UBR_UNBLOCK_REQ) | - S(V51_CUP_LE_MPH_BI_BLOCK_CMD) | - S(V51_CUP_LE_FE202_UNBLOCK) | - S(V51_CUP_LE_FE204_BLOCK_CMD) | - S(V51_CUP_LE_FE205_BLOCK_REQ), - .out_state_mask = S(V51_LE_UP_I_S_LE21_OP_ACTIVATION_INITIATED) | - S(V51_LE_UP_I_S_LE22_OP_ACCESS_ACTIVATED) | - S(V51_LE_UP_I_S_LE10_NOP_BLOCKED) | - S(V51_LE_UP_I_S_LE20_OP_OPERATIONAL_DEACTIVTED), - .action = isdn_up_le11_local_unblock, - }, - [V51_LE_UP_I_S_LE12_NOP_REMOTE_UNBLOCK] = { - .name = "LE1.2_REMOTE_UNBLOCK", - .in_event_mask = S(V51_CUP_LE_FE103_DS_ACTIVATED_IND) | - S(V51_CUP_LE_MPH_DR_DEACTIVATE_ACCESS_REQ) | - S(V51_CUP_LE_FE106_ACCESS_DEACTIVATED_IND) | - S(V51_CUP_LE_MPH_UBR_UNBLOCK_REQ) | - S(V51_CUP_LE_MPH_BI_BLOCK_CMD) | - S(V51_CUP_LE_FE202_UNBLOCK) | - S(V51_CUP_LE_FE204_BLOCK_CMD) | - S(V51_CUP_LE_FE205_BLOCK_REQ), - .out_state_mask = S(V51_LE_UP_I_S_LE20_OP_OPERATIONAL_DEACTIVTED) | - S(V51_LE_UP_I_S_LE10_NOP_BLOCKED), - .action = isdn_up_le12_remote_unblock, - }, - [V51_LE_UP_I_S_LE20_OP_OPERATIONAL_DEACTIVTED] = { - .name = "LE2.0_OPERATIONAL_DEACTIVATED", - .in_event_mask = S(V51_CUP_LE_MPH_AR_ACTIVATE_ACCESS_REQ) | - S(V51_CUP_LE_FE102_ACTIV_INIT_USER_IND) | - S(V51_CUP_LE_FE103_DS_ACTIVATED_IND) | - S(V51_CUP_LE_FE104_ACCESS_ACTIVATED_IND) | - S(V51_CUP_LE_MPH_DR_DEACTIVATE_ACCESS_REQ) | - S(V51_CUP_LE_FE106_ACCESS_DEACTIVATED_IND) | - S(V51_CUP_LE_MPH_UBR_UNBLOCK_REQ) | - S(V51_CUP_LE_MPH_BI_BLOCK_CMD) | - S(V51_CUP_LE_FE202_UNBLOCK) | - S(V51_CUP_LE_FE204_BLOCK_CMD) | - S(V51_CUP_LE_FE205_BLOCK_REQ) | - S(V51_CUP_LE_FE206_PREFORMANCE_GRADING_IND), - .out_state_mask = S(V51_LE_UP_I_S_LE21_OP_ACTIVATION_INITIATED) | - S(V51_LE_UP_I_S_LE22_OP_ACCESS_ACTIVATED) | - S(V51_LE_UP_I_S_LE10_NOP_BLOCKED), - .action = isdn_up_le20_op_deact, - }, - [V51_LE_UP_I_S_LE21_OP_ACTIVATION_INITIATED] = { - .name = "LE2.1_ACTIVATION_INITIATED", - .in_event_mask = S(V51_CUP_LE_MPH_AR_ACTIVATE_ACCESS_REQ) | - S(V51_CUP_LE_FE102_ACTIV_INIT_USER_IND) | - S(V51_CUP_LE_FE103_DS_ACTIVATED_IND) | - S(V51_CUP_LE_FE104_ACCESS_ACTIVATED_IND) | - S(V51_CUP_LE_MPH_DR_DEACTIVATE_ACCESS_REQ) | - S(V51_CUP_LE_FE106_ACCESS_DEACTIVATED_IND) | - S(V51_CUP_LE_MPH_UBR_UNBLOCK_REQ) | - S(V51_CUP_LE_MPH_BI_BLOCK_CMD) | - S(V51_CUP_LE_FE202_UNBLOCK) | - S(V51_CUP_LE_FE204_BLOCK_CMD) | - S(V51_CUP_LE_FE205_BLOCK_REQ), - .out_state_mask = S(V51_LE_UP_I_S_LE22_OP_ACCESS_ACTIVATED) | - S(V51_LE_UP_I_S_LE20_OP_OPERATIONAL_DEACTIVTED) | - S(V51_LE_UP_I_S_LE10_NOP_BLOCKED), - .action = isdn_up_le21_op_act_init, - }, - [V51_LE_UP_I_S_LE22_OP_ACCESS_ACTIVATED] = { - .name = "LE2.2_ACCESS_ACTIVATED", - .in_event_mask = S(V51_CUP_LE_FE104_ACCESS_ACTIVATED_IND) | - S(V51_CUP_LE_MPH_DR_DEACTIVATE_ACCESS_REQ) | - S(V51_CUP_LE_FE106_ACCESS_DEACTIVATED_IND) | - S(V51_CUP_LE_MPH_UBR_UNBLOCK_REQ) | - S(V51_CUP_LE_MPH_BI_BLOCK_CMD) | - S(V51_CUP_LE_FE202_UNBLOCK) | - S(V51_CUP_LE_FE204_BLOCK_CMD) | - S(V51_CUP_LE_FE205_BLOCK_REQ) | - S(V51_CUP_LE_FE206_PREFORMANCE_GRADING_IND) | - S(V51_CUP_LE_MPH_DB_BLOCK_DCHAN_REQ) | - S(V51_CUP_LE_MPH_DU_BLOCK_DCHAN_REQ), - .out_state_mask = S(V51_LE_UP_I_S_LE20_OP_OPERATIONAL_DEACTIVTED) | - S(V51_LE_UP_I_S_LE10_NOP_BLOCKED), - .action = isdn_up_le22_op_acc_act, - }, -}; - -struct osmo_fsm v51_ctrl_le_i_port_fsm = { - .name = "V51_CTRL_ISDN", - .states = v51_ctrl_le_i_port_fsm_states, - .num_states = ARRAY_SIZE(v51_ctrl_le_i_port_fsm_states), - .allstate_event_mask = 0, - .allstate_action = NULL, - .cleanup = NULL, - .log_subsys = DV5PORT, - .event_names = v51_ctrl_le_port_fsm_event_names, -}; - -struct osmo_fsm_inst *v51_ctrl_le_i_port_create(struct v5x_user_port *v5up, uint16_t nr) -{ - struct osmo_fsm_inst *fi; - - OSMO_ASSERT(v5up); - - fi = osmo_fsm_inst_alloc(&v51_ctrl_le_i_port_fsm, v5up, v5up, LOGL_DEBUG, NULL); - if (!fi) - return NULL; - osmo_fsm_inst_update_id_f(fi, "%d", nr); - - return fi; -} - -void v51_ctrl_le_i_port_rcv(struct v5x_user_port *v5up, uint8_t cfe, uint8_t perf_grading) -{ - enum v51_ctrl_le_port_fsm_event event; - - switch (cfe) { - case V51_CTRL_FE102_ACT_INIT_BY_USER: - event = V51_CUP_LE_FE102_ACTIV_INIT_USER_IND; - break; - case V51_CTRL_FE103_DS_ACTIVATED: - event = V51_CUP_LE_FE103_DS_ACTIVATED_IND; - break; - case V51_CTRL_FE104_ACCESS_ACTIVATED: - event = V51_CUP_LE_FE104_ACCESS_ACTIVATED_IND; - break; - case V51_CTRL_FE106_ACCESS_DEACTIVATED: - event = V51_CUP_LE_FE106_ACCESS_DEACTIVATED_IND; - break; - case V51_CTRL_FE201_UNBLOCK: // actually FE202 - event = V51_CUP_LE_FE202_UNBLOCK; - break; - case V51_CTRL_FE203_BLOCK: // actually FE204 - event = V51_CUP_LE_FE204_BLOCK_CMD; - break; - case V51_CTRL_FE205_BLOCK_REQ: - event = V51_CUP_LE_FE205_BLOCK_REQ; - break; - case V51_CTRL_FE206_PERFORMANCE_GRADING: - event = V51_CUP_LE_FE206_PREFORMANCE_GRADING_IND; - break; - default: - LOGP(DV5PORT, LOGL_NOTICE, "Received cfe %d not valid at this protocol\n", cfe); - break; - } - - /* send event to FSM */ - osmo_fsm_inst_dispatch(v5up->port_fi, event, &perf_grading); -} - -/***********************************************************************/ -/* PSTN port state FSM */ -/***********************************************************************/ - -static void pstn_up_le10_blocked(struct osmo_fsm_inst *fi, uint32_t event, void *data) -{ - struct v5x_user_port *v5up = fi->priv; - - switch (event) { - case V51_CUP_LE_MPH_UBR_UNBLOCK_REQ: - osmo_fsm_inst_state_chg(fi, V51_LE_UP_P_S_LE11_NOP_LOCAL_UNBLOCK, 0, 0); - /* Send FE201 */ - v51_snd_ctrl_port(v5up, V51_CTRL_FE201_UNBLOCK); - break; - case V51_CUP_LE_MPH_BI_BLOCK_CMD: - /* Send FE203 */ - v51_snd_ctrl_port(v5up, V51_CTRL_FE203_BLOCK); - break; - case V51_CUP_LE_FE202_UNBLOCK: - osmo_fsm_inst_state_chg(fi, V51_LE_UP_P_S_LE12_NOP_REMOTE_UNBLOCK, 0, 0); - /* Send MPU-UBR */ - v51_mph_rcv(fi, MPH_UBR, 0); - break; - case V51_CUP_LE_FE204_BLOCK_CMD: - case V51_CUP_LE_FE205_BLOCK_REQ: - /* ignore */ - break; - default: - OSMO_ASSERT(0); - } - -} - -static void pstn_up_le11_local_unblock(struct osmo_fsm_inst *fi, uint32_t event, void *data) -{ - struct v5x_user_port *v5up = fi->priv; - - switch (event) { - case V51_CUP_LE_MPH_UBR_UNBLOCK_REQ: - /* send FE201 */ - v51_snd_ctrl_port(v5up, V51_CTRL_FE201_UNBLOCK); - break; - case V51_CUP_LE_MPH_BI_BLOCK_CMD: - osmo_fsm_inst_state_chg(fi, V51_LE_UP_P_S_LE10_NOP_BLOCKED, 0, 0); - /* send FE203 */ - v51_snd_ctrl_port(v5up, V51_CTRL_FE203_BLOCK); - break; - case V51_CUP_LE_FE202_UNBLOCK: - osmo_fsm_inst_state_chg(fi, V51_LE_UP_P_S_LE20_OPERATIONAL, 0, 0); - /* send MPH-UBI */ - v51_mph_rcv(fi, MPH_UBI, 0); - break; - case V51_CUP_LE_FE204_BLOCK_CMD: - osmo_fsm_inst_state_chg(fi, V51_LE_UP_P_S_LE10_NOP_BLOCKED, 0, 0); - /* send MPH-BI */ - v51_mph_rcv(fi, MPH_BI, 0); - break; - case V51_CUP_LE_FE205_BLOCK_REQ: - /* ignore */ - break; - default: - OSMO_ASSERT(0); - } -} - -static void pstn_up_le12_remote_unblock(struct osmo_fsm_inst *fi, uint32_t event, void *data) -{ - struct v5x_user_port *v5up = fi->priv; - - switch (event) { - case V51_CUP_LE_MPH_UBR_UNBLOCK_REQ: - osmo_fsm_inst_state_chg(fi, V51_LE_UP_P_S_LE20_OPERATIONAL, 0, 0); - /* send FE201 */ - v51_snd_ctrl_port(v5up, V51_CTRL_FE201_UNBLOCK); - /* send MPH-UBI */ - v51_mph_rcv(fi, MPH_UBI, 0); - break; - case V51_CUP_LE_MPH_BI_BLOCK_CMD: - osmo_fsm_inst_state_chg(fi, V51_LE_UP_P_S_LE10_NOP_BLOCKED, 0, 0); - /* send FE203 */ - v51_snd_ctrl_port(v5up, V51_CTRL_FE203_BLOCK); - break; - case V51_CUP_LE_FE202_UNBLOCK: - /* send MPH-UBR */ - v51_mph_rcv(fi, MPH_UBR, 0); - break; - case V51_CUP_LE_FE204_BLOCK_CMD: - osmo_fsm_inst_state_chg(fi, V51_LE_UP_P_S_LE10_NOP_BLOCKED, 0, 0); - /* send MPH-BI */ - v51_mph_rcv(fi, MPH_BI, 0); - break; - case V51_CUP_LE_FE205_BLOCK_REQ: - /* ignore */ - break; - default: - OSMO_ASSERT(0); - } -} - -/* LE 2.0 Operational deactivated */ -static void pstn_up_le20_operational(struct osmo_fsm_inst *fi, uint32_t event, void *data) -{ - struct v5x_user_port *v5up = fi->priv; - - switch (event) { - case V51_CUP_LE_MPH_UBR_UNBLOCK_REQ: - /* Send FE201 */ - v51_snd_ctrl_port(v5up, V51_CTRL_FE201_UNBLOCK); - break; - case V51_CUP_LE_MPH_BI_BLOCK_CMD: - osmo_fsm_inst_state_chg(fi, V51_LE_UP_P_S_LE10_NOP_BLOCKED, 0, 0); - /* Send FE203 */ - v51_snd_ctrl_port(v5up, V51_CTRL_FE203_BLOCK); - break; - case V51_CUP_LE_FE202_UNBLOCK: - /* Send MPH-UBI */ - v51_mph_rcv(fi, MPH_UBI, 0); - break; - case V51_CUP_LE_FE204_BLOCK_CMD: - osmo_fsm_inst_state_chg(fi, V51_LE_UP_P_S_LE10_NOP_BLOCKED, 0, 0); - /* Send MPH-BI */ - v51_mph_rcv(fi, MPH_BI, 0); - break; - case V51_CUP_LE_FE205_BLOCK_REQ: - /* Send MPH-BR */ - v51_mph_rcv(fi, MPH_BR, 0); - break; - default: - OSMO_ASSERT(0); - } -} - -/* Table 43/G.964 LE (ISDN port) FSM for PSTN user ports */ -static const struct osmo_fsm_state v51_ctrl_le_p_port_fsm_states[] = { - [V51_LE_UP_P_S_LE10_NOP_BLOCKED] = { - .name = "LE1.0_BLOCKED", - .in_event_mask = S(V51_CUP_LE_MPH_UBR_UNBLOCK_REQ) | - S(V51_CUP_LE_MPH_BI_BLOCK_CMD) | - S(V51_CUP_LE_FE202_UNBLOCK) | - S(V51_CUP_LE_FE204_BLOCK_CMD) | - S(V51_CUP_LE_FE205_BLOCK_REQ), - .out_state_mask = S(V51_LE_UP_P_S_LE11_NOP_LOCAL_UNBLOCK) | - S(V51_LE_UP_P_S_LE12_NOP_REMOTE_UNBLOCK), - .action = pstn_up_le10_blocked, - }, - [V51_LE_UP_P_S_LE11_NOP_LOCAL_UNBLOCK] = { - .name = "LE1.1_LOCAL_UNBLOCK", - .in_event_mask = S(V51_CUP_LE_MPH_UBR_UNBLOCK_REQ) | - S(V51_CUP_LE_MPH_BI_BLOCK_CMD) | - S(V51_CUP_LE_FE202_UNBLOCK) | - S(V51_CUP_LE_FE204_BLOCK_CMD) | - S(V51_CUP_LE_FE205_BLOCK_REQ), - .out_state_mask = S(V51_LE_UP_P_S_LE10_NOP_BLOCKED) | - S(V51_LE_UP_P_S_LE20_OPERATIONAL), - .action = pstn_up_le11_local_unblock, - }, - [V51_LE_UP_P_S_LE12_NOP_REMOTE_UNBLOCK] = { - .name = "LE1.2_REMOTE_UNBLOCK", - .in_event_mask = S(V51_CUP_LE_MPH_UBR_UNBLOCK_REQ) | - S(V51_CUP_LE_MPH_BI_BLOCK_CMD) | - S(V51_CUP_LE_FE202_UNBLOCK) | - S(V51_CUP_LE_FE204_BLOCK_CMD) | - S(V51_CUP_LE_FE205_BLOCK_REQ), - .out_state_mask = S(V51_LE_UP_P_S_LE20_OPERATIONAL) | - S(V51_LE_UP_P_S_LE10_NOP_BLOCKED), - .action = pstn_up_le12_remote_unblock, - }, - [V51_LE_UP_P_S_LE20_OPERATIONAL] = { - .name = "LE2.0_OPERATIONAL", - .in_event_mask = S(V51_CUP_LE_MPH_UBR_UNBLOCK_REQ) | - S(V51_CUP_LE_MPH_BI_BLOCK_CMD) | - S(V51_CUP_LE_FE202_UNBLOCK) | - S(V51_CUP_LE_FE204_BLOCK_CMD) | - S(V51_CUP_LE_FE205_BLOCK_REQ), - .out_state_mask = S(V51_LE_UP_P_S_LE10_NOP_BLOCKED), - .action = pstn_up_le20_operational, - }, -}; - -struct osmo_fsm v51_ctrl_le_p_port_fsm = { - .name = "V51_CTRL_PSTN", - .states = v51_ctrl_le_p_port_fsm_states, - .num_states = ARRAY_SIZE(v51_ctrl_le_p_port_fsm_states), - .allstate_event_mask = 0, - .allstate_action = NULL, - .cleanup = NULL, - .log_subsys = DV5PORT, - .event_names = v51_ctrl_le_port_fsm_event_names, -}; - -struct osmo_fsm_inst *v51_ctrl_le_p_port_create(struct v5x_user_port *v5up, uint16_t nr) -{ - struct osmo_fsm_inst *fi; - - OSMO_ASSERT(v5up); - - fi = osmo_fsm_inst_alloc(&v51_ctrl_le_p_port_fsm, v5up, v5up, LOGL_DEBUG, NULL); - if (!fi) - return NULL; - osmo_fsm_inst_update_id_f(fi, "%d", nr); - - return fi; -} - -void v51_ctrl_le_p_port_rcv(struct v5x_user_port *v5up, uint8_t cfe) -{ - struct osmo_fsm_inst *fi = v5up->port_fi; - enum v51_ctrl_le_port_fsm_event event; - - switch (cfe) { - case V51_CTRL_FE201_UNBLOCK: // actually FE202 - event = V51_CUP_LE_FE202_UNBLOCK; - break; - case V51_CTRL_FE203_BLOCK: // actually FE204 - event = V51_CUP_LE_FE204_BLOCK_CMD; - break; - case V51_CTRL_FE205_BLOCK_REQ: - event = V51_CUP_LE_FE205_BLOCK_REQ; - break; - default: - LOGP(DV5PORT, LOGL_NOTICE, "Received cfe %d not valid at this protocol\n", cfe); - } - - /* send event to FSM */ - osmo_fsm_inst_dispatch(fi, event, NULL); -} - -void v51_port_ctrl_init(void) -{ - int rc; - - rc = osmo_fsm_register(&v51_ctrl_le_i_port_fsm); - OSMO_ASSERT(!rc); - rc = osmo_fsm_register(&v51_ctrl_le_p_port_fsm); - OSMO_ASSERT(!rc); - LOGP(DV5PORT, LOGL_NOTICE, "Using V5x port control protocol\n"); -} diff --git a/v52_le_user_port_fsm.h b/v52_le_user_port_fsm.h deleted file mode 100644 index e9c55e8..0000000 --- a/v52_le_user_port_fsm.h +++ /dev/null @@ -1,12 +0,0 @@ - -extern struct osmo_fsm v51_ctrl_le_i_port_fsm; -extern struct osmo_fsm v51_ctrl_le_p_port_fsm; - -void v51_mph_snd(struct v5x_user_port *v5up, enum v5x_mph_prim prim); - -struct osmo_fsm_inst *v51_ctrl_le_i_port_create(struct v5x_user_port *v5up, uint16_t nr); -void v51_ctrl_le_i_port_rcv(struct v5x_user_port *v5up, uint8_t cfe, uint8_t perf_grading); -struct osmo_fsm_inst *v51_ctrl_le_p_port_create(struct v5x_user_port *v5up, uint16_t nr); -void v51_ctrl_le_p_port_rcv(struct v5x_user_port *v5up, uint8_t cfe); - -void v51_port_ctrl_init(void);