changeset 24:84d427017d2f

endp: implement RTP Tx
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 07 Jul 2024 07:33:48 +0000
parents 9e477a4b485a
children e67b3bb87d1b
files include/endp.h src/Makefile src/endp_create.c src/rtp_tx.c
diffstat 4 files changed, 98 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/include/endp.h	Sun Jul 07 06:27:56 2024 +0000
+++ b/include/endp.h	Sun Jul 07 07:33:48 2024 +0000
@@ -64,3 +64,7 @@
 
 void twrtp_endp_set_remote_ipv4(struct twrtp_endp *endp,
 				const struct in_addr *ip, uint16_t port);
+
+int twrtp_endp_tx_quantum(struct twrtp_endp *endp, const uint8_t *payload,
+			  unsigned payload_len, uint8_t payload_type,
+			  bool marker, bool send_rtcp);
--- a/src/Makefile	Sun Jul 07 06:27:56 2024 +0000
+++ b/src/Makefile	Sun Jul 07 07:33:48 2024 +0000
@@ -1,5 +1,5 @@
 OBJS=	bind_fdpair.o endp_bind.o endp_create.o endp_register.o rtp_rx.o \
-	set_remote.o twjit.o twjit_in.o twjit_out.o twjit_vty.o
+	rtp_tx.o set_remote.o twjit.o twjit_in.o twjit_out.o twjit_vty.o
 LIB=	libtwrtp.a
 
 include ../config.defs
--- a/src/endp_create.c	Sun Jul 07 06:27:56 2024 +0000
+++ b/src/endp_create.c	Sun Jul 07 07:33:48 2024 +0000
@@ -4,7 +4,7 @@
 
 #include <stdint.h>
 #include <stdbool.h>
-#include <string.h>
+#include <stdlib.h>
 
 #include <osmocom/core/talloc.h>
 #include <osmocom/core/osmo_io.h>
@@ -48,6 +48,7 @@
 		return NULL;
 	}
 
+	endp->tx.ssrc = random();
 	return endp;
 }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/rtp_tx.c	Sun Jul 07 07:33:48 2024 +0000
@@ -0,0 +1,91 @@
+/*
+ * Here we implement RTP Tx functionality.
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+#include <errno.h>
+
+#include <osmocom/core/msgb.h>
+#include <osmocom/core/osmo_io.h>
+#include <osmocom/core/timer.h>
+
+#include <themwi/rtp/endp.h>
+#include <themwi/rtp/rtp_basic_hdr.h>
+#include <themwi/rtp/twjit.h>
+
+static uint32_t gen_timestamp(struct timespec *now,
+			      struct twrtp_jibuf_inst *twjit)
+{
+	uint32_t ts;
+
+	ts = now->tv_sec * twjit->ts_units_per_sec +
+	     now->tv_nsec / twjit->ns_to_ts_units;
+	return ts;
+}
+
+int twrtp_endp_tx_quantum(struct twrtp_endp *endp, const uint8_t *payload,
+			  unsigned payload_len, uint8_t payload_type,
+			  bool marker, bool send_rtcp)
+{
+	uint32_t ts_quantum = endp->twjit->ts_quantum;
+	struct msgb *msg;
+	struct timespec now;
+	uint32_t restart_ts;
+	int32_t ts_delta;
+	struct rtp_basic_hdr *rtph;
+	uint8_t *pl_out;
+	int rc;
+
+	if (!endp->register_done || !endp->remote_set)
+		return -EINVAL;
+	msg = msgb_alloc_c(endp, sizeof(struct rtp_basic_hdr) + payload_len,
+			   "ThemWi-RTP-Tx");
+	if (!msg)
+		return -ENOMEM;
+
+	/* timestamp generation is where we do some trickery */
+	osmo_clock_gettime(CLOCK_REALTIME, &now);
+	if (!endp->tx.started) {
+		endp->tx.ts = gen_timestamp(&now, endp->twjit);
+		endp->tx.started = true;
+		endp->tx.restart = false;
+	} else if (endp->tx.restart) {
+		restart_ts = gen_timestamp(&now, endp->twjit);
+		ts_delta = (int32_t)(restart_ts - endp->tx.ts);
+		if (ts_delta <= 0) {
+			/* shouldn't happen, unless something funky w/clock */
+			endp->tx.ts++;
+		} else {
+			if (ts_delta % ts_quantum == 0)
+				restart_ts++;
+			endp->tx.ts = restart_ts;
+		}
+		endp->tx.restart = false;
+	}
+
+	rtph = (struct rtp_basic_hdr *)
+			msgb_put(msg, sizeof(struct rtp_basic_hdr));
+	rtph->v_p_x_cc = 0x80;
+	rtph->m_pt = payload_type;
+	if (marker)
+		rtph->m_pt |= 0x80;
+	rtph->ssrc = endp->tx.ssrc;
+	rtph->seq = endp->tx.seq;
+	rtph->tstamp = endp->tx.ts;
+	pl_out = msgb_put(msg, payload_len);
+	memcpy(pl_out, payload, payload_len);
+	endp->tx.seq++;
+	endp->tx.ts += ts_quantum;
+
+	rc = osmo_iofd_sendto_msgb(endp->iofd_rtp, msg, 0, &endp->rtp_remote);
+	if (rc < 0) {
+		msgb_free(msg);
+		return rc;
+	}
+
+	/* TODO: send RTCP if requested */
+
+	return 0;
+}