[PATCH] libosmo-netif[master]: osmux: Add RTP marker bit support

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/gerrit-log@lists.osmocom.org/.

Pau Espin Pedrol gerrit-no-reply at lists.osmocom.org
Wed Apr 26 09:25:13 UTC 2017


Hello Jenkins Builder,

I'd like you to reexamine a change.  Please visit

    https://gerrit.osmocom.org/2407

to look at the new patch set (#2).

osmux: Add RTP marker bit support

According to RFC4867 (RTP payload format for AMR):
"The RTP header marker bit (M) SHALL be set to 1 if the first frameblock
carried in the packet contains a speech frame which is the first in a
talkspurt.  For all other packets the marker bit SHALL be set to zero (M=0)."

This information bit provides a way for the receiver to better
synchronize the delay with ther sender.

This is specially useful if AMR DTX features are supported and
enabled on the sender.

Change-Id: I0315658159429603f1d80a168718b026015060e9
---
M include/osmocom/netif/osmux.h
M src/osmux.c
M tests/osmux/osmux_test.c
3 files changed, 81 insertions(+), 7 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/libosmo-netif refs/changes/07/2407/2

diff --git a/include/osmocom/netif/osmux.h b/include/osmocom/netif/osmux.h
index 1d93aa0..5283059 100644
--- a/include/osmocom/netif/osmux.h
+++ b/include/osmocom/netif/osmux.h
@@ -13,7 +13,8 @@
 
 /* OSmux header:
  *
- *	ft (3 bits):		0=signalling, 1=voice, 2=dummy
+ *	rtp_m (1 bit):		RTP M field (RFC3550, RFC4867)
+ *	ft (2 bits):		0=signalling, 1=voice, 2=dummy
  *	ctr (3 bits):		Number of batched AMR payloads (starting 0)
  *	amr_f (1 bit):		AMR F field (RFC3267)
  *	amr_q (1 bit): 		AMR Q field (RFC3267)
@@ -29,7 +30,8 @@
 
 struct osmux_hdr {
 #if OSMO_IS_BIG_ENDIAN
-	uint8_t ft:3,
+	uint8_t rtp_m:1,
+		ft:2,
 		ctr:3,
 		amr_f:1,
 		amr_q:1;
@@ -37,7 +39,8 @@
 	uint8_t amr_q:1,
 		amr_f:1,
 		ctr:3,
-		ft:3;
+		ft:2,
+		rtp_m:1;
 #endif
 	uint8_t seq;
 #define OSMUX_CID_MAX		255	/* determined by circuit_id */
diff --git a/src/osmux.c b/src/osmux.c
index 1dcd04f..4d12427 100644
--- a/src/osmux.c
+++ b/src/osmux.c
@@ -105,8 +105,8 @@
 }
 
 static struct msgb *
-osmux_rebuild_rtp(struct osmux_out_handle *h,
-		  struct osmux_hdr *osmuxh, void *payload, int payload_len)
+osmux_rebuild_rtp(struct osmux_out_handle *h, struct osmux_hdr *osmuxh,
+		  void *payload, int payload_len, bool first_pkt)
 {
 	struct msgb *out_msg;
 	struct rtp_hdr *rtph;
@@ -129,6 +129,8 @@
 	rtph->timestamp = htonl(h->rtp_timestamp);
 	rtph->sequence = htons(h->rtp_seq);
 	rtph->ssrc = htonl(h->rtp_ssrc);
+	/* rtp packet with the marker bit is always warranted to be the first one */
+	rtph->marker = first_pkt && osmuxh->rtp_m;
 
 	msgb_put(out_msg, sizeof(struct rtp_hdr));
 
@@ -166,7 +168,7 @@
 		msg = osmux_rebuild_rtp(h, osmuxh,
 					osmux_get_payload(osmuxh) +
 					i * osmo_amr_bytes(osmuxh->amr_ft),
-					osmo_amr_bytes(osmuxh->amr_ft));
+					osmo_amr_bytes(osmuxh->amr_ft), !i);
 		if (msg == NULL)
 			continue;
 
@@ -264,6 +266,7 @@
 		osmuxh = (struct osmux_hdr *)state->out_msg->tail;
 		osmuxh->ft = OSMUX_FT_VOICE_AMR;
 		osmuxh->ctr = 0;
+		osmuxh->rtp_m = osmuxh->rtp_m || state->rtph->marker;
 		osmuxh->amr_f = state->amrh->f;
 		osmuxh->amr_q= state->amrh->q;
 		osmuxh->seq = batch->seq++;
@@ -593,6 +596,13 @@
 	if (bytes > batch->remaining_bytes)
 		return 1;
 
