dexter has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795 )
Change subject: mgw_fsm: add MGW support to osmo-hnbgw ......................................................................
mgw_fsm: add MGW support to osmo-hnbgw
osmo-hnbgw lacks support for an co-located media gateway. This makes it virtually impossible to isolate the HNB from the core network properly.
Lets add MGCP support to osmo-hnbgw so that it can control a co-located media gateway to relay the RTP streams between HNB and core network.
Change-Id: Ib9b62e0145184b91c56ce5d8870760bfa49cc5a4 Related: OS#515 --- M configure.ac M contrib/osmo-hnbgw.spec.in M debian/control M include/osmocom/hnbgw/context_map.h M include/osmocom/hnbgw/hnbgw.h A include/osmocom/hnbgw/mgw_fsm.h A include/osmocom/hnbgw/tdefs.h M include/osmocom/hnbgw/vty.h M src/osmo-hnbgw/Makefile.am M src/osmo-hnbgw/hnbgw.c M src/osmo-hnbgw/hnbgw_cn.c M src/osmo-hnbgw/hnbgw_rua.c M src/osmo-hnbgw/hnbgw_vty.c A src/osmo-hnbgw/mgw_fsm.c A src/osmo-hnbgw/tdefs.c 15 files changed, 705 insertions(+), 1 deletion(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-hnbgw refs/changes/95/26795/1
diff --git a/configure.ac b/configure.ac index 4dc8087..f9bca78 100644 --- a/configure.ac +++ b/configure.ac @@ -65,7 +65,7 @@ PKG_CHECK_MODULES(LIBOSMORUA, libosmo-rua >= 1.1.0) PKG_CHECK_MODULES(LIBOSMORANAP, libosmo-ranap >= 1.1.0) PKG_CHECK_MODULES(LIBOSMOHNBAP, libosmo-hnbap >= 1.1.0) - +PKG_CHECK_MODULES(LIBOSMOMGCPCLIENT, libosmo-mgcp-client >= 1.9.0)
dnl checks for header files AC_HEADER_STDC diff --git a/contrib/osmo-hnbgw.spec.in b/contrib/osmo-hnbgw.spec.in index 5ab0f5a..04fad1f 100644 --- a/contrib/osmo-hnbgw.spec.in +++ b/contrib/osmo-hnbgw.spec.in @@ -33,6 +33,7 @@ BuildRequires: systemd-rpm-macros %endif BuildRequires: pkgconfig(libcrypto) >= 0.9.5 +BuildRequires: pkgconfig(libosmo-mgcp-client) >= 1.9.0 BuildRequires: pkgconfig(libosmo-netif) >= 1.1.0 BuildRequires: pkgconfig(libosmo-sigtran) >= 1.5.0 BuildRequires: pkgconfig(libosmoabis) >= 1.2.0 diff --git a/debian/control b/debian/control index 1ea3ad2..f7b1047 100644 --- a/debian/control +++ b/debian/control @@ -18,6 +18,7 @@ libosmo-sigtran-dev (>= 1.5.0), libosmo-abis-dev (>= 1.2.0), libosmo-netif-dev (>= 1.1.0), + libosmo-mgcp-client-dev (>= 1.9.0), libosmo-hnbap-dev (>= 1.1.0), libosmo-ranap-dev (>= 1.1.0), libosmo-rua-dev (>= 1.1.0), diff --git a/include/osmocom/hnbgw/context_map.h b/include/osmocom/hnbgw/context_map.h index 6279b91..6910fe8 100644 --- a/include/osmocom/hnbgw/context_map.h +++ b/include/osmocom/hnbgw/context_map.h @@ -35,6 +35,9 @@ uint32_t scu_conn_id;
enum hnbgw_context_map_state state; + + /* FSM instance for the MGW */ + struct osmo_fsm_inst *mgw_fi; };
diff --git a/include/osmocom/hnbgw/hnbgw.h b/include/osmocom/hnbgw/hnbgw.h index fc8298d..9a46301 100644 --- a/include/osmocom/hnbgw/hnbgw.h +++ b/include/osmocom/hnbgw/hnbgw.h @@ -16,6 +16,7 @@ DHNBAP, DRUA, DRANAP, + DMGW, };
#define LOGHNB(x, ss, lvl, fmt, args ...) \ @@ -133,6 +134,7 @@ bool hnbap_allow_tmsi; /*! print hnb-id (true) or MCC-MNC-LAC-RAC-SAC (false) in logs */ bool log_prefix_hnb_id; + struct mgcp_client_conf *mgcp_client; } config; /*! SCTP listen socket for incoming connections */ struct osmo_stream_srv_link *iuh; @@ -151,6 +153,7 @@ struct osmo_sccp_addr iucs_remote_addr; struct osmo_sccp_addr iups_remote_addr; } sccp; + struct mgcp_client *mgcp_client; };
extern void *talloc_asn1_ctx; diff --git a/include/osmocom/hnbgw/mgw_fsm.h b/include/osmocom/hnbgw/mgw_fsm.h new file mode 100644 index 0000000..219026d --- /dev/null +++ b/include/osmocom/hnbgw/mgw_fsm.h @@ -0,0 +1,5 @@ +#pragma once + +int mgw_fsm_alloc_and_handle_rab_ass_req(struct hnbgw_context_map *map, struct osmo_prim_hdr *oph_rab_ass_req); +int mgw_fsm_handle_iu_release(struct hnbgw_context_map *map); +int mgw_fsm_handle_rab_ass_resp(struct hnbgw_context_map *map, struct osmo_prim_hdr *oph); diff --git a/include/osmocom/hnbgw/tdefs.h b/include/osmocom/hnbgw/tdefs.h new file mode 100644 index 0000000..4f98a36 --- /dev/null +++ b/include/osmocom/hnbgw/tdefs.h @@ -0,0 +1,6 @@ +#pragma once + +#include <osmocom/core/tdef.h> + +extern struct osmo_tdef mgw_fsm_T_defs[]; +extern struct osmo_tdef_group hnbgw_tdef_group[]; diff --git a/include/osmocom/hnbgw/vty.h b/include/osmocom/hnbgw/vty.h index 3d05da5..93b3c45 100644 --- a/include/osmocom/hnbgw/vty.h +++ b/include/osmocom/hnbgw/vty.h @@ -7,5 +7,6 @@ IUH_NODE, IUCS_NODE, IUPS_NODE, + MGCP_NODE, };
diff --git a/src/osmo-hnbgw/Makefile.am b/src/osmo-hnbgw/Makefile.am index 0948170..64d5ccd 100644 --- a/src/osmo-hnbgw/Makefile.am +++ b/src/osmo-hnbgw/Makefile.am @@ -19,6 +19,7 @@ $(LIBOSMORUA_CFLAGS) \ $(LIBOSMORANAP_CFLAGS) \ $(LIBOSMOHNBAP_CFLAGS) \ + $(LIBOSMOMGCPCLIENT_CFLAGS) \ $(NULL)
AM_LDFLAGS = \ @@ -38,6 +39,8 @@ context_map.c \ hnbgw_cn.c \ ranap_rab_ass.c \ + mgw_fsm.c \ + tdefs.c \ $(NULL)
osmo_hnbgw_LDADD = \ @@ -52,5 +55,7 @@ $(LIBOSMORUA_LIBS) \ $(LIBOSMORANAP_LIBS) \ $(LIBOSMOHNBAP_LIBS) \ + $(LIBOSMOMGCPCLIENT_LIBS) \ $(LIBSCTP_LIBS) \ + $(LIBOSMOMGCPCLIENT_LIBS) \ $(NULL) diff --git a/src/osmo-hnbgw/hnbgw.c b/src/osmo-hnbgw/hnbgw.c index da15bfc..cc6197c 100644 --- a/src/osmo-hnbgw/hnbgw.c +++ b/src/osmo-hnbgw/hnbgw.c @@ -52,6 +52,8 @@ #include <osmocom/vty/command.h> #include <osmocom/vty/ports.h>
+#include <osmocom/mgcp_client/mgcp_client.h> + #include <osmocom/netif/stream.h>
#include <osmocom/ranap/ranap_common.h> @@ -372,6 +374,11 @@ .color = "", .description = "RAN Application Part", }, + [DMGW] = { + .name = "DMGW", .loglevel = LOGL_NOTICE, .enabled = 1, + .color = "\033[1;33m", + .description = "Media Gateway", + }, };
static const struct log_info hnbgw_log_info = { @@ -681,6 +688,19 @@ } g_hnb_gw->iuh = srv;
+ /* Initialize and connect MGCP client. */ + g_hnb_gw->mgcp_client = mgcp_client_init(tall_hnb_ctx, g_hnb_gw->config.mgcp_client); + if (!g_hnb_gw->mgcp_client) { + LOGP(DMGW, LOGL_ERROR, "MGW client initalization failed\n"); + return -EINVAL; + } + if (mgcp_client_connect(g_hnb_gw->mgcp_client)) { + LOGP(DMGW, LOGL_ERROR, "MGW connect failed at (%s:%u)\n", + g_hnb_gw->config.mgcp_client->remote_addr, + g_hnb_gw->config.mgcp_client->remote_port); + return -EINVAL; + } + if (hnbgw_cmdline_config.daemonize) { rc = osmo_daemonize(); if (rc < 0) { diff --git a/src/osmo-hnbgw/hnbgw_cn.c b/src/osmo-hnbgw/hnbgw_cn.c index 7fbb691..c3deba5 100644 --- a/src/osmo-hnbgw/hnbgw_cn.c +++ b/src/osmo-hnbgw/hnbgw_cn.c @@ -34,6 +34,7 @@ #include <osmocom/ranap/ranap_ies_defs.h> #include <osmocom/ranap/ranap_msg_factory.h> #include <osmocom/hnbgw/context_map.h> +#include <osmocom/hnbgw/mgw_fsm.h>
/*********************************************************************** * Outbound RANAP RESET to CN @@ -356,6 +357,21 @@ return 0; }
+ /* Intercept RAB Assignment Request, Setup MGW FSM */ + if (!map->is_ps && msgb_l2len(oph->msg) > 2) { + switch (((uint8_t*)msgb_l2(oph->msg))[1]) { + case RANAP_ProcedureCode_id_RAB_Assignment: + /* Just like rua_tx_dt(), mgw_fsm_inst_alloc() will not take ownership of oph. Instead it will + * make its own copy of the message contents, so it is safe to free oph->msg() in sccp_sap_up() + * below. */ + return mgw_fsm_alloc_and_handle_rab_ass_req(map, oph); + case RANAP_ProcedureCode_id_Iu_Release: + /* Any IU Release will terminate the MGW FSM */ + mgw_fsm_handle_iu_release(map); + break; + } + } + return rua_tx_dt(map->hnb_ctx, map->is_ps, map->rua_ctx_id, msgb_l2(oph->msg), msgb_l2len(oph->msg)); } diff --git a/src/osmo-hnbgw/hnbgw_rua.c b/src/osmo-hnbgw/hnbgw_rua.c index 24ca167..202007f 100644 --- a/src/osmo-hnbgw/hnbgw_rua.c +++ b/src/osmo-hnbgw/hnbgw_rua.c @@ -38,6 +38,8 @@ #include <osmocom/rua/rua_ies_defs.h> #include <osmocom/hnbgw/context_map.h> #include <osmocom/hnbap/HNBAP_CN-DomainIndicator.h> +#include <osmocom/hnbgw/mgw_fsm.h> +#include <osmocom/ranap/RANAP_ProcedureCode.h>
static const char *cn_domain_indicator_to_str(RUA_CN_DomainIndicator_t cN_DomainIndicator) { @@ -265,6 +267,17 @@ memcpy(msg->l2h, data, len); }
+ /* Intercept RAB Assignment Response, inform MGW FSM. */ + if (map && !map->is_ps && !release_context_map && msgb_l2len(prim->oph.msg) > 2) + { + switch (((uint8_t*)msgb_l2(prim->oph.msg))[1]) { + case RANAP_ProcedureCode_id_RAB_Assignment: + /* Note: Just like osmo_sccp_user_sap_down(), mgw_fsm_handle_rab_as_resp() will take ownership + * of oph */ + return mgw_fsm_handle_rab_ass_resp(map, &prim->oph); + } + } + rc = osmo_sccp_user_sap_down(cn->sccp_user, &prim->oph);
if (map && release_context_map) diff --git a/src/osmo-hnbgw/hnbgw_vty.c b/src/osmo-hnbgw/hnbgw_vty.c index 4ad1ddb..0ec16fe 100644 --- a/src/osmo-hnbgw/hnbgw_vty.c +++ b/src/osmo-hnbgw/hnbgw_vty.c @@ -22,15 +22,19 @@
#include <osmocom/core/socket.h> #include <osmocom/vty/command.h> +#include <osmocom/vty/tdef_vty.h>
#include <osmocom/hnbgw/vty.h>
#include <osmocom/hnbgw/hnbgw.h> #include <osmocom/hnbgw/context_map.h> +#include <osmocom/hnbgw/tdefs.h> #include <osmocom/sigtran/protocol/sua.h> #include <osmocom/sigtran/sccp_helpers.h> #include <osmocom/netif/stream.h>
+#include <osmocom/mgcp_client/mgcp_client.h> + static void *tall_hnb_ctx = NULL; static struct hnb_gw *g_hnb_gw = NULL;
@@ -86,6 +90,19 @@ return CMD_SUCCESS; }
+static struct cmd_node mgcp_node = { + MGCP_NODE, + "%s(config-hnbgw-mgcp)# ", + 1, +}; + +DEFUN(cfg_hnbgw_mgcp, cfg_hnbgw_mgcp_cmd, + "mgcp", "Configure MGCP client") +{ + vty->node = MGCP_NODE; + return CMD_SUCCESS; +} + int hnbgw_vty_go_parent(struct vty *vty) { switch (vty->node) { @@ -95,6 +112,10 @@ vty->node = HNBGW_NODE; vty->index = NULL; break; + case MGCP_NODE: + vty->node = HNBGW_NODE; + vty->index = NULL; + break; case HNBGW_NODE: vty->node = CONFIG_NODE; vty->index = NULL; @@ -382,6 +403,14 @@ return CMD_SUCCESS; }
+static int config_write_hnbgw_mgcp(struct vty *vty) +{ + vty_out(vty, " mgcp%s", VTY_NEWLINE); + mgcp_client_config_write(vty, " "); + + return CMD_SUCCESS; +} + void hnbgw_vty_init(struct hnb_gw *gw, void *tall_ctx) { g_hnb_gw = gw; @@ -415,4 +444,13 @@ install_element_ve(&show_one_hnb_cmd); install_element_ve(&show_ue_cmd); install_element_ve(&show_talloc_cmd); + + install_element(HNBGW_NODE, &cfg_hnbgw_mgcp_cmd); + install_node(&mgcp_node, config_write_hnbgw_mgcp); + + g_hnb_gw->config.mgcp_client = talloc_zero(tall_hnb_ctx, struct mgcp_client_conf); + mgcp_client_conf_init(g_hnb_gw->config.mgcp_client); + mgcp_client_vty_init(tall_hnb_ctx, MGCP_NODE, g_hnb_gw->config.mgcp_client); + + osmo_tdef_vty_groups_init(HNBGW_NODE, hnbgw_tdef_group); } diff --git a/src/osmo-hnbgw/mgw_fsm.c b/src/osmo-hnbgw/mgw_fsm.c new file mode 100644 index 0000000..df97c1a --- /dev/null +++ b/src/osmo-hnbgw/mgw_fsm.c @@ -0,0 +1,562 @@ +/* (C) 2021 by sysmocom s.f.m.c. GmbH info@sysmocom.de + * All Rights Reserved + * + * Author: Philipp Maier + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 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 General Public License for more details. + */ + +#include <errno.h> + +#include <osmocom/core/msgb.h> +#include <osmocom/core/utils.h> +#include <osmocom/core/prim.h> + +#include <osmocom/core/fsm.h> +#include <osmocom/core/byteswap.h> +#include <arpa/inet.h> +#include <osmocom/core/logging.h> +#include <osmocom/core/sockaddr_str.h> + +#include <osmocom/ranap/ranap_common.h> +#include <osmocom/ranap/ranap_ies_defs.h> +#include <osmocom/ranap/ranap_msg_factory.h> + +#include <osmocom/ranap/ranap_ies_defs.h> +#include <osmocom/ranap/iu_helpers.h> +#include <asn1c/asn1helpers.h> + +#include <osmocom/hnbgw/hnbgw.h> +#include <osmocom/hnbgw/context_map.h> +#include <osmocom/hnbgw/ranap_rab_ass.h> + +#include <osmocom/hnbgw/hnbgw_rua.h> + +#include <osmocom/core/tdef.h> +#include <osmocom/hnbgw/tdefs.h> +#include <osmocom/mgcp_client/mgcp_client_endpoint_fsm.h> + +#define S(x) (1 << (x)) + +extern int asn1_xer_print; + +enum mgw_fsm_event { + MGW_EV_MGCP_OK, + MGW_EV_MGCP_FAIL, + MGW_EV_MGCP_TERM, + MGW_EV_RAB_ASS_RESP, + MGW_EV_RELEASE, +}; + +static const struct value_string mgw_fsm_event_names[] = { + OSMO_VALUE_STRING(MGW_EV_MGCP_OK), + OSMO_VALUE_STRING(MGW_EV_MGCP_FAIL), + OSMO_VALUE_STRING(MGW_EV_MGCP_TERM), + OSMO_VALUE_STRING(MGW_EV_RAB_ASS_RESP), + OSMO_VALUE_STRING(MGW_EV_RELEASE), + { } +}; + +enum mgw_fsm_state { + MGW_ST_CRCX_HNB, + MGW_ST_ASSIGN, + MGW_ST_MDCX_HNB, + MGW_ST_CRCX_MSC, + MGW_ST_ESTABLISHED, + MGW_ST_RELEASE, +}; + +struct mgw_fsm_priv { + /* Backpointer to HNBGW context */ + struct hnbgw_context_map *map; + + /* RAB-ID from RANAP RAB AssignmentRequest message */ + uint8_t rab_id; + + /* We have to store the RANAP RAB AssignmentRequest message, since we can not take ownership of the osmo prim + * header (oph). */ + uint8_t rab_ass_req[IUH_MSGB_SIZE]; + unsigned int rab_ass_req_len; + + /* The RANAP RAB AssignmentResponse is handled differently. In this case we must take the ownership of the + * osmo prim header */ + struct osmo_prim_hdr *oph_rab_ass_resp; + + /* MGW context */ + struct osmo_mgcpc_ep *mgcpc_ep; + struct osmo_mgcpc_ep_ci *mgcpc_ep_ci_hnb; + struct osmo_mgcpc_ep_ci *mgcpc_ep_ci_msc; + char msc_rtp_addr[INET6_ADDRSTRLEN]; + uint16_t msc_rtp_port; +}; + +struct osmo_tdef mgw_tdefs[] = { + {.T = -2427,.default_val = 5,.desc = "timeout for MGCP response from MGW" }, + { } +}; + +struct osmo_tdef_state_timeout mgw_fsm_timeouts[32] = { + [MGW_ST_CRCX_HNB] = {.T = -1001 }, + [MGW_ST_ASSIGN] = {.T = -1002 }, + [MGW_ST_MDCX_HNB] = {.T = -1003 }, + [MGW_ST_CRCX_MSC] = {.T = -1004 }, +}; + +#define mgw_fsm_state_chg(state) \ + osmo_tdef_fsm_inst_state_chg(fi, state, \ + mgw_fsm_timeouts, \ + mgw_fsm_T_defs, \ + -1) + +static void mgw_fsm_crcx_hnb_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + struct mgw_fsm_priv *mgw_fsm_priv = fi->priv; + struct hnbgw_context_map *map = mgw_fsm_priv->map; + const char *epname; + struct mgcp_conn_peer mgw_info; + + LOGPFSML(fi, LOGL_DEBUG, "RAB-AssignmentRequest received, creating HNB side call-leg on MGW...\n"); + + mgw_info = (struct mgcp_conn_peer) { + .call_id = (map->rua_ctx_id << 8) | mgw_fsm_priv->rab_id, + .ptime = 20, + .conn_mode = MGCP_CONN_LOOPBACK, + }; + mgw_info.codecs[0] = CODEC_IUFP; + mgw_info.codecs_len = 1; + + epname = mgcp_client_rtpbridge_wildcard(map->hnb_ctx->gw->mgcp_client); + mgw_fsm_priv->mgcpc_ep = + osmo_mgcpc_ep_alloc(fi, MGW_EV_MGCP_TERM, map->hnb_ctx->gw->mgcp_client, mgw_tdefs, fi->id, "%s", epname); + mgw_fsm_priv->mgcpc_ep_ci_hnb = osmo_mgcpc_ep_ci_add(mgw_fsm_priv->mgcpc_ep, "to-HNB"); + + osmo_mgcpc_ep_ci_request(mgw_fsm_priv->mgcpc_ep_ci_hnb, MGCP_VERB_CRCX, &mgw_info, fi, MGW_EV_MGCP_OK, + MGW_EV_MGCP_FAIL, NULL); +} + +static void mgw_fsm_crcx_hnb(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct mgw_fsm_priv *mgw_fsm_priv = fi->priv; + const struct mgcp_conn_peer *mgw_info; + int rc; + + switch (event) { + case MGW_EV_MGCP_OK: + mgw_info = osmo_mgcpc_ep_ci_get_rtp_info(mgw_fsm_priv->mgcpc_ep_ci_hnb); + if (!mgw_info) { + LOGPFSML(fi, LOGL_ERROR, "Got no response from MGW\n"); + osmo_fsm_inst_state_chg(fi, MGW_ST_RELEASE, 0, 0); + return; + } + + rc = ranap_rab_ass_req_replace_inet_addr(mgw_fsm_priv->rab_ass_req, sizeof(mgw_fsm_priv->rab_ass_req), + mgw_info->addr, mgw_info->port); + if (rc < 0) { + LOGPFSML(fi, LOGL_ERROR, + "Failed to replace RTP IP-address (%s) and Port (%u) in RAB-AssignmentRequest\n", + mgw_info->addr, mgw_info->port); + osmo_fsm_inst_state_chg(fi, MGW_ST_RELEASE, 0, 0); + mgw_fsm_priv->rab_ass_req_len = 0; + return; + } + mgw_fsm_priv->rab_ass_req_len = rc; + + mgw_fsm_state_chg(MGW_ST_ASSIGN); + return; + case MGW_EV_MGCP_FAIL: + osmo_fsm_inst_state_chg(fi, MGW_ST_RELEASE, 0, 0); + return; + default: + OSMO_ASSERT(false); + } +} + +static void mgw_fsm_assign_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + struct mgw_fsm_priv *mgw_fsm_priv = fi->priv; + struct hnbgw_context_map *map = mgw_fsm_priv->map; + + LOGPFSML(fi, LOGL_DEBUG, "forwarding modified RAB-AssignmentRequest to HNB\n"); + rua_tx_dt(map->hnb_ctx, map->is_ps, map->rua_ctx_id, mgw_fsm_priv->rab_ass_req, mgw_fsm_priv->rab_ass_req_len); +} + +static void mgw_fsm_assign(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct mgw_fsm_priv *mgw_fsm_priv = fi->priv; + struct osmo_prim_hdr *oph = data; + + switch (event) { + case MGW_EV_RAB_ASS_RESP: + mgw_fsm_priv->oph_rab_ass_resp = oph; + mgw_fsm_state_chg(MGW_ST_MDCX_HNB); + return; + default: + OSMO_ASSERT(false); + } +} + +static void mgw_fsm_mdcx_hnb_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + struct mgw_fsm_priv *mgw_fsm_priv = fi->priv; + struct hnbgw_context_map *map = mgw_fsm_priv->map; + struct mgcp_conn_peer mgw_info; + int rc; + + LOGPFSML(fi, LOGL_DEBUG, "RAB-AssignmentResponse received, completing HNB side call-leg on MGW...\n"); + + mgw_info = (struct mgcp_conn_peer) { + .call_id = map->rua_ctx_id, + .ptime = 20, + .conn_mode = MGCP_CONN_RECV_SEND, + }; + mgw_info.codecs[0] = CODEC_IUFP; + mgw_info.codecs_len = 1; + + rc = ranap_rab_ass_resp_extract_inet_addr(mgw_info.addr, &mgw_info.port, + msgb_l2(mgw_fsm_priv->oph_rab_ass_resp->msg), + msgb_l2len(mgw_fsm_priv->oph_rab_ass_resp->msg)); + if (rc < 0) { + LOGPFSML(fi, LOGL_ERROR, "Failed to extract RTP IP-address and Port from RAB-AssignmentResponse\n"); + osmo_fsm_inst_state_chg(fi, MGW_ST_RELEASE, 0, 0); + return; + } + + osmo_mgcpc_ep_ci_request(mgw_fsm_priv->mgcpc_ep_ci_hnb, MGCP_VERB_MDCX, &mgw_info, fi, MGW_EV_MGCP_OK, + MGW_EV_MGCP_FAIL, NULL); +} + +static void mgw_fsm_mdcx_hnb(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct mgw_fsm_priv *mgw_fsm_priv = fi->priv; + const struct mgcp_conn_peer *mgw_info; + + switch (event) { + case MGW_EV_MGCP_OK: + mgw_info = osmo_mgcpc_ep_ci_get_rtp_info(mgw_fsm_priv->mgcpc_ep_ci_hnb); + if (!mgw_info) { + LOGPFSML(fi, LOGL_ERROR, "Got no response from MGW\n"); + osmo_fsm_inst_state_chg(fi, MGW_ST_RELEASE, 0, 0); + return; + } + mgw_fsm_state_chg(MGW_ST_CRCX_MSC); + return; + case MGW_EV_MGCP_FAIL: + osmo_fsm_inst_state_chg(fi, MGW_ST_RELEASE, 0, 0); + return; + default: + OSMO_ASSERT(false); + } +} + +static void mgw_fsm_crcx_msc_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + struct mgw_fsm_priv *mgw_fsm_priv = fi->priv; + struct hnbgw_context_map *map = mgw_fsm_priv->map; + struct mgcp_conn_peer mgw_info; + + LOGPFSML(fi, LOGL_DEBUG, "creating MSC side call-leg on MGW...\n"); + + mgw_info = (struct mgcp_conn_peer) { + .call_id = (map->rua_ctx_id << 8) | mgw_fsm_priv->rab_id, + .ptime = 20, + .port = mgw_fsm_priv->msc_rtp_port, + }; + + osmo_strlcpy(mgw_info.addr, mgw_fsm_priv->msc_rtp_addr, sizeof(mgw_info.addr)); + mgw_info.codecs[0] = CODEC_IUFP; + mgw_info.codecs_len = 1; + + mgw_fsm_priv->mgcpc_ep_ci_msc = osmo_mgcpc_ep_ci_add(mgw_fsm_priv->mgcpc_ep, "to-MSC"); + osmo_mgcpc_ep_ci_request(mgw_fsm_priv->mgcpc_ep_ci_msc, MGCP_VERB_CRCX, &mgw_info, fi, MGW_EV_MGCP_OK, + MGW_EV_MGCP_FAIL, NULL); +} + +static void mgw_fsm_crcx_msc(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct mgw_fsm_priv *mgw_fsm_priv = fi->priv; + const struct mgcp_conn_peer *mgw_info; + int rc; + int msg_max_len; + + switch (event) { + case MGW_EV_MGCP_OK: + mgw_info = osmo_mgcpc_ep_ci_get_rtp_info(mgw_fsm_priv->mgcpc_ep_ci_msc); + if (!mgw_info) { + LOGPFSML(fi, LOGL_ERROR, "Got no response from MGW\n"); + osmo_fsm_inst_state_chg(fi, MGW_ST_RELEASE, 0, 0); + return; + } + + /* When the RTP IP-Address/Port is replaced the message might grow. Ensure that there is enough room in + * l2h to grow. (The current implementation should yield a message with the same size, but there is no + * guarantee for that) */ + msg_max_len = + msgb_l2len(mgw_fsm_priv->oph_rab_ass_resp->msg) + + msgb_tailroom(mgw_fsm_priv->oph_rab_ass_resp->msg); + rc = msgb_resize_area(mgw_fsm_priv->oph_rab_ass_resp->msg, mgw_fsm_priv->oph_rab_ass_resp->msg->l2h, + msgb_l2len(mgw_fsm_priv->oph_rab_ass_resp->msg), msg_max_len); + OSMO_ASSERT(rc == 0); + + /* Replace RTP IP-Address/Port. */ + rc = ranap_rab_ass_resp_replace_inet_addr(msgb_l2(mgw_fsm_priv->oph_rab_ass_resp->msg), + msgb_l2len(mgw_fsm_priv->oph_rab_ass_resp->msg), + mgw_info->addr, mgw_info->port); + if (rc < 0) { + LOGPFSML(fi, LOGL_ERROR, + "Failed to replace RTP IP-address (%s) and Port (%u) in RAB-AssignmentResponse\n", + mgw_info->addr, mgw_info->port); + osmo_fsm_inst_state_chg(fi, MGW_ST_RELEASE, 0, 0); + return; + } + + /* Resize l2h back to the actual message length */ + rc = msgb_resize_area(mgw_fsm_priv->oph_rab_ass_resp->msg, mgw_fsm_priv->oph_rab_ass_resp->msg->l2h, + msgb_l2len(mgw_fsm_priv->oph_rab_ass_resp->msg), rc); + OSMO_ASSERT(rc == 0); + + /* When the established state is entered, the modified RAB AssignmentResponse is forwarded to the MSC. + * The call is then established any way may stay for an indefinate amount of time in this state until + * there is an IU Release happening. */ + osmo_fsm_inst_state_chg(fi, MGW_ST_ESTABLISHED, 0, 0); + return; + case MGW_EV_MGCP_FAIL: + osmo_fsm_inst_state_chg(fi, MGW_ST_RELEASE, 0, 0); + return; + default: + OSMO_ASSERT(false); + } +} + +static void mgw_fsm_established_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + struct mgw_fsm_priv *mgw_fsm_priv = fi->priv; + struct hnbgw_context_map *map = mgw_fsm_priv->map; + struct osmo_prim_hdr *oph = mgw_fsm_priv->oph_rab_ass_resp; + struct hnb_context *hnb = map->hnb_ctx; + struct hnbgw_cnlink *cn = hnb->gw->sccp.cnlink; + int rc; + + rc = osmo_sccp_user_sap_down(cn->sccp_user, oph); + mgw_fsm_priv->oph_rab_ass_resp = NULL; + if (rc < 0) + osmo_fsm_inst_state_chg(fi, MGW_ST_RELEASE, 0, 0); + + LOGPFSML(fi, LOGL_DEBUG, "HNB and MSC side call-legs completed!\n"); +} + +static void mgw_fsm_release_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REGULAR, NULL); +} + +static void mgw_fsm_allstate_action(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct mgw_fsm_priv *mgw_fsm_priv = fi->priv; + + switch (event) { + case MGW_EV_RELEASE: + osmo_fsm_inst_state_chg(fi, MGW_ST_RELEASE, 0, 0); + return; + case MGW_EV_MGCP_TERM: + mgw_fsm_priv->mgcpc_ep = NULL; + osmo_fsm_inst_state_chg(fi, MGW_ST_RELEASE, 0, 0); + return; + default: + OSMO_ASSERT(false); + } +} + +static int mgw_fsm_timer_cb(struct osmo_fsm_inst *fi) +{ + osmo_fsm_inst_term(fi, OSMO_FSM_TERM_ERROR, NULL); + return 0; +} + +void mgw_fsm_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause) +{ + struct mgw_fsm_priv *mgw_fsm_priv = fi->priv; + struct osmo_scu_prim *scu_prim; + struct msgb *scu_msg; + + /* In case we were unable to deliver the RANAP RAB AssignmentResponse we are responsible to free it since se + * have taken ownership of the prim header */ + if (mgw_fsm_priv->oph_rab_ass_resp) { + scu_prim = (struct osmo_scu_prim *)mgw_fsm_priv->oph_rab_ass_resp; + scu_msg = scu_prim->oph.msg; + msgb_free(scu_msg); + mgw_fsm_priv->oph_rab_ass_resp = NULL; + } + + talloc_free(mgw_fsm_priv); +} + +static void mgw_fsm_pre_term(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause) +{ + struct mgw_fsm_priv *mgw_fsm_priv = fi->priv; + struct hnbgw_context_map *map = mgw_fsm_priv->map; + + if (mgw_fsm_priv->mgcpc_ep) { + osmo_mgcpc_ep_clear(mgw_fsm_priv->mgcpc_ep); + mgw_fsm_priv->mgcpc_ep = NULL; + } + + /* Remove FSM from the context map. This will make this FSM unreachable for events comming from outside */ + map->mgw_fi = NULL; +} + +static const struct osmo_fsm_state mgw_fsm_states[] = { + [MGW_ST_CRCX_HNB] = { + .name = "MGW_ST_CRCX_HNB", + .onenter = mgw_fsm_crcx_hnb_onenter, + .action = mgw_fsm_crcx_hnb, + .in_event_mask = S(MGW_EV_MGCP_OK) | S(MGW_EV_MGCP_FAIL), + .out_state_mask = S(MGW_ST_ASSIGN) | S(MGW_ST_RELEASE) | S(MGW_ST_CRCX_HNB), + }, + [MGW_ST_ASSIGN] = { + .name = "MGW_ST_ASSIGN", + .onenter = mgw_fsm_assign_onenter, + .action = mgw_fsm_assign, + .in_event_mask = S(MGW_EV_RAB_ASS_RESP), + .out_state_mask = S(MGW_ST_MDCX_HNB) | S(MGW_ST_RELEASE), + }, + [MGW_ST_MDCX_HNB] = { + .name = "MGW_ST_MDCX_HNB", + .onenter = mgw_fsm_mdcx_hnb_onenter, + .action = mgw_fsm_mdcx_hnb, + .in_event_mask = S(MGW_EV_MGCP_OK) | S(MGW_EV_MGCP_FAIL), + .out_state_mask = S(MGW_ST_CRCX_MSC) | S(MGW_ST_RELEASE), + }, + [MGW_ST_CRCX_MSC] = { + .name = "MGW_ST_CRCX_MSC", + .onenter = mgw_fsm_crcx_msc_onenter, + .action = mgw_fsm_crcx_msc, + .in_event_mask = S(MGW_EV_MGCP_OK) | S(MGW_EV_MGCP_FAIL), + .out_state_mask = S(MGW_ST_ESTABLISHED) | S(MGW_ST_RELEASE), + }, + [MGW_ST_ESTABLISHED] = { + .name = "MGW_ST_ESTABLISHED", + .onenter = mgw_fsm_established_onenter, + .in_event_mask = 0, + .out_state_mask = S(MGW_ST_RELEASE), + }, + [MGW_ST_RELEASE] = { + .name = "MGW_ST_RELEASE", + .onenter = mgw_fsm_release_onenter, + .in_event_mask = 0, + .out_state_mask = 0, + }, +}; + +static struct osmo_fsm mgw_fsm = { + .name = "mgw", + .states = mgw_fsm_states, + .num_states = ARRAY_SIZE(mgw_fsm_states), + .log_subsys = DMGW, + .event_names = mgw_fsm_event_names, + .allstate_action = mgw_fsm_allstate_action, + .allstate_event_mask = S(MGW_EV_MGCP_TERM) | S(MGW_EV_RELEASE), + .timer_cb = mgw_fsm_timer_cb, + .cleanup = mgw_fsm_cleanup, + .pre_term = mgw_fsm_pre_term, +}; + +/*! Allocate MGW FSM and handle RANAP RAB AssignmentRequest). + * \ptmap[in] map hanbgw context map that is responsible for this call. + * \ptmap[in] oph osmo prim header with RANAP RAB AssignmentRequest (function does not take ownership). + * \returns 0 on success; negative on error. */ +int mgw_fsm_alloc_and_handle_rab_ass_req(struct hnbgw_context_map *map, struct osmo_prim_hdr *oph_rab_ass_req) +{ + static bool initialized = false; + struct osmo_fsm_inst *fi; + struct mgw_fsm_priv *mgw_fsm_priv; + int rc; + char fsm_name[255]; + + /* Initialize FSM if not done yet */ + if (!initialized) { + OSMO_ASSERT(osmo_fsm_register(&mgw_fsm) == 0); + initialized = true; + } + + /* When there is already an FSM, make sure that it is terminated. Under normal circumstances this situation + * should not occur. */ + if (map->mgw_fi) { + LOGPFSML(map->mgw_fi, LOGL_ERROR, "another FSM instance is about to replace this FSM!\n"); + osmo_fsm_inst_dispatch(map->mgw_fi, MGW_EV_RELEASE, NULL); + map->mgw_fi = NULL; + } + + /* Create context and keep a local copy of the RAB AssignmentRequest, we will need this copy later to + * modify and forward it. We cannot take ownership of the prim header oph_rab_ass_req. */ + mgw_fsm_priv = talloc_zero(map, struct mgw_fsm_priv); + OSMO_ASSERT(msgb_l2len(oph_rab_ass_req->msg) <= sizeof(mgw_fsm_priv->rab_ass_req)); + memcpy(mgw_fsm_priv->rab_ass_req, msgb_l2(oph_rab_ass_req->msg), msgb_l2len(oph_rab_ass_req->msg)); + mgw_fsm_priv->rab_ass_req_len = msgb_l2len(oph_rab_ass_req->msg); + + /* Parse the RAB Assignment Request now, if it is bad for some reason we will exit early and not bother with + * creating an FSM etc. */ + rc = ranap_rab_ass_req_extract_inet_addr(mgw_fsm_priv->msc_rtp_addr, &mgw_fsm_priv->msc_rtp_port, + &mgw_fsm_priv->rab_id, mgw_fsm_priv->rab_ass_req, + mgw_fsm_priv->rab_ass_req_len); + if (rc < 0) { + LOGP(DMGW, LOGL_ERROR, + "mgw_fsm_alloc_and_handle_rab_ass_req() rua_ctx_id=%d, invalid RAB-AssignmentRequest -- abort!\n", + map->rua_ctx_id); + talloc_free(mgw_fsm_priv); + return -EINVAL; + } + + /* Allocate the FSM and start it. */ + mgw_fsm_priv->map = map; + snprintf(fsm_name, sizeof(fsm_name), "mgw-fsm-%u-%u", map->rua_ctx_id, mgw_fsm_priv->rab_id); + fi = osmo_fsm_inst_alloc(&mgw_fsm, map, mgw_fsm_priv, LOGL_DEBUG, fsm_name); + map->mgw_fi = fi; + mgw_fsm_state_chg(MGW_ST_CRCX_HNB); + + return 0; +} + +/*! Handlie IU release (terminate RTP streams). + * \ptmap[in] map hanbgw context map that is responsible for this call. + * \returns 0 on success; negative on error. */ +int mgw_fsm_handle_iu_release(struct hnbgw_context_map *map) +{ + if (!map->mgw_fi) { + LOGP(DMGW, LOGL_ERROR, "mgw_fsm_handle_iu_release() rua_ctx_id=%d, no MGW fsm -- ignored!\n", + map->rua_ctx_id); + return -EINVAL; + } + + osmo_fsm_inst_dispatch(map->mgw_fi, MGW_EV_RELEASE, NULL); + return 0; +} + +/*! Handlie RANAP RAB AssignmentResponse (deliver message, complete RTP stream switching). + * \ptmap[in] map hanbgw context map that is responsible for this call. + * \ptmap[in] oph osmo prim header with RANAP RAB AssignmentResponse (function takes ownership). + * \returns 0 on success; negative on error. */ +int mgw_fsm_handle_rab_ass_resp(struct hnbgw_context_map *map, struct osmo_prim_hdr *oph) +{ + struct osmo_scu_prim *scu_prim; + struct msgb *scu_msg; + + if (!map->mgw_fi) { + LOGP(DMGW, LOGL_ERROR, "mgw_fsm_handle_rab_ass_resp() rua_ctx_id=%d, no MGW fsm -- abort!\n", + map->rua_ctx_id); + scu_prim = (struct osmo_scu_prim *)oph; + scu_msg = scu_prim->oph.msg; + msgb_free(scu_msg); + return -EINVAL; + } + + osmo_fsm_inst_dispatch(map->mgw_fi, MGW_EV_RAB_ASS_RESP, oph); + return 0; +} diff --git a/src/osmo-hnbgw/tdefs.c b/src/osmo-hnbgw/tdefs.c new file mode 100644 index 0000000..d8198f2 --- /dev/null +++ b/src/osmo-hnbgw/tdefs.c @@ -0,0 +1,30 @@ +/* (C) 2021 by sysmocom s.f.m.c. GmbH info@sysmocom.de + * All Rights Reserved + * + * Author: Philipp Maier + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 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 General Public License for more details. + */ + +#include <osmocom/hnbgw/tdefs.h> + +struct osmo_tdef mgw_fsm_T_defs[] = { + {.T = -1001, .default_val = 5, .desc = "Timeout for HNB side call-leg (to-HNB) creation" }, + {.T = -1002, .default_val = 10, .desc = "Timeout for the HNB to respond to RAB Assignment Request" }, + {.T = -1003, .default_val = 5, .desc = "Timeout for HNB side call-leg (to-HNB) completion" }, + {.T = -1004, .default_val = 5, .desc = "Timeout for MSC side call-leg (to-MSC) completion" }, + { } +}; + +struct osmo_tdef_group hnbgw_tdef_group[] = { + {.name = "mgw", .tdefs = mgw_fsm_T_defs, .desc = "MGW (Media Gateway) interface" }, + { } +};
pespin has posted comments on this change. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795 )
Change subject: mgw_fsm: add MGW support to osmo-hnbgw ......................................................................
Patch Set 1:
(3 comments)
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/1/src/osmo-hnbgw/hnbgw_vty.c File src/osmo-hnbgw/hnbgw_vty.c:
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/1/src/osmo-hnbgw/hnbgw_vty.c... PS1, Line 451: g_hnb_gw->config.mgcp_client = talloc_zero(tall_hnb_ctx, struct mgcp_client_conf); This doesn't look like the proper place to do this. Please move this to the g_hnb_gw alloc function.
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/1/src/osmo-hnbgw/mgw_fsm.c File src/osmo-hnbgw/mgw_fsm.c:
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/1/src/osmo-hnbgw/mgw_fsm.c@8... PS1, Line 84: /* We have to store the RANAP RAB AssignmentRequest message, since we can not take ownership of the osmo prim why can't you take ownsership? is it freed by the callback caller? If not, talloc_steal, if yes, msgb_copy.
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/1/src/osmo-hnbgw/mgw_fsm.c@4... PS1, Line 420: .in_event_mask = S(MGW_EV_MGCP_OK) | S(MGW_EV_MGCP_FAIL), I find it much more clear having one per line, but OK.
Hello Jenkins Builder, pespin,
I'd like you to reexamine a change. Please visit
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795
to look at the new patch set (#2).
Change subject: mgw_fsm: add MGW support to osmo-hnbgw ......................................................................
mgw_fsm: add MGW support to osmo-hnbgw
osmo-hnbgw lacks support for an co-located media gateway. This makes it virtually impossible to isolate the HNB from the core network properly.
Lets add MGCP support to osmo-hnbgw so that it can control a co-located media gateway to relay the RTP streams between HNB and core network.
Change-Id: Ib9b62e0145184b91c56ce5d8870760bfa49cc5a4 Related: OS#515 --- M configure.ac M contrib/osmo-hnbgw.spec.in M debian/control M include/osmocom/hnbgw/context_map.h M include/osmocom/hnbgw/hnbgw.h A include/osmocom/hnbgw/mgw_fsm.h A include/osmocom/hnbgw/tdefs.h M include/osmocom/hnbgw/vty.h M src/osmo-hnbgw/Makefile.am M src/osmo-hnbgw/hnbgw.c M src/osmo-hnbgw/hnbgw_cn.c M src/osmo-hnbgw/hnbgw_rua.c M src/osmo-hnbgw/hnbgw_vty.c A src/osmo-hnbgw/mgw_fsm.c A src/osmo-hnbgw/tdefs.c 15 files changed, 760 insertions(+), 1 deletion(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-hnbgw refs/changes/95/26795/2
Hello Jenkins Builder, pespin,
I'd like you to reexamine a change. Please visit
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795
to look at the new patch set (#7).
Change subject: mgw_fsm: add MGW support to osmo-hnbgw ......................................................................
mgw_fsm: add MGW support to osmo-hnbgw
osmo-hnbgw lacks support for an co-located media gateway. This makes it virtually impossible to isolate the HNB from the core network properly.
Lets add MGCP support to osmo-hnbgw so that it can control a co-located media gateway to relay the RTP streams between HNB and core network.
Change-Id: Ib9b62e0145184b91c56ce5d8870760bfa49cc5a4 Related: OS#515 --- M configure.ac M contrib/osmo-hnbgw.spec.in M debian/control M include/osmocom/hnbgw/context_map.h M include/osmocom/hnbgw/hnbgw.h A include/osmocom/hnbgw/mgw_fsm.h A include/osmocom/hnbgw/tdefs.h M include/osmocom/hnbgw/vty.h M src/osmo-hnbgw/Makefile.am M src/osmo-hnbgw/hnbgw.c M src/osmo-hnbgw/hnbgw_cn.c M src/osmo-hnbgw/hnbgw_rua.c M src/osmo-hnbgw/hnbgw_vty.c A src/osmo-hnbgw/mgw_fsm.c A src/osmo-hnbgw/tdefs.c 15 files changed, 759 insertions(+), 1 deletion(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-hnbgw refs/changes/95/26795/7
Hello Jenkins Builder, pespin,
I'd like you to reexamine a change. Please visit
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795
to look at the new patch set (#8).
Change subject: mgw_fsm: add MGW support to osmo-hnbgw ......................................................................
mgw_fsm: add MGW support to osmo-hnbgw
osmo-hnbgw lacks support for an co-located media gateway. This makes it virtually impossible to isolate the HNB from the core network properly.
Lets add MGCP support to osmo-hnbgw so that it can control a co-located media gateway to relay the RTP streams between HNB and core network.
Change-Id: Ib9b62e0145184b91c56ce5d8870760bfa49cc5a4 Related: OS#515 --- M configure.ac M contrib/jenkins.sh M contrib/osmo-hnbgw.spec.in M debian/control M include/osmocom/hnbgw/context_map.h M include/osmocom/hnbgw/hnbgw.h A include/osmocom/hnbgw/mgw_fsm.h A include/osmocom/hnbgw/tdefs.h M include/osmocom/hnbgw/vty.h M src/osmo-hnbgw/Makefile.am M src/osmo-hnbgw/hnbgw.c M src/osmo-hnbgw/hnbgw_cn.c M src/osmo-hnbgw/hnbgw_rua.c M src/osmo-hnbgw/hnbgw_vty.c A src/osmo-hnbgw/mgw_fsm.c A src/osmo-hnbgw/tdefs.c 16 files changed, 760 insertions(+), 1 deletion(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-hnbgw refs/changes/95/26795/8
Hello Jenkins Builder, pespin,
I'd like you to reexamine a change. Please visit
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795
to look at the new patch set (#9).
Change subject: mgw_fsm: add MGW support to osmo-hnbgw ......................................................................
mgw_fsm: add MGW support to osmo-hnbgw
osmo-hnbgw lacks support for an co-located media gateway. This makes it virtually impossible to isolate the HNB from the core network properly.
Lets add MGCP support to osmo-hnbgw so that it can control a co-located media gateway to relay the RTP streams between HNB and core network.
Change-Id: Ib9b62e0145184b91c56ce5d8870760bfa49cc5a4 Related: OS#515 --- M configure.ac M contrib/jenkins.sh M contrib/osmo-hnbgw.spec.in M debian/control M include/osmocom/hnbgw/Makefile.am M include/osmocom/hnbgw/context_map.h M include/osmocom/hnbgw/hnbgw.h A include/osmocom/hnbgw/mgw_fsm.h A include/osmocom/hnbgw/tdefs.h M include/osmocom/hnbgw/vty.h M src/osmo-hnbgw/Makefile.am M src/osmo-hnbgw/hnbgw.c M src/osmo-hnbgw/hnbgw_cn.c M src/osmo-hnbgw/hnbgw_rua.c M src/osmo-hnbgw/hnbgw_vty.c A src/osmo-hnbgw/mgw_fsm.c A src/osmo-hnbgw/tdefs.c 17 files changed, 761 insertions(+), 2 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-hnbgw refs/changes/95/26795/9
laforge has posted comments on this change. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795 )
Change subject: mgw_fsm: add MGW support to osmo-hnbgw ......................................................................
Patch Set 9:
(2 comments)
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/7/src/osmo-hnbgw/hnbgw_cn.c File src/osmo-hnbgw/hnbgw_cn.c:
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/7/src/osmo-hnbgw/hnbgw_cn.c@... PS7, Line 362: switch (((uint8_t *)msgb_l2(oph->msg))[1]) { why such a hack here and peek into the raw msgb without the use of the decoder? Why not simply decode the message first (at least the first level of decode into a RANAP_RANAP_PDU_t) and then check the procedure code?
If you want to go for this low-level-hackish approach, you need to be able to prove that there is no flexibility within the encoding rules that would permit a message to have e.g. a multi-byte RAB assignment type. I know that BER leaves a lot of flexibility to the sender, and you can format any integer any number of bytes wide, so the same value has any number of different encodings. APER is probably stricter, but have you studied the encoding rules?
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/7/src/osmo-hnbgw/hnbgw_rua.c File src/osmo-hnbgw/hnbgw_rua.c:
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/7/src/osmo-hnbgw/hnbgw_rua.c... PS7, Line 273: case RANAP_ProcedureCode_id_RAB_Assignment: likewise the same here.
Hello Jenkins Builder, pespin,
I'd like you to reexamine a change. Please visit
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795
to look at the new patch set (#10).
Change subject: mgw_fsm: add MGW support to osmo-hnbgw ......................................................................
mgw_fsm: add MGW support to osmo-hnbgw
osmo-hnbgw lacks support for an co-located media gateway. This makes it virtually impossible to isolate the HNB from the core network properly.
Lets add MGCP support to osmo-hnbgw so that it can control a co-located media gateway to relay the RTP streams between HNB and core network.
Change-Id: Ib9b62e0145184b91c56ce5d8870760bfa49cc5a4 Related: OS#515 --- M configure.ac M contrib/jenkins.sh M contrib/osmo-hnbgw.spec.in M debian/control M include/osmocom/hnbgw/Makefile.am M include/osmocom/hnbgw/context_map.h M include/osmocom/hnbgw/hnbgw.h A include/osmocom/hnbgw/mgw_fsm.h A include/osmocom/hnbgw/tdefs.h M include/osmocom/hnbgw/vty.h M src/osmo-hnbgw/Makefile.am M src/osmo-hnbgw/hnbgw.c M src/osmo-hnbgw/hnbgw_cn.c M src/osmo-hnbgw/hnbgw_rua.c M src/osmo-hnbgw/hnbgw_vty.c A src/osmo-hnbgw/mgw_fsm.c A src/osmo-hnbgw/tdefs.c 17 files changed, 761 insertions(+), 2 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-hnbgw refs/changes/95/26795/10
Hello Jenkins Builder, pespin,
I'd like you to reexamine a change. Please visit
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795
to look at the new patch set (#11).
Change subject: mgw_fsm: add MGW support to osmo-hnbgw ......................................................................
mgw_fsm: add MGW support to osmo-hnbgw
osmo-hnbgw lacks support for an co-located media gateway. This makes it virtually impossible to isolate the HNB from the core network properly.
Lets add MGCP support to osmo-hnbgw so that it can control a co-located media gateway to relay the RTP streams between HNB and core network.
Change-Id: Ib9b62e0145184b91c56ce5d8870760bfa49cc5a4 Related: OS#515 --- M configure.ac M contrib/jenkins.sh M contrib/osmo-hnbgw.spec.in M debian/control M include/osmocom/hnbgw/Makefile.am M include/osmocom/hnbgw/context_map.h M include/osmocom/hnbgw/hnbgw.h A include/osmocom/hnbgw/mgw_fsm.h A include/osmocom/hnbgw/tdefs.h M include/osmocom/hnbgw/vty.h M src/osmo-hnbgw/Makefile.am M src/osmo-hnbgw/hnbgw.c M src/osmo-hnbgw/hnbgw_cn.c M src/osmo-hnbgw/hnbgw_rua.c M src/osmo-hnbgw/hnbgw_vty.c A src/osmo-hnbgw/mgw_fsm.c A src/osmo-hnbgw/tdefs.c 17 files changed, 761 insertions(+), 2 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-hnbgw refs/changes/95/26795/11
dexter has posted comments on this change. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795 )
Change subject: mgw_fsm: add MGW support to osmo-hnbgw ......................................................................
Patch Set 11:
(1 comment)
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/7/src/osmo-hnbgw/hnbgw_cn.c File src/osmo-hnbgw/hnbgw_cn.c:
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/7/src/osmo-hnbgw/hnbgw_cn.c@... PS7, Line 362: switch (((uint8_t *)msgb_l2(oph->msg))[1]) {
why such a hack here and peek into the raw msgb without the use of the decoder? Why not simply deco […]
hmm. I was hoping that at least the procedure code would be in a fixed position and we could rely on this. My idea was to safe the effort for the decoding when the procedure is not about RAB assignment. I will see how this can be solved. Probably we will have to decode it properly then.
Hello Jenkins Builder, pespin,
I'd like you to reexamine a change. Please visit
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795
to look at the new patch set (#13).
Change subject: mgw_fsm: add MGW support to osmo-hnbgw ......................................................................
mgw_fsm: add MGW support to osmo-hnbgw
osmo-hnbgw lacks support for an co-located media gateway. This makes it virtually impossible to isolate the HNB from the core network properly.
Lets add MGCP support to osmo-hnbgw so that it can control a co-located media gateway to relay the RTP streams between HNB and core network.
Change-Id: Ib9b62e0145184b91c56ce5d8870760bfa49cc5a4 Related: OS#515 --- M configure.ac M contrib/jenkins.sh M contrib/osmo-hnbgw.spec.in M debian/control M include/osmocom/hnbgw/Makefile.am M include/osmocom/hnbgw/context_map.h M include/osmocom/hnbgw/hnbgw.h A include/osmocom/hnbgw/mgw_fsm.h A include/osmocom/hnbgw/tdefs.h M include/osmocom/hnbgw/vty.h M src/osmo-hnbgw/Makefile.am M src/osmo-hnbgw/hnbgw.c M src/osmo-hnbgw/hnbgw_cn.c M src/osmo-hnbgw/hnbgw_rua.c M src/osmo-hnbgw/hnbgw_vty.c A src/osmo-hnbgw/mgw_fsm.c A src/osmo-hnbgw/tdefs.c 17 files changed, 806 insertions(+), 2 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-hnbgw refs/changes/95/26795/13
dexter has posted comments on this change. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795 )
Change subject: mgw_fsm: add MGW support to osmo-hnbgw ......................................................................
Patch Set 13:
(5 comments)
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/7/src/osmo-hnbgw/hnbgw_cn.c File src/osmo-hnbgw/hnbgw_cn.c:
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/7/src/osmo-hnbgw/hnbgw_cn.c@... PS7, Line 362: switch (((uint8_t *)msgb_l2(oph->msg))[1]) {
hmm. […]
Done
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/7/src/osmo-hnbgw/hnbgw_rua.c File src/osmo-hnbgw/hnbgw_rua.c:
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/7/src/osmo-hnbgw/hnbgw_rua.c... PS7, Line 273: case RANAP_ProcedureCode_id_RAB_Assignment:
likewise the same here.
Done
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/1/src/osmo-hnbgw/hnbgw_vty.c File src/osmo-hnbgw/hnbgw_vty.c:
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/1/src/osmo-hnbgw/hnbgw_vty.c... PS1, Line 451: g_hnb_gw->config.mgcp_client = talloc_zero(tall_hnb_ctx, struct mgcp_client_conf);
This doesn't look like the proper place to do this. Please move this to the g_hnb_gw alloc function.
Done
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/1/src/osmo-hnbgw/mgw_fsm.c File src/osmo-hnbgw/mgw_fsm.c:
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/1/src/osmo-hnbgw/mgw_fsm.c@8... PS1, Line 84: /* We have to store the RANAP RAB AssignmentRequest message, since we can not take ownership of the osmo prim
why can't you take ownsership? is it freed by the callback caller? If not, talloc_steal, if yes, msg […]
It is freed by the code that calls mgw_fsm_alloc_and_handle_rab_ass_req() from hnbgw_cn.c. See also sccp_sap_up() It is built that way. We could try to change it though its only 4 functions that would have to be changed so that we can take ownership of the msg buffer.
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/1/src/osmo-hnbgw/mgw_fsm.c@4... PS1, Line 420: .in_event_mask = S(MGW_EV_MGCP_OK) | S(MGW_EV_MGCP_FAIL),
I find it much more clear having one per line, but OK.
If you give me an example from somewhere in the osmocom codebase I can replicate the coding style.
pespin has posted comments on this change. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795 )
Change subject: mgw_fsm: add MGW support to osmo-hnbgw ......................................................................
Patch Set 13:
(1 comment)
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/1/src/osmo-hnbgw/mgw_fsm.c File src/osmo-hnbgw/mgw_fsm.c:
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/1/src/osmo-hnbgw/mgw_fsm.c@4... PS1, Line 420: .in_event_mask = S(MGW_EV_MGCP_OK) | S(MGW_EV_MGCP_FAIL),
If you give me an example from somewhere in the osmocom codebase I can replicate the coding style.
Something like: osmo-bsc.git: ./src/osmo-bsc/nm_bts_fsm.c osmo-bsc.git: ./src/osmo-bsc/lchan_rtp_fsm.c
I personally prefer the first one (I wrote that file ;) but the second one is good enough too in general.
Hello Jenkins Builder, pespin,
I'd like you to reexamine a change. Please visit
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795
to look at the new patch set (#14).
Change subject: mgw_fsm: add MGW support to osmo-hnbgw ......................................................................
mgw_fsm: add MGW support to osmo-hnbgw
osmo-hnbgw lacks support for an co-located media gateway. This makes it virtually impossible to isolate the HNB from the core network properly.
Lets add MGCP support to osmo-hnbgw so that it can control a co-located media gateway to relay the RTP streams between HNB and core network.
Change-Id: Ib9b62e0145184b91c56ce5d8870760bfa49cc5a4 Related: OS#515 --- M configure.ac M contrib/jenkins.sh M contrib/osmo-hnbgw.spec.in M debian/control M include/osmocom/hnbgw/Makefile.am M include/osmocom/hnbgw/context_map.h M include/osmocom/hnbgw/hnbgw.h A include/osmocom/hnbgw/mgw_fsm.h A include/osmocom/hnbgw/tdefs.h M include/osmocom/hnbgw/vty.h M src/osmo-hnbgw/Makefile.am M src/osmo-hnbgw/hnbgw.c M src/osmo-hnbgw/hnbgw_cn.c M src/osmo-hnbgw/hnbgw_rua.c M src/osmo-hnbgw/hnbgw_vty.c A src/osmo-hnbgw/mgw_fsm.c A src/osmo-hnbgw/tdefs.c 17 files changed, 822 insertions(+), 2 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-hnbgw refs/changes/95/26795/14
dexter has posted comments on this change. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795 )
Change subject: mgw_fsm: add MGW support to osmo-hnbgw ......................................................................
Patch Set 14:
(2 comments)
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/1/src/osmo-hnbgw/mgw_fsm.c File src/osmo-hnbgw/mgw_fsm.c:
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/1/src/osmo-hnbgw/mgw_fsm.c@8... PS1, Line 84: /* We have to store the RANAP RAB AssignmentRequest message, since we can not take ownership of the osmo prim
It is freed by the code that calls mgw_fsm_alloc_and_handle_rab_ass_req() from hnbgw_cn.c. […]
This is now solved by another change.
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/1/src/osmo-hnbgw/mgw_fsm.c@4... PS1, Line 420: .in_event_mask = S(MGW_EV_MGCP_OK) | S(MGW_EV_MGCP_FAIL),
Something like: […]
Done
Attention is currently required from: dexter. pespin has posted comments on this change. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795 )
Change subject: mgw_fsm: add MGW support to osmo-hnbgw ......................................................................
Patch Set 14:
(2 comments)
File src/osmo-hnbgw/hnbgw_cn.c:
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/comment/3104e454_f81d6767 PS14, Line 356: * towards the specific HNB, via a RUA connection identified by This comment needs updating, it's not longer the case.
File src/osmo-hnbgw/mgw_fsm.c:
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/comment/2b67920d_860fea40 PS14, Line 200: rval = this formatting is not usual in our code style.
Attention is currently required from: dexter. laforge has posted comments on this change. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795 )
Change subject: mgw_fsm: add MGW support to osmo-hnbgw ......................................................................
Patch Set 14:
(1 comment)
File src/osmo-hnbgw/hnbgw_cn.c:
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/comment/b174b956_91848ac5 PS14, Line 377: switch (ranap_pdu->choice.initiatingMessage.procedureCode) { what I'm somehow missing here is some code that puts this all into a "for CS domain only" clause. There are RAB assignments for CS and for PS, and the MGW only gets involved with the CS RAB assignments.
FYI: We will later in subsequent patches use the upcoming osmo-upf to do the same for the PS domain.
But for now, PS domain rab assignment should never be sent to mgw_fsm_* code, right?
Attention is currently required from: laforge. dexter has posted comments on this change. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795 )
Change subject: mgw_fsm: add MGW support to osmo-hnbgw ......................................................................
Patch Set 14:
(1 comment)
File src/osmo-hnbgw/hnbgw_cn.c:
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/comment/9d8c49c5_0fbfff1e PS14, Line 377: switch (ranap_pdu->choice.initiatingMessage.procedureCode) {
what I'm somehow missing here is some code that puts this all into a "for CS domain only" clause. […]
Checking with map->is_ps is not sufficient?
Attention is currently required from: laforge. Hello Jenkins Builder, pespin,
I'd like you to reexamine a change. Please visit
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795
to look at the new patch set (#15).
Change subject: mgw_fsm: add MGW support to osmo-hnbgw ......................................................................
mgw_fsm: add MGW support to osmo-hnbgw
osmo-hnbgw lacks support for an co-located media gateway. This makes it virtually impossible to isolate the HNB from the core network properly.
Lets add MGCP support to osmo-hnbgw so that it can control a co-located media gateway to relay the RTP streams between HNB and core network.
Change-Id: Ib9b62e0145184b91c56ce5d8870760bfa49cc5a4 Related: OS#515 --- M configure.ac M contrib/jenkins.sh M contrib/osmo-hnbgw.spec.in M debian/control M include/osmocom/hnbgw/Makefile.am M include/osmocom/hnbgw/context_map.h M include/osmocom/hnbgw/hnbgw.h A include/osmocom/hnbgw/mgw_fsm.h A include/osmocom/hnbgw/tdefs.h M include/osmocom/hnbgw/vty.h M src/osmo-hnbgw/Makefile.am M src/osmo-hnbgw/hnbgw.c M src/osmo-hnbgw/hnbgw_cn.c M src/osmo-hnbgw/hnbgw_rua.c M src/osmo-hnbgw/hnbgw_vty.c A src/osmo-hnbgw/mgw_fsm.c A src/osmo-hnbgw/tdefs.c 17 files changed, 799 insertions(+), 6 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-hnbgw refs/changes/95/26795/15
Attention is currently required from: laforge, pespin. dexter has posted comments on this change. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795 )
Change subject: mgw_fsm: add MGW support to osmo-hnbgw ......................................................................
Patch Set 16:
(2 comments)
File src/osmo-hnbgw/hnbgw_cn.c:
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/comment/a298738c_b36209d1 PS14, Line 356: * towards the specific HNB, via a RUA connection identified by
This comment needs updating, it's not longer the case.
Done
File src/osmo-hnbgw/mgw_fsm.c:
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/comment/3a60bda1_9cd2d4da PS14, Line 200: rval =
this formatting is not usual in our code style.
Done
Attention is currently required from: laforge, pespin. Hello Jenkins Builder, pespin,
I'd like you to reexamine a change. Please visit
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795
to look at the new patch set (#16).
Change subject: mgw_fsm: add MGW support to osmo-hnbgw ......................................................................
mgw_fsm: add MGW support to osmo-hnbgw
osmo-hnbgw lacks support for an co-located media gateway. This makes it virtually impossible to isolate the HNB from the core network properly.
Lets add MGCP support to osmo-hnbgw so that it can control a co-located media gateway to relay the RTP streams between HNB and core network.
Change-Id: Ib9b62e0145184b91c56ce5d8870760bfa49cc5a4 Related: OS#515 --- M configure.ac M contrib/jenkins.sh M contrib/osmo-hnbgw.spec.in M debian/control M include/osmocom/hnbgw/Makefile.am M include/osmocom/hnbgw/context_map.h M include/osmocom/hnbgw/hnbgw.h A include/osmocom/hnbgw/mgw_fsm.h A include/osmocom/hnbgw/tdefs.h M include/osmocom/hnbgw/vty.h M src/osmo-hnbgw/Makefile.am M src/osmo-hnbgw/hnbgw.c M src/osmo-hnbgw/hnbgw_cn.c M src/osmo-hnbgw/hnbgw_rua.c M src/osmo-hnbgw/hnbgw_vty.c A src/osmo-hnbgw/mgw_fsm.c A src/osmo-hnbgw/tdefs.c 17 files changed, 847 insertions(+), 5 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-hnbgw refs/changes/95/26795/16
Attention is currently required from: laforge, dexter. pespin has posted comments on this change. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795 )
Change subject: mgw_fsm: add MGW support to osmo-hnbgw ......................................................................
Patch Set 16:
(2 comments)
File src/osmo-hnbgw/hnbgw_cn.c:
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/comment/f227a747_05d404a8 PS16, Line 379: mgw_fsm_handle_iu_release(map); Is it expected that after handling IuRElease here, it is forwarded in rua_tx_dt below? If so, please document it here with some comment talking about fall through or whatever.
File src/osmo-hnbgw/mgw_fsm.c:
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/comment/f135c721_38e2d3e0 PS16, Line 376: rc = msgb_resize_area(mgw_fsm_priv->ranap_rab_ass_resp_oph->msg, Why is this needed? I don't see a point for it.
Attention is currently required from: laforge, dexter. Hello Jenkins Builder, pespin,
I'd like you to reexamine a change. Please visit
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795
to look at the new patch set (#17).
Change subject: mgw_fsm: add MGW support to osmo-hnbgw ......................................................................
mgw_fsm: add MGW support to osmo-hnbgw
osmo-hnbgw lacks support for an co-located media gateway. This makes it virtually impossible to isolate the HNB from the core network properly.
Lets add MGCP support to osmo-hnbgw so that it can control a co-located media gateway to relay the RTP streams between HNB and core network.
Change-Id: Ib9b62e0145184b91c56ce5d8870760bfa49cc5a4 Related: OS#515 --- M configure.ac M contrib/jenkins.sh M contrib/osmo-hnbgw.spec.in M debian/control M include/osmocom/hnbgw/Makefile.am M include/osmocom/hnbgw/context_map.h M include/osmocom/hnbgw/hnbgw.h A include/osmocom/hnbgw/mgw_fsm.h A include/osmocom/hnbgw/tdefs.h M include/osmocom/hnbgw/vty.h M src/osmo-hnbgw/Makefile.am M src/osmo-hnbgw/hnbgw.c M src/osmo-hnbgw/hnbgw_cn.c M src/osmo-hnbgw/hnbgw_rua.c M src/osmo-hnbgw/hnbgw_vty.c A src/osmo-hnbgw/mgw_fsm.c A src/osmo-hnbgw/tdefs.c 17 files changed, 847 insertions(+), 5 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-hnbgw refs/changes/95/26795/17
Attention is currently required from: laforge, dexter. pespin has posted comments on this change. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795 )
Change subject: mgw_fsm: add MGW support to osmo-hnbgw ......................................................................
Patch Set 17:
(1 comment)
Patchset:
PS17: my comments from previous version still apply.
Attention is currently required from: laforge, pespin. dexter has posted comments on this change. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795 )
Change subject: mgw_fsm: add MGW support to osmo-hnbgw ......................................................................
Patch Set 18:
(3 comments)
File src/osmo-hnbgw/hnbgw_cn.c:
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/comment/ea7db332_76340e25 PS14, Line 377: switch (ranap_pdu->choice.initiatingMessage.procedureCode) {
Checking with map->is_ps is not sufficient?
Done
File src/osmo-hnbgw/hnbgw_cn.c:
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/comment/f23ec48f_73aec1a8 PS16, Line 379: mgw_fsm_handle_iu_release(map);
Is it expected that after handling IuRElease here, it is forwarded in rua_tx_dt below? If so, please […]
yes, this is expected.
File src/osmo-hnbgw/mgw_fsm.c:
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/comment/a80b4922_9ee9a6cb PS16, Line 376: rc = msgb_resize_area(mgw_fsm_priv->ranap_rab_ass_resp_oph->msg,
Why is this needed? I don't see a point for it.
The msgb_resize_area shouldn't fail, but if it fails it is probably causes other problems that may be very difficult to detect. That is the reason for the OSMO_ASSERT
Attention is currently required from: laforge, pespin. Hello Jenkins Builder, pespin,
I'd like you to reexamine a change. Please visit
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795
to look at the new patch set (#18).
Change subject: mgw_fsm: add MGW support to osmo-hnbgw ......................................................................
mgw_fsm: add MGW support to osmo-hnbgw
osmo-hnbgw lacks support for an co-located media gateway. This makes it virtually impossible to isolate the HNB from the core network properly.
Lets add MGCP support to osmo-hnbgw so that it can control a co-located media gateway to relay the RTP streams between HNB and core network.
Change-Id: Ib9b62e0145184b91c56ce5d8870760bfa49cc5a4 Related: OS#515 --- M configure.ac M contrib/jenkins.sh M contrib/osmo-hnbgw.spec.in M debian/control M include/osmocom/hnbgw/Makefile.am M include/osmocom/hnbgw/context_map.h M include/osmocom/hnbgw/hnbgw.h A include/osmocom/hnbgw/mgw_fsm.h A include/osmocom/hnbgw/tdefs.h M include/osmocom/hnbgw/vty.h M src/osmo-hnbgw/Makefile.am M src/osmo-hnbgw/context_map.c M src/osmo-hnbgw/hnbgw.c M src/osmo-hnbgw/hnbgw_cn.c M src/osmo-hnbgw/hnbgw_rua.c M src/osmo-hnbgw/hnbgw_vty.c A src/osmo-hnbgw/mgw_fsm.c A src/osmo-hnbgw/tdefs.c 18 files changed, 856 insertions(+), 5 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-hnbgw refs/changes/95/26795/18
Attention is currently required from: laforge, pespin, dexter. dexter has posted comments on this change. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795 )
Change subject: mgw_fsm: add MGW support to osmo-hnbgw ......................................................................
Patch Set 18:
(2 comments)
Patchset:
PS17:
my comments from previous version still apply.
At the moment everything should be fixed. I might have overlooked something though.
Patchset:
PS18: This is still work in progress (I haven't set it to work in progress though because I have the feeling that would prevents people from reviewing this.)
One thing that still needs to be addressed is a better error handling. So, basically the question what happens when a RANAP RAB AssignmentRequest is processed but the FSM died because of an error. Or what happens when a RANAP RAB AssignmentResponse comes back from the HnodeB and the FSM is not there, or it is there, but the response is an unsuccessful outcome? This also needs to be covered by the TTCN3 tests as well, so that we can test. Otherwise the implementation behaves fine when tested manually.
Attention is currently required from: laforge, pespin, dexter. Hello Jenkins Builder, pespin,
I'd like you to reexamine a change. Please visit
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795
to look at the new patch set (#19).
Change subject: mgw_fsm: add MGW support to osmo-hnbgw ......................................................................
mgw_fsm: add MGW support to osmo-hnbgw
osmo-hnbgw lacks support for an co-located media gateway. This makes it virtually impossible to isolate the HNB from the core network properly.
Lets add MGCP support to osmo-hnbgw so that it can control a co-located media gateway to relay the RTP streams between HNB and core network.
Change-Id: Ib9b62e0145184b91c56ce5d8870760bfa49cc5a4 Related: OS#515 --- M configure.ac M contrib/jenkins.sh M contrib/osmo-hnbgw.spec.in M debian/control M include/osmocom/hnbgw/Makefile.am M include/osmocom/hnbgw/context_map.h M include/osmocom/hnbgw/hnbgw.h A include/osmocom/hnbgw/mgw_fsm.h A include/osmocom/hnbgw/tdefs.h M include/osmocom/hnbgw/vty.h M src/osmo-hnbgw/Makefile.am M src/osmo-hnbgw/context_map.c M src/osmo-hnbgw/hnbgw.c M src/osmo-hnbgw/hnbgw_cn.c M src/osmo-hnbgw/hnbgw_rua.c M src/osmo-hnbgw/hnbgw_vty.c A src/osmo-hnbgw/mgw_fsm.c A src/osmo-hnbgw/tdefs.c 18 files changed, 928 insertions(+), 5 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-hnbgw refs/changes/95/26795/19
Attention is currently required from: laforge, pespin, dexter. Hello Jenkins Builder, pespin,
I'd like you to reexamine a change. Please visit
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795
to look at the new patch set (#23).
Change subject: mgw_fsm: add MGW support to osmo-hnbgw ......................................................................
mgw_fsm: add MGW support to osmo-hnbgw
osmo-hnbgw lacks support for an co-located media gateway. This makes it virtually impossible to isolate the HNB from the core network properly.
Lets add MGCP support to osmo-hnbgw so that it can control a co-located media gateway to relay the RTP streams between HNB and core network.
Change-Id: Ib9b62e0145184b91c56ce5d8870760bfa49cc5a4 Related: OS#515 --- M configure.ac M contrib/jenkins.sh M contrib/osmo-hnbgw.spec.in M debian/control M include/osmocom/hnbgw/Makefile.am M include/osmocom/hnbgw/context_map.h M include/osmocom/hnbgw/hnbgw.h A include/osmocom/hnbgw/mgw_fsm.h A include/osmocom/hnbgw/tdefs.h M include/osmocom/hnbgw/vty.h M src/osmo-hnbgw/Makefile.am M src/osmo-hnbgw/context_map.c M src/osmo-hnbgw/hnbgw.c M src/osmo-hnbgw/hnbgw_cn.c M src/osmo-hnbgw/hnbgw_rua.c M src/osmo-hnbgw/hnbgw_vty.c A src/osmo-hnbgw/mgw_fsm.c A src/osmo-hnbgw/tdefs.c 18 files changed, 962 insertions(+), 5 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-hnbgw refs/changes/95/26795/23
Attention is currently required from: laforge, pespin, dexter. Hello Jenkins Builder, pespin,
I'd like you to reexamine a change. Please visit
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795
to look at the new patch set (#24).
Change subject: mgw_fsm: add MGW support to osmo-hnbgw ......................................................................
mgw_fsm: add MGW support to osmo-hnbgw
osmo-hnbgw lacks support for an co-located media gateway. This makes it virtually impossible to isolate the HNB from the core network properly.
Lets add MGCP support to osmo-hnbgw so that it can control a co-located media gateway to relay the RTP streams between HNB and core network.
Change-Id: Ib9b62e0145184b91c56ce5d8870760bfa49cc5a4 Related: OS#5152 --- M configure.ac M contrib/jenkins.sh M contrib/osmo-hnbgw.spec.in M debian/control M include/osmocom/hnbgw/Makefile.am M include/osmocom/hnbgw/context_map.h M include/osmocom/hnbgw/hnbgw.h A include/osmocom/hnbgw/mgw_fsm.h A include/osmocom/hnbgw/tdefs.h M include/osmocom/hnbgw/vty.h M src/osmo-hnbgw/Makefile.am M src/osmo-hnbgw/context_map.c M src/osmo-hnbgw/hnbgw.c M src/osmo-hnbgw/hnbgw_cn.c M src/osmo-hnbgw/hnbgw_rua.c M src/osmo-hnbgw/hnbgw_vty.c A src/osmo-hnbgw/mgw_fsm.c A src/osmo-hnbgw/tdefs.c 18 files changed, 962 insertions(+), 5 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-hnbgw refs/changes/95/26795/24
Attention is currently required from: laforge, pespin, dexter. Hello Jenkins Builder, pespin,
I'd like you to reexamine a change. Please visit
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795
to look at the new patch set (#25).
Change subject: mgw_fsm: add MGW support to osmo-hnbgw ......................................................................
mgw_fsm: add MGW support to osmo-hnbgw
osmo-hnbgw lacks support for an co-located media gateway. This makes it virtually impossible to isolate the HNB from the core network properly.
Lets add MGCP support to osmo-hnbgw so that it can control a co-located media gateway to relay the RTP streams between HNB and core network.
Change-Id: Ib9b62e0145184b91c56ce5d8870760bfa49cc5a4 Related: OS#5152 --- M configure.ac M contrib/jenkins.sh M contrib/osmo-hnbgw.spec.in M debian/control M include/osmocom/hnbgw/Makefile.am M include/osmocom/hnbgw/context_map.h M include/osmocom/hnbgw/hnbgw.h A include/osmocom/hnbgw/mgw_fsm.h A include/osmocom/hnbgw/tdefs.h M include/osmocom/hnbgw/vty.h M src/osmo-hnbgw/Makefile.am M src/osmo-hnbgw/context_map.c M src/osmo-hnbgw/hnbgw.c M src/osmo-hnbgw/hnbgw_cn.c M src/osmo-hnbgw/hnbgw_rua.c M src/osmo-hnbgw/hnbgw_vty.c A src/osmo-hnbgw/mgw_fsm.c A src/osmo-hnbgw/tdefs.c 18 files changed, 962 insertions(+), 5 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-hnbgw refs/changes/95/26795/25
Attention is currently required from: laforge, dexter. pespin has posted comments on this change. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795 )
Change subject: mgw_fsm: add MGW support to osmo-hnbgw ......................................................................
Patch Set 25:
(6 comments)
File src/osmo-hnbgw/context_map.c:
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/comment/d8015f32_fed1c4a0 PS25, Line 142: /* a possibly still existing MGW FSM must be termiated when the context terminated
File src/osmo-hnbgw/mgw_fsm.c:
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/comment/4d2caeb3_d7cfa334 PS25, Line 50: * do not support at the moemnt. */ moment
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/comment/0e787d32_8885d161 PS25, Line 52: /* Send Iu Release request, this is done in errornous cases from which we cannot recover */ Request
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/comment/265e6df2_45574422 PS25, Line 53: static void tx_release_req(struct hnbgw_context_map *map) This function doesn't really look like belonging in this file. It should be oved somewhere Iu related, not here which is MGW related.
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/comment/8297121e_e3e32ff0 PS25, Line 424: rc = msgb_resize_area(mgw_fsm_priv->ranap_rab_ass_resp_oph->msg, I'm still not understanding why is this resize here needed. Your previous answer didn't really explain it imho. Why do you need to resize if ranap_rab_ass_resp_encode gets passed msgb_l2len to make sure it doesn't overflow?
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/comment/0e23e35b_29de19b0 PS25, Line 627: static int handle_rab_release(struct hnbgw_context_map *map, struct osmo_prim_hdr *oph, ranap_message *message) Same, this function doesn't really look like belonging in this file.
Attention is currently required from: laforge, pespin. dexter has posted comments on this change. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795 )
Change subject: mgw_fsm: add MGW support to osmo-hnbgw ......................................................................
Patch Set 27:
(6 comments)
File src/osmo-hnbgw/context_map.c:
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/comment/4e83f824_60411522 PS25, Line 142: /* a possibly still existing MGW FSM must be termiated when the context
terminated
Done
File src/osmo-hnbgw/mgw_fsm.c:
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/comment/9d9c9c48_5f1916d2 PS25, Line 50: * do not support at the moemnt. */
moment
Done
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/comment/68537baa_c91c4407 PS25, Line 52: /* Send Iu Release request, this is done in errornous cases from which we cannot recover */
Request
Done
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/comment/6fb1dfb3_b2659bc3 PS25, Line 53: static void tx_release_req(struct hnbgw_context_map *map)
This function doesn't really look like belonging in this file. […]
Do you have any ideas where? This is a helper function that is called from to location of this FSM to format an IuRelease message.
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/comment/d4282147_7b3c8b4b PS25, Line 424: rc = msgb_resize_area(mgw_fsm_priv->ranap_rab_ass_resp_oph->msg,
I'm still not understanding why is this resize here needed. […]
In practice the message don't change ths size, but in theory they might either shrink or grow. So what is done here is to resize the area for l2 to have some headroom. Then we encode the message and resize again to the actual message lenght. So yes, this is to make sure that no overflow happens and that the memory in the msgb is accessed in a safe way.
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/comment/2c09115f_a1e8227d PS25, Line 627: static int handle_rab_release(struct hnbgw_context_map *map, struct osmo_prim_hdr *oph, ranap_message *message)
Same, this function doesn't really look like belonging in this file.
It does belong to here. This function is a helper function to interpret the content of the RabRelease that might be encapsulated in the RAB Assignment Request.
Attention is currently required from: laforge, pespin. Hello Jenkins Builder, pespin,
I'd like you to reexamine a change. Please visit
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795
to look at the new patch set (#27).
Change subject: mgw_fsm: add MGW support to osmo-hnbgw ......................................................................
mgw_fsm: add MGW support to osmo-hnbgw
osmo-hnbgw lacks support for an co-located media gateway. This makes it virtually impossible to isolate the HNB from the core network properly.
Lets add MGCP support to osmo-hnbgw so that it can control a co-located media gateway to relay the RTP streams between HNB and core network.
Change-Id: Ib9b62e0145184b91c56ce5d8870760bfa49cc5a4 Related: OS#5152 --- M configure.ac M contrib/jenkins.sh M contrib/osmo-hnbgw.spec.in M debian/control M include/osmocom/hnbgw/Makefile.am M include/osmocom/hnbgw/context_map.h M include/osmocom/hnbgw/hnbgw.h A include/osmocom/hnbgw/mgw_fsm.h A include/osmocom/hnbgw/tdefs.h M include/osmocom/hnbgw/vty.h M src/osmo-hnbgw/Makefile.am M src/osmo-hnbgw/context_map.c M src/osmo-hnbgw/hnbgw.c M src/osmo-hnbgw/hnbgw_cn.c M src/osmo-hnbgw/hnbgw_rua.c M src/osmo-hnbgw/hnbgw_vty.c A src/osmo-hnbgw/mgw_fsm.c A src/osmo-hnbgw/tdefs.c 18 files changed, 962 insertions(+), 5 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-hnbgw refs/changes/95/26795/27
Attention is currently required from: laforge, pespin. dexter has posted comments on this change. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795 )
Change subject: mgw_fsm: add MGW support to osmo-hnbgw ......................................................................
Patch Set 26:
(2 comments)
File src/osmo-hnbgw/context_map.c:
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/comment/c3f6537d_6bec76ad PS25, Line 142: /* a possibly still existing MGW FSM must be termiated when the context
terminated
Done
File src/osmo-hnbgw/mgw_fsm.c:
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/comment/73521caf_db2cbf50 PS25, Line 52: /* Send Iu Release request, this is done in errornous cases from which we cannot recover */
Request
I don't understand.
Attention is currently required from: pespin, daniel, dexter. laforge has posted comments on this change. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795 )
Change subject: mgw_fsm: add MGW support to osmo-hnbgw ......................................................................
Patch Set 27: Code-Review+1
Attention is currently required from: pespin, dexter. daniel has posted comments on this change. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795 )
Change subject: mgw_fsm: add MGW support to osmo-hnbgw ......................................................................
Patch Set 27: Code-Review+1
Attention is currently required from: dexter. pespin has posted comments on this change. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795 )
Change subject: mgw_fsm: add MGW support to osmo-hnbgw ......................................................................
Patch Set 27: Code-Review+1
(4 comments)
File src/osmo-hnbgw/mgw_fsm.c:
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/comment/54534cfb_7099f6d0 PS25, Line 52: /* Send Iu Release request, this is done in errornous cases from which we cannot recover */
I don't understand.
typo: errornous-> erroneous
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/comment/2a12365f_58927be2 PS25, Line 53: static void tx_release_req(struct hnbgw_context_map *map)
Do you have any ideas where? This is a helper function that is called from to location of this FSM t […]
We'd probably want to add a hnbgw_iu.c or alike, but ok, let's keep it here for now.
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/comment/0b656f0c_de71297b PS25, Line 424: rc = msgb_resize_area(mgw_fsm_priv->ranap_rab_ass_resp_oph->msg,
In practice the message don't change ths size, but in theory they might either shrink or grow. […]
ack
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/comment/821e89d6_4ca62ba0 PS25, Line 627: static int handle_rab_release(struct hnbgw_context_map *map, struct osmo_prim_hdr *oph, ranap_message *message)
It does belong to here. […]
Ok let's leave it here for now.
Attention is currently required from: pespin. Hello Jenkins Builder, laforge, pespin, daniel,
I'd like you to reexamine a change. Please visit
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795
to look at the new patch set (#28).
Change subject: mgw_fsm: add MGW support to osmo-hnbgw ......................................................................
mgw_fsm: add MGW support to osmo-hnbgw
osmo-hnbgw lacks support for an co-located media gateway. This makes it virtually impossible to isolate the HNB from the core network properly.
Lets add MGCP support to osmo-hnbgw so that it can control a co-located media gateway to relay the RTP streams between HNB and core network.
Change-Id: Ib9b62e0145184b91c56ce5d8870760bfa49cc5a4 Related: OS#5152 --- M configure.ac M contrib/jenkins.sh M contrib/osmo-hnbgw.spec.in M debian/control M include/osmocom/hnbgw/Makefile.am M include/osmocom/hnbgw/context_map.h M include/osmocom/hnbgw/hnbgw.h A include/osmocom/hnbgw/mgw_fsm.h A include/osmocom/hnbgw/tdefs.h M include/osmocom/hnbgw/vty.h M src/osmo-hnbgw/Makefile.am M src/osmo-hnbgw/context_map.c M src/osmo-hnbgw/hnbgw.c M src/osmo-hnbgw/hnbgw_cn.c M src/osmo-hnbgw/hnbgw_rua.c M src/osmo-hnbgw/hnbgw_vty.c A src/osmo-hnbgw/mgw_fsm.c A src/osmo-hnbgw/tdefs.c 18 files changed, 962 insertions(+), 5 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-hnbgw refs/changes/95/26795/28
Attention is currently required from: pespin. dexter has posted comments on this change. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795 )
Change subject: mgw_fsm: add MGW support to osmo-hnbgw ......................................................................
Patch Set 28:
(2 comments)
File src/osmo-hnbgw/mgw_fsm.c:
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/comment/9f35a32f_0eeac45e PS25, Line 52: /* Send Iu Release request, this is done in errornous cases from which we cannot recover */
typo: errornous-> erroneous
Done
https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795/comment/7d888675_2615f3c2 PS25, Line 53: static void tx_release_req(struct hnbgw_context_map *map)
We'd probably want to add a hnbgw_iu.c or alike, but ok, let's keep it here for now.
I think thats a good idea, but I also think that we should do this in a different patch. The planned FSM for the packet RABs will probably also have to send release requests when an error occurs.
Attention is currently required from: pespin. dexter has posted comments on this change. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795 )
Change subject: mgw_fsm: add MGW support to osmo-hnbgw ......................................................................
Patch Set 28: Code-Review+2
dexter has submitted this change. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/26795 )
Change subject: mgw_fsm: add MGW support to osmo-hnbgw ......................................................................
mgw_fsm: add MGW support to osmo-hnbgw
osmo-hnbgw lacks support for an co-located media gateway. This makes it virtually impossible to isolate the HNB from the core network properly.
Lets add MGCP support to osmo-hnbgw so that it can control a co-located media gateway to relay the RTP streams between HNB and core network.
Change-Id: Ib9b62e0145184b91c56ce5d8870760bfa49cc5a4 Related: OS#5152 --- M configure.ac M contrib/jenkins.sh M contrib/osmo-hnbgw.spec.in M debian/control M include/osmocom/hnbgw/Makefile.am M include/osmocom/hnbgw/context_map.h M include/osmocom/hnbgw/hnbgw.h A include/osmocom/hnbgw/mgw_fsm.h A include/osmocom/hnbgw/tdefs.h M include/osmocom/hnbgw/vty.h M src/osmo-hnbgw/Makefile.am M src/osmo-hnbgw/context_map.c M src/osmo-hnbgw/hnbgw.c M src/osmo-hnbgw/hnbgw_cn.c M src/osmo-hnbgw/hnbgw_rua.c M src/osmo-hnbgw/hnbgw_vty.c A src/osmo-hnbgw/mgw_fsm.c A src/osmo-hnbgw/tdefs.c 18 files changed, 962 insertions(+), 5 deletions(-)
Approvals: Jenkins Builder: Verified dexter: Looks good to me, approved
diff --git a/configure.ac b/configure.ac index 520cd68..39c65c0 100644 --- a/configure.ac +++ b/configure.ac @@ -60,7 +60,7 @@ PKG_CHECK_MODULES(LIBOSMORUA, libosmo-rua >= 1.1.0) PKG_CHECK_MODULES(LIBOSMORANAP, libosmo-ranap >= 1.1.0) PKG_CHECK_MODULES(LIBOSMOHNBAP, libosmo-hnbap >= 1.1.0) - +PKG_CHECK_MODULES(LIBOSMOMGCPCLIENT, libosmo-mgcp-client >= 1.9.0)
dnl checks for header files AC_HEADER_STDC diff --git a/contrib/jenkins.sh b/contrib/jenkins.sh index 24607db..b43eac6 100755 --- a/contrib/jenkins.sh +++ b/contrib/jenkins.sh @@ -35,6 +35,7 @@ osmo-build-dep.sh libosmo-sccp osmo-build-dep.sh libasn1c osmo-build-dep.sh osmo-iuh +osmo-build-dep.sh osmo-mgw
# Additional configure options and depends CONFIG="" diff --git a/contrib/osmo-hnbgw.spec.in b/contrib/osmo-hnbgw.spec.in index 1d30e56..0c6aac9 100644 --- a/contrib/osmo-hnbgw.spec.in +++ b/contrib/osmo-hnbgw.spec.in @@ -32,6 +32,7 @@ BuildRequires: systemd-rpm-macros %endif BuildRequires: pkgconfig(libcrypto) >= 0.9.5 +BuildRequires: pkgconfig(libosmo-mgcp-client) >= 1.9.0 BuildRequires: pkgconfig(libosmo-netif) >= 1.1.0 BuildRequires: pkgconfig(libosmo-sigtran) >= 1.5.0 BuildRequires: pkgconfig(libosmoabis) >= 1.2.0 diff --git a/debian/control b/debian/control index d9ab85f..7d449c0 100644 --- a/debian/control +++ b/debian/control @@ -17,6 +17,7 @@ libosmo-sigtran-dev (>= 1.5.0), libosmo-abis-dev (>= 1.2.0), libosmo-netif-dev (>= 1.1.0), + libosmo-mgcp-client-dev (>= 1.9.0), libosmo-hnbap-dev (>= 1.1.0), libosmo-ranap-dev (>= 1.1.0), libosmo-rua-dev (>= 1.1.0), diff --git a/include/osmocom/hnbgw/Makefile.am b/include/osmocom/hnbgw/Makefile.am index 0ddd42e..2a75df8 100644 --- a/include/osmocom/hnbgw/Makefile.am +++ b/include/osmocom/hnbgw/Makefile.am @@ -2,4 +2,4 @@ vty.h \ context_map.h hnbgw.h hnbgw_cn.h \ hnbgw_hnbap.h hnbgw_rua.h hnbgw_ranap.h \ - ranap_rab_ass.h + ranap_rab_ass.h mgw_fsm.h tdefs.h diff --git a/include/osmocom/hnbgw/context_map.h b/include/osmocom/hnbgw/context_map.h index 6279b91..6910fe8 100644 --- a/include/osmocom/hnbgw/context_map.h +++ b/include/osmocom/hnbgw/context_map.h @@ -35,6 +35,9 @@ uint32_t scu_conn_id;
enum hnbgw_context_map_state state; + + /* FSM instance for the MGW */ + struct osmo_fsm_inst *mgw_fi; };
diff --git a/include/osmocom/hnbgw/hnbgw.h b/include/osmocom/hnbgw/hnbgw.h index fc8298d..9a46301 100644 --- a/include/osmocom/hnbgw/hnbgw.h +++ b/include/osmocom/hnbgw/hnbgw.h @@ -16,6 +16,7 @@ DHNBAP, DRUA, DRANAP, + DMGW, };
#define LOGHNB(x, ss, lvl, fmt, args ...) \ @@ -133,6 +134,7 @@ bool hnbap_allow_tmsi; /*! print hnb-id (true) or MCC-MNC-LAC-RAC-SAC (false) in logs */ bool log_prefix_hnb_id; + struct mgcp_client_conf *mgcp_client; } config; /*! SCTP listen socket for incoming connections */ struct osmo_stream_srv_link *iuh; @@ -151,6 +153,7 @@ struct osmo_sccp_addr iucs_remote_addr; struct osmo_sccp_addr iups_remote_addr; } sccp; + struct mgcp_client *mgcp_client; };
extern void *talloc_asn1_ctx; diff --git a/include/osmocom/hnbgw/mgw_fsm.h b/include/osmocom/hnbgw/mgw_fsm.h new file mode 100644 index 0000000..8b14eaa --- /dev/null +++ b/include/osmocom/hnbgw/mgw_fsm.h @@ -0,0 +1,7 @@ +#pragma once + +#include <osmocom/ranap/ranap_ies_defs.h> + +int handle_rab_ass_req(struct hnbgw_context_map *map, struct osmo_prim_hdr *oph, ranap_message *message); +int mgw_fsm_handle_rab_ass_resp(struct hnbgw_context_map *map, struct osmo_prim_hdr *oph, ranap_message *message); +int mgw_fsm_release(struct hnbgw_context_map *map); diff --git a/include/osmocom/hnbgw/tdefs.h b/include/osmocom/hnbgw/tdefs.h new file mode 100644 index 0000000..4f98a36 --- /dev/null +++ b/include/osmocom/hnbgw/tdefs.h @@ -0,0 +1,6 @@ +#pragma once + +#include <osmocom/core/tdef.h> + +extern struct osmo_tdef mgw_fsm_T_defs[]; +extern struct osmo_tdef_group hnbgw_tdef_group[]; diff --git a/include/osmocom/hnbgw/vty.h b/include/osmocom/hnbgw/vty.h index 3d05da5..93b3c45 100644 --- a/include/osmocom/hnbgw/vty.h +++ b/include/osmocom/hnbgw/vty.h @@ -7,5 +7,6 @@ IUH_NODE, IUCS_NODE, IUPS_NODE, + MGCP_NODE, };
diff --git a/src/osmo-hnbgw/Makefile.am b/src/osmo-hnbgw/Makefile.am index 0948170..64d5ccd 100644 --- a/src/osmo-hnbgw/Makefile.am +++ b/src/osmo-hnbgw/Makefile.am @@ -19,6 +19,7 @@ $(LIBOSMORUA_CFLAGS) \ $(LIBOSMORANAP_CFLAGS) \ $(LIBOSMOHNBAP_CFLAGS) \ + $(LIBOSMOMGCPCLIENT_CFLAGS) \ $(NULL)
AM_LDFLAGS = \ @@ -38,6 +39,8 @@ context_map.c \ hnbgw_cn.c \ ranap_rab_ass.c \ + mgw_fsm.c \ + tdefs.c \ $(NULL)
osmo_hnbgw_LDADD = \ @@ -52,5 +55,7 @@ $(LIBOSMORUA_LIBS) \ $(LIBOSMORANAP_LIBS) \ $(LIBOSMOHNBAP_LIBS) \ + $(LIBOSMOMGCPCLIENT_LIBS) \ $(LIBSCTP_LIBS) \ + $(LIBOSMOMGCPCLIENT_LIBS) \ $(NULL) diff --git a/src/osmo-hnbgw/context_map.c b/src/osmo-hnbgw/context_map.c index 09aa965..18f71ce 100644 --- a/src/osmo-hnbgw/context_map.c +++ b/src/osmo-hnbgw/context_map.c @@ -26,6 +26,7 @@
#include <osmocom/hnbgw/hnbgw.h> #include <osmocom/hnbgw/context_map.h> +#include <osmocom/hnbgw/mgw_fsm.h>
const struct value_string hnbgw_context_map_state_names[] = { {MAP_S_NULL , "not-initialized"}, @@ -137,6 +138,13 @@
if (map->state != MAP_S_RESERVED2) map->state = MAP_S_RESERVED1; + + /* a possibly still existing MGW FSM must be terminated when the context + * map is deactivated. (this is a cornercase) */ + if (map->mgw_fi) { + mgw_fsm_release(map); + OSMO_ASSERT(map->mgw_fi == NULL); + } }
static struct osmo_timer_list context_map_tmr; diff --git a/src/osmo-hnbgw/hnbgw.c b/src/osmo-hnbgw/hnbgw.c index da15bfc..833486c 100644 --- a/src/osmo-hnbgw/hnbgw.c +++ b/src/osmo-hnbgw/hnbgw.c @@ -52,6 +52,8 @@ #include <osmocom/vty/command.h> #include <osmocom/vty/ports.h>
+#include <osmocom/mgcp_client/mgcp_client.h> + #include <osmocom/netif/stream.h>
#include <osmocom/ranap/ranap_common.h> @@ -92,6 +94,9 @@
context_map_init(gw);
+ gw->config.mgcp_client = talloc_zero(tall_hnb_ctx, struct mgcp_client_conf); + mgcp_client_conf_init(gw->config.mgcp_client); + return gw; }
@@ -372,6 +377,11 @@ .color = "", .description = "RAN Application Part", }, + [DMGW] = { + .name = "DMGW", .loglevel = LOGL_NOTICE, .enabled = 1, + .color = "\033[1;33m", + .description = "Media Gateway", + }, };
static const struct log_info hnbgw_log_info = { @@ -681,6 +691,19 @@ } g_hnb_gw->iuh = srv;
+ /* Initialize and connect MGCP client. */ + g_hnb_gw->mgcp_client = mgcp_client_init(tall_hnb_ctx, g_hnb_gw->config.mgcp_client); + if (!g_hnb_gw->mgcp_client) { + LOGP(DMGW, LOGL_ERROR, "MGW client initalization failed\n"); + return -EINVAL; + } + if (mgcp_client_connect(g_hnb_gw->mgcp_client)) { + LOGP(DMGW, LOGL_ERROR, "MGW connect failed at (%s:%u)\n", + g_hnb_gw->config.mgcp_client->remote_addr, + g_hnb_gw->config.mgcp_client->remote_port); + return -EINVAL; + } + if (hnbgw_cmdline_config.daemonize) { rc = osmo_daemonize(); if (rc < 0) { diff --git a/src/osmo-hnbgw/hnbgw_cn.c b/src/osmo-hnbgw/hnbgw_cn.c index 757c430..5ee5fd4 100644 --- a/src/osmo-hnbgw/hnbgw_cn.c +++ b/src/osmo-hnbgw/hnbgw_cn.c @@ -34,6 +34,11 @@ #include <osmocom/ranap/ranap_ies_defs.h> #include <osmocom/ranap/ranap_msg_factory.h> #include <osmocom/hnbgw/context_map.h> +#include <osmocom/hnbgw/mgw_fsm.h> +#include <osmocom/ranap/RANAP_ProcedureCode.h> +#include <osmocom/ranap/ranap_common.h> +#include <osmocom/ranap/ranap_common_ran.h> +#include <osmocom/ranap/RANAP_RANAP-PDU.h>
/*********************************************************************** * Outbound RANAP RESET to CN @@ -345,10 +350,13 @@ struct osmo_prim_hdr *oph) { struct hnbgw_context_map *map; + ranap_message *message; + int rc;
- /* connection-oriented data is always passed transparently - * towards the specific HNB, via a RUA connection identified by - * conn_id */ + /* Usually connection-oriented data is always passed transparently towards the specific HNB, via a RUA + * connection identified by conn_id. An exception is made for RANAP RAB AssignmentRequest and + * RANAP RAB AssignmentResponse, since those messages contain transport layer information (RTP stream IP/Port), + * which is rewritten by the FSM that controls the co-located media gateway. */
map = context_map_by_cn(cnlink, param->conn_id); if (!map) { @@ -356,6 +364,28 @@ return 0; }
+ /* Intercept RAB Assignment Request, Setup MGW FSM */ + if (!map->is_ps) { + message = talloc_zero(map, ranap_message); + rc = ranap_ran_rx_co_decode(map, message, msgb_l2(oph->msg), msgb_l2len(oph->msg)); + + if (rc == 0) { + switch (message->procedureCode) { + case RANAP_ProcedureCode_id_RAB_Assignment: + /* mgw_fsm_alloc_and_handle_rab_ass_req() takes ownership of (ranap) message */ + return handle_rab_ass_req(map, oph, message); + case RANAP_ProcedureCode_id_Iu_Release: + /* Any IU Release will terminate the MGW FSM, the message itsself is not passed to the + * FSM code. It is just forwarded normally by the rua_tx_dt() call below. */ + mgw_fsm_release(map); + break; + } + ranap_ran_rx_co_free(message); + } + + talloc_free(message); + } + return rua_tx_dt(map->hnb_ctx, map->is_ps, map->rua_ctx_id, msgb_l2(oph->msg), msgb_l2len(oph->msg)); } diff --git a/src/osmo-hnbgw/hnbgw_rua.c b/src/osmo-hnbgw/hnbgw_rua.c index 24ca167..1943ac0 100644 --- a/src/osmo-hnbgw/hnbgw_rua.c +++ b/src/osmo-hnbgw/hnbgw_rua.c @@ -38,6 +38,10 @@ #include <osmocom/rua/rua_ies_defs.h> #include <osmocom/hnbgw/context_map.h> #include <osmocom/hnbap/HNBAP_CN-DomainIndicator.h> +#include <osmocom/hnbgw/mgw_fsm.h> +#include <osmocom/ranap/RANAP_ProcedureCode.h> +#include <osmocom/ranap/ranap_common.h> +#include <osmocom/ranap/ranap_common_cn.h>
static const char *cn_domain_indicator_to_str(RUA_CN_DomainIndicator_t cN_DomainIndicator) { @@ -186,6 +190,7 @@ struct osmo_sccp_addr *remote_addr; bool is_ps; bool release_context_map = false; + ranap_message *message; int rc;
switch (cN_DomainIndicator) { @@ -265,6 +270,23 @@ memcpy(msg->l2h, data, len); }
+ /* Intercept RAB Assignment Response, inform MGW FSM. */ + if (map && !map->is_ps && !release_context_map) { + message = talloc_zero(map, ranap_message); + rc = ranap_cn_rx_co_decode(map, message, msgb_l2(prim->oph.msg), msgb_l2len(prim->oph.msg)); + + if (rc == 0) { + switch (message->procedureCode) { + case RANAP_ProcedureCode_id_RAB_Assignment: + /* mgw_fsm_handle_rab_ass_resp() takes ownership of prim->oph and (ranap) message */ + return mgw_fsm_handle_rab_ass_resp(map, &prim->oph, message); + } + ranap_cn_rx_co_free(message); + } + + talloc_free(message); + } + rc = osmo_sccp_user_sap_down(cn->sccp_user, &prim->oph);
if (map && release_context_map) diff --git a/src/osmo-hnbgw/hnbgw_vty.c b/src/osmo-hnbgw/hnbgw_vty.c index 4ad1ddb..d064b7d 100644 --- a/src/osmo-hnbgw/hnbgw_vty.c +++ b/src/osmo-hnbgw/hnbgw_vty.c @@ -22,15 +22,19 @@
#include <osmocom/core/socket.h> #include <osmocom/vty/command.h> +#include <osmocom/vty/tdef_vty.h>
#include <osmocom/hnbgw/vty.h>
#include <osmocom/hnbgw/hnbgw.h> #include <osmocom/hnbgw/context_map.h> +#include <osmocom/hnbgw/tdefs.h> #include <osmocom/sigtran/protocol/sua.h> #include <osmocom/sigtran/sccp_helpers.h> #include <osmocom/netif/stream.h>
+#include <osmocom/mgcp_client/mgcp_client.h> + static void *tall_hnb_ctx = NULL; static struct hnb_gw *g_hnb_gw = NULL;
@@ -86,6 +90,19 @@ return CMD_SUCCESS; }
+static struct cmd_node mgcp_node = { + MGCP_NODE, + "%s(config-hnbgw-mgcp)# ", + 1, +}; + +DEFUN(cfg_hnbgw_mgcp, cfg_hnbgw_mgcp_cmd, + "mgcp", "Configure MGCP client") +{ + vty->node = MGCP_NODE; + return CMD_SUCCESS; +} + int hnbgw_vty_go_parent(struct vty *vty) { switch (vty->node) { @@ -95,6 +112,10 @@ vty->node = HNBGW_NODE; vty->index = NULL; break; + case MGCP_NODE: + vty->node = HNBGW_NODE; + vty->index = NULL; + break; case HNBGW_NODE: vty->node = CONFIG_NODE; vty->index = NULL; @@ -382,6 +403,14 @@ return CMD_SUCCESS; }
+static int config_write_hnbgw_mgcp(struct vty *vty) +{ + vty_out(vty, " mgcp%s", VTY_NEWLINE); + mgcp_client_config_write(vty, " "); + + return CMD_SUCCESS; +} + void hnbgw_vty_init(struct hnb_gw *gw, void *tall_ctx) { g_hnb_gw = gw; @@ -415,4 +444,10 @@ install_element_ve(&show_one_hnb_cmd); install_element_ve(&show_ue_cmd); install_element_ve(&show_talloc_cmd); + + install_element(HNBGW_NODE, &cfg_hnbgw_mgcp_cmd); + install_node(&mgcp_node, config_write_hnbgw_mgcp); + + mgcp_client_vty_init(tall_hnb_ctx, MGCP_NODE, g_hnb_gw->config.mgcp_client); + osmo_tdef_vty_groups_init(HNBGW_NODE, hnbgw_tdef_group); } diff --git a/src/osmo-hnbgw/mgw_fsm.c b/src/osmo-hnbgw/mgw_fsm.c new file mode 100644 index 0000000..d4ef800 --- /dev/null +++ b/src/osmo-hnbgw/mgw_fsm.c @@ -0,0 +1,781 @@ +/* (C) 2021 by sysmocom s.f.m.c. GmbH info@sysmocom.de + * All Rights Reserved + * + * Author: Philipp Maier + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 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 General Public License for more details. + */ + +#include <errno.h> + +#include <osmocom/core/msgb.h> +#include <osmocom/core/utils.h> +#include <osmocom/core/prim.h> + +#include <osmocom/core/fsm.h> +#include <osmocom/core/byteswap.h> +#include <arpa/inet.h> +#include <osmocom/core/logging.h> +#include <osmocom/core/sockaddr_str.h> + +#include <osmocom/ranap/ranap_common.h> +#include <osmocom/ranap/ranap_common_cn.h> +#include <osmocom/ranap/ranap_common_ran.h> +#include <osmocom/ranap/ranap_msg_factory.h> + +#include <osmocom/ranap/ranap_ies_defs.h> +#include <osmocom/ranap/iu_helpers.h> +#include <asn1c/asn1helpers.h> + +#include <osmocom/hnbgw/hnbgw.h> +#include <osmocom/hnbgw/context_map.h> +#include <osmocom/hnbgw/ranap_rab_ass.h> + +#include <osmocom/hnbgw/hnbgw_rua.h> + +#include <osmocom/core/tdef.h> +#include <osmocom/hnbgw/tdefs.h> +#include <osmocom/mgcp_client/mgcp_client_endpoint_fsm.h> + +/* NOTE: This implementation can only handle one RAB per hnbgw context. This simplification was made because usually + * a voice call will require only one RAB at a time. An exception may be corner cases like video calls, which we + * do not support at the moment. */ + +/* Send Iu Release Request, this is done in erroneous cases from which we cannot recover */ +static void tx_release_req(struct hnbgw_context_map *map) +{ + struct hnb_context *hnb = map->hnb_ctx; + struct hnbgw_cnlink *cn = hnb->gw->sccp.cnlink; + struct msgb *msg; + struct osmo_scu_prim *prim; + static const struct RANAP_Cause cause = { + .present = RANAP_Cause_PR_transmissionNetwork, + .choice.transmissionNetwork = + RANAP_CauseTransmissionNetwork_iu_transport_connection_failed_to_establish, + }; + + msg = ranap_new_msg_iu_rel_req(&cause); + msg->l2h = msg->data; + + prim = (struct osmo_scu_prim *)msgb_push(msg, sizeof(*prim)); + prim->u.data.conn_id = map->scu_conn_id; + osmo_prim_init(&prim->oph, SCCP_SAP_USER, OSMO_SCU_PRIM_N_DATA, PRIM_OP_REQUEST, msg); + osmo_sccp_user_sap_down(cn->sccp_user, &prim->oph); +} + +#define S(x) (1 << (x)) + +extern int asn1_xer_print; + +enum mgw_fsm_event { + MGW_EV_MGCP_OK, + MGW_EV_MGCP_FAIL, + MGW_EV_MGCP_TERM, + MGW_EV_RAB_ASS_RESP, + MGW_EV_RELEASE, +}; + +static const struct value_string mgw_fsm_event_names[] = { + OSMO_VALUE_STRING(MGW_EV_MGCP_OK), + OSMO_VALUE_STRING(MGW_EV_MGCP_FAIL), + OSMO_VALUE_STRING(MGW_EV_MGCP_TERM), + OSMO_VALUE_STRING(MGW_EV_RAB_ASS_RESP), + OSMO_VALUE_STRING(MGW_EV_RELEASE), + {} +}; + +enum mgw_fsm_state { + MGW_ST_CRCX_HNB, + MGW_ST_ASSIGN, + MGW_ST_MDCX_HNB, + MGW_ST_CRCX_MSC, + MGW_ST_ESTABLISHED, + MGW_ST_RELEASE, + MGW_ST_FAILURE, +}; + +struct mgw_fsm_priv { + /* Backpointer to HNBGW context */ + struct hnbgw_context_map *map; + + /* RAB-ID from RANAP RAB AssignmentRequest message */ + uint8_t rab_id; + + /* Pointers to messages and prim header we take ownership of */ + ranap_message *ranap_rab_ass_req_message; + ranap_message *ranap_rab_ass_resp_message; + struct osmo_prim_hdr *ranap_rab_ass_resp_oph; + + /* MGW context */ + struct osmo_mgcpc_ep *mgcpc_ep; + struct osmo_mgcpc_ep_ci *mgcpc_ep_ci_hnb; + struct osmo_mgcpc_ep_ci *mgcpc_ep_ci_msc; + char msc_rtp_addr[INET6_ADDRSTRLEN]; + uint16_t msc_rtp_port; +}; + +struct osmo_tdef mgw_tdefs[] = { + {.T = -2427, .default_val = 5, .desc = "timeout for MGCP response from MGW" }, + { } +}; + +struct osmo_tdef_state_timeout mgw_fsm_timeouts[32] = { + [MGW_ST_CRCX_HNB] = {.T = -1001 }, + [MGW_ST_ASSIGN] = {.T = -1002 }, + [MGW_ST_MDCX_HNB] = {.T = -1003 }, + [MGW_ST_CRCX_MSC] = {.T = -1004 }, +}; + +#define mgw_fsm_state_chg(state) \ + osmo_tdef_fsm_inst_state_chg(fi, state, mgw_fsm_timeouts, mgw_fsm_T_defs, -1) + +static void mgw_fsm_crcx_hnb_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + struct mgw_fsm_priv *mgw_fsm_priv = fi->priv; + struct hnbgw_context_map *map = mgw_fsm_priv->map; + const char *epname; + struct mgcp_conn_peer mgw_info; + + LOGPFSML(fi, LOGL_DEBUG, "RAB-AssignmentRequest received, creating HNB side call-leg on MGW...\n"); + + mgw_info = (struct mgcp_conn_peer) { + .call_id = (map->rua_ctx_id << 8) | mgw_fsm_priv->rab_id, + .ptime = 20, + .conn_mode = MGCP_CONN_LOOPBACK, + }; + mgw_info.codecs[0] = CODEC_IUFP; + mgw_info.codecs_len = 1; + + epname = mgcp_client_rtpbridge_wildcard(map->hnb_ctx->gw->mgcp_client); + mgw_fsm_priv->mgcpc_ep = + osmo_mgcpc_ep_alloc(fi, MGW_EV_MGCP_TERM, map->hnb_ctx->gw->mgcp_client, mgw_tdefs, fi->id, "%s", epname); + mgw_fsm_priv->mgcpc_ep_ci_hnb = osmo_mgcpc_ep_ci_add(mgw_fsm_priv->mgcpc_ep, "to-HNB"); + + osmo_mgcpc_ep_ci_request(mgw_fsm_priv->mgcpc_ep_ci_hnb, MGCP_VERB_CRCX, &mgw_info, fi, MGW_EV_MGCP_OK, + MGW_EV_MGCP_FAIL, NULL); +} + +static void mgw_fsm_crcx_hnb(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct mgw_fsm_priv *mgw_fsm_priv = fi->priv; + const struct mgcp_conn_peer *mgw_info; + struct osmo_sockaddr addr; + struct osmo_sockaddr_str addr_str; + RANAP_RAB_AssignmentRequestIEs_t *ies; + int rc; + + switch (event) { + case MGW_EV_MGCP_OK: + mgw_info = osmo_mgcpc_ep_ci_get_rtp_info(mgw_fsm_priv->mgcpc_ep_ci_hnb); + if (!mgw_info) { + LOGPFSML(fi, LOGL_ERROR, "Got no response from MGW\n"); + osmo_fsm_inst_state_chg(fi, MGW_ST_FAILURE, 0, 0); + return; + } + + if (strchr(mgw_info->addr, '.')) + addr_str.af = AF_INET; + else + addr_str.af = AF_INET6; + addr_str.port = mgw_info->port; + osmo_strlcpy(addr_str.ip, mgw_info->addr, sizeof(addr_str.ip)); + rc = osmo_sockaddr_str_to_sockaddr(&addr_str, &addr.u.sas); + if (rc < 0) { + LOGPFSML(fi, LOGL_ERROR, + "Failed to convert RTP IP-address (%s) and Port (%u) to its binary representation\n", + mgw_info->addr, mgw_info->port); + osmo_fsm_inst_state_chg(fi, MGW_ST_FAILURE, 0, 0); + return; + } + + ies = &mgw_fsm_priv->ranap_rab_ass_req_message->msg.raB_AssignmentRequestIEs; + rc = ranap_rab_ass_req_ies_replace_inet_addr(ies, &addr, mgw_fsm_priv->rab_id); + if (rc < 0) { + LOGPFSML(fi, LOGL_ERROR, + "Failed to replace RTP IP-address (%s) and Port (%u) in RAB-AssignmentRequest\n", + mgw_info->addr, mgw_info->port); + osmo_fsm_inst_state_chg(fi, MGW_ST_FAILURE, 0, 0); + return; + } + + mgw_fsm_state_chg(MGW_ST_ASSIGN); + return; + default: + OSMO_ASSERT(false); + } +} + +static void mgw_fsm_assign_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + struct mgw_fsm_priv *mgw_fsm_priv = fi->priv; + struct hnbgw_context_map *map = mgw_fsm_priv->map; + uint8_t encoded[IUH_MSGB_SIZE]; + RANAP_RAB_AssignmentRequestIEs_t *ies; + int rc; + + ies = &mgw_fsm_priv->ranap_rab_ass_req_message->msg.raB_AssignmentRequestIEs; + rc = ranap_rab_ass_req_encode(encoded, sizeof(encoded), ies); + if (rc < 0) { + LOGPFSML(fi, LOGL_ERROR, "failed to re-encode RAB-AssignmentRequest message\n"); + osmo_fsm_inst_state_chg(fi, MGW_ST_FAILURE, 0, 0); + return; + } + + LOGPFSML(fi, LOGL_DEBUG, "forwarding modified RAB-AssignmentRequest to HNB\n"); + rua_tx_dt(map->hnb_ctx, map->is_ps, map->rua_ctx_id, encoded, rc); +} + +static void mgw_fsm_assign(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + switch (event) { + case MGW_EV_RAB_ASS_RESP: + mgw_fsm_state_chg(MGW_ST_MDCX_HNB); + return; + default: + OSMO_ASSERT(false); + } +} + +static void mgw_fsm_mdcx_hnb_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + struct mgw_fsm_priv *mgw_fsm_priv = fi->priv; + struct hnbgw_context_map *map = mgw_fsm_priv->map; + struct hnb_context *hnb = map->hnb_ctx; + struct hnbgw_cnlink *cn = hnb->gw->sccp.cnlink; + struct mgcp_conn_peer mgw_info; + struct osmo_sockaddr addr; + struct osmo_sockaddr_str addr_str; + RANAP_RAB_AssignmentResponseIEs_t *ies; + int rc; + bool rab_failed_at_hnb; + + LOGPFSML(fi, LOGL_DEBUG, "RAB-AssignmentResponse received, completing HNB side call-leg on MGW...\n"); + + mgw_info = (struct mgcp_conn_peer) { + .call_id = map->rua_ctx_id, + .ptime = 20, + .conn_mode = MGCP_CONN_RECV_SEND, + }; + mgw_info.codecs[0] = CODEC_IUFP; + mgw_info.codecs_len = 1; + + ies = &mgw_fsm_priv->ranap_rab_ass_resp_message->msg.raB_AssignmentResponseIEs; + rc = ranap_rab_ass_resp_ies_extract_inet_addr(&addr, ies, mgw_fsm_priv->rab_id); + if (rc < 0) { + rab_failed_at_hnb = ranap_rab_ass_resp_ies_check_failure(ies, mgw_fsm_priv->rab_id); + if (rab_failed_at_hnb) { + LOGPFSML(fi, LOGL_ERROR, + "The RAB-AssignmentResponse contains a RAB-FailedList, RAB-Assignment (%u) failed.\n", + mgw_fsm_priv->rab_id); + + /* Forward the RAB-AssignmentResponse transparently. This will ensure that the MSC is informed + * about the problem. */ + LOGPFSML(fi, LOGL_DEBUG, "forwarding unmodified RAB-AssignmentResponse to MSC\n"); + rc = osmo_sccp_user_sap_down(cn->sccp_user, mgw_fsm_priv->ranap_rab_ass_resp_oph); + mgw_fsm_priv->ranap_rab_ass_resp_oph = NULL; + if (rc < 0) { + LOGPFSML(fi, LOGL_DEBUG, "failed to forward RAB-AssignmentResponse message\n"); + osmo_fsm_inst_state_chg(fi, MGW_ST_FAILURE, 0, 0); + } + + /* Even though this is a failure situation, we still release normally as the error is located + * at the HNB. */ + osmo_fsm_inst_state_chg(fi, MGW_ST_RELEASE, 0, 0); + return; + } + + /* The RAB-ID we are dealing with is not on an FailedList and we were unable to parse the response + * normally. This is a situation we cannot recover from. */ + LOGPFSML(fi, LOGL_ERROR, "Failed to extract RTP IP-address and Port from RAB-AssignmentResponse\n"); + osmo_fsm_inst_state_chg(fi, MGW_ST_FAILURE, 0, 0); + return; + } + + rc = osmo_sockaddr_str_from_sockaddr(&addr_str, &addr.u.sas); + if (rc < 0) { + LOGPFSML(fi, LOGL_ERROR, "Invalid RTP IP-address or Port in RAB-AssignmentResponse\n"); + osmo_fsm_inst_state_chg(fi, MGW_ST_FAILURE, 0, 0); + return; + } + osmo_strlcpy(mgw_info.addr, addr_str.ip, sizeof(mgw_info.addr)); + mgw_info.port = addr_str.port; + + osmo_mgcpc_ep_ci_request(mgw_fsm_priv->mgcpc_ep_ci_hnb, MGCP_VERB_MDCX, &mgw_info, fi, MGW_EV_MGCP_OK, + MGW_EV_MGCP_FAIL, NULL); +} + +static void mgw_fsm_mdcx_hnb(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct mgw_fsm_priv *mgw_fsm_priv = fi->priv; + const struct mgcp_conn_peer *mgw_info; + + switch (event) { + case MGW_EV_MGCP_OK: + mgw_info = osmo_mgcpc_ep_ci_get_rtp_info(mgw_fsm_priv->mgcpc_ep_ci_hnb); + if (!mgw_info) { + LOGPFSML(fi, LOGL_ERROR, "Got no response from MGW\n"); + osmo_fsm_inst_state_chg(fi, MGW_ST_FAILURE, 0, 0); + return; + } + mgw_fsm_state_chg(MGW_ST_CRCX_MSC); + return; + default: + OSMO_ASSERT(false); + } +} + +static void mgw_fsm_crcx_msc_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + struct mgw_fsm_priv *mgw_fsm_priv = fi->priv; + struct hnbgw_context_map *map = mgw_fsm_priv->map; + struct mgcp_conn_peer mgw_info; + + LOGPFSML(fi, LOGL_DEBUG, "creating MSC side call-leg on MGW...\n"); + + mgw_info = (struct mgcp_conn_peer) { + .call_id = (map->rua_ctx_id << 8) | mgw_fsm_priv->rab_id, + .ptime = 20, + .port = mgw_fsm_priv->msc_rtp_port, + }; + + osmo_strlcpy(mgw_info.addr, mgw_fsm_priv->msc_rtp_addr, sizeof(mgw_info.addr)); + mgw_info.codecs[0] = CODEC_IUFP; + mgw_info.codecs_len = 1; + + mgw_fsm_priv->mgcpc_ep_ci_msc = osmo_mgcpc_ep_ci_add(mgw_fsm_priv->mgcpc_ep, "to-MSC"); + osmo_mgcpc_ep_ci_request(mgw_fsm_priv->mgcpc_ep_ci_msc, MGCP_VERB_CRCX, &mgw_info, fi, MGW_EV_MGCP_OK, + MGW_EV_MGCP_FAIL, NULL); +} + +static void mgw_fsm_crcx_msc(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct mgw_fsm_priv *mgw_fsm_priv = fi->priv; + const struct mgcp_conn_peer *mgw_info; + struct osmo_sockaddr addr; + struct osmo_sockaddr_str addr_str; + int rc; + int msg_max_len; + RANAP_RAB_AssignmentResponseIEs_t *ies; + + switch (event) { + case MGW_EV_MGCP_OK: + ies = &mgw_fsm_priv->ranap_rab_ass_resp_message->msg.raB_AssignmentResponseIEs; + + mgw_info = osmo_mgcpc_ep_ci_get_rtp_info(mgw_fsm_priv->mgcpc_ep_ci_msc); + if (!mgw_info) { + LOGPFSML(fi, LOGL_ERROR, "Got no response from MGW\n"); + osmo_fsm_inst_state_chg(fi, MGW_ST_FAILURE, 0, 0); + return; + } + + /* Replace RTP IP-Address/Port in ranap message container */ + if (strchr(mgw_info->addr, '.')) + addr_str.af = AF_INET; + else + addr_str.af = AF_INET6; + addr_str.port = mgw_info->port; + osmo_strlcpy(addr_str.ip, mgw_info->addr, sizeof(addr_str.ip)); + rc = osmo_sockaddr_str_to_sockaddr(&addr_str, &addr.u.sas); + if (rc < 0) { + LOGPFSML(fi, LOGL_ERROR, + "Failed to convert RTP IP-address (%s) and Port (%u) to its binary representation\n", + mgw_info->addr, mgw_info->port); + osmo_fsm_inst_state_chg(fi, MGW_ST_FAILURE, 0, 0); + return; + } + + rc = ranap_rab_ass_resp_ies_replace_inet_addr(ies, &addr, mgw_fsm_priv->rab_id); + if (rc < 0) { + LOGPFSML(fi, LOGL_ERROR, + "Failed to replace RTP IP-address (%s) and Port (%u) in RAB-AssignmentResponse\n", + mgw_info->addr, mgw_info->port); + osmo_fsm_inst_state_chg(fi, MGW_ST_FAILURE, 0, 0); + return; + } + + /* When the modified ranap message container is re-encoded, the resulting message might be larger then + * the original message. Ensure that there is enough room in l2h to grow. (The current implementation + * should yield a message with the same size, but there is no guarantee for that) */ + msg_max_len = + msgb_l2len(mgw_fsm_priv->ranap_rab_ass_resp_oph->msg) + + msgb_tailroom(mgw_fsm_priv->ranap_rab_ass_resp_oph->msg); + rc = msgb_resize_area(mgw_fsm_priv->ranap_rab_ass_resp_oph->msg, + mgw_fsm_priv->ranap_rab_ass_resp_oph->msg->l2h, + msgb_l2len(mgw_fsm_priv->ranap_rab_ass_resp_oph->msg), msg_max_len); + OSMO_ASSERT(rc == 0); + + rc = ranap_rab_ass_resp_encode(msgb_l2(mgw_fsm_priv->ranap_rab_ass_resp_oph->msg), + msgb_l2len(mgw_fsm_priv->ranap_rab_ass_resp_oph->msg), ies); + if (rc < 0) { + LOGPFSML(fi, LOGL_ERROR, "failed to re-encode RAB-AssignmentResponse message\n"); + osmo_fsm_inst_state_chg(fi, MGW_ST_FAILURE, 0, 0); + return; + } + + /* Resize l2h back to the actual message length */ + rc = msgb_resize_area(mgw_fsm_priv->ranap_rab_ass_resp_oph->msg, + mgw_fsm_priv->ranap_rab_ass_resp_oph->msg->l2h, + msgb_l2len(mgw_fsm_priv->ranap_rab_ass_resp_oph->msg), rc); + OSMO_ASSERT(rc == 0); + + /* When the established state is entered, the modified RAB AssignmentResponse is forwarded to the MSC. + * The call is then established any way may stay for an indefinate amount of time in this state until + * there is an IU Release happening. */ + osmo_fsm_inst_state_chg(fi, MGW_ST_ESTABLISHED, 0, 0); + return; + default: + OSMO_ASSERT(false); + } +} + +static void mgw_fsm_established_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + struct mgw_fsm_priv *mgw_fsm_priv = fi->priv; + struct hnbgw_context_map *map = mgw_fsm_priv->map; + struct osmo_prim_hdr *oph = mgw_fsm_priv->ranap_rab_ass_resp_oph; + struct hnb_context *hnb = map->hnb_ctx; + struct hnbgw_cnlink *cn = hnb->gw->sccp.cnlink; + int rc; + + LOGPFSML(fi, LOGL_DEBUG, "forwarding modified RAB-AssignmentResponse to MSC\n"); + rc = osmo_sccp_user_sap_down(cn->sccp_user, oph); + mgw_fsm_priv->ranap_rab_ass_resp_oph = NULL; + if (rc < 0) { + LOGPFSML(fi, LOGL_DEBUG, "failed to forward RAB-AssignmentResponse message\n"); + osmo_fsm_inst_state_chg(fi, MGW_ST_FAILURE, 0, 0); + } + + LOGPFSML(fi, LOGL_DEBUG, "HNB and MSC side call-legs completed!\n"); +} + +static void mgw_fsm_release_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REGULAR, NULL); +} + +static void mgw_fsm_failure_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + struct mgw_fsm_priv *mgw_fsm_priv = fi->priv; + tx_release_req(mgw_fsm_priv->map); + osmo_fsm_inst_term(fi, OSMO_FSM_TERM_ERROR, NULL); +} + +static void mgw_fsm_allstate_action(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct mgw_fsm_priv *mgw_fsm_priv = fi->priv; + + switch (event) { + case MGW_EV_MGCP_TERM: + mgw_fsm_priv->mgcpc_ep = NULL; + LOGPFSML(fi, LOGL_ERROR, "Media gateway failed\n"); + osmo_fsm_inst_state_chg(fi, MGW_ST_FAILURE, 0, 0); + return; + case MGW_EV_MGCP_FAIL: + LOGPFSML(fi, LOGL_ERROR, "Media gateway failed to switch RTP streams\n"); + osmo_fsm_inst_state_chg(fi, MGW_ST_FAILURE, 0, 0); + return; + case MGW_EV_RELEASE: + osmo_fsm_inst_state_chg(fi, MGW_ST_RELEASE, 0, 0); + return; + default: + OSMO_ASSERT(false); + } +} + +static int mgw_fsm_timer_cb(struct osmo_fsm_inst *fi) +{ + osmo_fsm_inst_term(fi, OSMO_FSM_TERM_ERROR, NULL); + return 0; +} + +static void mgw_fsm_priv_cleanup(struct mgw_fsm_priv *mgw_fsm_priv) +{ + struct osmo_scu_prim *scu_prim; + struct msgb *scu_msg; + + if (mgw_fsm_priv->ranap_rab_ass_req_message) { + ranap_ran_rx_co_free(mgw_fsm_priv->ranap_rab_ass_req_message); + talloc_free(mgw_fsm_priv->ranap_rab_ass_req_message); + mgw_fsm_priv->ranap_rab_ass_req_message = NULL; + } + + if (mgw_fsm_priv->ranap_rab_ass_resp_message) { + ranap_cn_rx_co_free(mgw_fsm_priv->ranap_rab_ass_resp_message); + talloc_free(mgw_fsm_priv->ranap_rab_ass_resp_message); + mgw_fsm_priv->ranap_rab_ass_resp_message = NULL; + } + + if (mgw_fsm_priv->ranap_rab_ass_resp_oph) { + scu_prim = (struct osmo_scu_prim *)mgw_fsm_priv->ranap_rab_ass_resp_oph; + scu_msg = scu_prim->oph.msg; + msgb_free(scu_msg); + mgw_fsm_priv->ranap_rab_ass_resp_oph = NULL; + } + + talloc_free(mgw_fsm_priv); +} + +static void mgw_fsm_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause) +{ + struct mgw_fsm_priv *mgw_fsm_priv = fi->priv; + mgw_fsm_priv_cleanup(mgw_fsm_priv); +} + +static void mgw_fsm_pre_term(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause) +{ + struct mgw_fsm_priv *mgw_fsm_priv = fi->priv; + struct hnbgw_context_map *map = mgw_fsm_priv->map; + + if (mgw_fsm_priv->mgcpc_ep) { + osmo_mgcpc_ep_clear(mgw_fsm_priv->mgcpc_ep); + mgw_fsm_priv->mgcpc_ep = NULL; + } + + /* Remove FSM from the context map. This will make this FSM unreachable for events coming from outside */ + map->mgw_fi = NULL; +} + +static const struct osmo_fsm_state mgw_fsm_states[] = { + [MGW_ST_CRCX_HNB] = { + .name = "MGW_ST_CRCX_HNB", + .onenter = mgw_fsm_crcx_hnb_onenter, + .action = mgw_fsm_crcx_hnb, + .in_event_mask = + S(MGW_EV_MGCP_OK), + .out_state_mask = + S(MGW_ST_ASSIGN) | + S(MGW_ST_FAILURE) | + S(MGW_ST_RELEASE) | + S(MGW_ST_CRCX_HNB), + }, + [MGW_ST_ASSIGN] = { + .name = "MGW_ST_ASSIGN", + .onenter = mgw_fsm_assign_onenter, + .action = mgw_fsm_assign, + .in_event_mask = S(MGW_EV_RAB_ASS_RESP), + .out_state_mask = + S(MGW_ST_MDCX_HNB) | + S(MGW_ST_FAILURE) | + S(MGW_ST_RELEASE), + }, + [MGW_ST_MDCX_HNB] = { + .name = "MGW_ST_MDCX_HNB", + .onenter = mgw_fsm_mdcx_hnb_onenter, + .action = mgw_fsm_mdcx_hnb, + .in_event_mask = + S(MGW_EV_MGCP_OK), + .out_state_mask = + S(MGW_ST_CRCX_MSC) | + S(MGW_ST_FAILURE) | + S(MGW_ST_RELEASE), + }, + [MGW_ST_CRCX_MSC] = { + .name = "MGW_ST_CRCX_MSC", + .onenter = mgw_fsm_crcx_msc_onenter, + .action = mgw_fsm_crcx_msc, + .in_event_mask = + S(MGW_EV_MGCP_OK), + .out_state_mask = + S(MGW_ST_ESTABLISHED) | + S(MGW_ST_FAILURE) | + S(MGW_ST_RELEASE), + }, + [MGW_ST_ESTABLISHED] = { + .name = "MGW_ST_ESTABLISHED", + .onenter = mgw_fsm_established_onenter, + .in_event_mask = 0, + .out_state_mask = + S(MGW_ST_FAILURE) | + S(MGW_ST_RELEASE), + }, + [MGW_ST_RELEASE] = { + .name = "MGW_ST_RELEASE", + .onenter = mgw_fsm_release_onenter, + .in_event_mask = 0, + .out_state_mask = 0, + }, + [MGW_ST_FAILURE] = { + .name = "MGW_ST_FAILURE", + .onenter = mgw_fsm_failure_onenter, + .in_event_mask = 0, + .out_state_mask = 0, + }, +}; + +static struct osmo_fsm mgw_fsm = { + .name = "mgw", + .states = mgw_fsm_states, + .num_states = ARRAY_SIZE(mgw_fsm_states), + .log_subsys = DMGW, + .event_names = mgw_fsm_event_names, + .allstate_action = mgw_fsm_allstate_action, + .allstate_event_mask = S(MGW_EV_MGCP_TERM) | S(MGW_EV_RELEASE) | S(MGW_EV_MGCP_FAIL), + .timer_cb = mgw_fsm_timer_cb, + .cleanup = mgw_fsm_cleanup, + .pre_term = mgw_fsm_pre_term, +}; + +/* The MSC may ask to release a specific RAB within a RAB-AssignmentRequest */ +static int handle_rab_release(struct hnbgw_context_map *map, struct osmo_prim_hdr *oph, ranap_message *message) +{ + bool rab_release_req; + struct osmo_fsm_inst *fi = map->mgw_fi; + struct mgw_fsm_priv *mgw_fsm_priv = fi->priv; + int rc; + + /* Check if the RAB that is handled by this FSM is addressed by the release request */ + rab_release_req = ranap_rab_ass_req_ies_check_release(&message->msg.raB_AssignmentRequestIEs, + mgw_fsm_priv->rab_id); + if (!rab_release_req) + return -EINVAL; + + LOGPFSML(map->mgw_fi, LOGL_NOTICE, "MSC asked to release RAB-ID %u\n", mgw_fsm_priv->rab_id); + + /* Forward the unmodifed RAB-AssignmentRequest to HNB, so that the HNB is informed about the RAB release as + * well */ + LOGPFSML(fi, LOGL_DEBUG, "forwarding unmodified RAB-AssignmentRequest to HNB\n"); + rc = rua_tx_dt(map->hnb_ctx, map->is_ps, map->rua_ctx_id, msgb_l2(oph->msg), msgb_l2len(oph->msg)); + + /* Release the FSM normally */ + osmo_fsm_inst_state_chg(fi, MGW_ST_RELEASE, 0, 0); + + return rc; +} + +/*! Allocate MGW FSM and handle RANAP RAB AssignmentRequest). + * \ptmap[in] map hanbgw context map that is responsible for this call. + * \ptmap[in] oph osmo prim header with RANAP RAB AssignmentResponse (function takes no ownership). + * \ptmap[in] message ranap message container (function takes ownership). + * \returns 0 on success; negative on error. */ +int handle_rab_ass_req(struct hnbgw_context_map *map, struct osmo_prim_hdr *oph, ranap_message *message) +{ + static bool initialized = false; + struct osmo_fsm_inst *fi; + struct mgw_fsm_priv *mgw_fsm_priv; + struct osmo_sockaddr addr; + struct osmo_sockaddr_str addr_str; + RANAP_RAB_AssignmentRequestIEs_t *ies; + int rc; + char fsm_name[255]; + + /* Initialize FSM if not done yet */ + if (!initialized) { + OSMO_ASSERT(osmo_fsm_register(&mgw_fsm) == 0); + initialized = true; + } + + /* The RTP stream negortiation usually begins with a RAB-AssignmentRequest and ends with an IU-Release, however + * it may also be thet the MSC decides to release the RAB with a dedicated RAB-AssignmentRequest that contains + * a ReleaseList. In this case an FSM will already be present. */ + if (map->mgw_fi) { + /* A RAB Release might be in progress, handle it */ + rc = handle_rab_release(map, oph, message); + if (rc >= 0) + return rc; + + LOGPFSML(map->mgw_fi, LOGL_ERROR, + "mgw_fsm_alloc_and_handle_rab_ass_req() unable to handle RAB-AssignmentRequest!\n"); + osmo_fsm_inst_state_chg(fi, MGW_ST_FAILURE, 0, 0); + } + + mgw_fsm_priv = talloc_zero(map, struct mgw_fsm_priv); + mgw_fsm_priv->ranap_rab_ass_req_message = message; + + /* Parse the RAB Assignment Request now, if it is bad for some reason we will exit early and not bother with + * creating an FSM etc. */ + ies = &mgw_fsm_priv->ranap_rab_ass_req_message->msg.raB_AssignmentRequestIEs; + rc = ranap_rab_ass_req_ies_extract_inet_addr(&addr, &mgw_fsm_priv->rab_id, ies, 0); + if (rc < 0) { + LOGP(DMGW, LOGL_ERROR, + "mgw_fsm_alloc_and_handle_rab_ass_req() rua_ctx_id=%d, invalid RAB-AssignmentRequest -- abort!\n", + map->rua_ctx_id); + goto error; + } + + rc = osmo_sockaddr_str_from_sockaddr(&addr_str, &addr.u.sas); + if (rc < 0) { + LOGP(DMGW, LOGL_ERROR, + "mgw_fsm_alloc_and_handle_rab_ass_req() rua_ctx_id=%d, Invalid RTP IP-address or Port in RAB-AssignmentRequest -- abort\n", + map->rua_ctx_id); + goto error; + } + osmo_strlcpy(mgw_fsm_priv->msc_rtp_addr, addr_str.ip, sizeof(mgw_fsm_priv->msc_rtp_addr)); + mgw_fsm_priv->msc_rtp_port = addr_str.port; + + /* Allocate the FSM and start it. */ + mgw_fsm_priv->map = map; + snprintf(fsm_name, sizeof(fsm_name), "mgw-fsm-%u-%u", map->rua_ctx_id, mgw_fsm_priv->rab_id); + fi = osmo_fsm_inst_alloc(&mgw_fsm, map, mgw_fsm_priv, LOGL_DEBUG, fsm_name); + map->mgw_fi = fi; + mgw_fsm_state_chg(MGW_ST_CRCX_HNB); + + return 0; +error: + /* TODO: If we fail in this early stage, we should generate an appropriate RAB AssignmentResponse to inform + * the core network about the failure. */ + mgw_fsm_priv_cleanup(mgw_fsm_priv); + return -EINVAL; +} + +/*! Handlie RANAP RAB AssignmentResponse (deliver message, complete RTP stream switching). + * \ptmap[in] map hanbgw context map that is responsible for this call. + * \ptmap[in] oph osmo prim header with RANAP RAB AssignmentResponse (function takes ownership). + * \ptmap[in] message ranap message container with decoded ranap message (function takes ownership). + * \returns 0 on success; negative on error. */ +int mgw_fsm_handle_rab_ass_resp(struct hnbgw_context_map *map, struct osmo_prim_hdr *oph, ranap_message *message) +{ + struct mgw_fsm_priv *mgw_fsm_priv; + struct osmo_scu_prim *prim; + struct msgb *msg; + + OSMO_ASSERT(oph); + + if (!map->mgw_fi) { + /* NOTE: This situation is a corner-case. We may end up here when the co-located MGW caused a problem + * on the way between RANAP RAB Assignment Request and RANAP RAB Assignment Response. */ + + LOGP(DMGW, LOGL_ERROR, + "mgw_fsm_handle_rab_ass_resp() rua_ctx_id=%d, no MGW fsm -- sending Iu-Release-Request!\n", + map->rua_ctx_id); + + /* Cleanup ranap message */ + ranap_cn_rx_co_free(message); + talloc_free(message); + + /* Toss RAB-AssignmentResponse */ + prim = (struct osmo_scu_prim *)oph; + msg = prim->oph.msg; + msgb_free(msg); + + /* Send a release request, to make sure that the MSC is aware of the problem. */ + tx_release_req(map); + } + + mgw_fsm_priv = map->mgw_fi->priv; + mgw_fsm_priv->ranap_rab_ass_resp_oph = oph; + mgw_fsm_priv->ranap_rab_ass_resp_message = message; + osmo_fsm_inst_dispatch(map->mgw_fi, MGW_EV_RAB_ASS_RESP, NULL); + return 0; +} + +/*! Release the FSM and clear its associated RTP streams. + * \ptmap[in] map hanbgw context map that is responsible for this call. + * \returns 0 on success; negative on error. */ +int mgw_fsm_release(struct hnbgw_context_map *map) +{ + if (!map->mgw_fi) { + LOGP(DMGW, LOGL_ERROR, "mgw_fsm_release() rua_ctx_id=%d, no MGW fsm -- ignored!\n", map->rua_ctx_id); + return -EINVAL; + } + + osmo_fsm_inst_dispatch(map->mgw_fi, MGW_EV_RELEASE, NULL); + return 0; +} diff --git a/src/osmo-hnbgw/tdefs.c b/src/osmo-hnbgw/tdefs.c new file mode 100644 index 0000000..d8198f2 --- /dev/null +++ b/src/osmo-hnbgw/tdefs.c @@ -0,0 +1,30 @@ +/* (C) 2021 by sysmocom s.f.m.c. GmbH info@sysmocom.de + * All Rights Reserved + * + * Author: Philipp Maier + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 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 General Public License for more details. + */ + +#include <osmocom/hnbgw/tdefs.h> + +struct osmo_tdef mgw_fsm_T_defs[] = { + {.T = -1001, .default_val = 5, .desc = "Timeout for HNB side call-leg (to-HNB) creation" }, + {.T = -1002, .default_val = 10, .desc = "Timeout for the HNB to respond to RAB Assignment Request" }, + {.T = -1003, .default_val = 5, .desc = "Timeout for HNB side call-leg (to-HNB) completion" }, + {.T = -1004, .default_val = 5, .desc = "Timeout for MSC side call-leg (to-MSC) completion" }, + { } +}; + +struct osmo_tdef_group hnbgw_tdef_group[] = { + {.name = "mgw", .tdefs = mgw_fsm_T_defs, .desc = "MGW (Media Gateway) interface" }, + { } +};