[PATCH 7/9] Allow dynamic RTP payload types between application and MNCC interface

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/OpenBSC@lists.osmocom.org/.

Andreas Eversberg jolly at eversberg.eu
Wed Feb 19 06:57:56 UTC 2014


Since EFR/AMR/HR codecs use dynamic RTP payload, the payload type can
be set. If it is set, the frame type must be set also, so OpenBSC
knows what frame types are received via RTP.

This modification only affects traffic beween application and MNCC
interface, not the RTP traffic between OpenBSC and BTS.
---
 openbsc/include/openbsc/mncc.h      |  2 ++
 openbsc/include/openbsc/rtp_proxy.h |  2 ++
 openbsc/src/libmsc/gsm_04_08.c      |  2 ++
 openbsc/src/libtrau/rtp_proxy.c     | 57 ++++++++++++++++++++++++++-----------
 4 files changed, 46 insertions(+), 17 deletions(-)

diff --git a/openbsc/include/openbsc/mncc.h b/openbsc/include/openbsc/mncc.h
index 32a60e9..46ba237 100644
--- a/openbsc/include/openbsc/mncc.h
+++ b/openbsc/include/openbsc/mncc.h
@@ -187,6 +187,8 @@ struct gsm_mncc_rtp {
 	uint32_t	callref;
 	uint32_t	ip;
 	uint16_t	port;
+	uint32_t	payload_type;
+	uint32_t	payload_msg_type;
 };
 
 char *get_mncc_name(int value);
diff --git a/openbsc/include/openbsc/rtp_proxy.h b/openbsc/include/openbsc/rtp_proxy.h
index a5f6a2b..61ad325 100644
--- a/openbsc/include/openbsc/rtp_proxy.h
+++ b/openbsc/include/openbsc/rtp_proxy.h
@@ -74,6 +74,8 @@ struct rtp_socket {
 		struct {
 			struct gsm_network *net;
 			uint32_t callref;
+			uint8_t payload_type; /* dynamic PT */
+			int msg_type; /* message type for dynamic PT */
 		} receive;
 	};
 	enum rtp_tx_action tx_action;
diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c
index ed3785d..663d855 100644
--- a/openbsc/src/libmsc/gsm_04_08.c
+++ b/openbsc/src/libmsc/gsm_04_08.c
@@ -1760,6 +1760,8 @@ static int mncc_rtp_connect(struct gsm_network *net, struct gsm_trans *trans,
 			(struct gsm_mncc *)mncc);
 		return -EIO;
 	}
+	rs->receive.msg_type = mncc->payload_msg_type;
+	rs->receive.payload_type = mncc->payload_type;
 	/* reply with local IP/port */
 	mncc->ip = ntohl(rs->rtp.sin_local.sin_addr.s_addr);
 	mncc->port = ntohs(rs->rtp.sin_local.sin_port);
diff --git a/openbsc/src/libtrau/rtp_proxy.c b/openbsc/src/libtrau/rtp_proxy.c
index d2bf88d..d4dbe02 100644
--- a/openbsc/src/libtrau/rtp_proxy.c
+++ b/openbsc/src/libtrau/rtp_proxy.c
@@ -106,7 +106,7 @@ struct rtp_x_hdr {
 #define RTP_VERSION	2
 
 /* decode an rtp frame and create a new buffer with payload */
-static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data)
+static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data, int msg_type)
 {
 	struct msgb *new_msg;
 	struct gsm_data_frame *frame;
@@ -114,7 +114,6 @@ static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data)
 	struct rtp_x_hdr *rtpxh;
 	uint8_t *payload;
 	int payload_len;
-	int msg_type;
 	int x_len;
 	int is_amr = 0;
 
@@ -165,9 +164,31 @@ static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data)
 		}
 	}
 
