Add Osmux support on the Abis-side data plane
Related: SYS#5987 Change-Id: I48483b278ff829ee29d3e7fbcab0dd3a54728825
This commit is contained in:
parent
b2c7d0ab32
commit
d8b5bf08e8
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue