[PATCH 4/9] Add support for AMR frames to MNCC/RTP 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 Jan 22 09:05:53 UTC 2014


AMR rate is currently fixed to 5.9k.
---
 openbsc/include/openbsc/mncc.h    |  1 +
 openbsc/src/libmsc/gsm_04_08.c    |  1 +
 openbsc/src/libmsc/mncc.c         |  5 ++++-
 openbsc/src/libmsc/mncc_builtin.c |  2 ++
 openbsc/src/libmsc/mncc_sock.c    |  3 ++-
 openbsc/src/libtrau/rtp_proxy.c   | 21 +++++++++++++++++----
 6 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/openbsc/include/openbsc/mncc.h b/openbsc/include/openbsc/mncc.h
index ec4dac9..45ad83e 100644
--- a/openbsc/include/openbsc/mncc.h
+++ b/openbsc/include/openbsc/mncc.h
@@ -96,6 +96,7 @@ struct gsm_call {
 #define GSM_TCHF_FRAME		0x0300
 #define GSM_TCHF_FRAME_EFR	0x0301
 #define GSM_TCHH_FRAME		0x0302
+#define GSM_TCH_FRAME_AMR	0x0303
 #define GSM_TCHF_BAD_FRAME	0x03ff
 
 #define MNCC_SOCKET_HELLO	0x0400
diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c
index 46ad719..e36a142 100644
--- a/openbsc/src/libmsc/gsm_04_08.c
+++ b/openbsc/src/libmsc/gsm_04_08.c
@@ -2946,6 +2946,7 @@ int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg)
 	case GSM_TCHF_FRAME:
 	case GSM_TCHF_FRAME_EFR:
 	case GSM_TCHH_FRAME:
+	case GSM_TCH_FRAME_AMR:
 		/* Find callref */
 		trans = trans_find_by_callref(net, data->callref);
 		if (!trans) {
diff --git a/openbsc/src/libmsc/mncc.c b/openbsc/src/libmsc/mncc.c
index b484772..01e9c67 100644
--- a/openbsc/src/libmsc/mncc.c
+++ b/openbsc/src/libmsc/mncc.c
@@ -84,7 +84,10 @@ static struct mncc_names {
 	{"MNCC_FRAME_DROP",	0x0202},
 	{"MNCC_LCHAN_MODIFY",	0x0203},
 
-	{"GSM_TCH_FRAME",	0x0300},
+	{"GSM_TCHF_FRAME",	0x0300},
+	{"GSM_TCHF_FRAME_EFR",	0x0301},
+	{"GSM_TCHH_FRAME",	0x0302},
+	{"GSM_TCH_FRAME_AMR",	0x0303},
 
 	{NULL, 0} };
 
diff --git a/openbsc/src/libmsc/mncc_builtin.c b/openbsc/src/libmsc/mncc_builtin.c
index 506d004..5d71983 100644
--- a/openbsc/src/libmsc/mncc_builtin.c
+++ b/openbsc/src/libmsc/mncc_builtin.c
@@ -343,6 +343,7 @@ int int_mncc_recv(struct gsm_network *net, struct msgb *msg)
 	case GSM_TCHF_FRAME:
 	case GSM_TCHF_FRAME_EFR:
 	case GSM_TCHH_FRAME:
+	case GSM_TCH_FRAME_AMR:
 		break;
 	default:
 		DEBUGP(DMNCC, "(call %x) Received message %s\n", call->callref,
@@ -412,6 +413,7 @@ int int_mncc_recv(struct gsm_network *net, struct msgb *msg)
 	case GSM_TCHF_FRAME:
 	case GSM_TCHF_FRAME_EFR:
 	case GSM_TCHH_FRAME:
+	case GSM_TCH_FRAME_AMR:
 		rc = mncc_rcv_tchf(call, msg_type, arg);
 		break;
 	default:
diff --git a/openbsc/src/libmsc/mncc_sock.c b/openbsc/src/libmsc/mncc_sock.c
index 8d8e505..4a880c7 100644
--- a/openbsc/src/libmsc/mncc_sock.c
+++ b/openbsc/src/libmsc/mncc_sock.c
@@ -56,7 +56,8 @@ int mncc_sock_from_cc(struct gsm_network *net, struct msgb *msg)
 			"but socket is gone\n", get_mncc_name(msg_type));
 		if (msg_type != GSM_TCHF_FRAME
 		 && msg_type != GSM_TCHF_FRAME_EFR
-		 && msg_type != GSM_TCHH_FRAME) {
+		 && msg_type != GSM_TCHH_FRAME
+		 && msg_type != GSM_TCH_FRAME_AMR) {
 			/* release the request */
 			struct gsm_mncc mncc_out;
 			memset(&mncc_out, 0, sizeof(mncc_out));
diff --git a/openbsc/src/libtrau/rtp_proxy.c b/openbsc/src/libtrau/rtp_proxy.c
index 2587e12..59efa21 100644
--- a/openbsc/src/libtrau/rtp_proxy.c
+++ b/openbsc/src/libtrau/rtp_proxy.c
@@ -116,6 +116,7 @@ static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data)
 	int payload_len;
 	int msg_type;
 	int x_len;
+	int amr = 0;
 
 	if (msg->len < 12) {
 		DEBUGPC(DLMUX, "received RTP frame too short (len = %d)\n",
@@ -192,21 +193,26 @@ static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data)
 			return -EINVAL;
 		}
 		break;
+	case RTP_PT_AMR:
+		amr = 1;
+		break;
 	default:
 		DEBUGPC(DLMUX, "received RTP frame with unknown payload "
 			"type %d\n", rtph->payload_type);
 		return -EINVAL;
 	}
 
