From ebbf920a502d6d460ff3ea8a57db0c624e3a0747 Mon Sep 17 00:00:00 2001 From: "Alfred E. Heggestad" Date: Tue, 23 May 2017 19:43:29 +0200 Subject: rtpext: add RTP Header Extensions (RFC 5285) (#257) * rtpext: add RTP Header Extensions (RFC 5285) * whitespace fix --- src/core.h | 30 ++++++++++++++++ src/rtpext.c | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/srcs.mk | 1 + 3 files changed, 143 insertions(+) create mode 100644 src/rtpext.c diff --git a/src/core.h b/src/core.h index 51bfa6d..5dc5e9d 100644 --- a/src/core.h +++ b/src/core.h @@ -271,6 +271,36 @@ int reg_debug(struct re_printf *pf, const struct reg *reg); int reg_status(struct re_printf *pf, const struct reg *reg); +/* + * RTP Header Extensions + */ + +#define RTPEXT_HDR_SIZE 4 +#define RTPEXT_TYPE_MAGIC 0xbede + +enum { + RTPEXT_ID_MIN = 1, + RTPEXT_ID_MAX = 14, +}; + +enum { + RTPEXT_LEN_MIN = 1, + RTPEXT_LEN_MAX = 16, +}; + +struct rtpext { + unsigned id:4; + unsigned len:4; + uint8_t data[RTPEXT_LEN_MAX]; +}; + + +int rtpext_hdr_encode(struct mbuf *mb, size_t num_bytes); +int rtpext_encode(struct mbuf *mb, unsigned id, unsigned len, + const uint8_t *data); +int rtpext_decode(struct rtpext *ext, struct mbuf *mb); + + /* * RTP keepalive */ diff --git a/src/rtpext.c b/src/rtpext.c new file mode 100644 index 0000000..82a6f6e --- /dev/null +++ b/src/rtpext.c @@ -0,0 +1,112 @@ +/** + * @file rtpext.c RTP Header Extensions + * + * Copyright (C) 2017 Creytiv.com + */ + +#include +#include +#include +#include "core.h" + + +/* + * RFC 5285 A General Mechanism for RTP Header Extensions + * + * - One-Byte Header: Supported + * - Two-Byte Header: Not supported + */ + + +int rtpext_hdr_encode(struct mbuf *mb, size_t num_bytes) +{ + int err = 0; + + if (!mb || !num_bytes) + return EINVAL; + + if (num_bytes & 0x3) { + warning("rtpext: hdr_encode: num_bytes (%zu) must be multiple" + " of 4\n", num_bytes); + return EINVAL; + } + + err |= mbuf_write_u16(mb, htons(RTPEXT_TYPE_MAGIC)); + err |= mbuf_write_u16(mb, htons(num_bytes / 4)); + + return err; +} + + +int rtpext_encode(struct mbuf *mb, unsigned id, unsigned len, + const uint8_t *data) +{ + size_t start; + int err; + + if (!mb || !data) + return EINVAL; + + if (id < RTPEXT_ID_MIN || id > RTPEXT_ID_MAX) + return EINVAL; + if (len < RTPEXT_LEN_MIN || len > RTPEXT_LEN_MAX) + return EINVAL; + + start = mb->pos; + + err = mbuf_write_u8(mb, id << 4 | (len-1)); + err |= mbuf_write_mem(mb, data, len); + if (err) + return err; + + /* padding */ + while ((mb->pos - start) & 0x03) + err |= mbuf_write_u8(mb, 0x00); + + return err; +} + + +int rtpext_decode(struct rtpext *ext, struct mbuf *mb) +{ + uint8_t v; + int err; + + if (!ext || !mb) + return EINVAL; + + if (mbuf_get_left(mb) < 1) + return EBADMSG; + + memset(ext, 0, sizeof(*ext)); + + v = mbuf_read_u8(mb); + + ext->id = v >> 4; + ext->len = (v & 0x0f) + 1; + + if (ext->id < RTPEXT_ID_MIN || ext->id > RTPEXT_ID_MAX) { + warning("rtpext: invalid ID %u\n", ext->id); + return EBADMSG; + } + if (ext->len > mbuf_get_left(mb)) { + warning("rtpext: short read\n"); + return ENODATA; + } + + err = mbuf_read_mem(mb, ext->data, ext->len); + if (err) + return err; + + /* skip padding */ + while (mbuf_get_left(mb)) { + uint8_t pad = mbuf_buf(mb)[0]; + + if (pad != 0x00) + break; + + mbuf_advance(mb, 1); + } + + return 0; +} diff --git a/src/srcs.mk b/src/srcs.mk index cdb2a26..686ca7c 100644 --- a/src/srcs.mk +++ b/src/srcs.mk @@ -28,6 +28,7 @@ SRCS += net.c SRCS += play.c SRCS += realtime.c SRCS += reg.c +SRCS += rtpext.c SRCS += rtpkeep.c SRCS += sdp.c SRCS += sipreq.c -- cgit v1.2.3