mgcp_codec: be sensitive about IuFP when checking codecs

When two codecs are checked for convertibility we insist that
subtype_name and rate are equal since normally when those are different,
we assume a completely different codec that will require a transcoder,
which we do not have yet.

However when IuFP is used, the call agent will always negotiate IuFP as
VND.3GPP.IUFP with a rate of 16000, even though the IuFP payloads
contain regular AMR at a rate of 8000.

This means that if we detect IuFP on one side of the call leg and AMR on
the other side of the call leg, we must not insist on equal subtype_name
and rate.

This fixes the following TTCN3 testcases:
MGCP_Test.TC_two_crcx_mdcx_and_iuup_rtp
MGCP_Test.TC_two_crcx_mdcx_and_iuup_rtp_rfci_unordered

Related: OS#5461
Change-Id: I6bc1e6022efe21cb893ef213f3da35017960357d
This commit is contained in:
Philipp Maier 2023-05-23 13:58:38 +02:00
parent 3d0676a791
commit f5a01ce1b5
1 changed files with 13 additions and 2 deletions

View File

@ -330,9 +330,20 @@ static bool codecs_convertible(struct mgcp_rtp_codec *codec_a, struct mgcp_rtp_c
/* OsmoMGW currently has no ability to transcode from one codec to another. However OsmoMGW is still able to
* translate between different payload formats as long as the encoded voice data itself does not change.
* Therefore we must insist on equal codecs but still allow different payload formatting. */
if (strcmp(codec_a->subtype_name, codec_b->subtype_name))
bool iufp = false;
/* In 3G IuUP AMR may be encapsulated in IuFP, this means even though the codec name and negotiated rate is
* different, the formatting can still be converted by OsmoMGW. Therefore we won't insist on equal
* subtype_name and rate if we detect IuFP and AMR is used on the same tandem. */
if (strcmp(codec_a->subtype_name, "AMR") == 0 && strcmp(codec_b->subtype_name, "VND.3GPP.IUFP") == 0)
iufp = true;
if (strcmp(codec_a->subtype_name, "VND.3GPP.IUFP") == 0 && strcmp(codec_b->subtype_name, "AMR") == 0)
iufp = true;
if (!iufp && strcmp(codec_a->subtype_name, codec_b->subtype_name))
return false;
if (codec_a->rate != codec_b->rate)
if (!iufp && codec_a->rate != codec_b->rate)
return false;
if (codec_a->channels != codec_b->channels)
return false;