-	switch (rtph->payload_type) {
-	case RTP_PT_GSM_FULL:
-		msg_type = GSM_TCHF_FRAME;
+	/* If no explicit frame type is given, select frame type from
+	 * payload type. */
+	if (!msg_type) {
+		switch (rtph->payload_type) {
+		case RTP_PT_GSM_FULL:
+			msg_type = GSM_TCHF_FRAME;
+			break;
+		case RTP_PT_GSM_EFR:
+			msg_type = GSM_TCHF_FRAME_EFR;
+			break;
+		case RTP_PT_GSM_HALF:
+			msg_type = GSM_TCHH_FRAME;
+			break;
+		case RTP_PT_AMR:
+			msg_type = GSM_TCH_FRAME_AMR;
+			break;
+		default:
+			DEBUGPC(DLMUX, "received RTP frame with unknown "
+				"payload type %d\n", rtph->payload_type);
+			return -EINVAL;
+		}
+	}
+
+	switch (msg_type) {
+	case GSM_TCHF_FRAME:
 		if (payload_len != RTP_LEN_GSM_FULL) {
 			DEBUGPC(DLMUX, "received RTP full rate frame with "
 				"payload length != %d (len = %d)\n",
@@ -175,8 +196,7 @@ static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data)
 			return -EINVAL;
 		}
 		break;
-	case RTP_PT_GSM_EFR:
-		msg_type = GSM_TCHF_FRAME_EFR;
+	case GSM_TCHF_FRAME_EFR:
 		if (payload_len != RTP_LEN_GSM_EFR) {
 			DEBUGPC(DLMUX, "received RTP extended full rate frame "
 				"with payload length != %d (len = %d)\n",
@@ -184,8 +204,7 @@ static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data)
 			return -EINVAL;
 		}
 		break;
-	case RTP_PT_GSM_HALF:
-		msg_type = GSM_TCHH_FRAME;
+	case GSM_TCHH_FRAME:
 		if (payload_len != RTP_LEN_GSM_HALF) {
 			DEBUGPC(DLMUX, "received RTP half rate frame with "
 				"payload length != %d (len = %d)\n",
@@ -193,12 +212,11 @@ static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data)
 			return -EINVAL;
 		}
 		break;
-	case RTP_PT_AMR:
+	case GSM_TCH_FRAME_AMR:
 		is_amr = 1;
 		break;
 	default:
-		DEBUGPC(DLMUX, "received RTP frame with unknown payload "
-			"type %d\n", rtph->payload_type);
+		DEBUGPC(DLMUX, "Forced message type %x unknown\n", msg_type);
 		return -EINVAL;
 	}
 
@@ -246,6 +264,10 @@ int rtp_send_frame(struct rtp_socket *rs, struct gsm_data_frame *frame)
 	int payload_len;
 	int duration; /* in samples */
 	int is_amr = 0, is_bfi = 0;
+	uint8_t dynamic_pt = 0;
+
+	if (rs->rx_action == RTP_RECV_APP)
+		dynamic_pt = rs->receive.payload_type;
 
 	if (rs->tx_action != RTP_SEND_DOWNSTREAM) {
 		/* initialize sequences */
@@ -262,17 +284,17 @@ int rtp_send_frame(struct rtp_socket *rs, struct gsm_data_frame *frame)
 		duration = RTP_GSM_DURATION;
 		break;
 	case GSM_TCHF_FRAME_EFR:
-		payload_type = RTP_PT_GSM_EFR;
+		payload_type = (dynamic_pt) ? : RTP_PT_GSM_EFR;
 		payload_len = RTP_LEN_GSM_EFR;
 		duration = RTP_GSM_DURATION;
 		break;
 	case GSM_TCHH_FRAME:
-		payload_type = RTP_PT_GSM_HALF;
+		payload_type = (dynamic_pt) ? : RTP_PT_GSM_HALF;
 		payload_len = RTP_LEN_GSM_HALF;
 		duration = RTP_GSM_DURATION;
 		break;
 	case GSM_TCH_FRAME_AMR:
-		payload_type = RTP_PT_AMR;
+		payload_type = (dynamic_pt) ? : RTP_PT_AMR;
 		payload_len = frame->data[0];
 		duration = RTP_GSM_DURATION;
 		is_amr = 1;
@@ -495,7 +517,7 @@ static int rtp_socket_read(struct rtp_socket *rs, struct rtp_sub_socket *rss)
 			rc = -EINVAL;
 			goto out_free;
 		}
-		rc = rtp_decode(msg, rs->receive.callref, &new_msg);
+		rc = rtp_decode(msg, rs->receive.callref, &new_msg, 0);
 		if (rc < 0)
 			goto out_free;
 		msgb_free(msg);
@@ -511,7 +533,8 @@ static int rtp_socket_read(struct rtp_socket *rs, struct rtp_sub_socket *rss)
 			rc = ENOTSUP;
 			goto out_free;
 		}
-		rc = rtp_decode(msg, rs->receive.callref, &new_msg);
+		rc = rtp_decode(msg, rs->receive.callref, &new_msg,
+			rs->receive.msg_type);
 		if (rc < 0)
 			goto out_free;
 		msgb_free(msg);
-- 
1.8.1.5





More information about the OpenBSC mailing list