+	/* Init of talkspurt (RTP M marker bit) needs to be in the first AMR slot
+	 * of the OSMUX packet, enforce sending previous batch if required:
+	 */
+	if (rtph->marker && circuit->nmsgs != 0)
+		return 1;
+
+
 	/* Extra validation: check if this message already exists, should not
 	 * happen but make sure we don't propagate duplicated messages.
 	 */
diff --git a/tests/osmux/osmux_test.c b/tests/osmux/osmux_test.c
index 2f5a6cd..8b0a56c 100644
--- a/tests/osmux/osmux_test.c
+++ b/tests/osmux/osmux_test.c
@@ -55,6 +55,7 @@
 };
 
 static int rtp_pkts;
+static int mark_pkts;
 #if OSMUX_TEST_USE_TIMING
 static struct timeval last;
 #endif
@@ -62,6 +63,7 @@
 static void tx_cb(struct msgb *msg, void *data)
 {
 	char buf[4096];
+	struct rtp_hdr *rtph = (struct rtp_hdr *)msg->data;
 #if OSMUX_TEST_USE_TIMING
 	struct timeval now, diff;
 
@@ -87,6 +89,8 @@
 		exit(EXIT_FAILURE);
 	}
 
+	if (rtph->marker)
+		mark_pkts--;
 	rtp_pkts--;
 	msgb_free(msg);
 }
@@ -122,6 +126,48 @@
 {
 	printf("FAIL: test did not run successfully\n");
 	exit(EXIT_FAILURE);
+}
+
+static void osmux_test_marker(int ccid) {
+	struct msgb *msg;
+	struct rtp_hdr *rtph = (struct rtp_hdr *)rtp_pkt;
+	struct rtp_hdr *cpy_rtph;
+	uint16_t seq;
+	int i, j;
+
+	for (i = 0; i < 64; i++) {
+
+		seq = ntohs(rtph->sequence);
+		seq++;
+		rtph->sequence = htons(seq);
+
+		for (j=0; j<4; j++) {
+			msg = msgb_alloc(1500, "test");
+			if (!msg)
+				exit(EXIT_FAILURE);
+
+			memcpy(msg->data, rtp_pkt, sizeof(rtp_pkt));
+			cpy_rtph = (struct rtp_hdr *) msgb_put(msg, sizeof(rtp_pkt));
+
+			if ((i+j) % 7 == 0) {
+				cpy_rtph->marker = 1;
+				mark_pkts++;
+			}
+
+			rtp_pkts++;
+			while (osmux_xfrm_input(&h_input, msg, j + ccid) > 0) {
+				osmux_xfrm_input_deliver(&h_input);
+			}
+		}
+	}
+
+	while (rtp_pkts)
+		osmo_select_main(0);
+
+	if (mark_pkts) {
+		fprintf(stdout, "RTP M bit (marker) mismatch! %d\n", mark_pkts);
+		exit(EXIT_FAILURE);
+	}
 }
 
 static void osmux_test_loop(int ccid)
@@ -177,6 +223,11 @@
 			k = 0;
 		}
 	}
+
+	if (mark_pkts) {
+		fprintf(stdout, "RTP M bit (marker) mismatch! %d\n", mark_pkts);
+		exit(EXIT_FAILURE);
+	}
 }
 
 int main(void)
@@ -192,12 +243,22 @@
 	osmo_init_logging(&osmux_test_log_info);
 	log_set_log_level(osmo_stderr_target, LOGL_DEBUG);
 
-	osmux_xfrm_input_init(&h_input);
 	osmux_xfrm_output_init(&h_output, 0x7000000);
 
 	/* If the test takes longer than 10 seconds, abort it */
 	alarm(10);
 
+	/* Check if marker bit features work correctly */
+	osmux_xfrm_input_init(&h_input);
+	for (i = 0; i < 4; i++)
+		osmux_xfrm_input_open_circuit(&h_input, i, 0);
+	osmux_test_marker(0);
+	for (i = 0; i < 4; i++)
+		osmux_xfrm_input_close_circuit(&h_input, i);
+	osmux_xfrm_input_fini(&h_input);
+
+	osmux_xfrm_input_init(&h_input);
+
 	for (i = 0; i < 2; i++)
 		osmux_xfrm_input_open_circuit(&h_input, i, 0);
 

-- 
To view, visit https://gerrit.osmocom.org/2407
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newpatchset
Gerrit-Change-Id: I0315658159429603f1d80a168718b026015060e9
Gerrit-PatchSet: 2
Gerrit-Project: libosmo-netif
Gerrit-Branch: master
Gerrit-Owner: Pau Espin Pedrol <pespin at sysmocom.de>
Gerrit-Reviewer: Harald Welte <laforge at gnumonks.org>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: Pau Espin Pedrol <pespin at sysmocom.de>
Gerrit-Reviewer: daniel <dwillmann at sysmocom.de>



More information about the gerrit-log mailing list