aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2023-04-23 12:20:55 +0200
committerlaforge <laforge@osmocom.org>2023-07-17 12:29:42 +0000
commite24636c6bbe573bed5a5a602160cd5ec928ba875 (patch)
tree7546c335c09df6644d92bfacc3e8abf14f98dcb4 /include
parent9bbdc34a658d8a8f17f1fe677d8fbd28be363894 (diff)
ASCI: Add call control for VGCS/VBS
Diffstat (limited to 'include')
-rw-r--r--include/osmocom/msc/Makefile.am1
-rw-r--r--include/osmocom/msc/msc_vgcs.h228
-rw-r--r--include/osmocom/msc/ran_conn.h10
-rw-r--r--include/osmocom/msc/transaction.h19
4 files changed, 257 insertions, 1 deletions
diff --git a/include/osmocom/msc/Makefile.am b/include/osmocom/msc/Makefile.am
index 3c54dee5b..9fa06eb8e 100644
--- a/include/osmocom/msc/Makefile.am
+++ b/include/osmocom/msc/Makefile.am
@@ -25,6 +25,7 @@ noinst_HEADERS = \
msc_a_remote.h \
msc_common.h \
msc_ho.h \
+ msc_vgcs.h \
msc_i.h \
msc_i_remote.h \
msc_roles.h \
diff --git a/include/osmocom/msc/msc_vgcs.h b/include/osmocom/msc/msc_vgcs.h
new file mode 100644
index 000000000..2b2f45d31
--- /dev/null
+++ b/include/osmocom/msc/msc_vgcs.h
@@ -0,0 +1,228 @@
+/* Handle a call via VGCS/VBCS (Voice Group/Broadcast Call Service). */
+/*
+ * (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
+ * All Rights Reserved
+ *
+ * SPDX-License-Identifier: AGPL-3.0+
+ *
+ * Author: Andreas Eversberg
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#pragma once
+
+#include <osmocom/msc/transaction.h>
+
+#define GSM44068_ALLOC_SIZE 2048
+#define GSM44068_ALLOC_HEADROOM 256
+
+static inline struct msgb *gsm44068_msgb_alloc_name(const char *name)
+{
+ return msgb_alloc_headroom(GSM44068_ALLOC_SIZE, GSM44068_ALLOC_HEADROOM, name);
+}
+
+/* VGCS/VBS "call control" connection to each BSS */
+struct vgcs_bss {
+ struct llist_head list; /* List entry */
+ struct llist_head cell_list; /* List of cells */
+ struct gsm_trans *trans; /* Back pointer to transaction */
+ struct osmo_fsm_inst *fi; /* State machine of each BSS */
+ struct ran_conn *conn; /* RAN ("SCCP") connection */
+ enum trans_type trans_type; /* Transaction type */
+ uint32_t callref; /* Callref */
+ int pc; /* Point code for debug purpose */
+};
+
+/* VGCS/VBS "resource control" connection to each cell in BSS */
+struct vgcs_bss_cell {
+ struct llist_head list_bss; /* List entry in vgcs_bss */
+ struct llist_head list_mgw; /* List entry in MGW endpoint */
+ struct vgcs_bss *bss; /* Back pointer to vgcs_bss */
+ struct vgcs_mgw_ep *mgw; /* Back pointer to vgcs_mgw_ep */
+ struct osmo_fsm_inst *fi; /* State machine of each cell */
+ int cell_id; /* Id of cell (BTS) to use */
+ struct ran_conn *conn; /* RAN ("SCCP") connection */
+ enum trans_type trans_type; /* Transaction type */
+ uint32_t callref; /* Callref */
+ int call_id; /* Id of call (used for MGW connections) */
+ int pc; /* Point code for debug purpose */
+ bool assigned; /* Flags if assignment is complete */
+ struct rtp_stream *rtps; /* MGW connection process */
+};
+
+/* VGCS/VBS MGW endpoint for each call */
+struct vgcs_mgw_ep {
+ struct llist_head cell_list; /* List of cells with connections */
+ struct llist_head list; /* List entry */
+ struct osmo_fsm_inst *fi; /* State machine of each cell */
+ struct osmo_mgcpc_ep *mgw_ep; /* MGW endpoint */
+};
+
+/* Events for the GCC/BCC state machine.
+ * There is no primitive definition like MNGCC-* oder MNBCC-* in the standard. */
+enum vgcs_gcc_fsm_event {
+ /* The network sets up a call. */
+ VGCS_GCC_EV_NET_SETUP,
+ /* The network requests termination. */
+ VGCS_GCC_EV_NET_TERM,
+ /* The user sets up a call. */
+ VGCS_GCC_EV_USER_SETUP,
+ /* The user requests termination. */
+ VGCS_GCC_EV_USER_TERM,
+ /* BSS completed call establishment (all BSCs) */
+ VGCS_GCC_EV_BSS_ESTABLISHED,
+ /* Assignment was completed. */
+ VGCS_GCC_EV_BSS_ASSIGN_CPL,
+ /* Assignment failed. */
+ VGCS_GCC_EV_BSS_ASSIGN_FAIL,
+ /* BSS released call establishment (all BSCs) */
+ VGCS_GCC_EV_BSS_RELEASED,
+ /* Inactivity timeout */
+ VGCS_GCC_EV_TIMEOUT,
+};
+
+/* 3GPP TS 44.068 6.1.2.2 States of GCC/BCC */
+enum vgcs_gcc_fsm_state {
+ /* No call. Initial state when instance is created. */
+ VGCS_GCC_ST_N0_NULL = 0,
+ /* An MS wants to establish a call. */
+ VGCS_GCC_ST_N1_CALL_INITIATED,
+ /* Call established in at least one cell. */
+ VGCS_GCC_ST_N2_CALL_ACTIVE,
+ /* Channel activation is requested, CONNECT already sent to MS. */
+ VGCS_GCC_ST_N3_CALL_EST_PROC,
+ /* Call termination is requested, waiting for all cells to confirm. */
+ VGCS_GCC_ST_N4_TERMINATION_REQ,
+};
+
+const char *vgcs_bcc_gcc_state_name(struct osmo_fsm_inst *fi);
+
+/* Events for the VGCS/VBS "call control" state machine */
+enum vgcs_bss_fsm_event {
+ /* Start a VGCS/VBS call using VGCS/VBS SETUP message */
+ VGCS_BSS_EV_SETUP,
+ /* VGCS/VBS SETUP ACK is received */
+ VGCS_BSS_EV_SETUP_ACK,
+ /* VGCS/VBS SETUP REFUSE is received */
+ VGCS_BSS_EV_SETUP_REFUSE,
+ /* VGCS/VBS ASSIGNMENT complete or failed */
+ VGCS_BSS_EV_ACTIVE_OR_FAIL,
+ /* Talker request */
+ VGCS_BSS_EV_UL_REQUEST,
+ /* Talker established uplink */
+ VGCS_BSS_EV_UL_REQUEST_CNF,
+ /* Talker send app data */
+ VGCS_BSS_EV_UL_APP_DATA,
+ /* Talker send signaling data */
+ VGCS_BSS_EV_BSS_DTAP,
+ /* Talker becomes listener */
+ VGCS_BSS_EV_UL_RELEASE,
+ /* Release channel towards BSS */
+ VGCS_BSS_EV_CLEAR,
+ /* Channel closed from BSS */
+ VGCS_BSS_EV_CLOSE,
+ /* Release is complete */
+ VGCS_BSS_EV_RELEASED,
+};
+
+/* States of the VGCS/VBS "call control" state machine */
+enum vgcs_bss_fsm_state {
+ /* No call. Initial state when instance is created. */
+ VGCS_BSS_ST_NULL = 0,
+ /* VGCS/VBS SETUP is sent towards BSC */
+ VGCS_BSS_ST_SETUP,
+ /* VGCS/VBS ASSIGNMENT REQUEST is sent towards BSC */
+ VGCS_BSS_ST_ASSIGNMENT,
+ /* VGCS/VBS is establised */
+ VGCS_BSS_ST_ACTIVE,
+ /* CLEAR COMMAND was sent */
+ VGCS_BSS_ST_RELEASE,
+};
+
+/* Events for the VGCS/VBS "resource control" state machine */
+enum vgcs_cell_fsm_event {
+ /* RTP stream gone */
+ VGCS_CELL_EV_RTP_STREAM_GONE,
+ /* RTP stream remote addr available */
+ VGCS_CELL_EV_RTP_STREAM_ADDR_AVAILABLE,
+ /* RTP stream established */
+ VGCS_CELL_EV_RTP_STREAM_ESTABLISHED,
+ /* Start a VGCS/VBS channel using VGCS/VBS ASSIGNMENT message */
+ VGCS_CELL_EV_ASSIGN,
+ /* VGCS/VBS ASSIGNMENT RESULT is received */
+ VGCS_CELL_EV_ASSIGN_RES,
+ /* VGCS/VBS ASSIGNMENT FAILURE is received */
+ VGCS_CELL_EV_ASSIGN_FAIL,
+ /* Release channel towards BSS */
+ VGCS_CELL_EV_CLEAR,
+ /* Channel closed from BSS */
+ VGCS_CELL_EV_CLOSE,
+ /* Release is complete */
+ VGCS_CELL_EV_RELEASED,
+};
+
+/* States of the VGCS/VBS "resource control" state machine */
+enum vgcs_cell_fsm_state {
+ /* No call. Initial state when instance is created. */
+ VGCS_CELL_ST_NULL = 0,
+ /* VGCS/VBS ASSIGNMENT REQUEST is sent towards BSC */
+ VGCS_CELL_ST_ASSIGNMENT,
+ /* Channel is establised */
+ VGCS_CELL_ST_ACTIVE,
+ /* CLEAR COMMAND was sent */
+ VGCS_CELL_ST_RELEASE,
+};
+
+/* Events for the VGCS/VBS MGW endpoint state machine */
+enum vgcs_mgw_ep_fsm_event {
+ /* MGW endpoint gone */
+ VGCS_MGW_EP_EV_FREE,
+ /* Destroy MGW endpoint */
+ VGCS_MGW_EP_EV_CLEAR,
+};
+
+/* States of the VGCS/VBS MGW endpoint state machine */
+enum vgcs_mgw_ep_fsm_state {
+ VGCS_MGW_EP_ST_NULL = 0,
+ /* MGW endpoint allocated */
+ VGCS_MGW_EP_ST_ACTIVE,
+};
+
+const char *gsm44068_group_id_string(uint32_t callref);
+
+struct gcr;
+
+int gsm44068_rcv_rr(struct msc_a *msc_a, struct msgb *msg);
+int gsm44068_rcv_bcc_gcc(struct msc_a *msc_a, struct gsm_trans *trans, struct msgb *msg);
+const char *vgcs_vty_initiate(struct gsm_network *gsmnet, struct gcr *gcr);
+const char *vgcs_vty_terminate(struct gsm_network *gsmnet, struct gcr *gcr);
+void gsm44068_bcc_gcc_trans_free(struct gsm_trans *trans);
+
+void vgcs_vbs_setup_ack(struct vgcs_bss *bss, const struct ran_msg *ran_msg);
+void vgcs_vbs_setup_refuse(struct vgcs_bss *bss, const struct ran_msg *ran_msg);
+void vgcs_vbs_assign_result(struct vgcs_bss_cell *cell, const struct ran_msg *ran_msg);
+void vgcs_vbs_assign_fail(struct vgcs_bss_cell *cell, const struct ran_msg *ran_msg);
+void vgcs_vbs_queuing_ind(struct vgcs_bss_cell *cell);
+void vgcs_uplink_request(struct vgcs_bss *bss, const struct ran_msg *ran_msg);
+void vgcs_uplink_request_cnf(struct vgcs_bss *bss, const struct ran_msg *ran_msg);
+void vgcs_app_data(struct vgcs_bss *bss, const struct ran_msg *ran_msg);
+void vgcs_bss_dtap(struct vgcs_bss *bss, const struct ran_msg *ran_msg);
+void vgcs_uplink_release_ind(struct vgcs_bss *bss, const struct ran_msg *ran_msg);
+void vgcs_vbs_assign_status(struct vgcs_bss_cell *cell, const struct ran_msg *ran_msg);
+void vgcs_vbs_clear_req_channel(struct vgcs_bss_cell *cell, const struct ran_msg *ran_msg);
+void vgcs_vbs_clear_cpl_channel(struct vgcs_bss_cell *cell, const struct ran_msg *ran_msg);
+void vgcs_vbs_clear_req(struct vgcs_bss *bss, const struct ran_msg *ran_msg);
+void vgcs_vbs_clear_cpl(struct vgcs_bss *bss, const struct ran_msg *ran_msg);
+void vgcs_vbs_caller_assign_cpl(struct gsm_trans *trans);
+void vgcs_vbs_caller_assign_fail(struct gsm_trans *trans);
diff --git a/include/osmocom/msc/ran_conn.h b/include/osmocom/msc/ran_conn.h
index 7aa50df07..cdaa02652 100644
--- a/include/osmocom/msc/ran_conn.h
+++ b/include/osmocom/msc/ran_conn.h
@@ -18,9 +18,17 @@ struct ran_conn {
uint32_t sccp_conn_id;
/* MSC role that this RAN connection belongs to. This will be either an msc_i (currently active
- * connection) or an msc_t (transitory new connection during Handover). */
+ * connection) or an msc_t (transitory new connection during Handover).
+ * Used for usual L3 ran_conn to a subscriber. */
struct osmo_fsm_inst *msc_role;
+ /* For VGCS/VBS, we have additional N connections to BSS. When receiving messages for a group call peer,
+ * dispatch to the VGCS management. */
+ struct {
+ void *bss;
+ void *cell;
+ } vgcs;
+
bool closing;
};
diff --git a/include/osmocom/msc/transaction.h b/include/osmocom/msc/transaction.h
index 356bd6c8b..a5a2e84ea 100644
--- a/include/osmocom/msc/transaction.h
+++ b/include/osmocom/msc/transaction.h
@@ -99,6 +99,25 @@ struct gsm_trans {
union {
struct {
+ /* State machine of setup process towards BSS */
+ struct osmo_fsm_inst *fi;
+ /* BSS list with all VGCS/VBS calls */
+ struct llist_head bss_list;
+ /* Inactivity timeout and timer */
+ int inactivity_to;
+ struct osmo_timer_list timer_inactivity;
+ /* If talker's downlink shall be muted */
+ bool mute_talker;
+ /* Indicator, if Uplink is used in one cell */
+ bool uplink_busy;
+ /* BSS that uses the uplink */
+ struct vgcs_bss *uplink_bss;
+ /* Cell that uses the uplink */
+ struct vgcs_bss_cell *uplink_cell;
+ /* If uplink is used by the originator */
+ bool uplink_originator;
+ } gcc;
+ struct {
/* current call state */
int state;