diff options
author | Alfred E. Heggestad <alfred.heggestad@gmail.com> | 2017-05-23 19:43:29 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-05-23 19:43:29 +0200 |
commit | ebbf920a502d6d460ff3ea8a57db0c624e3a0747 (patch) | |
tree | f809f27ad20915fa73849ae3bec53fef1d9eb01b | |
parent | 97229c0c2e13415d0fa1c808742c22adeb9b2f33 (diff) |
rtpext: add RTP Header Extensions (RFC 5285) (#257)
* rtpext: add RTP Header Extensions (RFC 5285)
* whitespace fix
-rw-r--r-- | src/core.h | 30 | ||||
-rw-r--r-- | src/rtpext.c | 112 | ||||
-rw-r--r-- | src/srcs.mk | 1 |
3 files changed, 143 insertions, 0 deletions
@@ -272,6 +272,36 @@ 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 <string.h> +#include <re.h> +#include <baresip.h> +#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 |