rtp_stream: allow multiple codecs / use codec filter from Assignment

Allow configuring MGW conns with multiple codecs. The new codecs filter
can have multiple results, and MGCP can configure multiple codecs. Get
rid of this bottleneck, that so far limits to a single codec to MGW.

On Assignment Complete, set codec_filter.assignment to the assigned
codec, and use that to set the resulting codec (possibly multiple codecs
in the future) to create the CN side MGW endpoint.

Related: SYS#5066
Change-Id: If9c67b298b30f893ec661f84c9fc622ad01b5ee5
This commit is contained in:
Neels Hofmeyr 2022-10-31 18:51:07 +01:00
parent 1dc3961a0a
commit 62bfa37eae
12 changed files with 187 additions and 106 deletions

View File

@ -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);

View File

@ -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;
};

View File

@ -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);

View File

@ -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;
}

View File

@ -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) {

View File

@ -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;
}

View File

@ -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)

View File

@ -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);
}

View File

@ -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");
}

View File

@ -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;

View File

@ -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

View File

@ -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);
}