diff options
author | Andreas Eversberg <jolly@eversberg.eu> | 2023-04-23 12:10:42 +0200 |
---|---|---|
committer | laforge <laforge@osmocom.org> | 2023-07-17 12:29:42 +0000 |
commit | f7c6f1424fc907096bb99a25f99564f663b112e0 (patch) | |
tree | 20cf54dac728d2ab0568be4d1553c3da745a1cdb | |
parent | e24636c6bbe573bed5a5a602160cd5ec928ba875 (diff) |
ASCI: Add decoder for VGCS/VBS messages to msc_a.c
VGCS/VBS messages from BSS are decoded and a receiver funktion for
the GCC/BCC (VGCS/VBS call control) is selected.
Change-Id: Ief6259ba3914eeaceb063b562a0bcbc48349ce60
Related: OS#4854
-rw-r--r-- | src/libmsc/msc_a.c | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/src/libmsc/msc_a.c b/src/libmsc/msc_a.c index 5a5bb8afe..701317670 100644 --- a/src/libmsc/msc_a.c +++ b/src/libmsc/msc_a.c @@ -48,6 +48,7 @@ #include <osmocom/msc/rtp_stream.h> #include <osmocom/msc/msc_ho.h> #include <osmocom/msc/codec_mapping.h> +#include <osmocom/msc/msc_vgcs.h> #define MSC_A_USE_WAIT_CLEAR_COMPLETE "wait-Clear-Complete" @@ -1718,6 +1719,136 @@ int msc_a_ran_dec_from_msc_i(struct msc_a *msc_a, struct msc_a_ran_dec_data *d) return rc; } +static int msc_a_rx_vgcs_bss_decoded(struct osmo_fsm_inst *caller_fi, void *caller_data, const struct ran_msg *msg) +{ + struct vgcs_bss *bss = caller_data; + struct msc_a *msc_a = (bss->trans) ? bss->trans->msc_a : NULL; + int rc = 0; + + switch (msg->msg_type) { + case RAN_MSG_VGCS_VBS_SETUP_ACK: + /* The BSS accepts VGCS/VBS and sends us supported features. */ + vgcs_vbs_setup_ack(bss, msg); + break; + case RAN_MSG_VGCS_VBS_SETUP_REFUSE: + /* The BSS refuses VGCS/VBS. */ + vgcs_vbs_setup_refuse(bss, msg); + break; + case RAN_MSG_UPLINK_REQUEST: + /* A mobile station requests the uplink on a VGCS channel. */ + vgcs_uplink_request(bss, msg); + break; + case RAN_MSG_UPLINK_REQUEST_CNF: + /* The uplink on a VGCS channel has been established. */ + vgcs_uplink_request_cnf(bss, msg); + break; + case RAN_MSG_UPLINK_APPLICATION_DATA: + /* Application data received on the uplink of a VGCS channel. */ + vgcs_app_data(bss, msg); + break; + case RAN_MSG_DTAP: + /* BSS confirms the release of the channel. */ + vgcs_bss_dtap(bss, msg); + break; + case RAN_MSG_UPLINK_RELEASE_IND: + /* A mobile station releases the uplink on a VGCS channel. */ + vgcs_uplink_release_ind(bss, msg); + break; + case RAN_MSG_CLEAR_REQUEST: + /* BSS indicated that the channel has been released. */ + vgcs_vbs_clear_req(bss, msg); + break; + case RAN_MSG_CLEAR_COMPLETE: + /* BSS confirms the release of the channel. */ + vgcs_vbs_clear_cpl(bss, msg); + break; + default: + LOG_MSC_A(msc_a, LOGL_ERROR, "VGCS message from BSS not implemented: %s\n", + ran_msg_type_name(msg->msg_type)); + rc = -ENOTSUP; + break; + } + return rc; +} + +int msc_a_rx_vgcs_bss(struct vgcs_bss *bss, struct ran_conn *from_conn, struct msgb *msg) +{ + struct ran_dec ran_dec; + + /* Feed through the decoding mechanism ran_msg. The decoded message arrives in msc_a_rx_vgcs_decoded() */ + ran_dec = (struct ran_dec) { + .caller_data = bss, + .decode_cb = msc_a_rx_vgcs_bss_decoded, + }; + struct ran_peer *ran_peer = from_conn->ran_peer; + struct ran_infra *ran = ran_peer->sri->ran; + if (!ran->ran_dec_l2) { + LOGP(DMSC, LOGL_ERROR, "No ran_dec_l2() defined for RAN type %s\n", + osmo_rat_type_name(ran->type)); + return -ENOTSUP; + } + return ran->ran_dec_l2(&ran_dec, msg); +} + +static int msc_a_rx_vgcs_cell_decoded(struct osmo_fsm_inst *caller_fi, void *caller_data, const struct ran_msg *msg) +{ + struct vgcs_bss_cell *cell = caller_data; + struct msc_a *msc_a = (cell->bss && cell->bss->trans) ? cell->bss->trans->msc_a : NULL; + int rc = 0; + + switch (msg->msg_type) { + case RAN_MSG_VGCS_VBS_ASSIGN_RES: + /* The BSS accepts VGCS/VBS channel assignment. */ + vgcs_vbs_assign_result(cell, msg); + break; + case RAN_MSG_VGCS_VBS_ASSIGN_FAIL: + /* The BSS refuses VGCS/VBS channel assignment. */ + vgcs_vbs_assign_fail(cell, msg); + break; + case RAN_MSG_VGCS_VBS_QUEUING_IND: + /* The BSS needs more time for VGCS/VBS channel assignment. */ + vgcs_vbs_queuing_ind(cell); + break; + case RAN_MSG_VGCS_VBS_ASSIGN_STATUS: + /* The BSS gives cell status about VGCS/VBS channel. */ + vgcs_vbs_assign_status(cell, msg); + break; + case RAN_MSG_CLEAR_REQUEST: + /* BSS indicated that the channel has been released. */ + vgcs_vbs_clear_req_channel(cell, msg); + break; + case RAN_MSG_CLEAR_COMPLETE: + /* BSS confirms the release of the channel. */ + vgcs_vbs_clear_cpl_channel(cell, msg); + break; + default: + LOG_MSC_A(msc_a, LOGL_ERROR, "Message from BSS leg not implemented: %s\n", + ran_msg_type_name(msg->msg_type)); + rc = -ENOTSUP; + break; + } + return rc; +} + +int msc_a_rx_vgcs_cell(struct vgcs_bss_cell *cell, struct ran_conn *from_conn, struct msgb *msg) +{ + struct ran_dec ran_dec; + + /* Feed through the decoding mechanism ran_msg. The decoded message arrives in msc_a_rx_vgcs_decoded() */ + ran_dec = (struct ran_dec) { + .caller_data = cell, + .decode_cb = msc_a_rx_vgcs_cell_decoded, + }; + struct ran_peer *ran_peer = from_conn->ran_peer; + struct ran_infra *ran = ran_peer->sri->ran; + if (!ran->ran_dec_l2) { + LOGP(DMSC, LOGL_ERROR, "No ran_dec_l2() defined for RAN type %s\n", + osmo_rat_type_name(ran->type)); + return -ENOTSUP; + } + return ran->ran_dec_l2(&ran_dec, msg); +} + static int msc_a_ran_dec_from_msc_t(struct msc_a *msc_a, struct msc_a_ran_dec_data *d) { struct msc_t *msc_t = msc_a_msc_t(msc_a); |