osmo-msc/include/osmocom/msc/mncc.h

239 lines
6.3 KiB
C
Raw Normal View History

large refactoring: support inter-BSC and inter-MSC Handover 3GPP TS 49.008 '4.3 Roles of MSC-A, MSC-I and MSC-T' defines distinct roles: - MSC-A is responsible for managing subscribers, - MSC-I is the gateway to the RAN. - MSC-T is a second transitory gateway to another RAN during Handover. After inter-MSC Handover, the MSC-I is handled by a remote MSC instance, while the original MSC-A retains the responsibility of subscriber management. MSC-T exists in this patch but is not yet used, since Handover is only prepared for, not yet implemented. Facilitate Inter-MSC and inter-BSC Handover by the same internal split of MSC roles. Compared to inter-MSC Handover, mere inter-BSC has the obvious simplifications: - all of MSC-A, MSC-I and MSC-T roles will be served by the same osmo-msc instance, - messages between MSC-A and MSC-{I,T} don't need to be routed via E-interface (GSUP), - no call routing between MSC-A and -I via MNCC necessary. This is the largest code bomb I have submitted, ever. Out of principle, I apologize to everyone trying to read this as a whole. Unfortunately, I see no sense in trying to split this patch into smaller bits. It would be a huge amount of work to introduce these changes in separate chunks, especially if each should in turn be useful and pass all test suites. So, unfortunately, we are stuck with this code bomb. The following are some details and rationale for this rather huge refactoring: * separate MSC subscriber management from ran_conn struct ran_conn is reduced from the pivotal subscriber management entity it has been so far to a mere storage for an SCCP connection ID and an MSC subscriber reference. The new pivotal subscriber management entity is struct msc_a -- struct msub lists the msc_a, msc_i, msc_t roles, the vast majority of code paths however use msc_a, since MSC-A is where all the interesting stuff happens. Before handover, msc_i is an FSM implementation that encodes to the local ran_conn. After inter-MSC Handover, msc_i is a compatible but different FSM implementation that instead forwards via/from GSUP. Same goes for the msc_a struct: if osmo-msc is the MSC-I "RAN proxy" for a remote MSC-A role, the msc_a->fi is an FSM implementation that merely forwards via/from GSUP. * New SCCP implementation for RAN access To be able to forward BSSAP and RANAP messages via the GSUP interface, the individual message layers need to be cleanly separated. The IuCS implementation used until now (iu_client from libosmo-ranap) did not provide this level of separation, and needed a complete rewrite. It was trivial to implement this in such a way that both BSSAP and RANAP can be handled by the same SCCP code, hence the new SCCP-RAN layer also replaces BSSAP handling. sccp_ran.h: struct sccp_ran_inst provides an abstract handler for incoming RAN connections. A set of callback functions provides implementation specific details. * RAN Abstraction (BSSAP vs. RANAP) The common SCCP implementation did set the theme for the remaining refactoring: make all other MSC code paths entirely RAN-implementation-agnostic. ran_infra.c provides data structures that list RAN implementation specifics, from logging to RAN de-/encoding to SCCP callbacks and timers. A ran_infra pointer hence allows complete abstraction of RAN implementations: - managing connected RAN peers (BSC, RNC) in ran_peer.c, - classifying and de-/encoding RAN PDUs, - recording connected LACs and cell IDs and sending out Paging requests to matching RAN peers. * RAN RESET now also for RANAP ran_peer.c absorbs the reset_fsm from a_reset.c; in consequence, RANAP also supports proper RESET semantics now. Hence osmo-hnbgw now also needs to provide proper RESET handling, which it so far duly ignores. (TODO) * RAN de-/encoding abstraction The RAN abstraction mentioned above serves not only to separate RANAP and BSSAP implementations transparently, but also to be able to optionally handle RAN on distinct levels. Before Handover, all RAN messages are handled by the MSC-A role. However, after an inter-MSC Handover, a standalone MSC-I will need to decode RAN PDUs, at least in order to manage Assignment of RTP streams between BSS/RNC and MNCC call forwarding. ran_msg.h provides a common API with abstraction for: - receiving events from RAN, i.e. passing RAN decode from the BSC/RNC and MS/UE: struct ran_dec_msg represents RAN messages decoded from either BSSMAP or RANAP; - sending RAN events: ran_enc_msg is the counterpart to compose RAN messages that should be encoded to either BSSMAP or RANAP and passed down to the BSC/RNC and MS/UE. The RAN-specific implementations are completely contained by ran_msg_a.c and ran_msg_iu.c. In particular, Assignment and Ciphering have so far been distinct code paths for BSSAP and RANAP, with switch(via_ran){...} statements all over the place. Using RAN_DEC_* and RAN_ENC_* abstractions, these are now completely unified. Note that SGs does not qualify for RAN abstraction: the SGs interface always remains with the MSC-A role, and SGs messages follow quite distinct semantics from the fairly similar GERAN and UTRAN. * MGW and RTP stream management So far, managing MGW endpoints via MGCP was tightly glued in-between GSM-04.08-CC on the one and MNCC on the other side. Prepare for switching RTP streams between different RAN peers by moving to object-oriented implementations: implement struct call_leg and struct rtp_stream with distinct FSMs each. For MGW communication, use the osmo_mgcpc_ep API that has originated from osmo-bsc and recently moved to libosmo-mgcp-client for this purpose. Instead of implementing a sequence of events with code duplication for the RAN and CN sides, the idea is to manage each RTP stream separately by firing and receiving events as soon as codecs and RTP ports are negotiated, and letting the individual FSMs take care of the MGW management "asynchronously". The caller provides event IDs and an FSM instance that should be notified of RTP stream setup progress. Hence it becomes possible to reconnect RTP streams from one GSM-04.08-CC to another (inter-BSC Handover) or between CC and MNCC RTP peers (inter-MSC Handover) without duplicating the MGCP code for each transition. The number of FSM implementations used for MGCP handling may seem a bit of an overkill. But in fact, the number of perspectives on RTP forwarding are far from trivial: - an MGW endpoint is an entity with N connections, and MGCP "sessions" for configuring them by talking to the MGW; - an RTP stream is a remote peer connected to one of the endpoint's connections, which is asynchronously notified of codec and RTP port choices; - a call leg is the higher level view on either an MT or MO side of a voice call, a combination of two RTP streams to forward between two remote peers. BSC MGW PBX CI CI [MGW-endpoint] [--rtp_stream--] [--rtp_stream--] [----------------call_leg----------------] * Use counts Introduce using the new osmo_use_count API added to libosmocore for this purpose. Each use token has a distinct name in the logging, which can be a globally constant name or ad-hoc, like the local __func__ string constant. Use in the new struct msc_a, as well as change vlr_subscr to the new osmo_use_count API. * FSM Timeouts Introduce using the new osmo_tdef API, which provides a common VTY implementation for all timer numbers, and FSM state transitions with the correct timeout. Originated in osmo-bsc, recently moved to libosmocore. Depends: Ife31e6798b4e728a23913179e346552a7dd338c0 (libosmocore) Ib9af67b100c4583342a2103669732dab2e577b04 (libosmocore) Id617265337f09dfb6ddfe111ef5e578cd3dc9f63 (libosmocore) Ie9e2add7bbfae651c04e230d62e37cebeb91b0f5 (libosmo-sccp) I26be5c4b06a680f25f19797407ab56a5a4880ddc (osmo-mgw) Ida0e59f9a1f2dd18efea0a51680a67b69f141efa (osmo-mgw) I9a3effd38e72841529df6c135c077116981dea36 (osmo-mgw) Change-Id: I27e4988e0371808b512c757d2b52ada1615067bd
2018-12-07 13:47:34 +00:00
/* GSM Mobile Radio Interface Layer 3 messages on the A-bis interface
* 3GPP TS 04.08 version 7.21.0 Release 1998 / ETSI TS 100 940 V7.21.0 */
/* (C) 2008-2009 by Harald Welte <laforge@gnumonks.org>
* (C) 2008, 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
*
* All Rights Reserved
*
* 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/>.
*
*/
#ifndef _MNCC_H
#define _MNCC_H
#include <osmocom/core/linuxlist.h>
#include <osmocom/gsm/mncc.h>
#include <osmocom/gsm/gsm29205.h>
#include <stdint.h>
#include <netinet/in.h>
struct gsm_network;
struct msgb;
large refactoring: support inter-BSC and inter-MSC Handover 3GPP TS 49.008 '4.3 Roles of MSC-A, MSC-I and MSC-T' defines distinct roles: - MSC-A is responsible for managing subscribers, - MSC-I is the gateway to the RAN. - MSC-T is a second transitory gateway to another RAN during Handover. After inter-MSC Handover, the MSC-I is handled by a remote MSC instance, while the original MSC-A retains the responsibility of subscriber management. MSC-T exists in this patch but is not yet used, since Handover is only prepared for, not yet implemented. Facilitate Inter-MSC and inter-BSC Handover by the same internal split of MSC roles. Compared to inter-MSC Handover, mere inter-BSC has the obvious simplifications: - all of MSC-A, MSC-I and MSC-T roles will be served by the same osmo-msc instance, - messages between MSC-A and MSC-{I,T} don't need to be routed via E-interface (GSUP), - no call routing between MSC-A and -I via MNCC necessary. This is the largest code bomb I have submitted, ever. Out of principle, I apologize to everyone trying to read this as a whole. Unfortunately, I see no sense in trying to split this patch into smaller bits. It would be a huge amount of work to introduce these changes in separate chunks, especially if each should in turn be useful and pass all test suites. So, unfortunately, we are stuck with this code bomb. The following are some details and rationale for this rather huge refactoring: * separate MSC subscriber management from ran_conn struct ran_conn is reduced from the pivotal subscriber management entity it has been so far to a mere storage for an SCCP connection ID and an MSC subscriber reference. The new pivotal subscriber management entity is struct msc_a -- struct msub lists the msc_a, msc_i, msc_t roles, the vast majority of code paths however use msc_a, since MSC-A is where all the interesting stuff happens. Before handover, msc_i is an FSM implementation that encodes to the local ran_conn. After inter-MSC Handover, msc_i is a compatible but different FSM implementation that instead forwards via/from GSUP. Same goes for the msc_a struct: if osmo-msc is the MSC-I "RAN proxy" for a remote MSC-A role, the msc_a->fi is an FSM implementation that merely forwards via/from GSUP. * New SCCP implementation for RAN access To be able to forward BSSAP and RANAP messages via the GSUP interface, the individual message layers need to be cleanly separated. The IuCS implementation used until now (iu_client from libosmo-ranap) did not provide this level of separation, and needed a complete rewrite. It was trivial to implement this in such a way that both BSSAP and RANAP can be handled by the same SCCP code, hence the new SCCP-RAN layer also replaces BSSAP handling. sccp_ran.h: struct sccp_ran_inst provides an abstract handler for incoming RAN connections. A set of callback functions provides implementation specific details. * RAN Abstraction (BSSAP vs. RANAP) The common SCCP implementation did set the theme for the remaining refactoring: make all other MSC code paths entirely RAN-implementation-agnostic. ran_infra.c provides data structures that list RAN implementation specifics, from logging to RAN de-/encoding to SCCP callbacks and timers. A ran_infra pointer hence allows complete abstraction of RAN implementations: - managing connected RAN peers (BSC, RNC) in ran_peer.c, - classifying and de-/encoding RAN PDUs, - recording connected LACs and cell IDs and sending out Paging requests to matching RAN peers. * RAN RESET now also for RANAP ran_peer.c absorbs the reset_fsm from a_reset.c; in consequence, RANAP also supports proper RESET semantics now. Hence osmo-hnbgw now also needs to provide proper RESET handling, which it so far duly ignores. (TODO) * RAN de-/encoding abstraction The RAN abstraction mentioned above serves not only to separate RANAP and BSSAP implementations transparently, but also to be able to optionally handle RAN on distinct levels. Before Handover, all RAN messages are handled by the MSC-A role. However, after an inter-MSC Handover, a standalone MSC-I will need to decode RAN PDUs, at least in order to manage Assignment of RTP streams between BSS/RNC and MNCC call forwarding. ran_msg.h provides a common API with abstraction for: - receiving events from RAN, i.e. passing RAN decode from the BSC/RNC and MS/UE: struct ran_dec_msg represents RAN messages decoded from either BSSMAP or RANAP; - sending RAN events: ran_enc_msg is the counterpart to compose RAN messages that should be encoded to either BSSMAP or RANAP and passed down to the BSC/RNC and MS/UE. The RAN-specific implementations are completely contained by ran_msg_a.c and ran_msg_iu.c. In particular, Assignment and Ciphering have so far been distinct code paths for BSSAP and RANAP, with switch(via_ran){...} statements all over the place. Using RAN_DEC_* and RAN_ENC_* abstractions, these are now completely unified. Note that SGs does not qualify for RAN abstraction: the SGs interface always remains with the MSC-A role, and SGs messages follow quite distinct semantics from the fairly similar GERAN and UTRAN. * MGW and RTP stream management So far, managing MGW endpoints via MGCP was tightly glued in-between GSM-04.08-CC on the one and MNCC on the other side. Prepare for switching RTP streams between different RAN peers by moving to object-oriented implementations: implement struct call_leg and struct rtp_stream with distinct FSMs each. For MGW communication, use the osmo_mgcpc_ep API that has originated from osmo-bsc and recently moved to libosmo-mgcp-client for this purpose. Instead of implementing a sequence of events with code duplication for the RAN and CN sides, the idea is to manage each RTP stream separately by firing and receiving events as soon as codecs and RTP ports are negotiated, and letting the individual FSMs take care of the MGW management "asynchronously". The caller provides event IDs and an FSM instance that should be notified of RTP stream setup progress. Hence it becomes possible to reconnect RTP streams from one GSM-04.08-CC to another (inter-BSC Handover) or between CC and MNCC RTP peers (inter-MSC Handover) without duplicating the MGCP code for each transition. The number of FSM implementations used for MGCP handling may seem a bit of an overkill. But in fact, the number of perspectives on RTP forwarding are far from trivial: - an MGW endpoint is an entity with N connections, and MGCP "sessions" for configuring them by talking to the MGW; - an RTP stream is a remote peer connected to one of the endpoint's connections, which is asynchronously notified of codec and RTP port choices; - a call leg is the higher level view on either an MT or MO side of a voice call, a combination of two RTP streams to forward between two remote peers. BSC MGW PBX CI CI [MGW-endpoint] [--rtp_stream--] [--rtp_stream--] [----------------call_leg----------------] * Use counts Introduce using the new osmo_use_count API added to libosmocore for this purpose. Each use token has a distinct name in the logging, which can be a globally constant name or ad-hoc, like the local __func__ string constant. Use in the new struct msc_a, as well as change vlr_subscr to the new osmo_use_count API. * FSM Timeouts Introduce using the new osmo_tdef API, which provides a common VTY implementation for all timer numbers, and FSM state transitions with the correct timeout. Originated in osmo-bsc, recently moved to libosmocore. Depends: Ife31e6798b4e728a23913179e346552a7dd338c0 (libosmocore) Ib9af67b100c4583342a2103669732dab2e577b04 (libosmocore) Id617265337f09dfb6ddfe111ef5e578cd3dc9f63 (libosmocore) Ie9e2add7bbfae651c04e230d62e37cebeb91b0f5 (libosmo-sccp) I26be5c4b06a680f25f19797407ab56a5a4880ddc (osmo-mgw) Ida0e59f9a1f2dd18efea0a51680a67b69f141efa (osmo-mgw) I9a3effd38e72841529df6c135c077116981dea36 (osmo-mgw) Change-Id: I27e4988e0371808b512c757d2b52ada1615067bd
2018-12-07 13:47:34 +00:00
struct gsm0808_channel_type;
/* One end of a call */
struct gsm_call {
struct llist_head entry;
/* network handle */
struct gsm_network *net;
/* the 'local' transaction */
uint32_t callref;
/* the 'remote' transaction */
uint32_t remote_ref;
};
#define MNCC_SETUP_REQ 0x0101
#define MNCC_SETUP_IND 0x0102
#define MNCC_SETUP_RSP 0x0103
#define MNCC_SETUP_CNF 0x0104
#define MNCC_SETUP_COMPL_REQ 0x0105
#define MNCC_SETUP_COMPL_IND 0x0106
/* MNCC_REJ_* is performed via MNCC_REL_* */
#define MNCC_CALL_CONF_IND 0x0107
#define MNCC_CALL_PROC_REQ 0x0108
#define MNCC_PROGRESS_REQ 0x0109
#define MNCC_ALERT_REQ 0x010a
#define MNCC_ALERT_IND 0x010b
#define MNCC_NOTIFY_REQ 0x010c
#define MNCC_NOTIFY_IND 0x010d
#define MNCC_DISC_REQ 0x010e
#define MNCC_DISC_IND 0x010f
#define MNCC_REL_REQ 0x0110
#define MNCC_REL_IND 0x0111
#define MNCC_REL_CNF 0x0112
#define MNCC_FACILITY_REQ 0x0113
#define MNCC_FACILITY_IND 0x0114
#define MNCC_START_DTMF_IND 0x0115
#define MNCC_START_DTMF_RSP 0x0116
#define MNCC_START_DTMF_REJ 0x0117
#define MNCC_STOP_DTMF_IND 0x0118
#define MNCC_STOP_DTMF_RSP 0x0119
#define MNCC_MODIFY_REQ 0x011a
#define MNCC_MODIFY_IND 0x011b
#define MNCC_MODIFY_RSP 0x011c
#define MNCC_MODIFY_CNF 0x011d
#define MNCC_MODIFY_REJ 0x011e
#define MNCC_HOLD_IND 0x011f
#define MNCC_HOLD_CNF 0x0120
#define MNCC_HOLD_REJ 0x0121
#define MNCC_RETRIEVE_IND 0x0122
#define MNCC_RETRIEVE_CNF 0x0123
#define MNCC_RETRIEVE_REJ 0x0124
#define MNCC_USERINFO_REQ 0x0125
#define MNCC_USERINFO_IND 0x0126
#define MNCC_REJ_REQ 0x0127
#define MNCC_REJ_IND 0x0128
#define MNCC_BRIDGE 0x0200
#define MNCC_FRAME_RECV 0x0201
#define MNCC_FRAME_DROP 0x0202
#define MNCC_LCHAN_MODIFY 0x0203
#define MNCC_RTP_CREATE 0x0204
#define MNCC_RTP_CONNECT 0x0205
#define MNCC_RTP_FREE 0x0206
#define GSM_TCHF_FRAME 0x0300
#define GSM_TCHF_FRAME_EFR 0x0301
#define GSM_TCHH_FRAME 0x0302
#define GSM_TCH_FRAME_AMR 0x0303
#define GSM_BAD_FRAME 0x03ff
#define MNCC_SOCKET_HELLO 0x0400
#define GSM_MAX_FACILITY 128
#define GSM_MAX_SSVERSION 128
#define GSM_MAX_USERUSER 128
#define MNCC_F_BEARER_CAP 0x0001
#define MNCC_F_CALLED 0x0002
#define MNCC_F_CALLING 0x0004
#define MNCC_F_REDIRECTING 0x0008
#define MNCC_F_CONNECTED 0x0010
#define MNCC_F_CAUSE 0x0020
#define MNCC_F_USERUSER 0x0040
#define MNCC_F_PROGRESS 0x0080
#define MNCC_F_EMERGENCY 0x0100
#define MNCC_F_FACILITY 0x0200
#define MNCC_F_SSVERSION 0x0400
#define MNCC_F_CCCAP 0x0800
#define MNCC_F_KEYPAD 0x1000
#define MNCC_F_SIGNAL 0x2000
struct gsm_mncc {
/* context based information */
uint32_t msg_type;
uint32_t callref;
/* which fields are present */
uint32_t fields;
/* data derived information (MNCC_F_ based) */
struct gsm_mncc_bearer_cap bearer_cap;
struct gsm_mncc_number called;
struct gsm_mncc_number calling;
struct gsm_mncc_number redirecting;
struct gsm_mncc_number connected;
struct gsm_mncc_cause cause;
struct gsm_mncc_progress progress;
struct gsm_mncc_useruser useruser;
struct gsm_mncc_facility facility;
struct gsm_mncc_cccap cccap;
struct gsm_mncc_ssversion ssversion;
struct {
int sup;
int inv;
} clir;
int signal;
/* data derived information, not MNCC_F based */
int keypad;
int more;
int notify; /* 0..127 */
int emergency;
char imsi[16];
unsigned char lchan_type;
unsigned char lchan_mode;
struct osmo_gcr_parsed gcr;
/* A buffer to contain SDP ('\0' terminated) */
char sdp[1024];
};
struct gsm_data_frame {
uint32_t msg_type;
uint32_t callref;
unsigned char data[0];
};
#define MNCC_SOCK_VERSION 8
struct gsm_mncc_hello {
uint32_t msg_type;
uint32_t version;
/* send the sizes of the structs */
uint32_t mncc_size;
uint32_t data_frame_size;
/* send some offsets */
uint32_t called_offset;
uint32_t signal_offset;
uint32_t emergency_offset;
uint32_t lchan_type_offset;
};
struct gsm_mncc_rtp {
uint32_t msg_type;
uint32_t callref;
struct sockaddr_storage addr;
uint32_t payload_type;
uint32_t payload_msg_type;
char sdp[1024];
};
struct gsm_mncc_bridge {
uint32_t msg_type;
uint32_t callref[2];
};
large refactoring: support inter-BSC and inter-MSC Handover 3GPP TS 49.008 '4.3 Roles of MSC-A, MSC-I and MSC-T' defines distinct roles: - MSC-A is responsible for managing subscribers, - MSC-I is the gateway to the RAN. - MSC-T is a second transitory gateway to another RAN during Handover. After inter-MSC Handover, the MSC-I is handled by a remote MSC instance, while the original MSC-A retains the responsibility of subscriber management. MSC-T exists in this patch but is not yet used, since Handover is only prepared for, not yet implemented. Facilitate Inter-MSC and inter-BSC Handover by the same internal split of MSC roles. Compared to inter-MSC Handover, mere inter-BSC has the obvious simplifications: - all of MSC-A, MSC-I and MSC-T roles will be served by the same osmo-msc instance, - messages between MSC-A and MSC-{I,T} don't need to be routed via E-interface (GSUP), - no call routing between MSC-A and -I via MNCC necessary. This is the largest code bomb I have submitted, ever. Out of principle, I apologize to everyone trying to read this as a whole. Unfortunately, I see no sense in trying to split this patch into smaller bits. It would be a huge amount of work to introduce these changes in separate chunks, especially if each should in turn be useful and pass all test suites. So, unfortunately, we are stuck with this code bomb. The following are some details and rationale for this rather huge refactoring: * separate MSC subscriber management from ran_conn struct ran_conn is reduced from the pivotal subscriber management entity it has been so far to a mere storage for an SCCP connection ID and an MSC subscriber reference. The new pivotal subscriber management entity is struct msc_a -- struct msub lists the msc_a, msc_i, msc_t roles, the vast majority of code paths however use msc_a, since MSC-A is where all the interesting stuff happens. Before handover, msc_i is an FSM implementation that encodes to the local ran_conn. After inter-MSC Handover, msc_i is a compatible but different FSM implementation that instead forwards via/from GSUP. Same goes for the msc_a struct: if osmo-msc is the MSC-I "RAN proxy" for a remote MSC-A role, the msc_a->fi is an FSM implementation that merely forwards via/from GSUP. * New SCCP implementation for RAN access To be able to forward BSSAP and RANAP messages via the GSUP interface, the individual message layers need to be cleanly separated. The IuCS implementation used until now (iu_client from libosmo-ranap) did not provide this level of separation, and needed a complete rewrite. It was trivial to implement this in such a way that both BSSAP and RANAP can be handled by the same SCCP code, hence the new SCCP-RAN layer also replaces BSSAP handling. sccp_ran.h: struct sccp_ran_inst provides an abstract handler for incoming RAN connections. A set of callback functions provides implementation specific details. * RAN Abstraction (BSSAP vs. RANAP) The common SCCP implementation did set the theme for the remaining refactoring: make all other MSC code paths entirely RAN-implementation-agnostic. ran_infra.c provides data structures that list RAN implementation specifics, from logging to RAN de-/encoding to SCCP callbacks and timers. A ran_infra pointer hence allows complete abstraction of RAN implementations: - managing connected RAN peers (BSC, RNC) in ran_peer.c, - classifying and de-/encoding RAN PDUs, - recording connected LACs and cell IDs and sending out Paging requests to matching RAN peers. * RAN RESET now also for RANAP ran_peer.c absorbs the reset_fsm from a_reset.c; in consequence, RANAP also supports proper RESET semantics now. Hence osmo-hnbgw now also needs to provide proper RESET handling, which it so far duly ignores. (TODO) * RAN de-/encoding abstraction The RAN abstraction mentioned above serves not only to separate RANAP and BSSAP implementations transparently, but also to be able to optionally handle RAN on distinct levels. Before Handover, all RAN messages are handled by the MSC-A role. However, after an inter-MSC Handover, a standalone MSC-I will need to decode RAN PDUs, at least in order to manage Assignment of RTP streams between BSS/RNC and MNCC call forwarding. ran_msg.h provides a common API with abstraction for: - receiving events from RAN, i.e. passing RAN decode from the BSC/RNC and MS/UE: struct ran_dec_msg represents RAN messages decoded from either BSSMAP or RANAP; - sending RAN events: ran_enc_msg is the counterpart to compose RAN messages that should be encoded to either BSSMAP or RANAP and passed down to the BSC/RNC and MS/UE. The RAN-specific implementations are completely contained by ran_msg_a.c and ran_msg_iu.c. In particular, Assignment and Ciphering have so far been distinct code paths for BSSAP and RANAP, with switch(via_ran){...} statements all over the place. Using RAN_DEC_* and RAN_ENC_* abstractions, these are now completely unified. Note that SGs does not qualify for RAN abstraction: the SGs interface always remains with the MSC-A role, and SGs messages follow quite distinct semantics from the fairly similar GERAN and UTRAN. * MGW and RTP stream management So far, managing MGW endpoints via MGCP was tightly glued in-between GSM-04.08-CC on the one and MNCC on the other side. Prepare for switching RTP streams between different RAN peers by moving to object-oriented implementations: implement struct call_leg and struct rtp_stream with distinct FSMs each. For MGW communication, use the osmo_mgcpc_ep API that has originated from osmo-bsc and recently moved to libosmo-mgcp-client for this purpose. Instead of implementing a sequence of events with code duplication for the RAN and CN sides, the idea is to manage each RTP stream separately by firing and receiving events as soon as codecs and RTP ports are negotiated, and letting the individual FSMs take care of the MGW management "asynchronously". The caller provides event IDs and an FSM instance that should be notified of RTP stream setup progress. Hence it becomes possible to reconnect RTP streams from one GSM-04.08-CC to another (inter-BSC Handover) or between CC and MNCC RTP peers (inter-MSC Handover) without duplicating the MGCP code for each transition. The number of FSM implementations used for MGCP handling may seem a bit of an overkill. But in fact, the number of perspectives on RTP forwarding are far from trivial: - an MGW endpoint is an entity with N connections, and MGCP "sessions" for configuring them by talking to the MGW; - an RTP stream is a remote peer connected to one of the endpoint's connections, which is asynchronously notified of codec and RTP port choices; - a call leg is the higher level view on either an MT or MO side of a voice call, a combination of two RTP streams to forward between two remote peers. BSC MGW PBX CI CI [MGW-endpoint] [--rtp_stream--] [--rtp_stream--] [----------------call_leg----------------] * Use counts Introduce using the new osmo_use_count API added to libosmocore for this purpose. Each use token has a distinct name in the logging, which can be a globally constant name or ad-hoc, like the local __func__ string constant. Use in the new struct msc_a, as well as change vlr_subscr to the new osmo_use_count API. * FSM Timeouts Introduce using the new osmo_tdef API, which provides a common VTY implementation for all timer numbers, and FSM state transitions with the correct timeout. Originated in osmo-bsc, recently moved to libosmocore. Depends: Ife31e6798b4e728a23913179e346552a7dd338c0 (libosmocore) Ib9af67b100c4583342a2103669732dab2e577b04 (libosmocore) Id617265337f09dfb6ddfe111ef5e578cd3dc9f63 (libosmocore) Ie9e2add7bbfae651c04e230d62e37cebeb91b0f5 (libosmo-sccp) I26be5c4b06a680f25f19797407ab56a5a4880ddc (osmo-mgw) Ida0e59f9a1f2dd18efea0a51680a67b69f141efa (osmo-mgw) I9a3effd38e72841529df6c135c077116981dea36 (osmo-mgw) Change-Id: I27e4988e0371808b512c757d2b52ada1615067bd
2018-12-07 13:47:34 +00:00
union mncc_msg {
uint32_t msg_type;
struct gsm_mncc signal;
struct gsm_mncc_hello hello;
struct gsm_data_frame data_frame;
struct gsm_mncc_rtp rtp;
struct gsm_mncc_bridge bridge;
};
const char *get_mncc_name(int value);
void mncc_set_cause(struct gsm_mncc *data, int loc, int val);
void cc_tx_to_mncc(struct gsm_network *net, struct msgb *msg);
/* input from CC code into mncc_builtin */
int int_mncc_recv(struct gsm_network *net, struct msgb *msg);
/* input from CC code into mncc_sock */
int mncc_sock_from_cc(struct gsm_network *net, struct msgb *msg);
int mncc_sock_init(struct gsm_network *net, const char *sock_path);
#define mncc_is_data_frame(msg_type) \
(msg_type == GSM_TCHF_FRAME \
|| msg_type == GSM_TCHF_FRAME_EFR \
|| msg_type == GSM_TCHH_FRAME \
|| msg_type == GSM_TCH_FRAME_AMR \
|| msg_type == GSM_BAD_FRAME)
int mncc_prim_check(const struct gsm_mncc *mncc_prim, unsigned int len);
int mncc_check_sdp_termination(const char *label, const struct gsm_mncc *mncc, unsigned int len, const char *sdp);
large refactoring: support inter-BSC and inter-MSC Handover 3GPP TS 49.008 '4.3 Roles of MSC-A, MSC-I and MSC-T' defines distinct roles: - MSC-A is responsible for managing subscribers, - MSC-I is the gateway to the RAN. - MSC-T is a second transitory gateway to another RAN during Handover. After inter-MSC Handover, the MSC-I is handled by a remote MSC instance, while the original MSC-A retains the responsibility of subscriber management. MSC-T exists in this patch but is not yet used, since Handover is only prepared for, not yet implemented. Facilitate Inter-MSC and inter-BSC Handover by the same internal split of MSC roles. Compared to inter-MSC Handover, mere inter-BSC has the obvious simplifications: - all of MSC-A, MSC-I and MSC-T roles will be served by the same osmo-msc instance, - messages between MSC-A and MSC-{I,T} don't need to be routed via E-interface (GSUP), - no call routing between MSC-A and -I via MNCC necessary. This is the largest code bomb I have submitted, ever. Out of principle, I apologize to everyone trying to read this as a whole. Unfortunately, I see no sense in trying to split this patch into smaller bits. It would be a huge amount of work to introduce these changes in separate chunks, especially if each should in turn be useful and pass all test suites. So, unfortunately, we are stuck with this code bomb. The following are some details and rationale for this rather huge refactoring: * separate MSC subscriber management from ran_conn struct ran_conn is reduced from the pivotal subscriber management entity it has been so far to a mere storage for an SCCP connection ID and an MSC subscriber reference. The new pivotal subscriber management entity is struct msc_a -- struct msub lists the msc_a, msc_i, msc_t roles, the vast majority of code paths however use msc_a, since MSC-A is where all the interesting stuff happens. Before handover, msc_i is an FSM implementation that encodes to the local ran_conn. After inter-MSC Handover, msc_i is a compatible but different FSM implementation that instead forwards via/from GSUP. Same goes for the msc_a struct: if osmo-msc is the MSC-I "RAN proxy" for a remote MSC-A role, the msc_a->fi is an FSM implementation that merely forwards via/from GSUP. * New SCCP implementation for RAN access To be able to forward BSSAP and RANAP messages via the GSUP interface, the individual message layers need to be cleanly separated. The IuCS implementation used until now (iu_client from libosmo-ranap) did not provide this level of separation, and needed a complete rewrite. It was trivial to implement this in such a way that both BSSAP and RANAP can be handled by the same SCCP code, hence the new SCCP-RAN layer also replaces BSSAP handling. sccp_ran.h: struct sccp_ran_inst provides an abstract handler for incoming RAN connections. A set of callback functions provides implementation specific details. * RAN Abstraction (BSSAP vs. RANAP) The common SCCP implementation did set the theme for the remaining refactoring: make all other MSC code paths entirely RAN-implementation-agnostic. ran_infra.c provides data structures that list RAN implementation specifics, from logging to RAN de-/encoding to SCCP callbacks and timers. A ran_infra pointer hence allows complete abstraction of RAN implementations: - managing connected RAN peers (BSC, RNC) in ran_peer.c, - classifying and de-/encoding RAN PDUs, - recording connected LACs and cell IDs and sending out Paging requests to matching RAN peers. * RAN RESET now also for RANAP ran_peer.c absorbs the reset_fsm from a_reset.c; in consequence, RANAP also supports proper RESET semantics now. Hence osmo-hnbgw now also needs to provide proper RESET handling, which it so far duly ignores. (TODO) * RAN de-/encoding abstraction The RAN abstraction mentioned above serves not only to separate RANAP and BSSAP implementations transparently, but also to be able to optionally handle RAN on distinct levels. Before Handover, all RAN messages are handled by the MSC-A role. However, after an inter-MSC Handover, a standalone MSC-I will need to decode RAN PDUs, at least in order to manage Assignment of RTP streams between BSS/RNC and MNCC call forwarding. ran_msg.h provides a common API with abstraction for: - receiving events from RAN, i.e. passing RAN decode from the BSC/RNC and MS/UE: struct ran_dec_msg represents RAN messages decoded from either BSSMAP or RANAP; - sending RAN events: ran_enc_msg is the counterpart to compose RAN messages that should be encoded to either BSSMAP or RANAP and passed down to the BSC/RNC and MS/UE. The RAN-specific implementations are completely contained by ran_msg_a.c and ran_msg_iu.c. In particular, Assignment and Ciphering have so far been distinct code paths for BSSAP and RANAP, with switch(via_ran){...} statements all over the place. Using RAN_DEC_* and RAN_ENC_* abstractions, these are now completely unified. Note that SGs does not qualify for RAN abstraction: the SGs interface always remains with the MSC-A role, and SGs messages follow quite distinct semantics from the fairly similar GERAN and UTRAN. * MGW and RTP stream management So far, managing MGW endpoints via MGCP was tightly glued in-between GSM-04.08-CC on the one and MNCC on the other side. Prepare for switching RTP streams between different RAN peers by moving to object-oriented implementations: implement struct call_leg and struct rtp_stream with distinct FSMs each. For MGW communication, use the osmo_mgcpc_ep API that has originated from osmo-bsc and recently moved to libosmo-mgcp-client for this purpose. Instead of implementing a sequence of events with code duplication for the RAN and CN sides, the idea is to manage each RTP stream separately by firing and receiving events as soon as codecs and RTP ports are negotiated, and letting the individual FSMs take care of the MGW management "asynchronously". The caller provides event IDs and an FSM instance that should be notified of RTP stream setup progress. Hence it becomes possible to reconnect RTP streams from one GSM-04.08-CC to another (inter-BSC Handover) or between CC and MNCC RTP peers (inter-MSC Handover) without duplicating the MGCP code for each transition. The number of FSM implementations used for MGCP handling may seem a bit of an overkill. But in fact, the number of perspectives on RTP forwarding are far from trivial: - an MGW endpoint is an entity with N connections, and MGCP "sessions" for configuring them by talking to the MGW; - an RTP stream is a remote peer connected to one of the endpoint's connections, which is asynchronously notified of codec and RTP port choices; - a call leg is the higher level view on either an MT or MO side of a voice call, a combination of two RTP streams to forward between two remote peers. BSC MGW PBX CI CI [MGW-endpoint] [--rtp_stream--] [--rtp_stream--] [----------------call_leg----------------] * Use counts Introduce using the new osmo_use_count API added to libosmocore for this purpose. Each use token has a distinct name in the logging, which can be a globally constant name or ad-hoc, like the local __func__ string constant. Use in the new struct msc_a, as well as change vlr_subscr to the new osmo_use_count API. * FSM Timeouts Introduce using the new osmo_tdef API, which provides a common VTY implementation for all timer numbers, and FSM state transitions with the correct timeout. Originated in osmo-bsc, recently moved to libosmocore. Depends: Ife31e6798b4e728a23913179e346552a7dd338c0 (libosmocore) Ib9af67b100c4583342a2103669732dab2e577b04 (libosmocore) Id617265337f09dfb6ddfe111ef5e578cd3dc9f63 (libosmocore) Ie9e2add7bbfae651c04e230d62e37cebeb91b0f5 (libosmo-sccp) I26be5c4b06a680f25f19797407ab56a5a4880ddc (osmo-mgw) Ida0e59f9a1f2dd18efea0a51680a67b69f141efa (osmo-mgw) I9a3effd38e72841529df6c135c077116981dea36 (osmo-mgw) Change-Id: I27e4988e0371808b512c757d2b52ada1615067bd
2018-12-07 13:47:34 +00:00
int mncc_bearer_cap_to_channel_type(struct gsm0808_channel_type *ct, const struct gsm_mncc_bearer_cap *bc);
#endif