diff --git a/daemon/call.c b/daemon/call.c index 5ff820381..44d69b17c 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -670,6 +670,9 @@ static struct rtp_extension *call_media_ext_lookup_ht(struct call_media *m, unsi static const struct extmap_ops extmap_ops_short = { .lookup = call_media_ext_lookup_array, + .length = extmap_length_short, + .header = extmap_header_short, + .print = extmap_print_short, }; static const struct extmap_ops extmap_ops_long = { .lookup = call_media_ext_lookup_ht, diff --git a/daemon/media_socket.c b/daemon/media_socket.c index dd835cfc5..64edcbfbf 100644 --- a/daemon/media_socket.c +++ b/daemon/media_socket.c @@ -2079,6 +2079,52 @@ const struct rtpext_printer rtpext_printer_copy = { +static bool extmap_short_is_valid(const struct rtp_extension_data *ext) { + // valid ranges for short form? + if (ext->ext->id <= 0 || ext->ext->id >= 15) + return false; + if (ext->content.len > 16) + return false; + return true; +} + +size_t extmap_length_short(const struct media_packet *mp) { + const extmap_data_q *q = &mp->extmap; + + size_t ret = 4; // 0xbede + int16 length + for (__auto_type l = q->head; l; l = l->next) { + __auto_type ext = l->data; + if (!extmap_short_is_valid(ext)) { + ilog(LOG_WARN | LOG_FLAG_LIMIT, "RTP extension with id %d length %zu not valid " + "for short form", ext->ext->id, ext->content.len); + continue; + } + ret++; // 1-byte header + ret += ext->content.len; + } + + return ret; +} + +void extmap_header_short(void *_dst) { + unsigned char *dst = _dst; + dst[0] = 0xbe; + dst[1] = 0xde; +} + +size_t extmap_print_short(void *_dst, const struct rtp_extension_data *ext) { + unsigned char *dst = _dst; + + if (!extmap_short_is_valid(ext)) + return 0; + + dst[0] = (ext->ext->id << 4) | (ext->content.len - 1); + memcpy(dst + 1, ext->content.s, ext->content.len); + return ext->content.len + 1; +} + + + // `out_media` can be NULL XXX streamline this to remove this exception const struct streamhandler *determine_handler(const struct transport_protocol *in_proto, struct call_media *out_media, bool must_recrypt) diff --git a/include/call.h b/include/call.h index 316ec91b5..dce3cbdaa 100644 --- a/include/call.h +++ b/include/call.h @@ -466,6 +466,10 @@ INLINE int64_t packet_stream_last_packet(const struct packet_stream *ps) { struct extmap_ops { struct rtp_extension *(*lookup)(struct call_media *, unsigned int); + + size_t (*length)(const struct media_packet *); + void (*header)(void *dst); + size_t (*print)(void *dst, const struct rtp_extension_data *); }; diff --git a/include/media_socket.h b/include/media_socket.h index 074f0f847..d35b63aa7 100644 --- a/include/media_socket.h +++ b/include/media_socket.h @@ -325,6 +325,11 @@ TYPED_GQUEUE(extmap, struct rtp_extension); TYPED_GHASHTABLE(extmap_ht, void, struct rtp_extension, g_direct_hash, g_direct_equal, NULL, NULL); TYPED_GHASHTABLE(ext_name_ht, str, struct rtp_extension, str_hash, str_equal, NULL, NULL); +size_t extmap_length_short(const struct media_packet *); +void extmap_header_short(void *); +size_t extmap_print_short(void *, const struct rtp_extension_data *); + + extern local_intf_q all_local_interfaces; // read-only during runtime