aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2023-04-23 12:10:42 +0200
committerlaforge <laforge@osmocom.org>2023-07-17 12:29:42 +0000
commitf7c6f1424fc907096bb99a25f99564f663b112e0 (patch)
tree20cf54dac728d2ab0568be4d1553c3da745a1cdb
parente24636c6bbe573bed5a5a602160cd5ec928ba875 (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.c131
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);