Change-Id: I974a02ecf8f280177c0ad616a05bb2aabf0d54ff
This commit is contained in:
Neels Hofmeyr 2024-02-22 19:40:41 +01:00
parent 757f793a9a
commit f5a7003d86
14 changed files with 95 additions and 81 deletions

View File

@ -75,7 +75,7 @@ int call_leg_local_bridge(struct call_leg *cl1, uint32_t call_id1, struct gsm_tr
int call_leg_ensure_rtp_alloc(struct call_leg *cl, enum rtp_direction dir, uint32_t call_id,
struct gsm_trans *for_trans);
int call_leg_ensure_ci(struct call_leg *cl, enum rtp_direction dir, uint32_t call_id, struct gsm_trans *for_trans,
const struct sdp_audio_codecs *codecs_if_known,
const struct osmo_sdp_codec_list *codecs_if_known,
const struct osmo_sockaddr_str *remote_addr_if_known);
struct osmo_sockaddr_str *call_leg_local_ip(struct call_leg *cl, enum rtp_direction dir);

View File

@ -32,19 +32,19 @@ struct gsm0808_speech_codec_list;
* Call codec_filter_run() and obtain the resulting set of codecs in codec_filter.result. */
struct codec_filter {
/* The fixed set of codecs available on the RAN type, per definition. */
struct sdp_audio_codecs ran;
struct osmo_sdp_codec_list *ran;
/* The codecs advertised by the MS Bearer Capabilities */
struct sdp_audio_codecs ms;
struct osmo_sdp_codec_list *ms;
/* If known, the set of codecs the current RAN cell allows / has available.
* This may not be available if the BSC does not issue this information early enough.
* Should be ignored if empty. */
struct sdp_audio_codecs bss;
struct osmo_sdp_codec_list *bss;
/* After a channel was assigned, this reflects the chosen codec. */
struct sdp_audio_codec assignment;
struct osmo_sdp_codec *assignment;
};
void codec_filter_set_ran(struct codec_filter *codec_filter, const struct sdp_audio_codecs *codecs);
void codec_filter_set_ran(struct codec_filter *codec_filter, const struct osmo_sdp_codec_list *codecs);
void codec_filter_set_bss(struct codec_filter *codec_filter,
const struct gsm0808_speech_codec_list *codec_list_bss_supported);
int codec_filter_run(struct codec_filter *codec_filter, struct osmo_sdp_msg *result, const struct osmo_sdp_msg *remote);

View File

@ -20,7 +20,7 @@ enum codec_frhr {
struct codec_mapping {
/* The sdp.payload_type number in a mapping is not necessarily imperative, but may just reflect the usual
* payload type number for a given codec. */
struct sdp_audio_codec sdp;
struct osmo_sdp_codec sdp;
/* The id that mgcp_client.h uses for this codec. Must be set in each mapping, because 0 means PCMU. */
enum mgcp_codecs mgcp;
/* Nr of used entries in speech_ver[] below. */
@ -78,19 +78,19 @@ const struct codec_mapping *codec_mapping_by_subtype_name(const char *subtype_na
const struct codec_mapping *codec_mapping_by_mgcp_codec(enum mgcp_codecs mgcp);
int bearer_cap_add_speech_ver(struct gsm_mncc_bearer_cap *bearer_cap, enum gsm48_bcap_speech_ver speech_ver);
int sdp_audio_codec_add_to_bearer_cap(struct gsm_mncc_bearer_cap *bearer_cap, const struct sdp_audio_codec *codec);
int sdp_audio_codecs_to_bearer_cap(struct gsm_mncc_bearer_cap *bearer_cap, const struct sdp_audio_codecs *ac);
int sdp_audio_codec_add_to_bearer_cap(struct gsm_mncc_bearer_cap *bearer_cap, const struct osmo_sdp_codec *codec);
int sdp_audio_codecs_to_bearer_cap(struct gsm_mncc_bearer_cap *bearer_cap, const struct osmo_sdp_codec_list *ac);
int bearer_cap_set_radio(struct gsm_mncc_bearer_cap *bearer_cap);
struct sdp_audio_codec *sdp_audio_codecs_add_speech_ver(struct sdp_audio_codecs *ac,
struct osmo_sdp_codec *sdp_audio_codecs_add_speech_ver(struct osmo_sdp_codec_list *ac,
enum gsm48_bcap_speech_ver speech_ver);
struct sdp_audio_codec *sdp_audio_codecs_add_mgcp_codec(struct sdp_audio_codecs *ac, enum mgcp_codecs mgcp_codec);
void sdp_audio_codecs_from_bearer_cap(struct sdp_audio_codecs *ac, const struct gsm_mncc_bearer_cap *bc);
struct osmo_sdp_codec *sdp_audio_codecs_add_mgcp_codec(struct osmo_sdp_codec_list *ac, enum mgcp_codecs mgcp_codec);
void sdp_audio_codecs_from_bearer_cap(struct osmo_sdp_codec_list *ac, const struct gsm_mncc_bearer_cap *bc);
int sdp_audio_codec_to_speech_codec_list(struct gsm0808_speech_codec_list *scl, const struct sdp_audio_codec *codec);
void sdp_audio_codecs_to_speech_codec_list(struct gsm0808_speech_codec_list *cl, const struct sdp_audio_codecs *ac);
void sdp_audio_codecs_from_speech_codec_list(struct sdp_audio_codecs *ac, const struct gsm0808_speech_codec_list *cl);
int sdp_audio_codec_to_speech_codec_list(struct gsm0808_speech_codec_list *scl, const struct osmo_sdp_codec *codec);
void sdp_audio_codecs_to_speech_codec_list(struct gsm0808_speech_codec_list *cl, const struct osmo_sdp_codec_list *ac);
void sdp_audio_codecs_from_speech_codec_list(struct osmo_sdp_codec_list *ac, const struct gsm0808_speech_codec_list *cl);
int sdp_audio_codecs_to_gsm0808_channel_type(struct gsm0808_channel_type *ct, const struct sdp_audio_codecs *ac);
int sdp_audio_codecs_to_gsm0808_channel_type(struct gsm0808_channel_type *ct, const struct osmo_sdp_codec_list *ac);
enum mgcp_codecs sdp_audio_codec_to_mgcp_codec(const struct sdp_audio_codec *codec);
enum mgcp_codecs sdp_audio_codec_to_mgcp_codec(const struct osmo_sdp_codec *codec);

View File

@ -45,7 +45,8 @@ struct csd_filter {
};
void csd_filter_set_ran(struct csd_filter *filter, enum osmo_rat_type ran_type);
int csd_filter_run(struct csd_filter *filter, struct osmo_sdp_msg *result, const struct osmo_sdp_msg *remote);
int csd_filter_run(struct csd_filter *filter, struct osmo_sdp_msg *sdp_result, struct csd_bs_list *bs_result,
const struct csd_bs_list *remote);
int csd_filter_to_str_buf(char *buf, size_t buflen, const struct csd_filter *filter,
const struct osmo_sdp_msg *result, const struct osmo_sdp_msg *remote);

View File

@ -92,7 +92,7 @@ struct msc_ho_state {
struct {
/* Saved RTP IP:port and codec in case we need to roll back */
struct osmo_sockaddr_str ran_remote_rtp;
struct sdp_audio_codecs codecs;
struct sdp_codec_list *codecs;
} old_cell;
};

View File

@ -28,11 +28,11 @@ struct ran_infra {
struct sccp_ran_inst *sri;
/* Codecs available on this RAN type by default, in order of preference. If empty, all known codecs will be
* allowed and offered to peers. */
struct sdp_audio_codecs codecs;
struct osmo_sdp_codec_list *codecs;
/* To always set up the MGW endpoint facing the RAN side with specific codecs, list those here. Otherwise leave
* empty (to use the result of codecs filtering). This exists for IuCS, to always set the MGW endpoint facing
* RAN to IUFP, to decapsulate the IuUP headers. */
struct sdp_audio_codecs force_mgw_codecs_to_ran;
struct osmo_sdp_codec_list *force_mgw_codecs_to_ran;
};
extern struct ran_infra msc_ran_infra[];

View File

@ -40,7 +40,7 @@ struct rtp_stream {
bool remote_sent_to_mgw;
bool codecs_known;
struct sdp_audio_codecs codecs;
struct osmo_sdp_codec_list *codecs;
bool codecs_sent_to_mgw;
struct osmo_mgcpc_ep_ci *ci;
@ -69,8 +69,8 @@ int rtp_stream_ensure_ci(struct rtp_stream *rtps, struct osmo_mgcpc_ep *at_endpo
int rtp_stream_do_mdcx(struct rtp_stream *rtps);
bool rtp_stream_set_codecs_from_mgcp_codec(struct rtp_stream *rtps, enum mgcp_codecs codec);
void rtp_stream_set_one_codec(struct rtp_stream *rtps, const struct sdp_audio_codec *codec);
void rtp_stream_set_codecs(struct rtp_stream *rtps, const struct sdp_audio_codecs *codecs);
void rtp_stream_set_one_codec(struct rtp_stream *rtps, const struct osmo_sdp_codec *codec);
void rtp_stream_set_codecs(struct rtp_stream *rtps, const struct osmo_sdp_codec_list *codecs);
void rtp_stream_set_mode(struct rtp_stream *rtps, enum mgcp_connection_mode mode);
void rtp_stream_set_remote_addr(struct rtp_stream *rtps, const struct osmo_sockaddr_str *r);
void rtp_stream_set_remote_addr_and_codecs(struct rtp_stream *rtps, const struct osmo_sdp_msg *sdp);

View File

@ -3,4 +3,4 @@
#include <osmocom/sdp/sdp_msg.h>
#include <osmocom/msc/csd_bs.h>
void sdp_audio_codecs_set_csd(struct osmo_sdp_codec_list *ac);
void sdp_codecs_set_csd(void *ctx, struct osmo_sdp_codec_list *codecs);

View File

@ -333,7 +333,7 @@ struct osmo_sockaddr_str *call_leg_local_ip(struct call_leg *cl, enum rtp_direct
* MDCX.
*/
int call_leg_ensure_ci(struct call_leg *cl, enum rtp_direction dir, uint32_t call_id, struct gsm_trans *for_trans,
const struct sdp_audio_codecs *codecs_if_known,
const struct osmo_sdp_codec_list *codecs_if_known,
const struct osmo_sockaddr_str *remote_addr_if_known)
{
if (call_leg_ensure_rtp_alloc(cl, dir, call_id, for_trans))
@ -353,7 +353,7 @@ int call_leg_ensure_ci(struct call_leg *cl, enum rtp_direction dir, uint32_t cal
int call_leg_local_bridge(struct call_leg *cl1, uint32_t call_id1, struct gsm_trans *trans1,
struct call_leg *cl2, uint32_t call_id2, struct gsm_trans *trans2)
{
struct sdp_audio_codecs *cn_codecs = NULL;
struct osmo_sdp_codec_list *cn_codecs = NULL;
cl1->local_bridge = cl2;
cl2->local_bridge = cl1;
@ -381,9 +381,9 @@ int call_leg_local_bridge(struct call_leg *cl1, uint32_t call_id1, struct gsm_tr
* ^MGW-endpoint converts payload type numbers between 112 and 96.
*/
if (cl1->rtp[RTP_TO_CN] && cl1->rtp[RTP_TO_CN]->codecs_known)
cn_codecs = &cl1->rtp[RTP_TO_CN]->codecs;
cn_codecs = cl1->rtp[RTP_TO_CN]->codecs;
else if (cl2->rtp[RTP_TO_CN] && cl2->rtp[RTP_TO_CN]->codecs_known)
cn_codecs = &cl2->rtp[RTP_TO_CN]->codecs;
cn_codecs = cl2->rtp[RTP_TO_CN]->codecs;
if (!cn_codecs) {
LOG_CALL_LEG(cl1, LOGL_ERROR, "RAN-side CN stream codec is not known, not ready for bridging\n");
LOG_CALL_LEG(cl2, LOGL_ERROR, "RAN-side CN stream codec is not known, not ready for bridging\n");

View File

@ -28,49 +28,65 @@
#include <osmocom/msc/ran_infra.h>
#include <osmocom/msc/debug.h>
void codec_filter_set_ran(struct codec_filter *codec_filter, const struct sdp_audio_codecs *codecs)
static void ensure_empty_list(void *ctx, struct osmo_sdp_codec_list **codecs)
{
const struct sdp_audio_codec *c;
codec_filter->ran = (struct sdp_audio_codecs){};
if (*codecs)
osmo_sdp_codec_list_free_items(*codecs);
else
*codecs = osmo_sdp_codec_list_alloc(ctx);
}
void codec_filter_set_ran(struct codec_filter *codec_filter, const struct osmo_sdp_codec_list *codecs)
{
const struct osmo_sdp_codec *c;
ensure_empty_list(codec_filter, &codec_filter->ran);
/* Add codecs one by one, to resolve any payload type number conflicts or duplicates. */
sdp_audio_codecs_foreach (c, codecs)
sdp_audio_codecs_add_copy(&codec_filter->ran, c, true, true);
osmo_sdp_codec_list_foreach (c, codecs)
osmo_sdp_codec_list_add(codec_filter->ran, c, &osmo_sdp_codec_cmp_equivalent, true);
}
void codec_filter_set_bss(struct codec_filter *codec_filter,
const struct gsm0808_speech_codec_list *codec_list_bss_supported)
{
codec_filter->bss = (struct sdp_audio_codecs){};
ensure_empty_list(codec_filter, &codec_filter->bss);
if (codec_list_bss_supported)
sdp_audio_codecs_from_speech_codec_list(&codec_filter->bss, codec_list_bss_supported);
sdp_audio_codecs_from_speech_codec_list(codec_filter->bss, codec_list_bss_supported);
}
/* Render intersections of all known audio codec constraints to reach a resulting choice of favorite audio codec, plus
* possible set of alternative audio codecs, in codec_filter->result. (The result.rtp address remains unchanged.) */
int codec_filter_run(struct codec_filter *codec_filter, struct osmo_sdp_msg *result, const struct osmo_sdp_msg *remote)
{
struct sdp_audio_codecs *r = &result->audio_codecs;
struct sdp_audio_codec *a = &codec_filter->assignment;
*r = codec_filter->ran;
if (codec_filter->ms.count)
sdp_audio_codecs_intersection(r, &codec_filter->ms, false);
if (codec_filter->bss.count)
sdp_audio_codecs_intersection(r, &codec_filter->bss, false);
if (remote->audio_codecs.count)
sdp_audio_codecs_intersection(r, &remote->audio_codecs, true);
struct osmo_sdp_codec_list *r;
struct osmo_sdp_codec *c;
struct osmo_sdp_codec *a = codec_filter->assignment;
if (sdp_audio_codec_is_set(a)) {
ensure_empty_list(result, &result->codecs);
r = result->codecs;
osmo_sdp_codec_list_foreach (c, codec_filter->ran) {
osmo_sdp_codec_list_add(r, c, &osmo_sdp_codec_cmp_equivalent, true);
}
if (!osmo_sdp_codec_list_is_empty(codec_filter->ms))
osmo_sdp_codec_list_intersection(r, codec_filter->ms, &osmo_sdp_codec_cmp_equivalent, false);
if (!osmo_sdp_codec_list_is_empty(codec_filter->bss))
osmo_sdp_codec_list_intersection(r, codec_filter->bss, &osmo_sdp_codec_cmp_equivalent, false);
if (!osmo_sdp_codec_list_is_empty(remote->codecs))
osmo_sdp_codec_list_intersection(r, remote->codecs, &osmo_sdp_codec_cmp_equivalent, false);
if (osmo_sdp_codec_is_set(a)) {
/* Assignment has completed, the chosen codec should be the first of the resulting SDP.
* If present, make sure this is listed in first place.
* If the assigned codec is not present in the intersection of possible choices for TrFO, just omit the
* assigned codec from the filter result, and it is the CC code's responsibility to detect this and
* assign a working codec instead. */
sdp_audio_codecs_select(r, a);
} else if (remote && remote->audio_codecs.count) {
osmo_sdp_codec_list_move_to_first(r, a, &osmo_sdp_codec_cmp_equivalent);
} else if (remote && !osmo_sdp_codec_list_is_empty(remote->codecs)) {
/* If we haven't assigned yet, favor remote's first pick. Assume that the remote side has placed its
* favorite codec up first. Remote may already have assigned a codec, and picking a different one might
* trigger a change of codec mode (Re-Assignment). So try to adhere to the first codec listed. */
sdp_audio_codecs_select(r, &remote->audio_codecs.codec[0]);
osmo_sdp_codec_list_move_to_first(r, osmo_sdp_codec_list_first(remote->codecs),
&osmo_sdp_codec_cmp_equivalent);
}
return 0;
}
@ -82,9 +98,9 @@ int codec_filter_to_str_buf(char *buf, size_t buflen, const struct codec_filter
OSMO_STRBUF_APPEND(sb, sdp_msg_to_str_buf, result);
OSMO_STRBUF_PRINTF(sb, " (from:");
if (sdp_audio_codec_is_set(&codec_filter->assignment)) {
if (osmo_sdp_codec_is_set(&codec_filter->assignment)) {
OSMO_STRBUF_PRINTF(sb, " assigned=");
OSMO_STRBUF_APPEND(sb, sdp_audio_codec_to_str_buf, &codec_filter->assignment);
OSMO_STRBUF_APPEND(sb, osmo_sdp_codec_to_str_buf, &codec_filter->assignment);
}
if (remote->audio_codecs.count
@ -95,18 +111,18 @@ int codec_filter_to_str_buf(char *buf, size_t buflen, const struct codec_filter
if (codec_filter->ms.count) {
OSMO_STRBUF_PRINTF(sb, " MS={");
OSMO_STRBUF_APPEND(sb, sdp_audio_codecs_to_str_buf, &codec_filter->ms);
OSMO_STRBUF_APPEND(sb, osmo_sdp_codec_list_to_str_buf, &codec_filter->ms);
OSMO_STRBUF_PRINTF(sb, "}");
}
if (codec_filter->bss.count) {
OSMO_STRBUF_PRINTF(sb, " bss={");
OSMO_STRBUF_APPEND(sb, sdp_audio_codecs_to_str_buf, &codec_filter->bss);
OSMO_STRBUF_APPEND(sb, osmo_sdp_codec_list_to_str_buf, &codec_filter->bss);
OSMO_STRBUF_PRINTF(sb, "}");
}
OSMO_STRBUF_PRINTF(sb, " RAN={");
OSMO_STRBUF_APPEND(sb, sdp_audio_codecs_to_str_buf, &codec_filter->ran);
OSMO_STRBUF_APPEND(sb, osmo_sdp_codec_list_to_str_buf, &codec_filter->ran);
OSMO_STRBUF_PRINTF(sb, "}");
OSMO_STRBUF_PRINTF(sb, ")");

View File

@ -39,7 +39,7 @@ static const struct codec_mapping codec_map[] = {
{
.sdp = {
.payload_type = 0,
.subtype_name = "PCMU",
.encoding_name = "PCMU",
.rate = 8000,
},
.mgcp = CODEC_PCMU_8000_1,
@ -47,7 +47,7 @@ static const struct codec_mapping codec_map[] = {
{
.sdp = {
.payload_type = 3,
.subtype_name = "GSM",
.encoding_name = "GSM",
.rate = 8000,
},
.mgcp = CODEC_GSM_8000_1,
@ -65,7 +65,7 @@ static const struct codec_mapping codec_map[] = {
{
.sdp = {
.payload_type = 8,
.subtype_name = "PCMA",
.encoding_name = "PCMA",
.rate = 8000,
},
.mgcp = CODEC_PCMA_8000_1,
@ -73,7 +73,7 @@ static const struct codec_mapping codec_map[] = {
{
.sdp = {
.payload_type = 18,
.subtype_name = "G729",
.encoding_name = "G729",
.rate = 8000,
},
.mgcp = CODEC_G729_8000_1,
@ -81,7 +81,7 @@ static const struct codec_mapping codec_map[] = {
{
.sdp = {
.payload_type = 110,
.subtype_name = "GSM-EFR",
.encoding_name = "GSM-EFR",
.rate = 8000,
},
.mgcp = CODEC_GSMEFR_8000_1,
@ -99,7 +99,7 @@ static const struct codec_mapping codec_map[] = {
{
.sdp = {
.payload_type = 111,
.subtype_name = "GSM-HR-08",
.encoding_name = "GSM-HR-08",
.rate = 8000,
},
.mgcp = CODEC_GSMHR_8000_1,
@ -120,7 +120,7 @@ static const struct codec_mapping codec_map[] = {
{ \
.sdp = { \
.payload_type = 112, \
.subtype_name = "AMR", \
.encoding_name = "AMR", \
.rate = 8000, \
.fmtp = FMTP, \
}, \
@ -146,7 +146,7 @@ static const struct codec_mapping codec_map[] = {
{ \
.sdp = { \
.payload_type = 112, \
.subtype_name = "AMR", \
.encoding_name = "AMR", \
.rate = 8000, \
.fmtp = FMTP, \
}, \
@ -226,7 +226,7 @@ static const struct codec_mapping codec_map[] = {
{
.sdp = {
.payload_type = 113,
.subtype_name = "AMR-WB",
.encoding_name = "AMR-WB",
.rate = 16000,
.fmtp = OSMO_SDP_STR_AMR_OCTET_ALIGN_1,
},
@ -246,7 +246,7 @@ static const struct codec_mapping codec_map[] = {
{
.sdp = {
.payload_type = 96,
.subtype_name = "VND.3GPP.IUFP",
.encoding_name = "VND.3GPP.IUFP",
.rate = 16000,
},
.mgcp = CODEC_IUFP,
@ -254,7 +254,7 @@ static const struct codec_mapping codec_map[] = {
{
.sdp = {
.payload_type = 120,
.subtype_name = "CLEARMODE",
.encoding_name = "CLEARMODE",
.rate = 8000,
},
.has_gsm0808_speech_codec = true,
@ -368,11 +368,11 @@ const struct codec_mapping *codec_mapping_by_perm_speech(enum gsm0808_permitted_
return NULL;
}
const struct codec_mapping *codec_mapping_by_subtype_name(const char *subtype_name)
const struct codec_mapping *codec_mapping_by_encoding_name(const char *encoding_name)
{
const struct codec_mapping *m;
codec_mapping_foreach(m) {
if (!strcmp(m->sdp.subtype_name, subtype_name))
if (!strcmp(m->sdp.encoding_name, encoding_name))
return m;
}
return NULL;
@ -579,7 +579,7 @@ void sdp_audio_codecs_from_speech_codec_list(struct sdp_audio_codecs *ac, const
codec_mapping_foreach (m) {
if (!codec_mapping_matches_gsm0808_speech_codec(m, sc))
continue;
sdp_audio_codecs_add_copy(ac, &m->sdp, true, true);
osmo_sdp_codec_list_add(ac, &m->sdp, &osmo_sdp_codec_cmp_equivalent, true);
}
}
}

View File

@ -75,9 +75,10 @@ void csd_filter_set_ran(struct csd_filter *filter, enum osmo_rat_type ran_type)
}
}
int csd_filter_run(struct csd_filter *filter, struct osmo_sdp_msg *result, const struct osmo_sdp_msg *remote)
int csd_filter_run(struct csd_filter *filter, struct osmo_sdp_msg *sdp_result, struct csd_bs_list *bs_result,
const struct csd_bs_list *remote)
{
struct csd_bs_list *r = &result->bearer_services;
struct csd_bs_list *r = bs_result;
enum csd_bs a = filter->assignment;
*r = filter->ran;
@ -86,8 +87,8 @@ int csd_filter_run(struct csd_filter *filter, struct osmo_sdp_msg *result, const
csd_bs_list_intersection(r, &filter->ms);
if (filter->bss.count)
csd_bs_list_intersection(r, &filter->bss);
if (remote->bearer_services.count)
csd_bs_list_intersection(r, &remote->bearer_services);
if (remote->count)
csd_bs_list_intersection(r, remote);
/* Future: If osmo-msc were able to trigger a re-assignment [...] see
* comment in codec_filter_run(). */
@ -97,13 +98,7 @@ int csd_filter_run(struct csd_filter *filter, struct osmo_sdp_msg *result, const
csd_bs_list_add_bs(r, a);
}
result->audio_codecs.count = 1;
result->audio_codecs.codec[0] = (struct sdp_audio_codec){
.payload_type = CODEC_CLEARMODE,
.subtype_name = "CLEARMODE",
.rate = 8000,
};
sdp_codecs_set_csd(sdp_result, &result->codecs);
return 0;
}

View File

@ -21,8 +21,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <osmocom/msc/sdp_msg.h>
static const struct osmo_sdp_codec codec_csd = {
.payload_type = 120,
.payload_type = CODEC_CLEARMODE,
.encoding_name = "CLEARMODE",
.rate = 8000,
};

View File

@ -58,7 +58,7 @@ void _trans_cc_filter_run(const char *file, int line, struct gsm_trans *trans)
case GSM48_BCAP_ITCAP_3k1_AUDIO:
case GSM48_BCAP_ITCAP_FAX_G3:
case GSM48_BCAP_ITCAP_UNR_DIG_INF:
csd_filter_run(&trans->cc.csd, &trans->cc.local, &trans->cc.remote);
csd_filter_run(&trans->cc.csd, &trans->cc.local, &trans->cc.csd_bs, &trans->cc.remote);
LOG_TRANS_CAT_SRC(trans, DCC, LOGL_DEBUG, file, line, "codec/BS: %s\n",
csd_filter_to_str(&trans->cc.csd, &trans->cc.local, &trans->cc.remote));
break;