From e24636c6bbe573bed5a5a602160cd5ec928ba875 Mon Sep 17 00:00:00 2001 From: Andreas Eversberg Date: Sun, 23 Apr 2023 12:20:55 +0200 Subject: ASCI: Add call control for VGCS/VBS Change-Id: I9947403fde8212b66758104443c60aaacc8b1e7b Related: OS#4854 --- include/osmocom/msc/Makefile.am | 1 + include/osmocom/msc/msc_vgcs.h | 228 ++++++++++++++++++++++++++++++++++++++ include/osmocom/msc/ran_conn.h | 10 +- include/osmocom/msc/transaction.h | 19 ++++ 4 files changed, 257 insertions(+), 1 deletion(-) create mode 100644 include/osmocom/msc/msc_vgcs.h (limited to 'include') 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 + * 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 . + */ +#pragma once + +#include + +#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 @@ -98,6 +98,25 @@ struct gsm_trans { struct gsm_mncc_bearer_cap bearer_cap; 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 */ -- cgit v1.2.3