-	new_msg = msgb_alloc(sizeof(struct gsm_data_frame) + payload_len,
+	new_msg = msgb_alloc(sizeof(struct gsm_data_frame) + payload_len + amr,
 				"GSM-DATA");
 	if (!new_msg)
 		return -ENOMEM;
 	frame = (struct gsm_data_frame *)(new_msg->data);
 	frame->msg_type = msg_type;
 	frame->callref = callref;
-	memcpy(frame->data, payload, payload_len);
-	msgb_put(new_msg, sizeof(struct gsm_data_frame) + payload_len);
+	if (amr)
+		frame->data[0] = payload_len;
+	memcpy(frame->data + amr, payload, payload_len);
+	msgb_put(new_msg, sizeof(struct gsm_data_frame) + amr + payload_len);
 
 	*data = new_msg;
 	return 0;
@@ -239,6 +245,7 @@ int rtp_send_frame(struct rtp_socket *rs, struct gsm_data_frame *frame)
 	int payload_type;
 	int payload_len;
 	int duration; /* in samples */
+	int amr = 0;
 
 	if (rs->tx_action != RTP_SEND_DOWNSTREAM) {
 		/* initialize sequences */
@@ -264,6 +271,12 @@ int rtp_send_frame(struct rtp_socket *rs, struct gsm_data_frame *frame)
 		payload_len = RTP_LEN_GSM_HALF;
 		duration = RTP_GSM_DURATION;
 		break;
+	case GSM_TCH_FRAME_AMR:
+		payload_type = RTP_PT_AMR;
+		payload_len = frame->data[0];
+		duration = RTP_GSM_DURATION;
+		amr = 1;
+		break;
 	default:
 		DEBUGPC(DLMUX, "unsupported message type %d\n",
 			frame->msg_type);
@@ -305,7 +318,7 @@ int rtp_send_frame(struct rtp_socket *rs, struct gsm_data_frame *frame)
 	rtph->timestamp = htonl(rs->transmit.timestamp);
 	rs->transmit.timestamp += duration;
 	rtph->ssrc = htonl(rs->transmit.ssrc);
-	memcpy(msg->data + sizeof(struct rtp_hdr), frame->data, payload_len);
+	memcpy(msg->data + sizeof(struct rtp_hdr), frame->data + amr, payload_len);
 	msgb_put(msg, sizeof(struct rtp_hdr) + payload_len);
 	msgb_enqueue(&rss->tx_queue, msg);
 	rss->bfd.when |= BSC_FD_WRITE;
-- 
1.8.1.5





More information about the OpenBSC mailing list