# HG changeset patch # User Mychaela Falconia # Date 1720337628 0 # Node ID 84d427017d2f8fc5eeeb4348bd4521c883035605 # Parent 9e477a4b485a55dfcb07ac163703f20738cb25be endp: implement RTP Tx diff -r 9e477a4b485a -r 84d427017d2f include/endp.h --- 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); diff -r 9e477a4b485a -r 84d427017d2f src/Makefile --- 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 diff -r 9e477a4b485a -r 84d427017d2f src/endp_create.c --- 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 #include -#include +#include #include #include @@ -48,6 +48,7 @@ return NULL; } + endp->tx.ssrc = random(); return endp; } diff -r 9e477a4b485a -r 84d427017d2f src/rtp_tx.c --- /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 +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +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; +}