aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPau Espin Pedrol <pespin@sysmocom.de>2022-08-08 13:50:39 +0200
committerPau Espin Pedrol <pespin@sysmocom.de>2022-09-13 17:37:35 +0200
commitd8b5bf08e8089ad7d8fc1194e5a247cdb261a476 (patch)
tree64636b95fac72d166dfea3b378cb5cb10e9232ed
parentb2c7d0ab32ba31cc401daf53c2170e06574b929d (diff)
Add Osmux support on the Abis-side data plane
-rw-r--r--TODO-RELEASE1
-rw-r--r--include/osmocom/bsc/bts.h3
-rw-r--r--include/osmocom/bsc/lchan.h6
-rw-r--r--src/osmo-bsc/abis_rsl.c27
-rw-r--r--src/osmo-bsc/bts.c9
-rw-r--r--src/osmo-bsc/bts_vty.c42
-rw-r--r--src/osmo-bsc/lchan_rtp_fsm.c29
7 files changed, 111 insertions, 6 deletions
diff --git a/TODO-RELEASE b/TODO-RELEASE
index d0852fc9b..f172501ae 100644
--- a/TODO-RELEASE
+++ b/TODO-RELEASE
@@ -7,3 +7,4 @@
# If any interfaces have been added since the last public release: c:r:a + 1.
# If any interfaces have been removed or changed since the last public release: c:r:0.
#library what description / commit summary line
+libosmogsm >1.7.0 BTS_FEAT_OSMUX, RSL_IE_OSMO_OSMUX_CID
diff --git a/include/osmocom/bsc/bts.h b/include/osmocom/bsc/bts.h
index 752a00a73..b690652f3 100644
--- a/include/osmocom/bsc/bts.h
+++ b/include/osmocom/bsc/bts.h
@@ -590,6 +590,9 @@ struct gsm_bts {
struct amr_multirate_conf mr_full;
struct amr_multirate_conf mr_half;
+ /* osmux config: */
+ enum osmux_usage use_osmux;
+
/* PCU socket state */
char *pcu_sock_path;
struct pcu_sock_state *pcu_state;
diff --git a/include/osmocom/bsc/lchan.h b/include/osmocom/bsc/lchan.h
index a6048c26b..2de1227a7 100644
--- a/include/osmocom/bsc/lchan.h
+++ b/include/osmocom/bsc/lchan.h
@@ -299,6 +299,12 @@ struct gsm_lchan {
uint8_t rr_cause;
bool valid;
} ass_compl;
+
+ struct {
+ bool use;
+ uint8_t local_cid;
+ uint8_t remote_cid;
+ } osmux;
} abis_ip;
/* At first, the Timing Advance from the initial Channel Request. Later, the Timing Advance value received from
diff --git a/src/osmo-bsc/abis_rsl.c b/src/osmo-bsc/abis_rsl.c
index 8ec94a91d..1c60405c4 100644
--- a/src/osmo-bsc/abis_rsl.c
+++ b/src/osmo-bsc/abis_rsl.c
@@ -2739,11 +2739,15 @@ static void ipac_parse_rtp(struct gsm_lchan *lchan, struct tlv_parsed *tv, const
port = ntohs(port);
lchan->abis_ip.connect_port = port;
}
+ if (TLVP_PRESENT(tv, RSL_IE_OSMO_OSMUX_CID)) {
+ lchan->abis_ip.osmux.remote_cid = tlvp_val8(tv, RSL_IE_OSMO_OSMUX_CID, 0);
+ }
LOG_LCHAN(lchan, LOGL_DEBUG, "Rx IPACC %s ACK:"
- " BTS=%s:%u conn_id=%u rtp_payload2=0x%02x speech_mode=0x%02x\n",
+ " BTS=%s:%u conn_id=%u rtp_payload2=0x%02x speech_mode=0x%02x osmux_use=%d osmux_loc_cid=%d\n",
label, ip_to_a(lchan->abis_ip.bound_ip), lchan->abis_ip.bound_port,
- lchan->abis_ip.conn_id, lchan->abis_ip.rtp_payload2, lchan->abis_ip.speech_mode);
+ lchan->abis_ip.conn_id, lchan->abis_ip.rtp_payload2, lchan->abis_ip.speech_mode,
+ lchan->abis_ip.osmux.use, lchan->abis_ip.osmux.local_cid);
}
/*! Send Issue IPA RSL CRCX to configure the RTP port of the BTS.
@@ -2768,9 +2772,13 @@ int rsl_tx_ipacc_crcx(const struct gsm_lchan *lchan)
/* 0x1- == receive-only, 0x-1 == EFR codec */
msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
+ if (lchan->abis_ip.osmux.use)
+ msgb_tlv_put(msg, RSL_IE_OSMO_OSMUX_CID, 1, &lchan->abis_ip.osmux.local_cid);
- LOG_LCHAN(lchan, LOGL_DEBUG, "Sending IPACC CRCX to BTS: speech_mode=0x%02x RTP_PAYLOAD=%d\n",
- lchan->abis_ip.speech_mode, lchan->abis_ip.rtp_payload);
+ LOG_LCHAN(lchan, LOGL_DEBUG,
+ "Sending IPACC CRCX to BTS: speech_mode=0x%02x RTP_PAYLOAD=%d osmux_use=%d osmux_loc_cid=%d\n",
+ lchan->abis_ip.speech_mode, lchan->abis_ip.rtp_payload,
+ lchan->abis_ip.osmux.use, lchan->abis_ip.osmux.local_cid);
msg->dst = rsl_chan_link(lchan);
@@ -2808,6 +2816,8 @@ struct msgb *rsl_make_ipacc_mdcx(const struct gsm_lchan *lchan, uint32_t dest_ip
msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
if (lchan->abis_ip.rtp_payload2)
msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD2, lchan->abis_ip.rtp_payload2);
+ if (lchan->abis_ip.osmux.use)
+ msgb_tlv_put(msg, RSL_IE_OSMO_OSMUX_CID, 1, &lchan->abis_ip.osmux.local_cid);
msg->dst = rsl_chan_link(lchan);
@@ -2865,6 +2875,15 @@ static int abis_rsl_rx_ipacc_crcx_ack(struct msgb *msg)
return -EINVAL;
}
+ if (!lchan->abis_ip.osmux.use && TLVP_PRESENT(&tv, RSL_IE_OSMO_OSMUX_CID)) {
+ LOGP(DRSL, LOGL_NOTICE, "Received unexpected IE Osmux CID\n");
+ return -EINVAL;
+ }
+ if (lchan->abis_ip.osmux.use && !TLVP_PRESENT(&tv, RSL_IE_OSMO_OSMUX_CID)) {
+ LOGP(DRSL, LOGL_NOTICE, "Mandatory IE Osmux CID missing\n");
+ return -EINVAL;
+ }
+
ipac_parse_rtp(lchan, &tv, "CRCX");
osmo_fsm_inst_dispatch(lchan->fi_rtp, LCHAN_RTP_EV_IPACC_CRCX_ACK, 0);
diff --git a/src/osmo-bsc/bts.c b/src/osmo-bsc/bts.c
index 4976fe660..95e7430b1 100644
--- a/src/osmo-bsc/bts.c
+++ b/src/osmo-bsc/bts.c
@@ -428,6 +428,8 @@ struct gsm_bts *gsm_bts_alloc(struct gsm_network *net, struct gsm_bts_sm *bts_sm
memcpy(&bts->mr_half.bts_mode[0], &amr_hr_ms_bts_mode[0], sizeof(amr_hr_ms_bts_mode));
bts->mr_half.num_modes = ARRAY_SIZE(amr_hr_ms_bts_mode);
+ bts->use_osmux = OSMUX_USAGE_OFF;
+
bts_cbch_init(bts);
bts_etws_init(bts);
@@ -507,6 +509,13 @@ int gsm_bts_check_cfg(struct gsm_bts *bts)
bts_gprs_mode_name(bts->gprs.mode));
return -EINVAL;
}
+ if (bts->use_osmux == OSMUX_USAGE_ONLY &&
+ !osmo_bts_has_feature(&bts->features, BTS_FEAT_OSMUX)) {
+ LOGP(DNM, LOGL_ERROR,
+ "(bts=%u) osmux use set to 'only', but BTS does not support Osmux\n",
+ bts->nr);
+ return -EINVAL;
+ }
}
/* Verify the physical channel mapping */
diff --git a/src/osmo-bsc/bts_vty.c b/src/osmo-bsc/bts_vty.c
index 492cb9a5b..39007685f 100644
--- a/src/osmo-bsc/bts_vty.c
+++ b/src/osmo-bsc/bts_vty.c
@@ -2965,6 +2965,42 @@ DEFUN_USRATTR(cfg_bts_amr_hr_hyst3,
return check_amr_config(vty);
}
+#define OSMUX_STR "RTP multiplexing\n"
+DEFUN_USRATTR(cfg_bts_osmux,
+ cfg_bts_osmux_cmd,
+ X(BSC_VTY_ATTR_NEW_LCHAN),
+ "osmux (on|off|only)",
+ OSMUX_STR "Enable OSMUX\n" "Disable OSMUX\n" "Only use OSMUX\n")
+{
+ struct gsm_bts *bts = vty->index;
+ enum osmux_usage use;
+
+ if (strcmp(argv[0], "off") == 0)
+ use = OSMUX_USAGE_OFF;
+ else if (strcmp(argv[0], "on") == 0)
+ use = OSMUX_USAGE_ON;
+ else if (strcmp(argv[0], "only") == 0)
+ use = OSMUX_USAGE_ONLY;
+ else
+ goto err;
+
+ if (!is_osmobts(bts))
+ goto err;
+
+ if (bts->features_known && use != OSMUX_USAGE_OFF &&
+ !osmo_bts_has_feature(&bts->features, BTS_FEAT_OSMUX))
+ goto err;
+
+ bts->use_osmux = use;
+ return CMD_SUCCESS;
+
+err:
+ LOGP(DNM, LOGL_ERROR,
+ "(bts=%u) Unable to set 'osmux %s', BTS does not support Osmux\n",
+ bts->nr, argv[0]);
+ return CMD_WARNING;
+}
+
#define TNUM_STR "T-number, optionally preceded by 't' or 'T'\n"
DEFUN_ATTR(cfg_bts_t3113_dynamic, cfg_bts_t3113_dynamic_cmd,
"timer-dynamic TNNNN",
@@ -4512,6 +4548,11 @@ static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts)
config_write_bts_amr(vty, bts, &bts->mr_full, 1);
config_write_bts_amr(vty, bts, &bts->mr_half, 0);
+ if (bts->use_osmux != OSMUX_USAGE_OFF) {
+ vty_out(vty, " osmux %s%s", bts->use_osmux == OSMUX_USAGE_ON ? "on" : "only",
+ VTY_NEWLINE);
+ }
+
config_write_bts_gprs(vty, bts);
if (bts->excl_from_rf_lock)
@@ -4773,6 +4814,7 @@ int bts_vty_init(void)
install_element(BTS_NODE, &cfg_bts_amr_hr_hyst2_cmd);
install_element(BTS_NODE, &cfg_bts_amr_hr_hyst3_cmd);
install_element(BTS_NODE, &cfg_bts_amr_hr_start_mode_cmd);
+ install_element(BTS_NODE, &cfg_bts_osmux_cmd);
install_element(BTS_NODE, &cfg_bts_pcu_sock_cmd);
install_element(BTS_NODE, &cfg_bts_acc_rotate_cmd);
install_element(BTS_NODE, &cfg_bts_acc_rotate_quantum_cmd);
diff --git a/src/osmo-bsc/lchan_rtp_fsm.c b/src/osmo-bsc/lchan_rtp_fsm.c
index 504bb342e..87c235f36 100644
--- a/src/osmo-bsc/lchan_rtp_fsm.c
+++ b/src/osmo-bsc/lchan_rtp_fsm.c
@@ -138,9 +138,10 @@ static void lchan_rtp_fsm_wait_mgw_endpoint_available_onenter(struct osmo_fsm_in
uint32_t prev_state)
{
struct gsm_lchan *lchan = lchan_rtp_fi_lchan(fi);
+ struct gsm_bts *bts = lchan->ts->trx->bts;
struct osmo_mgcpc_ep *mgwep;
struct osmo_mgcpc_ep_ci *use_mgwep_ci = lchan_use_mgw_endpoint_ci_bts(lchan);
- struct mgcp_conn_peer crcx_info = {};
+ struct mgcp_conn_peer crcx_info;
if (!is_ipaccess_bts(lchan->ts->trx->bts)) {
LOG_LCHAN_RTP(lchan, LOGL_DEBUG, "Audio link to-BTS via E1, skipping IPACC\n");
@@ -163,13 +164,20 @@ static void lchan_rtp_fsm_wait_mgw_endpoint_available_onenter(struct osmo_fsm_in
lchan->mgw_endpoint_ci_bts = osmo_mgcpc_ep_ci_add(mgwep, "to-BTS");
+ crcx_info = (struct mgcp_conn_peer){
+ .ptime = 20,
+ .x_osmo_osmux_use = bts->use_osmux != OSMUX_USAGE_OFF,
+ .x_osmo_osmux_cid = -1, /* -1 is wildcard */
+ };
if (lchan->conn) {
crcx_info.call_id = lchan->conn->sccp.conn_id;
if (lchan->conn->sccp.msc)
crcx_info.x_osmo_ign = lchan->conn->sccp.msc->x_osmo_ign;
}
- crcx_info.ptime = 20;
mgcp_pick_codec(&crcx_info, lchan, true);
+ /* TODO: lchan_rtp_fail() here if crcx_info->codecs[] contains non-AMR and bts->use_osmux=ONLY.
+ If bts->use_osmux=ON, only set .x_osmo_osmux_use if there's an AMR in crcx_info->codecs[].
+ IF osmux=no, always set x_osmo_osmux_use=false*/
osmo_mgcpc_ep_ci_request(lchan->mgw_endpoint_ci_bts, MGCP_VERB_CRCX, &crcx_info,
fi, LCHAN_RTP_EV_MGW_ENDPOINT_AVAILABLE, LCHAN_RTP_EV_MGW_ENDPOINT_ERROR,
@@ -179,11 +187,26 @@ static void lchan_rtp_fsm_wait_mgw_endpoint_available_onenter(struct osmo_fsm_in
static void lchan_rtp_fsm_wait_mgw_endpoint_available(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
struct gsm_lchan *lchan = lchan_rtp_fi_lchan(fi);
+ struct gsm_bts *bts = lchan->ts->trx->bts;
switch (event) {
case LCHAN_RTP_EV_MGW_ENDPOINT_AVAILABLE:
LOG_LCHAN_RTP(lchan, LOGL_DEBUG, "MGW endpoint: %s\n",
osmo_mgcpc_ep_ci_name(lchan_use_mgw_endpoint_ci_bts(lchan)));
+ if (osmo_mgcpc_ep_ci_get_crcx_info_to_osmux_cid(lchan->mgw_endpoint_ci_bts,
+ &lchan->abis_ip.osmux.local_cid)) {
+ if (bts->use_osmux == OSMUX_USAGE_OFF) {
+ lchan_rtp_fail("Got Osmux CID from MGW but we didn't ask for it");
+ return;
+ }
+ lchan->abis_ip.osmux.use = true;
+ } else {
+ if (bts->use_osmux == OSMUX_USAGE_ONLY) {
+ lchan_rtp_fail("Got no Osmux CID from MGW but Osmux is mandatory");
+ return;
+ }
+ lchan->abis_ip.osmux.use = false;
+ }
lchan_rtp_fsm_state_chg(LCHAN_RTP_ST_WAIT_LCHAN_READY);
return;
@@ -415,6 +438,8 @@ static void connect_mgw_endpoint_to_lchan(struct osmo_fsm_inst *fi,
mdcx_info = (struct mgcp_conn_peer){
.port = to_lchan->abis_ip.bound_port,
.ptime = 20,
+ .x_osmo_osmux_use = lchan->abis_ip.osmux.use,
+ .x_osmo_osmux_cid = lchan->abis_ip.osmux.remote_cid,
};
mgcp_pick_codec(&mdcx_info, to_lchan, true);