diff --git a/src/libmsc/gsm_04_08_cc.c b/src/libmsc/gsm_04_08_cc.c index e65fecbcf..cfa511742 100644 --- a/src/libmsc/gsm_04_08_cc.c +++ b/src/libmsc/gsm_04_08_cc.c @@ -768,6 +768,19 @@ void gsm48_cc_rx_setup_cn_local_rtp_port_known(struct gsm_trans *trans) mncc_recvmsg(trans->net, trans, MNCC_SETUP_IND, &setup); } +static bool codecs_match(const struct sdp_audio_codec *a, const struct sdp_audio_codec *b) +{ + if (!sdp_audio_codec_cmp(a, b, true, false)) + return true; + + /* Codecs are not identical. But will the MGW be able to transcode? */ + if (!strcmp("AMR", a->subtype_name) && !strcmp("AMR", b->subtype_name)) { + /* TODO: compare matching mode-set. */ + return true; + } + return false; +} + static void rx_mncc_sdp(struct gsm_trans *trans, uint32_t mncc_msg_type, const char *sdp, const struct gsm_mncc_bearer_cap *bcap) { @@ -814,15 +827,14 @@ static void rx_mncc_sdp(struct gsm_trans *trans, uint32_t mncc_msg_type, const c /* Assume that the remote side put its actually assigned codec in first place. If our assigned codec doesn't * match that, continue re-assignment below. If they do match, exit here to leave as-is. - * I'm not sure if this is common practice, or just a workaround: we cannot dynamically switch between all of - * the payload types, but we still want to communicate all supported codecs. Maybe the proper way to tell the - * other side to use a single codec is to leave only that single codec in the SDP; but at least MO *must* send - * all possible codecs along, to give MT a chance to find a good match. Maybe MO should offer all supported - * codecs, but MT should limit to a single pick -- but what do other SDP peers do, say via SIP? */ - if (!sdp_audio_codec_cmp(&trans->cc.remote.audio_codecs.codec[0], &codecs->assignment, true, false)) { - /* remote's first codec matches our assigned codec. All is well. */ + * I'm not sure if assuming the special role for the codec that is listed first is common practice, or just a + * workaround: we cannot dynamically switch between all of the payload types, but we still want to communicate + * all supported codecs. Maybe the proper way to tell the other side to use a single codec is to leave only that + * single codec in the SDP; but at least MO *must* send all possible codecs along, to give MT a chance to find a + * good match. Maybe MO should offer all supported codecs, but MT should limit to a single pick -- but what do + * other SDP peers do, say via SIP? */ + if (codecs_match(&trans->cc.remote.audio_codecs.codec[0], &codecs->assignment)) return; - } /* We've already completed Assignment of a voice channel (some time ago), and now the remote side has changed * to a mismatching codec (list). Try to re-assign this side to a matching codec. */ diff --git a/tests/msc_vlr/msc_vlr_test_call.c b/tests/msc_vlr/msc_vlr_test_call.c index b959bc1c4..97be00adf 100644 --- a/tests/msc_vlr/msc_vlr_test_call.c +++ b/tests/msc_vlr/msc_vlr_test_call.c @@ -1258,10 +1258,12 @@ static const struct codec_test codec_tests[] = { .mt_tx_sdp_mncc_alert_ind = SDP_CODECS_ALL_GSM_AMR_HR_FIRST, /* mo_rx_sdp_mncc_alert_req == mt_tx_sdp_mncc_alert_ind */ + /* .mo_expect_reassignment = true, .mo_tx_reassignment_perm_speech = PERM_SPEECH_ALL_GSM_HR3_FIRST, .mo_rx_reassigned_codec_fr = false, .mo_rx_reassigned_codec = "AMR:octet-align=1;mode-set=0,2,4", + */ .mt_tx_sdp_mncc_setup_cnf = SDP_CODECS_ALL_GSM_AMR_HR_FIRST, .mo_tx_sdp_mncc_setup_compl_ind = {},