aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeels Hofmeyr <nhofmeyr@sysmocom.de>2023-03-05 04:58:36 +0100
committerNeels Hofmeyr <nhofmeyr@sysmocom.de>2023-03-05 04:58:36 +0100
commit341b3185293129ece88acfdc2404f9e5c53a6ac0 (patch)
treeb26fe917db9998fed0650d1540a4c322bab7c07e
parentecf764652ce3263d8e6d7c413b04a66e2eab0524 (diff)
wip
-rw-r--r--include/osmocom/msc/codec_filter.h3
-rw-r--r--src/libmsc/codec_filter.c15
-rw-r--r--src/libmsc/gsm_04_08_cc.c29
3 files changed, 44 insertions, 3 deletions
diff --git a/include/osmocom/msc/codec_filter.h b/include/osmocom/msc/codec_filter.h
index 16315c791..1b027a8c9 100644
--- a/include/osmocom/msc/codec_filter.h
+++ b/include/osmocom/msc/codec_filter.h
@@ -25,6 +25,7 @@
#include <osmocom/msc/sdp_msg.h>
+struct osmo_sockaddr;
struct gsm0808_speech_codec_list;
/* Combine various codec selections to obtain a resulting set of codecs allowed by all of them.
@@ -58,6 +59,8 @@ void codec_filter_set_ms_from_bc(struct codec_filter *codec_filter, const struct
void codec_filter_set_bss(struct codec_filter *codec_filter,
const struct gsm0808_speech_codec_list *codec_list_bss_supported);
int codec_filter_set_remote(struct codec_filter *codec_filter, const char *remote_sdp);
+int codec_filter_set_remote_rtp_osa(struct codec_filter *codec_filter, const struct osmo_sockaddr *rtp);
+int codec_filter_set_remote_codec_pt(struct codec_filter *codec_filter, enum mgcp_codecs pt);
void codec_filter_set_local_rtp(struct codec_filter *codec_filter, const struct osmo_sockaddr_str *rtp);
int codec_filter_run(struct codec_filter *codec_filter);
diff --git a/src/libmsc/codec_filter.c b/src/libmsc/codec_filter.c
index c77aeb9ce..6549fb251 100644
--- a/src/libmsc/codec_filter.c
+++ b/src/libmsc/codec_filter.c
@@ -22,6 +22,7 @@
*/
#include <osmocom/gsm/protocol/gsm_08_08.h>
+#include <osmocom/core/socket.h>
#include <osmocom/msc/codec_filter.h>
#include <osmocom/msc/codec_mapping.h>
@@ -101,6 +102,20 @@ int codec_filter_set_remote(struct codec_filter *codec_filter, const char *remot
return sdp_msg_from_sdp_str(&codec_filter->remote, remote_sdp);
}
+int codec_filter_set_remote_rtp_osa(struct codec_filter *codec_filter, const struct osmo_sockaddr *rtp)
+{
+ return osmo_sockaddr_str_from_sockaddr(&codec_filter->remote.rtp, &rtp->u.sas);
+}
+
+int codec_filter_set_remote_codec_pt(struct codec_filter *codec_filter, enum mgcp_codecs pt)
+{
+ const struct codec_mapping *m = codec_mapping_by_mgcp_codec(pt);
+ if (!m)
+ return -EINVAL;
+ sdp_audio_codecs_add_copy(&codec_filter->remote.audio_codecs, &m->sdp);
+ return 0;
+}
+
void codec_filter_set_local_rtp(struct codec_filter *codec_filter, const struct osmo_sockaddr_str *rtp)
{
if (!rtp)
diff --git a/src/libmsc/gsm_04_08_cc.c b/src/libmsc/gsm_04_08_cc.c
index 718ca5834..bcd573e5c 100644
--- a/src/libmsc/gsm_04_08_cc.c
+++ b/src/libmsc/gsm_04_08_cc.c
@@ -1886,9 +1886,13 @@ static void mncc_recv_rtp_err(struct gsm_network *net, struct gsm_trans *trans,
mncc_recv_rtp(net, trans, callref, cmd, NULL, 0, 0, NULL);
}
-static int tch_rtp_create(struct gsm_network *net, uint32_t callref)
+static int tch_rtp_create(struct gsm_network *net, const struct gsm_mncc_rtp *rtp_msg)
{
struct gsm_trans *trans;
+ uint32_t callref = rtp_msg->callref;
+ struct osmo_sockaddr rtp_addr;
+ struct call_leg *cl;
+ struct rtp_stream *rtp_cn;
/* Find callref */
trans = trans_find_by_callref(net, callref);
@@ -1906,7 +1910,26 @@ static int tch_rtp_create(struct gsm_network *net, uint32_t callref)
LOG_TRANS_CAT(trans, DMNCC, LOGL_DEBUG, "rx %s\n", get_mncc_name(MNCC_RTP_CREATE));
/* Assign call (if not done yet) */
- return msc_a_try_call_assignment(trans);
+ msc_a_try_call_assignment(trans);
+
+ /* Update remote RTP and codec info */
+ if (rtp_msg->sdp[0]) {
+ /* SDP present */
+ codec_filter_set_remote(&trans->cc.codecs, rtp_msg->sdp);
+ } else {
+ /* No SDP present, use legacy items */
+ rtp_addr.u.sas = rtp_msg->addr;
+ codec_filter_set_remote_rtp_osa(&trans->cc.codecs, &rtp_addr);
+ codec_filter_set_remote_codec_pt(&trans->cc.codecs, rtp_msg->payload_msg_type);
+ }
+ cl = trans->msc_a->cc.call_leg;
+ rtp_cn = cl ? cl->rtp[RTP_TO_CN] : NULL;
+ if (rtp_cn) {
+ rtp_stream_set_remote_addr_and_codecs(rtp_cn, &trans->cc.codecs.remote);
+ rtp_stream_commit(rtp_cn);
+ }
+
+ return 0;
}
int cc_on_cn_local_rtp_port_known(struct gsm_trans *cc_trans)
@@ -2152,7 +2175,7 @@ static int mncc_tx_to_gsm_cc(struct gsm_network *net, const union mncc_msg *msg)
disconnect_bridge(net, &msg->bridge, -rc);
return rc;
case MNCC_RTP_CREATE:
- return tch_rtp_create(net, msg->rtp.callref);
+ return tch_rtp_create(net, &msg->rtp);
case MNCC_RTP_CONNECT:
return tch_rtp_connect(net, &msg->rtp);
case MNCC_RTP_FREE: