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.orgHello 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>