This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/OpenBSC@lists.osmocom.org/.
msuraev at sysmocom.de msuraev at sysmocom.deFrom: Max <msuraev at sysmocom.de> In case both TCH/H and TCH/F are configured and internal MNCC handler is used we might end up in a situation where call legs with incompatible channel types would be connected resulting in a broken audio. Disconnect such calls with appropriate error message. Fixes: OS#1663 --- openbsc/src/libmsc/gsm_04_08.c | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c index 7b78d48..2507d74 100644 --- a/openbsc/src/libmsc/gsm_04_08.c +++ b/openbsc/src/libmsc/gsm_04_08.c @@ -1614,6 +1614,14 @@ static int tch_map(struct gsm_lchan *lchan, struct gsm_lchan *remote_lchan) return -EINVAL; } + if (lt != rt) { + LOGP(DCC, LOGL_ERROR, "Cannot patch through call with different" + " channel types: local = %s, remote = %s\n", + get_value_string(gsm_chan_t_names, lt), + get_value_string(gsm_chan_t_names, rt)); + return -EBADSLT; + } + // todo: map between different bts types switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: @@ -1851,6 +1859,30 @@ static void gsm48_cc_timeout(void *arg) } +/* disconnect both calls from the bridge */ +static inline void disconnect_bridge(struct gsm_network *net, + struct gsm_mncc_bridge *bridge, int err) +{ + struct gsm_trans *trans0 = trans_find_by_callref(net, bridge->callref[0]); + struct gsm_trans *trans1 = trans_find_by_callref(net, bridge->callref[1]); + struct gsm_mncc mx_rel; + if (!trans0 || !trans1) + return; + + DEBUGP(DCC, "Failed to bridge TCH for calls %x <-> %x :: %s \n", + trans0->callref, trans1->callref, strerror(err)); + + memset(&mx_rel, 0, sizeof(struct gsm_mncc)); + mncc_set_cause(&mx_rel, GSM48_CAUSE_LOC_INN_NET, + GSM48_CC_CAUSE_CHAN_UNACCEPT); + + mx_rel.callref = trans0->callref; + gsm48_cc_tx_disconnect(trans0, &mx_rel); + + mx_rel.callref = trans1->callref; + gsm48_cc_tx_disconnect(trans1, &mx_rel); +} + static void gsm48_start_cc_timer(struct gsm_trans *trans, int current, int sec, int micro) { @@ -3221,7 +3253,10 @@ int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg) /* handle special messages */ switch(msg_type) { case MNCC_BRIDGE: - return tch_bridge(net, arg); + rc = tch_bridge(net, arg); + if (rc < 0) + disconnect_bridge(net, arg, -rc); + return rc; case MNCC_FRAME_DROP: return tch_recv_mncc(net, data->callref, 0); case MNCC_FRAME_RECV: -- 2.7.4