Request Osmux CID and forward it in Assign Req and Assign Compl
Related: OS#2551 Depends: osmo-mgw.git I73b4c62baf39050da81d65553cbea07bc51163de Change-Id: I5b14e34481e890669c9ee02dba81eba84293cebb
This commit is contained in:
parent
643270f717
commit
a3cdab4481
|
@ -44,6 +44,8 @@ struct call_leg {
|
|||
|
||||
/* Prevent events from deallocating for certain release code paths, to prevent use-after-free problems. */
|
||||
bool deallocating;
|
||||
|
||||
bool ran_peer_supports_osmux;
|
||||
};
|
||||
|
||||
enum call_leg_event {
|
||||
|
|
|
@ -84,6 +84,8 @@ struct ran_assignment_command {
|
|||
const struct osmo_sockaddr_str *cn_rtp;
|
||||
const struct gsm0808_channel_type *channel_type;
|
||||
enum nsap_addr_enc rab_assign_addr_enc;
|
||||
bool osmux_present;
|
||||
uint8_t osmux_cid;
|
||||
};
|
||||
|
||||
struct ran_cipher_mode_command {
|
||||
|
@ -223,6 +225,8 @@ struct ran_msg {
|
|||
struct osmo_sockaddr_str remote_rtp;
|
||||
bool codec_present;
|
||||
enum mgcp_codecs codec;
|
||||
bool osmux_present;
|
||||
uint8_t osmux_cid;
|
||||
} assignment_complete;
|
||||
struct {
|
||||
enum gsm0808_cause bssap_cause;
|
||||
|
|
|
@ -44,6 +44,15 @@ struct rtp_stream {
|
|||
struct osmo_mgcpc_ep_ci *ci;
|
||||
|
||||
enum mgcp_connection_mode crcx_conn_mode;
|
||||
|
||||
/* configured to use Osmux */
|
||||
bool use_osmux;
|
||||
/* Allocated by our MGW, negative means invalid, not yet known */
|
||||
int local_osmux_cid;
|
||||
/* Allocated by BSC MGW, negative means invalid, not yet known */
|
||||
int remote_osmux_cid;
|
||||
/* Whether remote_osmux_cid has been communicated to MGW */
|
||||
bool remote_osmux_cid_sent_to_mgw;
|
||||
};
|
||||
|
||||
#define RTP_STREAM_FMT "local=" RTP_IP_PORT_FMT ",remote=" RTP_IP_PORT_FMT
|
||||
|
@ -57,6 +66,7 @@ int rtp_stream_do_mdcx(struct rtp_stream *rtps);
|
|||
|
||||
void rtp_stream_set_codec(struct rtp_stream *rtps, enum mgcp_codecs codec);
|
||||
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);
|
||||
|
||||
void rtp_stream_release(struct rtp_stream *rtps);
|
||||
|
|
|
@ -321,6 +321,10 @@ int call_leg_ensure_ci(struct call_leg *cl, enum rtp_direction dir, uint32_t cal
|
|||
if (call_leg_ensure_rtp_alloc(cl, dir, call_id, for_trans))
|
||||
return -EIO;
|
||||
cl->rtp[dir]->crcx_conn_mode = cl->crcx_conn_mode[dir];
|
||||
if (dir == RTP_TO_RAN && cl->ran_peer_supports_osmux) {
|
||||
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 (remote_addr_if_known && osmo_sockaddr_str_is_set(remote_addr_if_known))
|
||||
|
|
|
@ -527,6 +527,8 @@ static void msc_a_call_leg_ran_local_addr_available(struct msc_a *msc_a)
|
|||
.assignment_command = {
|
||||
.cn_rtp = &msc_a->cc.call_leg->rtp[RTP_TO_RAN]->local,
|
||||
.channel_type = &channel_type,
|
||||
.osmux_present = msc_a->cc.call_leg->rtp[RTP_TO_RAN]->use_osmux,
|
||||
.osmux_cid = msc_a->cc.call_leg->rtp[RTP_TO_RAN]->local_osmux_cid,
|
||||
},
|
||||
};
|
||||
if (msc_a_ran_down(msc_a, MSC_ROLE_I, &msg)) {
|
||||
|
@ -620,8 +622,9 @@ static void msc_a_fsm_communicating(struct osmo_fsm_inst *fi, uint32_t event, vo
|
|||
return;
|
||||
}
|
||||
LOG_MSC_A(msc_a, LOGL_DEBUG,
|
||||
"MGW endpoint's RTP address available for the CI %s: " OSMO_SOCKADDR_STR_FMT "\n",
|
||||
rtp_direction_name(rtps->dir), OSMO_SOCKADDR_STR_FMT_ARGS(&rtps->local));
|
||||
"MGW endpoint's RTP address available for the CI %s: " OSMO_SOCKADDR_STR_FMT " (osmux=%s:%d)\n",
|
||||
rtp_direction_name(rtps->dir), OSMO_SOCKADDR_STR_FMT_ARGS(&rtps->local),
|
||||
rtps->use_osmux ? "yes" : "no", rtps->local_osmux_cid);
|
||||
switch (rtps->dir) {
|
||||
case RTP_TO_RAN:
|
||||
msc_a_call_leg_ran_local_addr_available(msc_a);
|
||||
|
@ -1257,9 +1260,20 @@ static void msc_a_up_call_assignment_complete(struct msc_a *msc_a, const struct
|
|||
return;
|
||||
}
|
||||
|
||||
if (rtps_to_ran->use_osmux != ac->assignment_complete.osmux_present) {
|
||||
LOG_MSC_A_CAT(msc_a, DCC, LOGL_ERROR, "Osmux usage ass request and complete don't match: %d vs %d\n",
|
||||
rtps_to_ran->use_osmux, ac->assignment_complete.osmux_present);
|
||||
call_leg_release(msc_a->cc.call_leg);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Update RAN-side endpoint CI: */
|
||||
rtp_stream_set_codec(rtps_to_ran, ac->assignment_complete.codec);
|
||||
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,
|
||||
ac->assignment_complete.osmux_cid);
|
||||
|
||||
rtp_stream_commit(rtps_to_ran);
|
||||
|
||||
/* Setup CN side endpoint CI:
|
||||
|
@ -1592,6 +1606,8 @@ int msc_tx_common_id(struct msc_a *msc_a, enum msc_role to_role)
|
|||
static int msc_a_start_assignment(struct msc_a *msc_a, struct gsm_trans *cc_trans)
|
||||
{
|
||||
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);
|
||||
|
||||
OSMO_ASSERT(!msc_a->cc.active_trans);
|
||||
msc_a->cc.active_trans = cc_trans;
|
||||
|
@ -1612,6 +1628,16 @@ static int msc_a_start_assignment(struct msc_a *msc_a, struct gsm_trans *cc_tran
|
|||
cl->crcx_conn_mode[RTP_TO_RAN] = MGCP_CONN_LOOPBACK;
|
||||
}
|
||||
|
||||
if (net->use_osmux != OSMUX_USAGE_OFF) {
|
||||
msc_i = msc_a_msc_i(msc_a);
|
||||
if (msc_i->c.remote_to) {
|
||||
/* TODO: investigate what to do in this case */
|
||||
LOG_MSC_A(msc_a, LOGL_ERROR, "Osmux not yet supported for inter-MSC");
|
||||
} else {
|
||||
cl->ran_peer_supports_osmux = msc_i->ran_conn->ran_peer->remote_supports_osmux;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
if (call_leg_local_ip(cl, RTP_TO_RAN))
|
||||
|
|
|
@ -269,6 +269,7 @@ static int ran_a_decode_assignment_complete(struct ran_dec *ran_dec, struct msgb
|
|||
{
|
||||
struct tlv_p_entry *ie_aoip_transp_addr = TLVP_GET(tp, GSM0808_IE_AOIP_TRASP_ADDR);
|
||||
struct tlv_p_entry *ie_speech_codec = TLVP_GET(tp, GSM0808_IE_SPEECH_CODEC);
|
||||
struct tlv_p_entry *ie_osmux_cid = TLVP_GET(tp, GSM0808_IE_OSMO_OSMUX_CID);
|
||||
struct sockaddr_storage rtp_addr;
|
||||
struct sockaddr_in *rtp_addr_in;
|
||||
struct gsm0808_speech_codec sc;
|
||||
|
@ -300,6 +301,15 @@ static int ran_a_decode_assignment_complete(struct ran_dec *ran_dec, struct msgb
|
|||
}
|
||||
}
|
||||
|
||||
if (ie_osmux_cid) {
|
||||
rc = gsm0808_dec_osmux_cid(&ran_dec_msg.assignment_complete.osmux_cid, ie_osmux_cid->val, ie_osmux_cid->len);
|
||||
if (rc < 0) {
|
||||
LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Unable to decode Osmux CID\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
ran_dec_msg.assignment_complete.osmux_present = true;
|
||||
}
|
||||
|
||||
if (ie_speech_codec) {
|
||||
/* Decode Speech Codec (Chosen) element */
|
||||
rc = gsm0808_dec_speech_codec(&sc, ie_speech_codec->val, ie_speech_codec->len);
|
||||
|
@ -902,6 +912,13 @@ static int ran_a_channel_type_to_speech_codec_list(struct gsm0808_speech_codec_l
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void _gsm0808_assignment_extend_osmux(struct msgb *msg, uint8_t cid)
|
||||
{
|
||||
OSMO_ASSERT(msg->l3h[1] == msgb_l3len(msg) - 2); /*TL not in len */
|
||||
msgb_tv_put(msg, GSM0808_IE_OSMO_OSMUX_CID, cid);
|
||||
msg->l3h[1] = msgb_l3len(msg) - 2;
|
||||
}
|
||||
|
||||
/* Compose a BSSAP Assignment Command.
|
||||
* Passing an RTP address is optional.
|
||||
* The msub is passed merely for error logging. */
|
||||
|
@ -912,6 +929,7 @@ static struct msgb *ran_a_make_assignment_command(struct osmo_fsm_inst *log_fi,
|
|||
struct gsm0808_speech_codec_list *use_scl = NULL;
|
||||
struct sockaddr_storage rtp_addr;
|
||||
struct sockaddr_storage *use_rtp_addr = NULL;
|
||||
struct msgb *msg;
|
||||
int rc;
|
||||
|
||||
if (!ac->channel_type) {
|
||||
|
@ -952,7 +970,10 @@ static struct msgb *ran_a_make_assignment_command(struct osmo_fsm_inst *log_fi,
|
|||
}
|
||||
}
|
||||
|
||||
return gsm0808_create_ass(ac->channel_type, NULL, use_rtp_addr, use_scl, NULL);
|
||||
msg = gsm0808_create_ass(ac->channel_type, NULL, use_rtp_addr, use_scl, NULL);
|
||||
if (ac->osmux_present)
|
||||
_gsm0808_assignment_extend_osmux(msg, ac->osmux_cid);
|
||||
return msg;
|
||||
}
|
||||
|
||||
/* For an A5/N number a5_n set dst to the matching GSM0808_ALG_ID_A5_<n>. */
|
||||
|
|
|
@ -82,11 +82,19 @@ void rtp_stream_update_id(struct rtp_stream *rtps)
|
|||
OSMO_STRBUF_PRINTF(sb, ":no-codec");
|
||||
else if (!rtps->codec_sent_to_mgw)
|
||||
OSMO_STRBUF_PRINTF(sb, ":codec-not-sent");
|
||||
if (rtps->use_osmux) {
|
||||
if (rtps->remote_osmux_cid < 0)
|
||||
OSMO_STRBUF_PRINTF(sb, ":no-remote-osmux-cid");
|
||||
else if (!rtps->remote_osmux_cid_sent_to_mgw)
|
||||
OSMO_STRBUF_PRINTF(sb, ":remote-osmux-cid-not-sent");
|
||||
}
|
||||
}
|
||||
if (osmo_sockaddr_str_is_set(&rtps->local))
|
||||
OSMO_STRBUF_PRINTF(sb, ":local-%s-%u", rtps->local.ip, rtps->local.port);
|
||||
if (osmo_sockaddr_str_is_set(&rtps->remote))
|
||||
OSMO_STRBUF_PRINTF(sb, ":remote-%s-%u", rtps->remote.ip, rtps->remote.port);
|
||||
if (rtps->use_osmux)
|
||||
OSMO_STRBUF_PRINTF(sb, ":osmux-%d-%d", rtps->local_osmux_cid, rtps->remote_osmux_cid);
|
||||
|
||||
/* Replace any dots in the IP address, dots not allowed as FSM instance name */
|
||||
for (p = buf; *p; p++)
|
||||
|
@ -117,6 +125,8 @@ struct rtp_stream *rtp_stream_alloc(struct call_leg *parent_call_leg, enum rtp_d
|
|||
.call_id = call_id,
|
||||
.for_trans = for_trans,
|
||||
.dir = dir,
|
||||
.local_osmux_cid = -2,
|
||||
.remote_osmux_cid = -2,
|
||||
};
|
||||
|
||||
rtp_stream_update_id(rtps);
|
||||
|
@ -130,6 +140,7 @@ static void check_established(struct rtp_stream *rtps)
|
|||
&& osmo_sockaddr_str_is_set(&rtps->local)
|
||||
&& osmo_sockaddr_str_is_set(&rtps->remote)
|
||||
&& rtps->remote_sent_to_mgw
|
||||
&& (!rtps->use_osmux || rtps->remote_osmux_cid_sent_to_mgw)
|
||||
&& rtps->codec_known)
|
||||
rtp_stream_state_chg(rtps, RTP_STREAM_ST_ESTABLISHED);
|
||||
}
|
||||
|
@ -148,17 +159,27 @@ static void rtp_stream_fsm_establishing_established(struct osmo_fsm_inst *fi, ui
|
|||
}
|
||||
|
||||
osmo_sockaddr_str_from_str(&rtps->local, crcx_info->addr, crcx_info->port);
|
||||
if (rtps->use_osmux != crcx_info->x_osmo_osmux_use) {
|
||||
LOG_RTPS(rtps, LOGL_ERROR, "Osmux usage request and response don't match: %d vs %d",
|
||||
rtps->use_osmux, crcx_info->x_osmo_osmux_use);
|
||||
/* TODO: proper failure path */
|
||||
OSMO_ASSERT(rtps->use_osmux != crcx_info->x_osmo_osmux_use);
|
||||
}
|
||||
if (crcx_info->x_osmo_osmux_use)
|
||||
rtps->local_osmux_cid = crcx_info->x_osmo_osmux_cid;
|
||||
rtp_stream_update_id(rtps);
|
||||
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)
|
||||
&& osmo_sockaddr_str_is_set(&rtps->remote)
|
||||
&& (!rtps->use_osmux || rtps->remote_osmux_cid_sent_to_mgw)
|
||||
&& rtps->codec_known) {
|
||||
LOG_RTPS(rtps, LOGL_DEBUG,
|
||||
"local ip:port set;%s%s triggering MDCX to send the new settings\n",
|
||||
"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->codec_sent_to_mgw)? " codec not yet sent," : "",
|
||||
(rtps->use_osmux && !rtps->remote_osmux_cid_sent_to_mgw) ? "Osmux CID not yet sent,": "");
|
||||
rtp_stream_do_mdcx(rtps);
|
||||
}
|
||||
return;
|
||||
|
@ -172,6 +193,7 @@ static void rtp_stream_fsm_establishing_established(struct osmo_fsm_inst *fi, ui
|
|||
case RTP_STREAM_EV_MDCX_FAIL:
|
||||
rtps->remote_sent_to_mgw = false;
|
||||
rtps->codec_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);
|
||||
return;
|
||||
|
@ -280,6 +302,8 @@ static int rtp_stream_do_mgcp_verb(struct rtp_stream *rtps, enum mgcp_verb verb,
|
|||
verb_info = (struct mgcp_conn_peer){
|
||||
.call_id = rtps->call_id,
|
||||
.ptime = 20,
|
||||
.x_osmo_osmux_use = rtps->use_osmux,
|
||||
.x_osmo_osmux_cid = rtps->remote_osmux_cid,
|
||||
};
|
||||
|
||||
if (verb == MGCP_VERB_CRCX)
|
||||
|
@ -353,9 +377,10 @@ int rtp_stream_commit(struct rtp_stream *rtps)
|
|||
return 0;
|
||||
}
|
||||
|
||||
LOG_RTPS(rtps, LOGL_DEBUG, "Committing: Tx MDCX to update the MGW: updating%s%s\n",
|
||||
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->codec_sent_to_mgw ? "" : " codec",
|
||||
(!rtps->use_osmux || rtps->remote_osmux_cid_sent_to_mgw) ? "" : " remote-Osmux-CID");
|
||||
return rtp_stream_do_mdcx(rtps);
|
||||
}
|
||||
|
||||
|
@ -380,6 +405,16 @@ void rtp_stream_set_remote_addr(struct rtp_stream *rtps, const struct osmo_socka
|
|||
rtp_stream_update_id(rtps);
|
||||
}
|
||||
|
||||
void rtp_stream_set_remote_osmux_cid(struct rtp_stream *rtps, uint8_t osmux_cid)
|
||||
{
|
||||
if (rtps->fi->state == RTP_STREAM_ST_ESTABLISHED)
|
||||
rtp_stream_state_chg(rtps, RTP_STREAM_ST_ESTABLISHING);
|
||||
LOG_RTPS(rtps, LOGL_DEBUG, "setting remote Osmux CID to %u\n", osmux_cid);
|
||||
rtps->remote_osmux_cid = osmux_cid;
|
||||
rtps->remote_osmux_cid_sent_to_mgw = false;
|
||||
rtp_stream_update_id(rtps);
|
||||
}
|
||||
|
||||
bool rtp_stream_is_established(struct rtp_stream *rtps)
|
||||
{
|
||||
if (!rtps)
|
||||
|
@ -389,7 +424,8 @@ 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->codec_sent_to_mgw
|
||||
|| (rtps->use_osmux && !rtps->remote_osmux_cid_sent_to_mgw))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue