/* 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);