Browse Source

MT#56465 sdp manipulations: add media types removal

In order to be able to control, which media types
one wants to have in the call session,
add support of the "sdp-media-remove" flag.

Syntax:
"sdp-media-remove" : ["<media-type>", "<media-type>", ...]

Additionally, add according unit tests.

Change-Id: Ic52456f8124319992ea9ca8c161daefb1df46b59
pull/1880/head
Donat Zenichev 1 year ago
parent
commit
ec21fe5cb7
4 changed files with 176 additions and 1 deletions
  1. +23
    -1
      daemon/call.c
  2. +32
    -0
      daemon/call_interfaces.c
  3. +3
    -0
      include/call_interfaces.h
  4. +118
    -0
      t/auto-daemon-tests.pl

+ 23
- 1
daemon/call.c View File

@ -2968,6 +2968,7 @@ int monologue_offer_answer(struct call_monologue *monologues[2], sdp_streams_q *
struct call_monologue *receiver_ml = monologues[1]; struct call_monologue *receiver_ml = monologues[1];
unsigned int num_ports_this, num_ports_other; unsigned int num_ports_this, num_ports_other;
bool is_offer = (flags->opmode == OP_OFFER); bool is_offer = (flags->opmode == OP_OFFER);
unsigned int medias_offset = 0; /* media indexes offset for case with media manipulations */
/* we must have a complete dialogue, even though the to-tag (monologue->tag) /* we must have a complete dialogue, even though the to-tag (monologue->tag)
* may not be known yet */ * may not be known yet */
@ -2995,10 +2996,31 @@ int monologue_offer_answer(struct call_monologue *monologues[2], sdp_streams_q *
* This affects later the sequencing of medias, e.g. for subscribe requests. * This affects later the sequencing of medias, e.g. for subscribe requests.
*/ */
/* TODO: refactor this into something more good looking code */
if (flags->sdp_media_remove[sp->type_id]) {
sp->rtp_endpoint.port = 0; /* pretend it was a zero stream */
sender_media = __get_media(sender_ml, sp, flags, 0);
sender_media->media_sdp_id = sp->media_sdp_id;
__media_init_from_flags(sender_media, NULL, sp, flags);
num_ports_other = proto_num_ports(sp->num_ports, sender_media, flags,
(flags->rtcp_mux_demux || flags->rtcp_mux_accept) ? true : false);
__disable_streams(sender_media, num_ports_other);
medias_offset++;
__init_interface(sender_media, &sp->direction[0], num_ports_other);
if (sender_media->logical_intf == NULL) {
goto error_intf;
}
ilog(LOG_DEBUG, "Media type '"STR_FORMAT"' is to be removed by SDP manipulations.", STR_FMT(&sp->type));
continue;
}
/* OP_OFFER, receiver's side, get by index */ /* OP_OFFER, receiver's side, get by index */
receiver_media = NULL; receiver_media = NULL;
if (is_offer) if (is_offer)
receiver_media = __get_media(receiver_ml, sp, flags, 0);
receiver_media = __get_media(receiver_ml, sp, flags, (medias_offset ? (sp->index - medias_offset) : 0));
/* OP_OFFER/OP_ANSWER, sender's side, get by index */ /* OP_OFFER/OP_ANSWER, sender's side, get by index */
sender_media = __get_media(sender_ml, sp, flags, 0); sender_media = __get_media(sender_ml, sp, flags, 0);


+ 32
- 0
daemon/call_interfaces.c View File

@ -642,6 +642,9 @@ err:
ilog(LOG_WARN, "SDP manipulations: Ignoring invalid contents of string-pair list"); ilog(LOG_WARN, "SDP manipulations: Ignoring invalid contents of string-pair list");
} }
/**
* SDP attribute manipulation praser helpers.
*/
static void ng_sdp_attr_media_iter(const ng_parser_t *parser, str *command_type, parser_arg command_value, static void ng_sdp_attr_media_iter(const ng_parser_t *parser, str *command_type, parser_arg command_value,
helper_arg arg) helper_arg arg)
{ {
@ -684,6 +687,27 @@ INLINE void ng_sdp_attr_manipulations(const ng_parser_t *parser, sdp_ng_flags *f
ilog(LOG_WARN, "SDP manipulations: Wrong type for this type of command."); ilog(LOG_WARN, "SDP manipulations: Wrong type for this type of command.");
} }
/**
* SDP media section manipulation parser helpers.
*/
static void ng_sdp_media_remove_iter(str *media_type, unsigned int i, helper_arg arg)
{
enum media_type id = codec_get_type(media_type);
if (id == MT_UNKNOWN || id == MT_OTHER)
{
ilog(LOG_WARN, "SDP manipulations: unsupported SDP section '" STR_FORMAT "' targeted.",
STR_FMT(media_type));
/* only known media types are supported */
return;
}
arg.flags->sdp_media_remove[id] = true;
}
INLINE void ng_sdp_media_remove(const ng_parser_t *parser, sdp_ng_flags *flags, parser_arg value) {
if (!parser->is_list(value))
return;
parser->list_iter(parser, value, ng_sdp_media_remove_iter, NULL, flags);
}
INLINE void ng_el_option(str *s, unsigned int idx, helper_arg arg) { INLINE void ng_el_option(str *s, unsigned int idx, helper_arg arg) {
sdp_ng_flags *out = arg.flags; sdp_ng_flags *out = arg.flags;
switch (__csh_lookup(s)) { switch (__csh_lookup(s)) {
@ -1290,6 +1314,8 @@ void call_ng_flags_init(sdp_ng_flags *out, enum call_opmode opmode) {
out->volume = 9999; out->volume = 9999;
out->digit = -1; out->digit = -1;
out->frequencies = g_array_new(false, false, sizeof(int)); out->frequencies = g_array_new(false, false, sizeof(int));
for (int i = 0; i < __MT_MAX; ++i)
out->sdp_media_remove[i] = false;
} }
static void call_ng_direction_flag_iter(str *s, unsigned int i, helper_arg arg) { static void call_ng_direction_flag_iter(str *s, unsigned int i, helper_arg arg) {
@ -1883,6 +1909,12 @@ void call_ng_main_flags(const ng_parser_t *parser, str *key, parser_arg value, h
case CSH_LOOKUP("SDP-attr"): case CSH_LOOKUP("SDP-attr"):
ng_sdp_attr_manipulations(parser, out, value); ng_sdp_attr_manipulations(parser, out, value);
break; break;
case CSH_LOOKUP("sdp-media-remove"):
case CSH_LOOKUP("SDP-media-remove"):
case CSH_LOOKUP("sdp_media_remove"):
case CSH_LOOKUP("SDP_media_remove"):
ng_sdp_media_remove(parser, out, value);
break;
case CSH_LOOKUP("set-label"): case CSH_LOOKUP("set-label"):
out->set_label = s; out->set_label = s;
break; break;


+ 3
- 0
include/call_interfaces.h View File

@ -72,6 +72,8 @@ struct sdp_ng_flags {
/* commands to manipulate attr lines in SDP */ /* commands to manipulate attr lines in SDP */
struct sdp_manipulations * sdp_manipulations[__MT_MAX]; struct sdp_manipulations * sdp_manipulations[__MT_MAX];
/* types of medias to be removed by media lvl manipulations */
bool sdp_media_remove[__MT_MAX];
enum { enum {
ICE_DEFAULT = 0, ICE_DEFAULT = 0,
@ -321,6 +323,7 @@ INLINE struct sdp_manipulations *sdp_manipulations_get_by_name(struct sdp_manipu
return NULL; return NULL;
return sdp_manipulations_get_create_by_id(array, id); return sdp_manipulations_get_create_by_id(array, id);
} }
// set all WebRTC-specific attributes // set all WebRTC-specific attributes
INLINE void ng_flags_webrtc(sdp_ng_flags *f) { INLINE void ng_flags_webrtc(sdp_ng_flags *f) {
f->transport_protocol = &transport_protocols[PROTO_UDP_TLS_RTP_SAVPF]; f->transport_protocol = &transport_protocols[PROTO_UDP_TLS_RTP_SAVPF];


+ 118
- 0
t/auto-daemon-tests.pl View File

@ -20541,6 +20541,124 @@ a=crypto:4 AES_256_CM_HMAC_SHA1_32 inline:CRYPTO256
SDP SDP
# Arbitrary SDP media level manipulations
new_call;
offer('SDP media manipulations - remove video', { ICE => 'remove', DTLS => 'off', SDES => [ 'nonew' ], 'sdp-media-remove' => ['video']}, <<SDP);
v=0
o=- 1545997027 1 IN IP4 198.51.100.1
s=tester
t=0 0
m=audio 2000 RTP/SAVP 0
c=IN IP4 198.51.100.1
a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:cJOJ7kxQjhFBp2fP6AYjs3vKw7CeBdWZCj0isbJv
a=crypto:2 AES_CM_128_HMAC_SHA1_32 inline:VAzLKvoE3jG9cdH/AZsl/ZqWNXrUzyM4Gw6chrFr
a=crypto:3 AES_256_CM_HMAC_SHA1_80 inline:8AbZePWwsKhLGX3GlXA+yHYPQ3cgraer/9DkFJYCOPZZy3o9wC0NIbIFYZfyHw==
a=crypto:4 AES_256_CM_HMAC_SHA1_32 inline:2GLk3p/csdno4KlGO1TxCVaEt+bifmDlQ5NjnCb5cJYPURiGRSTBEtEq37db8g==
a=sendrecv
m=video 3000 RTP/AVP 97
c=IN IP4 198.51.100.1
a=rtpmap:97 H264/90000
a=fmtp:97 0-15
a=sendrecv
----------------------------------
v=0
o=- 1545997027 1 IN IP4 198.51.100.1
s=tester
t=0 0
m=audio PORT RTP/SAVP 0
c=IN IP4 203.0.113.1
a=rtpmap:0 PCMU/8000
a=sendrecv
a=rtcp:PORT
a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:CRYPTO128
a=crypto:2 AES_CM_128_HMAC_SHA1_32 inline:CRYPTO128
a=crypto:3 AES_256_CM_HMAC_SHA1_80 inline:CRYPTO256
a=crypto:4 AES_256_CM_HMAC_SHA1_32 inline:CRYPTO256
SDP
answer('SDP media manipulations - remove video', { ICE => 'remove' }, <<SDP);
v=0
o=- 1545997027 1 IN IP4 198.51.100.3
s=tester
t=0 0
m=audio 2002 RTP/SAVP 0
c=IN IP4 198.51.100.3
a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:n2YhgclGcmcPp71u6pjbgu41KYAvsaTE3gRmJYJC
a=sendrecv
--------------------------------------
v=0
o=- 1545997027 1 IN IP4 198.51.100.3
s=tester
t=0 0
m=audio PORT RTP/SAVP 0
c=IN IP4 203.0.113.1
a=rtpmap:0 PCMU/8000
a=sendrecv
a=rtcp:PORT
a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:CRYPTO128
m=video 0 RTP/AVP 0
c=IN IP4 0.0.0.0
SDP
new_call;
offer('SDP media manipulations - remove audio', { ICE => 'remove', DTLS => 'off', SDES => [ 'nonew' ], 'sdp-media-remove' => ['audio']}, <<SDP);
v=0
o=- 1545997027 1 IN IP4 198.51.100.1
s=tester
t=0 0
m=audio 2000 RTP/SAVP 0
c=IN IP4 198.51.100.1
a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:cJOJ7kxQjhFBp2fP6AYjs3vKw7CeBdWZCj0isbJv
a=crypto:2 AES_CM_128_HMAC_SHA1_32 inline:VAzLKvoE3jG9cdH/AZsl/ZqWNXrUzyM4Gw6chrFr
a=crypto:3 AES_256_CM_HMAC_SHA1_80 inline:8AbZePWwsKhLGX3GlXA+yHYPQ3cgraer/9DkFJYCOPZZy3o9wC0NIbIFYZfyHw==
a=crypto:4 AES_256_CM_HMAC_SHA1_32 inline:2GLk3p/csdno4KlGO1TxCVaEt+bifmDlQ5NjnCb5cJYPURiGRSTBEtEq37db8g==
a=sendrecv
m=video 3000 RTP/AVP 97
c=IN IP4 198.51.100.1
a=rtpmap:97 H264/90000
a=fmtp:97 0-15
a=sendrecv
----------------------------------
v=0
o=- 1545997027 1 IN IP4 198.51.100.1
s=tester
t=0 0
m=video PORT RTP/AVP 97
c=IN IP4 203.0.113.1
a=rtpmap:97 H264/90000
a=fmtp:97 0-15
a=sendrecv
a=rtcp:PORT
SDP
answer('SDP media manipulations - remove audio', { ICE => 'remove' }, <<SDP);
v=0
o=- 1115997027 1 IN IP4 198.51.100.3
s=tester
t=0 0
m=video 4000 RTP/AVP 97
a=rtpmap:97 H264/90000
a=fmtp:97 0-15
c=IN IP4 198.51.100.3
a=sendrecv
--------------------------------------
v=0
o=- 1115997027 1 IN IP4 198.51.100.3
s=tester
t=0 0
m=audio 0 RTP/SAVP 0
c=IN IP4 0.0.0.0
m=video PORT RTP/AVP 97
c=IN IP4 203.0.113.1
a=rtpmap:97 H264/90000
a=fmtp:97 0-15
a=sendrecv
a=rtcp:PORT
SDP
# Arbitrary SDP manipulations # Arbitrary SDP manipulations
new_call; new_call;


Loading…
Cancel
Save