aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/osmocom/msc/call_leg.h4
-rw-r--r--include/osmocom/msc/msc_ho.h4
-rw-r--r--include/osmocom/msc/rtp_stream.h11
-rw-r--r--src/libmsc/call_leg.c19
-rw-r--r--src/libmsc/gsm_04_08_cc.c10
-rw-r--r--src/libmsc/mncc_call.c13
-rw-r--r--src/libmsc/msc_a.c50
-rw-r--r--src/libmsc/msc_ho.c20
-rw-r--r--src/libmsc/msc_t.c4
-rw-r--r--src/libmsc/rtp_stream.c94
-rw-r--r--tests/msc_vlr/msc_vlr_test_call.err50
-rw-r--r--tests/msc_vlr/msc_vlr_tests.c14
12 files changed, 187 insertions, 106 deletions
diff --git a/include/osmocom/msc/call_leg.h b/include/osmocom/msc/call_leg.h
index a225b6683..c7d3b9739 100644
--- a/include/osmocom/msc/call_leg.h
+++ b/include/osmocom/msc/call_leg.h
@@ -12,6 +12,7 @@ struct gsm_network;
struct gsm_trans;
struct rtp_stream;
enum rtp_direction;
+struct sdp_audio_codecs;
extern struct osmo_tdef g_mgw_tdefs[];
@@ -74,7 +75,8 @@ 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 enum mgcp_codecs *codec_if_known, const struct osmo_sockaddr_str *remote_addr_if_known);
+ const struct sdp_audio_codecs *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);
void call_leg_rtp_stream_gone(struct call_leg *cl, struct rtp_stream *rtps);
diff --git a/include/osmocom/msc/msc_ho.h b/include/osmocom/msc/msc_ho.h
index 99956f1e6..a3f60c7f2 100644
--- a/include/osmocom/msc/msc_ho.h
+++ b/include/osmocom/msc/msc_ho.h
@@ -31,7 +31,7 @@
#include <osmocom/msc/neighbor_ident.h>
#include <osmocom/msc/ran_msg.h>
#include <osmocom/msc/mncc_call.h>
-
+#include <osmocom/msc/sdp_msg.h>
struct gsm0808_handover_required;
@@ -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;
- enum mgcp_codecs codec;
+ struct sdp_audio_codecs codecs;
} old_cell;
};
diff --git a/include/osmocom/msc/rtp_stream.h b/include/osmocom/msc/rtp_stream.h
index c53c4f179..afc5725f9 100644
--- a/include/osmocom/msc/rtp_stream.h
+++ b/include/osmocom/msc/rtp_stream.h
@@ -5,6 +5,7 @@
#include <osmocom/core/sockaddr_str.h>
#include <osmocom/mgcp_client/mgcp_client.h>
+#include <osmocom/msc/sdp_msg.h>
struct gsm_trans;
@@ -37,9 +38,9 @@ struct rtp_stream {
struct osmo_sockaddr_str remote;
bool remote_sent_to_mgw;
- bool codec_known;
- enum mgcp_codecs codec;
- bool codec_sent_to_mgw;
+ bool codecs_known;
+ struct sdp_audio_codecs codecs;
+ bool codecs_sent_to_mgw;
struct osmo_mgcpc_ep_ci *ci;
@@ -64,7 +65,9 @@ struct rtp_stream *rtp_stream_alloc(struct call_leg *parent_call_leg, enum rtp_d
int rtp_stream_ensure_ci(struct rtp_stream *rtps, struct osmo_mgcpc_ep *at_endpoint);
int rtp_stream_do_mdcx(struct rtp_stream *rtps);
-void rtp_stream_set_codec(struct rtp_stream *rtps, enum mgcp_codecs codec);
+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_remote_addr(struct rtp_stream *rtps, const struct osmo_sockaddr_str *r);
void rtp_stream_set_remote_osmux_cid(struct rtp_stream *rtps, uint8_t osmux_cid);
int rtp_stream_commit(struct rtp_stream *rtps);
diff --git a/src/libmsc/call_leg.c b/src/libmsc/call_leg.c
index 03c988205..a8c5c4118 100644
--- a/src/libmsc/call_leg.c
+++ b/src/libmsc/call_leg.c
@@ -324,14 +324,15 @@ struct osmo_sockaddr_str *call_leg_local_ip(struct call_leg *cl, enum rtp_direct
/* Make sure an MGW endpoint CI is set up for an RTP connection.
* This is the one-stop for all to either completely set up a new endpoint connection, or to modify an existing one.
* If not yet present, allocate the rtp_stream for the given direction.
- * Then, call rtp_stream_set_codec() if codec_if_known is non-NULL, and/or rtp_stream_set_remote_addr() if
+ * Then, call rtp_stream_set_codecs() if codecs_if_known is non-NULL, and/or rtp_stream_set_remote_addr() if
* remote_addr_if_known is non-NULL.
* Finally make sure that a CRCX is sent out for this direction, if this has not already happened.
* If the CRCX has already happened but new codec / remote_addr data was passed, call rtp_stream_commit() to trigger an
* MDCX.
*/
int call_leg_ensure_ci(struct call_leg *cl, enum rtp_direction dir, uint32_t call_id, struct gsm_trans *for_trans,
- const enum mgcp_codecs *codec_if_known, const struct osmo_sockaddr_str *remote_addr_if_known)
+ const struct sdp_audio_codecs *codecs_if_known,
+ const struct osmo_sockaddr_str *remote_addr_if_known)
{
if (call_leg_ensure_rtp_alloc(cl, dir, call_id, for_trans))
return -EIO;
@@ -340,8 +341,8 @@ int call_leg_ensure_ci(struct call_leg *cl, enum rtp_direction dir, uint32_t cal
cl->rtp[dir]->use_osmux = true;
cl->rtp[dir]->remote_osmux_cid = -1; /* wildcard */
}
- if (codec_if_known)
- rtp_stream_set_codec(cl->rtp[dir], *codec_if_known);
+ if (codecs_if_known)
+ rtp_stream_set_codecs(cl->rtp[dir], codecs_if_known);
if (remote_addr_if_known && osmo_sockaddr_str_is_nonzero(remote_addr_if_known))
rtp_stream_set_remote_addr(cl->rtp[dir], remote_addr_if_known);
return rtp_stream_ensure_ci(cl->rtp[dir], cl->mgw_endpoint);
@@ -350,25 +351,25 @@ 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)
{
- enum mgcp_codecs codec;
+ struct sdp_audio_codecs *codecs;
cl1->local_bridge = cl2;
cl2->local_bridge = cl1;
/* We may just copy the codec info we have for the RAN side of the first leg to the CN side of both legs. This
* also means that if both legs use different codecs the MGW must perform transcoding on the second leg. */
- if (!cl1->rtp[RTP_TO_RAN] || !cl1->rtp[RTP_TO_RAN]->codec_known) {
+ if (!cl1->rtp[RTP_TO_RAN] || !cl1->rtp[RTP_TO_RAN]->codecs_known) {
LOG_CALL_LEG(cl1, LOGL_ERROR, "RAN-side RTP stream codec is not known, not ready for bridging\n");
return -EINVAL;
}
- codec = cl1->rtp[RTP_TO_RAN]->codec;
+ codecs = &cl1->rtp[RTP_TO_RAN]->codecs;
if (!cl1->rtp[RTP_TO_CN] || !cl2->rtp[RTP_TO_CN])
return -ENOTCONN;
call_leg_ensure_ci(cl1, RTP_TO_CN, call_id1, trans1,
- &codec, &cl2->rtp[RTP_TO_CN]->local);
+ codecs, &cl2->rtp[RTP_TO_CN]->local);
call_leg_ensure_ci(cl2, RTP_TO_CN, call_id2, trans2,
- &codec, &cl1->rtp[RTP_TO_CN]->local);
+ codecs, &cl1->rtp[RTP_TO_CN]->local);
return 0;
}
diff --git a/src/libmsc/gsm_04_08_cc.c b/src/libmsc/gsm_04_08_cc.c
index 4a484bb14..269fd5709 100644
--- a/src/libmsc/gsm_04_08_cc.c
+++ b/src/libmsc/gsm_04_08_cc.c
@@ -1822,18 +1822,18 @@ int gsm48_tch_rtp_create(struct gsm_trans *trans)
return -EINVAL;
}
- if (!rtp_cn->codec_known) {
+ if (!rtp_cn->codecs_known) {
LOG_TRANS_CAT(trans, DMNCC, LOGL_ERROR,
"Cannot RTP CREATE to MNCC, no codec set up for the RTP CN side\n");
return -EINVAL;
}
/* Codec */
- m = codec_mapping_by_mgcp_codec(rtp_cn->codec);
+ m = codec_mapping_by_subtype_name(rtp_cn->codecs.codec[0].subtype_name);
if (!m) {
LOG_TRANS_CAT(trans, DMNCC, LOGL_ERROR,
"Cannot RTP CREATE to MNCC, cannot resolve codec '%s'\n",
- osmo_mgcpc_codec_name(rtp_cn->codec));
+ sdp_audio_codec_to_str(&rtp_cn->codecs.codec[0]));
return -EINVAL;
}
payload_msg_type = m->mncc_payload_msg_type;
@@ -1841,9 +1841,9 @@ int gsm48_tch_rtp_create(struct gsm_trans *trans)
/* Payload Type number */
mgcp_info = osmo_mgcpc_ep_ci_get_rtp_info(rtp_cn->ci);
if (mgcp_info && mgcp_info->ptmap_len)
- payload_type = map_codec_to_pt(mgcp_info->ptmap, mgcp_info->ptmap_len, rtp_cn->codec);
+ payload_type = map_codec_to_pt(mgcp_info->ptmap, mgcp_info->ptmap_len, m->mgcp);
else
- payload_type = rtp_cn->codec;
+ payload_type = m->mgcp;
rtp_cn_local = call_leg_local_ip(cl, RTP_TO_CN);
if (!rtp_cn_local) {
diff --git a/src/libmsc/mncc_call.c b/src/libmsc/mncc_call.c
index fbf96f387..1cf0c3d2d 100644
--- a/src/libmsc/mncc_call.c
+++ b/src/libmsc/mncc_call.c
@@ -263,14 +263,14 @@ static bool mncc_call_rx_rtp_create(struct mncc_call *mncc_call)
return true;
}
- if (!mncc_call->rtps->codec_known) {
+ if (!mncc_call->rtps->codecs_known) {
LOG_MNCC_CALL(mncc_call, LOGL_DEBUG, "Got RTP_CREATE, but RTP stream has no codec set\n");
return true;
}
LOG_MNCC_CALL(mncc_call, LOGL_DEBUG, "Got RTP_CREATE, responding with " OSMO_SOCKADDR_STR_FMT " %s\n",
OSMO_SOCKADDR_STR_FMT_ARGS(&mncc_call->rtps->local),
- osmo_mgcpc_codec_name(mncc_call->rtps->codec));
+ sdp_audio_codecs_to_str(&mncc_call->rtps->codecs));
/* Already know what RTP IP:port to tell the MNCC. Send it. */
return mncc_call_tx_rtp_create(mncc_call);
}
@@ -295,15 +295,16 @@ static bool mncc_call_tx_rtp_create(struct mncc_call *mncc_call)
return false;
}
- if (mncc_call->rtps->codec_known) {
- const struct codec_mapping *m = codec_mapping_by_mgcp_codec(mncc_call->rtps->codec);
+ if (mncc_call->rtps->codecs_known) {
+ struct sdp_audio_codec *codec = &mncc_call->rtps->codecs.codec[0];
+ const struct codec_mapping *m = codec_mapping_by_subtype_name(codec->subtype_name);
if (!m) {
mncc_call_error(mncc_call, "Failed to resolve audio codec '%s'\n",
- osmo_mgcpc_codec_name(mncc_call->rtps->codec));
+ sdp_audio_codec_to_str(codec));
return false;
}
- mncc_msg.rtp.payload_type = m->sdp.payload_type;
+ mncc_msg.rtp.payload_type = codec->payload_type;
mncc_msg.rtp.payload_msg_type = m->mncc_payload_msg_type;
}
diff --git a/src/libmsc/msc_a.c b/src/libmsc/msc_a.c
index 7db1d0a40..e9f18407d 100644
--- a/src/libmsc/msc_a.c
+++ b/src/libmsc/msc_a.c
@@ -1327,6 +1327,7 @@ static void msc_a_up_call_assignment_complete(struct msc_a *msc_a, const struct
struct rtp_stream *rtps_to_ran = msc_a->cc.call_leg ? msc_a->cc.call_leg->rtp[RTP_TO_RAN] : NULL;
const enum mgcp_codecs *codec_if_known = ac->assignment_complete.codec_present ?
&ac->assignment_complete.codec : NULL;
+ const struct codec_mapping *codec_cn = NULL;
if (!rtps_to_ran) {
LOG_MSC_A(msc_a, LOGL_ERROR, "Rx Assignment Complete, but no RTP stream is set up\n");
@@ -1344,9 +1345,26 @@ static void msc_a_up_call_assignment_complete(struct msc_a *msc_a, const struct
return;
}
- /* Update RAN-side endpoint CI: */
- if (codec_if_known)
- rtp_stream_set_codec(rtps_to_ran, *codec_if_known);
+ if (codec_if_known) {
+ codec_cn = codec_mapping_by_mgcp_codec(*codec_if_known);
+ if (!codec_cn) {
+ LOG_TRANS(cc_trans, LOGL_ERROR, "Unknown codec in Assignment Complete: %s\n",
+ osmo_mgcpc_codec_name(*codec_if_known));
+ call_leg_release(msc_a->cc.call_leg);
+ return;
+ }
+
+ /* Update RAN-side endpoint CI from Assignment result */
+ rtp_stream_set_one_codec(rtps_to_ran, &codec_cn->sdp);
+
+ /* Update codec filter with Assignment result, for the CN side */
+ cc_trans->cc.codecs.assignment = codec_cn->sdp;
+ } else {
+ /* No codec passed in Assignment Complete, set 'codecs.assignment' to none. */
+ cc_trans->cc.codecs.assignment = (struct sdp_audio_codec){};
+ LOG_TRANS(cc_trans, LOGL_INFO, "Assignment Complete without voice codec\n");
+ }
+
rtp_stream_set_remote_addr(rtps_to_ran, &ac->assignment_complete.remote_rtp);
if (rtps_to_ran->use_osmux)
rtp_stream_set_remote_osmux_cid(rtps_to_ran,
@@ -1364,8 +1382,9 @@ static void msc_a_up_call_assignment_complete(struct msc_a *msc_a, const struct
* endpoint,
* - the Assignment has chosen a speech codec
* go on to create the CN side RTP stream's CI. */
+ codec_filter_run(&cc_trans->cc.codecs);
if (call_leg_ensure_ci(msc_a->cc.call_leg, RTP_TO_CN, cc_trans->callref, cc_trans,
- codec_if_known, NULL)) {
+ &cc_trans->cc.codecs.result.audio_codecs, NULL)) {
LOG_MSC_A_CAT(msc_a, DCC, LOGL_ERROR, "Error creating MGW CI towards CN\n");
call_leg_release(msc_a->cc.call_leg);
return;
@@ -1760,11 +1779,13 @@ static int msc_a_start_assignment(struct msc_a *msc_a, struct gsm_trans *cc_tran
struct call_leg *cl = msc_a->cc.call_leg;
struct msc_i *msc_i = msc_a_msc_i(msc_a);
struct gsm_network *net = msc_a_net(msc_a);
- enum mgcp_codecs codec, *codec_ptr;
+ struct sdp_audio_codecs *codecs;
OSMO_ASSERT(!msc_a->cc.active_trans);
msc_a->cc.active_trans = cc_trans;
+ cc_trans->cc.codecs.assignment = (struct sdp_audio_codec){};
+
OSMO_ASSERT(cc_trans && cc_trans->type == TRANS_CC);
if (!cl) {
@@ -1785,20 +1806,17 @@ static int msc_a_start_assignment(struct msc_a *msc_a, struct gsm_trans *cc_tran
}
}
- /* This will lead to either MSC_EV_CALL_LEG_LOCAL_ADDR_AVAILABLE or MSC_EV_CALL_LEG_TERM.
- * If the local address is already known, then immediately trigger. */
+ /* Make sure an MGW endpoint towards RAN is present. If it is already set up, "skip" to
+ * MSC_EV_CALL_LEG_LOCAL_ADDR_AVAILABLE immediately. If not, set it up. */
if (call_leg_local_ip(cl, RTP_TO_RAN))
return osmo_fsm_inst_dispatch(msc_a->c.fi, MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE, cl->rtp[RTP_TO_RAN]);
- if (msc_a->c.ran->type == OSMO_RAT_UTRAN_IU) {
- /* FUTURE: ran_infra->force_mgw_codecs_to_ran is intended to be used here instead of the special
- * condition on OSMO_RAT_UTRAN_IU and the mgcp_codecs value CODEC_IUFP */
- codec = CODEC_IUFP;
- codec_ptr = &codec;
- } else {
- codec_ptr = NULL;
- }
- return call_leg_ensure_ci(msc_a->cc.call_leg, RTP_TO_RAN, cc_trans->callref, cc_trans, codec_ptr, NULL);
+ codec_filter_run(&cc_trans->cc.codecs);
+ if (msc_a->c.ran->force_mgw_codecs_to_ran.count)
+ codecs = &msc_a->c.ran->force_mgw_codecs_to_ran;
+ else
+ codecs = &cc_trans->cc.codecs.result.audio_codecs;
+ return call_leg_ensure_ci(msc_a->cc.call_leg, RTP_TO_RAN, cc_trans->callref, cc_trans, codecs, NULL);
}
int msc_a_try_call_assignment(struct gsm_trans *cc_trans)
diff --git a/src/libmsc/msc_ho.c b/src/libmsc/msc_ho.c
index 7e7905bb7..d53bb9e4d 100644
--- a/src/libmsc/msc_ho.c
+++ b/src/libmsc/msc_ho.c
@@ -39,6 +39,7 @@
#include <osmocom/msc/call_leg.h>
#include <osmocom/msc/rtp_stream.h>
#include <osmocom/msc/mncc_call.h>
+#include <osmocom/msc/codec_mapping.h>
struct osmo_fsm msc_ho_fsm;
@@ -570,7 +571,7 @@ static int msc_ho_start_inter_msc_call_forwarding(struct msc_a *msc_a, struct ms
/* Backup old cell's RTP IP:port and codec data */
msc_a->ho.old_cell.ran_remote_rtp = rtp_to_ran->remote;
- msc_a->ho.old_cell.codec = rtp_to_ran->codec;
+ msc_a->ho.old_cell.codecs = rtp_to_ran->codecs;
/* Blindly taken over from an MNCC trace of existing code: send an all-zero CCCAP: */
outgoing_call_req.fields |= MNCC_F_CCCAP;
@@ -707,7 +708,7 @@ static void msc_ho_rtp_switch_to_new_cell(struct msc_a *msc_a)
/* Backup old cell's RTP IP:port and codec data */
msc_a->ho.old_cell.ran_remote_rtp = rtp_to_ran->remote;
- msc_a->ho.old_cell.codec = rtp_to_ran->codec;
+ msc_a->ho.old_cell.codecs = rtp_to_ran->codecs;
LOG_HO(msc_a, LOGL_DEBUG, "Switching RTP stream to new cell: from " OSMO_SOCKADDR_STR_FMT " to " OSMO_SOCKADDR_STR_FMT "\n",
OSMO_SOCKADDR_STR_FMT_ARGS(&msc_a->ho.old_cell.ran_remote_rtp),
@@ -726,10 +727,17 @@ static void msc_ho_rtp_switch_to_new_cell(struct msc_a *msc_a)
/* Switch over to the new peer */
rtp_stream_set_remote_addr(rtp_to_ran, &msc_a->ho.new_cell.ran_remote_rtp);
- if (msc_a->ho.new_cell.codec_present)
- rtp_stream_set_codec(rtp_to_ran, msc_a->ho.new_cell.codec);
- else
+ if (msc_a->ho.new_cell.codec_present) {
+ struct sdp_audio_codecs codecs = {};
+ if (!sdp_audio_codecs_add_mgcp_codec(&codecs, msc_a->ho.new_cell.codec)) {
+ LOG_HO(msc_a, LOGL_ERROR,
+ "Cannot resolve codec: %s\n", osmo_mgcpc_codec_name(msc_a->ho.new_cell.codec));
+ } else {
+ rtp_stream_set_codecs(rtp_to_ran, &codecs);
+ }
+ } else {
LOG_HO(msc_a, LOGL_ERROR, "No codec is set\n");
+ }
rtp_stream_commit(rtp_to_ran);
}
@@ -768,7 +776,7 @@ static void msc_ho_rtp_rollback_to_old_cell(struct msc_a *msc_a)
/* Switch back to the old cell */
rtp_stream_set_remote_addr(rtp_to_ran, &msc_a->ho.old_cell.ran_remote_rtp);
- rtp_stream_set_codec(rtp_to_ran, msc_a->ho.old_cell.codec);
+ rtp_stream_set_codecs(rtp_to_ran, &msc_a->ho.old_cell.codecs);
rtp_stream_commit(rtp_to_ran);
}
diff --git a/src/libmsc/msc_t.c b/src/libmsc/msc_t.c
index 43bc74e0c..787d7362f 100644
--- a/src/libmsc/msc_t.c
+++ b/src/libmsc/msc_t.c
@@ -450,9 +450,9 @@ static int msc_t_patch_and_send_ho_request_ack(struct msc_t *msc_t, const struct
if (r->codec_present) {
LOG_MSC_T(msc_t, LOGL_DEBUG, "From Handover Request Ack, got %s\n",
osmo_mgcpc_codec_name(r->codec));
- rtp_stream_set_codec(rtp_ran, r->codec);
+ rtp_stream_set_codecs_from_mgcp_codec(rtp_ran, r->codec);
if (rtp_cn)
- rtp_stream_set_codec(rtp_cn, r->codec);
+ rtp_stream_set_codecs_from_mgcp_codec(rtp_cn, r->codec);
} else {
LOG_MSC_T(msc_t, LOGL_DEBUG, "No codec in Handover Request Ack\n");
}
diff --git a/src/libmsc/rtp_stream.c b/src/libmsc/rtp_stream.c
index b7e7381f3..ac444148e 100644
--- a/src/libmsc/rtp_stream.c
+++ b/src/libmsc/rtp_stream.c
@@ -28,6 +28,7 @@
#include <osmocom/msc/transaction.h>
#include <osmocom/msc/call_leg.h>
#include <osmocom/msc/rtp_stream.h>
+#include <osmocom/msc/codec_mapping.h>
#define LOG_RTPS(rtps, level, fmt, args...) \
LOGPFSML(rtps->fi, level, fmt, ##args)
@@ -78,10 +79,10 @@ void rtp_stream_update_id(struct rtp_stream *rtps)
OSMO_STRBUF_PRINTF(sb, ":no-remote-port");
else if (!rtps->remote_sent_to_mgw)
OSMO_STRBUF_PRINTF(sb, ":remote-port-not-sent");
- if (!rtps->codec_known)
- OSMO_STRBUF_PRINTF(sb, ":no-codec");
- else if (!rtps->codec_sent_to_mgw)
- OSMO_STRBUF_PRINTF(sb, ":codec-not-sent");
+ if (!rtps->codecs_known)
+ OSMO_STRBUF_PRINTF(sb, ":no-codecs");
+ else if (!rtps->codecs_sent_to_mgw)
+ OSMO_STRBUF_PRINTF(sb, ":codecs-not-sent");
if (rtps->use_osmux) {
if (rtps->remote_osmux_cid < 0)
OSMO_STRBUF_PRINTF(sb, ":no-remote-osmux-cid");
@@ -141,7 +142,7 @@ static void check_established(struct rtp_stream *rtps)
&& osmo_sockaddr_str_is_nonzero(&rtps->remote)
&& rtps->remote_sent_to_mgw
&& (!rtps->use_osmux || rtps->remote_osmux_cid_sent_to_mgw)
- && rtps->codec_known)
+ && rtps->codecs_known)
rtp_stream_state_chg(rtps, RTP_STREAM_ST_ESTABLISHED);
}
@@ -171,14 +172,14 @@ static void rtp_stream_fsm_establishing_established(struct osmo_fsm_inst *fi, ui
osmo_fsm_inst_dispatch(fi->proc.parent, CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE, rtps);
check_established(rtps);
- if ((!rtps->remote_sent_to_mgw || !rtps->codec_sent_to_mgw)
+ if ((!rtps->remote_sent_to_mgw || !rtps->codecs_sent_to_mgw)
&& osmo_sockaddr_str_is_nonzero(&rtps->remote)
&& (!rtps->use_osmux || rtps->remote_osmux_cid_sent_to_mgw)
- && rtps->codec_known) {
+ && rtps->codecs_known) {
LOG_RTPS(rtps, LOGL_DEBUG,
"local ip:port set;%s%s%s triggering MDCX to send the new settings\n",
- (!rtps->remote_sent_to_mgw)? " remote ip:port not yet sent," : "",
- (!rtps->codec_sent_to_mgw)? " codec not yet sent," : "",
+ (!rtps->remote_sent_to_mgw) ? " remote ip:port not yet sent," : "",
+ (!rtps->codecs_sent_to_mgw) ? " codecs not yet sent," : "",
(rtps->use_osmux && !rtps->remote_osmux_cid_sent_to_mgw) ? "Osmux CID not yet sent,": "");
rtp_stream_do_mdcx(rtps);
}
@@ -192,7 +193,7 @@ static void rtp_stream_fsm_establishing_established(struct osmo_fsm_inst *fi, ui
case RTP_STREAM_EV_CRCX_FAIL:
case RTP_STREAM_EV_MDCX_FAIL:
rtps->remote_sent_to_mgw = false;
- rtps->codec_sent_to_mgw = false;
+ rtps->codecs_sent_to_mgw = false;
rtps->remote_osmux_cid_sent_to_mgw = false;
rtp_stream_update_id(rtps);
rtp_stream_state_chg(rtps, RTP_STREAM_ST_DISCARDING);
@@ -310,10 +311,28 @@ static int rtp_stream_do_mgcp_verb(struct rtp_stream *rtps, enum mgcp_verb verb,
if (verb == MGCP_VERB_CRCX)
verb_info.conn_mode = rtps->crcx_conn_mode;
- if (rtps->codec_known) {
- verb_info.codecs[0] = rtps->codec;
- verb_info.codecs_len = 1;
- rtps->codec_sent_to_mgw = true;
+ if (rtps->codecs_known) {
+ /* Send the list of codecs to the MGW. Ideally we would just feed the SDP directly, but for legacy
+ * reasons we still need to translate to a struct mgcp_conn_peer representation to send it. */
+ struct sdp_audio_codec *codec;
+ int i = 0;
+ foreach_sdp_audio_codec(codec, &rtps->codecs) {
+ const struct codec_mapping *m = codec_mapping_by_subtype_name(codec->subtype_name);
+ if (!m) {
+ LOG_RTPS(rtps, LOGL_ERROR, "Cannot map codec '%s' to MGCP: codec is unknown\n",
+ codec->subtype_name);
+ continue;
+ }
+ verb_info.codecs[i] = m->mgcp;
+ verb_info.ptmap[i] = (struct ptmap){
+ .codec = m->mgcp,
+ .pt = codec->payload_type,
+ };
+ i++;
+ verb_info.codecs_len = i;
+ verb_info.ptmap_len = i;
+ }
+ rtps->codecs_sent_to_mgw = true;
}
if (osmo_sockaddr_str_is_nonzero(&rtps->remote)) {
int rc = osmo_strlcpy(verb_info.addr, rtps->remote.ip, sizeof(verb_info.addr));
@@ -368,12 +387,12 @@ int rtp_stream_commit(struct rtp_stream *rtps)
LOG_RTPS(rtps, LOGL_DEBUG, "Not committing: no remote RTP address known\n");
return -1;
}
- if (!rtps->codec_known) {
- LOG_RTPS(rtps, LOGL_DEBUG, "Not committing: no codec known\n");
+ if (!rtps->codecs_known) {
+ LOG_RTPS(rtps, LOGL_DEBUG, "Not committing: no codecs known\n");
return -1;
}
- if (rtps->remote_sent_to_mgw && rtps->codec_sent_to_mgw) {
- LOG_RTPS(rtps, LOGL_DEBUG, "Not committing: both remote RTP address and codec already set up at MGW\n");
+ if (rtps->remote_sent_to_mgw && rtps->codecs_sent_to_mgw) {
+ LOG_RTPS(rtps, LOGL_DEBUG, "Not committing: both remote RTP address and codecs already set up at MGW\n");
return 0;
}
if (!rtps->ci) {
@@ -383,22 +402,47 @@ int rtp_stream_commit(struct rtp_stream *rtps)
LOG_RTPS(rtps, LOGL_DEBUG, "Committing: Tx MDCX to update the MGW: updating%s%s%s\n",
rtps->remote_sent_to_mgw ? "" : " remote-RTP-IP-port",
- rtps->codec_sent_to_mgw ? "" : " codec",
+ rtps->codecs_sent_to_mgw ? "" : " codecs",
(!rtps->use_osmux || rtps->remote_osmux_cid_sent_to_mgw) ? "" : " remote-Osmux-CID");
return rtp_stream_do_mdcx(rtps);
}
-void rtp_stream_set_codec(struct rtp_stream *rtps, enum mgcp_codecs codec)
+void rtp_stream_set_codecs(struct rtp_stream *rtps, const struct sdp_audio_codecs *codecs)
{
+ if (!codecs || !codecs->count)
+ return;
+ if (sdp_audio_codecs_cmp(&rtps->codecs, codecs, false, true) == 0) {
+ LOG_RTPS(rtps, LOGL_DEBUG, "no change: codecs already set to %s\n",
+ sdp_audio_codecs_to_str(&rtps->codecs));
+ return;
+ }
if (rtps->fi->state == RTP_STREAM_ST_ESTABLISHED)
rtp_stream_state_chg(rtps, RTP_STREAM_ST_ESTABLISHING);
- LOG_RTPS(rtps, LOGL_DEBUG, "setting codec to %s\n", osmo_mgcpc_codec_name(codec));
- rtps->codec = codec;
- rtps->codec_known = true;
- rtps->codec_sent_to_mgw = false;
+ LOG_RTPS(rtps, LOGL_DEBUG, "setting codecs to %s\n", sdp_audio_codecs_to_str(codecs));
+ rtps->codecs = *codecs;
+ rtps->codecs_known = true;
+ rtps->codecs_sent_to_mgw = false;
rtp_stream_update_id(rtps);
}
+/* Convenience shortcut to call rtp_stream_set_codecs() with a list of only one sdp_audio_codec record. */
+void rtp_stream_set_one_codec(struct rtp_stream *rtps, const struct sdp_audio_codec *codec)
+{
+ struct sdp_audio_codecs codecs = {};
+ sdp_audio_codecs_add_copy(&codecs, codec);
+ rtp_stream_set_codecs(rtps, &codecs);
+}
+
+/* For legacy, rather use rtp_stream_set_codecs() with a full codecs list. */
+bool rtp_stream_set_codecs_from_mgcp_codec(struct rtp_stream *rtps, enum mgcp_codecs codec)
+{
+ struct sdp_audio_codecs codecs = {};
+ if (!sdp_audio_codecs_add_mgcp_codec(&codecs, codec))
+ return false;
+ rtp_stream_set_codecs(rtps, &codecs);
+ return true;
+}
+
void rtp_stream_set_remote_addr(struct rtp_stream *rtps, const struct osmo_sockaddr_str *r)
{
if (osmo_sockaddr_str_cmp(&rtps->remote, r) == 0) {
@@ -433,7 +477,7 @@ bool rtp_stream_is_established(struct rtp_stream *rtps)
if (rtps->fi->state != RTP_STREAM_ST_ESTABLISHED)
return false;
if (!rtps->remote_sent_to_mgw
- || !rtps->codec_sent_to_mgw
+ || !rtps->codecs_sent_to_mgw
|| (rtps->use_osmux && !rtps->remote_osmux_cid_sent_to_mgw))
return false;
return true;
diff --git a/tests/msc_vlr/msc_vlr_test_call.err b/tests/msc_vlr/msc_vlr_test_call.err
index fbe26010a..877015a21 100644
--- a/tests/msc_vlr/msc_vlr_test_call.err
+++ b/tests/msc_vlr/msc_vlr_test_call.err
@@ -301,10 +301,10 @@ DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN
DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Starting call assignment
DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: Allocated
DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ)
- MGW <--CRCX to RTP_TO_RAN-- MSC: callref=0x80000001
+ MGW <--CRCX to RTP_TO_RAN-- MSC: callref=0x80000001 codecs=VND.3GPP.IUFP/16000#96
DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){UNINITIALIZED}: Allocated
DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ)
-DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-2147483649:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codec to VND.3GPP.IUFP/16000
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-2147483649:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to VND.3GPP.IUFP/16000#96
- MGW acknowledges the CRCX, triggering Assignment
MGW --CRCX OK to RTP_TO_RAN--> MSC
DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE
@@ -314,13 +314,13 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE
DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
- Assignment succeeds, triggering CRCX to CN
DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: ASSIGNMENT_COMPLETE
-DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-2147483649:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codec to AMR/8000/1
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-2147483649:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112
DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-2147483649:RTP_TO_RAN:no-CI:local-10-23-23-1-23){UNINITIALIZED}: setting remote addr to 1.2.3.4:1234
DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-2147483649:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Not committing: no MGW endpoint CI set up
- MGW <--CRCX to RTP_TO_CN-- MSC: callref=0x80000001
+ MGW <--CRCX to RTP_TO_CN-- MSC: callref=0x80000001 codecs=AMR:octet-align=1#112
DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){UNINITIALIZED}: Allocated
DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ)
-DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-2147483649:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codec to AMR/8000/1
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-2147483649:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112
- CN RTP address is available, trigger MNCC_RTP_CREATE
MGW --CRCX OK to RTP_TO_CN--> MSC
DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE
@@ -779,10 +779,10 @@ DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRA
DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Starting call assignment
DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){ESTABLISHING}: Allocated
DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP)
- MGW <--CRCX to RTP_TO_RAN-- MSC: callref=0x423
+ MGW <--CRCX to RTP_TO_RAN-- MSC: callref=0x423 codecs=VND.3GPP.IUFP/16000#96
DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){UNINITIALIZED}: Allocated
DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP)
-DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-1059:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codec to VND.3GPP.IUFP/16000
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-1059:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to VND.3GPP.IUFP/16000#96
DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) tx MNCC_CALL_CONF_IND
MSC --> MNCC: callref 0x423: MNCC_CALL_CONF_IND
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
@@ -800,13 +800,13 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RES
DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
- Assignment completes, triggering CRCX to CN
DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: ASSIGNMENT_COMPLETE
-DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-1059:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codec to AMR/8000/1
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-1059:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112
DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-1059:RTP_TO_RAN:no-CI:local-10-23-23-1-23){UNINITIALIZED}: setting remote addr to 1.2.3.4:1234
DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-1059:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Not committing: no MGW endpoint CI set up
- MGW <--CRCX to RTP_TO_CN-- MSC: callref=0x423
+ MGW <--CRCX to RTP_TO_CN-- MSC: callref=0x423 codecs=AMR:octet-align=1#112
DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){UNINITIALIZED}: Allocated
DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP)
-DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-1059:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codec to AMR/8000/1
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-1059:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112
- When the CN side RTP address is known, send MNCC_RTP_CREATE
MGW --CRCX OK to RTP_TO_CN--> MSC
DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE
@@ -1249,10 +1249,10 @@ DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRA
DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Starting call assignment
DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){ESTABLISHING}: Allocated
DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP)
- MGW <--CRCX to RTP_TO_RAN-- MSC: callref=0x423
+ MGW <--CRCX to RTP_TO_RAN-- MSC: callref=0x423 codecs=VND.3GPP.IUFP/16000#96
DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){UNINITIALIZED}: Allocated
DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP)
-DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-1059:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codec to VND.3GPP.IUFP/16000
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-1059:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to VND.3GPP.IUFP/16000#96
DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) tx MNCC_CALL_CONF_IND
MSC --> MNCC: callref 0x423: MNCC_CALL_CONF_IND
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
@@ -1270,13 +1270,13 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RES
DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
- Assignment completes, triggering CRCX to CN
DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: ASSIGNMENT_COMPLETE
-DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-1059:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codec to AMR/8000/1
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-1059:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112
DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-1059:RTP_TO_RAN:no-CI:local-10-23-23-1-23){UNINITIALIZED}: setting remote addr to 1.2.3.4:1234
DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-1059:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Not committing: no MGW endpoint CI set up
- MGW <--CRCX to RTP_TO_CN-- MSC: callref=0x423
+ MGW <--CRCX to RTP_TO_CN-- MSC: callref=0x423 codecs=AMR:octet-align=1#112
DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){UNINITIALIZED}: Allocated
DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP)
-DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-1059:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codec to AMR/8000/1
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-1059:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112
- When the CN side RTP address is known, send MNCC_RTP_CREATE
MGW --CRCX OK to RTP_TO_CN--> MSC
DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE
@@ -1667,10 +1667,10 @@ DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN
DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Starting call assignment
DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: Allocated
DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ)
- MGW <--CRCX to RTP_TO_RAN-- MSC: callref=0x80000002
+ MGW <--CRCX to RTP_TO_RAN-- MSC: callref=0x80000002 codecs=VND.3GPP.IUFP/16000#96
DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){UNINITIALIZED}: Allocated
DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ)
-DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-2147483650:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codec to VND.3GPP.IUFP/16000
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-2147483650:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to VND.3GPP.IUFP/16000#96
- MGW acknowledges the CRCX, triggering Assignment
MGW --CRCX OK to RTP_TO_RAN--> MSC
DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE
@@ -1680,13 +1680,13 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE
DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
- Assignment succeeds, triggering CRCX to CN
DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: ASSIGNMENT_COMPLETE
-DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-2147483650:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codec to AMR/8000/1
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-2147483650:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112
DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-2147483650:RTP_TO_RAN:no-CI:local-10-23-23-1-23){UNINITIALIZED}: setting remote addr to 1.2.3.4:1234
DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-2147483650:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Not committing: no MGW endpoint CI set up
- MGW <--CRCX to RTP_TO_CN-- MSC: callref=0x80000002
+ MGW <--CRCX to RTP_TO_CN-- MSC: callref=0x80000002 codecs=AMR:octet-align=1#112
DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){UNINITIALIZED}: Allocated
DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ)
-DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-2147483650:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codec to AMR/8000/1
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-2147483650:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112
- CN RTP address is available, trigger MNCC_RTP_CREATE
MGW --CRCX OK to RTP_TO_CN--> MSC
DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE
@@ -2094,10 +2094,10 @@ DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN
DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Starting call assignment
DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: Allocated
DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ)
- MGW <--CRCX to RTP_TO_RAN-- MSC: callref=0x80000003
+ MGW <--CRCX to RTP_TO_RAN-- MSC: callref=0x80000003 codecs=VND.3GPP.IUFP/16000#96
DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){UNINITIALIZED}: Allocated
DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ)
-DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-2147483651:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codec to VND.3GPP.IUFP/16000
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-2147483651:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to VND.3GPP.IUFP/16000#96
- MGW acknowledges the CRCX, triggering Assignment
MGW --CRCX OK to RTP_TO_RAN--> MSC
DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE
@@ -2107,13 +2107,13 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE
DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
- Assignment succeeds, triggering CRCX to CN
DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: ASSIGNMENT_COMPLETE
-DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-2147483651:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codec to AMR/8000/1
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-2147483651:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112
DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-2147483651:RTP_TO_RAN:no-CI:local-10-23-23-1-23){UNINITIALIZED}: setting remote addr to 1.2.3.4:1234
DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-2147483651:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Not committing: no MGW endpoint CI set up
- MGW <--CRCX to RTP_TO_CN-- MSC: callref=0x80000003
+ MGW <--CRCX to RTP_TO_CN-- MSC: callref=0x80000003 codecs=AMR:octet-align=1#112
DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){UNINITIALIZED}: Allocated
DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ)
-DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-2147483651:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codec to AMR/8000/1
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-2147483651:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112
- CN RTP address is available, trigger MNCC_RTP_CREATE
MGW --CRCX OK to RTP_TO_CN--> MSC
DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE
diff --git a/tests/msc_vlr/msc_vlr_tests.c b/tests/msc_vlr/msc_vlr_tests.c
index b0c60edad..45b97a27a 100644
--- a/tests/msc_vlr/msc_vlr_tests.c
+++ b/tests/msc_vlr/msc_vlr_tests.c
@@ -41,6 +41,7 @@
#include <osmocom/msc/msc_t.h>
#include <osmocom/msc/call_leg.h>
#include <osmocom/msc/rtp_stream.h>
+#include <osmocom/msc/codec_mapping.h>
#include "msc_vlr_tests.h"
@@ -852,20 +853,23 @@ void expect_crcx(enum rtp_direction towards)
/* override, requires '-Wl,--wrap=call_leg_ensure_ci' */
int __real_call_leg_ensure_ci(struct call_leg *cl, enum rtp_direction dir, uint32_t call_id, struct gsm_trans *for_trans,
- const enum mgcp_codecs *codec_if_known, const struct osmo_sockaddr_str *remote_addr_if_known);
+ const struct sdp_audio_codecs *codecs_if_known,
+ const struct osmo_sockaddr_str *remote_addr_if_known);
int __wrap_call_leg_ensure_ci(struct call_leg *cl, enum rtp_direction dir, uint32_t call_id, struct gsm_trans *for_trans,
- const enum mgcp_codecs *codec_if_known, const struct osmo_sockaddr_str *remote_addr_if_known)
+ const struct sdp_audio_codecs *codecs_if_known,
+ const struct osmo_sockaddr_str *remote_addr_if_known)
{
if (!cl->rtp[dir]) {
- log("MGW <--CRCX to %s-- MSC: callref=0x%x", rtp_direction_name(dir), call_id);
+ log("MGW <--CRCX to %s-- MSC: callref=0x%x codecs=%s", rtp_direction_name(dir), call_id,
+ codecs_if_known ? sdp_audio_codecs_to_str(codecs_if_known) : "unset");
OSMO_ASSERT(expecting_crcx == dir);
expecting_crcx = -1;
got_crcx = true;
call_leg_ensure_rtp_alloc(cl, dir, call_id, for_trans);
- if (codec_if_known)
- rtp_stream_set_codec(cl->rtp[dir], *codec_if_known);
+ if (codecs_if_known)
+ rtp_stream_set_codecs(cl->rtp[dir], codecs_if_known);
if (remote_addr_if_known && osmo_sockaddr_str_is_nonzero(remote_addr_if_known))
rtp_stream_set_remote_addr(cl->rtp[dir], remote_addr_if_known);
}