diff --git a/README.md b/README.md index 6fd0b972c..872db362e 100644 --- a/README.md +++ b/README.md @@ -1631,9 +1631,10 @@ Optionally included keys are: * `all` Can be set to the string `none` to disable any extra behaviour (which - is the default if this key is omitted altogether) or to `all`. - Applicable to certain messages only. The behaviour is explained below - separately for each affected message. + is the default if this key is omitted altogether) or to one of `all`, + `offer-answer`, `except-offer-answer` or `flows`. Applicable to + certain messages only. The behaviour is explained below separately for + each affected message. An example of a complete `offer` request dictionary could be (SDP body abbreviated): @@ -2030,6 +2031,13 @@ request`. To select just one media flow for media blocking, in addition to selecting a source call participant as above, a destination call participant must be specified using the `to-tag` or `to-label`key in the message. +Another possibility to block media for individual media flows is to use one of +the special `all=` keywords instead of directly specifying a single `to-tag` or +`to-label`. With `all=offer-answer` all media flows from the given `from-tag` +that resulted from an offer/answer negotiation are affected. Respectively with +`all=except-offer-answer` the opposite happens. With `all=flows` all currently +established media flows are affected regardless or how they were created. + `silence media` and `unsilence media` Messages ---------------------------------------------- diff --git a/daemon/call_interfaces.c b/daemon/call_interfaces.c index 21a84a8f3..2f56357f3 100644 --- a/daemon/call_interfaces.c +++ b/daemon/call_interfaces.c @@ -1478,6 +1478,17 @@ static void call_ng_main_flags(struct sdp_ng_flags *out, str *key, bencode_item_ case CSH_LOOKUP("none"): out->all = ALL_NONE; break; + case CSH_LOOKUP("offer-answer"): + out->all = ALL_OFFER_ANSWER; + break; + case CSH_LOOKUP("not-offer-answer"): + case CSH_LOOKUP("non-offer-answer"): + case CSH_LOOKUP("except-offer-answer"): + out->all = ALL_NON_OFFER_ANSWER; + break; + case CSH_LOOKUP("flows"): + out->all = ALL_FLOWS; + break; default: ilog(LOG_WARN, "Unknown 'all' flag encountered: '" STR_FORMAT "'", STR_FMT(&s)); @@ -2697,6 +2708,25 @@ static const char *call_block_silence_media(bencode_item_t *input, bool on_off, } g_queue_push_tail(&sinks, sink); } + else if (flags.all == ALL_OFFER_ANSWER || flags.all == ALL_NON_OFFER_ANSWER + || flags.all == ALL_FLOWS) + { + for (GList *l = monologue->subscribers.head; l; l = l->next) { + struct call_subscription *cs = l->data; + if (flags.all == ALL_OFFER_ANSWER && !cs->attrs.offer_answer) + continue; + else if (flags.all == ALL_NON_OFFER_ANSWER && cs->attrs.offer_answer) + continue; + g_queue_push_tail(&sinks, cs->monologue); + } + if (!sinks.length) { + ilog(LOG_WARN, "No eligible subscriptions found for '" STR_FORMAT_M "' " + "for media %s", + STR_FMT_M(&monologue->tag), + lcase_verb); + return "No eligible subscriptions found"; + } + } if (sinks.length) { for (GList *l = sinks.head; l; l = l->next) { struct call_monologue *sink = l->data; diff --git a/include/call_interfaces.h b/include/call_interfaces.h index 4176c4134..b4edfa5d4 100644 --- a/include/call_interfaces.h +++ b/include/call_interfaces.h @@ -79,6 +79,9 @@ struct sdp_ng_flags { enum { ALL_NONE = 0, ALL_ALL, + ALL_OFFER_ANSWER, + ALL_NON_OFFER_ANSWER, + ALL_FLOWS, } all; enum endpoint_learning el_option; enum block_dtmf_mode block_dtmf_mode; diff --git a/utils/rtpengine-ng-client b/utils/rtpengine-ng-client index b6dcab8a9..980e6852b 100755 --- a/utils/rtpengine-ng-client +++ b/utils/rtpengine-ng-client @@ -69,7 +69,7 @@ GetOptions( 'xmlrpc-callback=s' => \$options{'xmlrpc-callback'}, 'always-transcode' => \$options{'always transcode'}, 'metadata=s' => \$options{'metadata'}, - 'all' => \$options{'all'}, + 'all=s' => \$options{'all'}, 'siprec' => \$options{'SIPREC'}, 'SIPREC' => \$options{'SIPREC'}, 'egress' => \$options{'egress'}, @@ -125,7 +125,7 @@ my $cmd = shift(@ARGV) or die; my %packet = (command => $cmd); -for my $x (split(/,/, 'from-tag,to-tag,call-id,transport protocol,media address,ICE,address family,DTLS,via-branch,media address,ptime,xmlrpc-callback,metadata,address,file,db-id,code,DTLS-fingerprint,ICE-lite,media echo,label,set-label,from-label,to-label,DTMF-security,digit,DTMF-security-trigger,DTMF-security-trigger-end,trigger,trigger-end')) { +for my $x (split(/,/, 'from-tag,to-tag,call-id,transport protocol,media address,ICE,address family,DTLS,via-branch,media address,ptime,xmlrpc-callback,metadata,address,file,db-id,code,DTLS-fingerprint,ICE-lite,media echo,label,set-label,from-label,to-label,DTMF-security,digit,DTMF-security-trigger,DTMF-security-trigger-end,trigger,trigger-end,all')) { if (defined($options{$x})) { if (!$options{json}) { $packet{$x} = \$options{$x}; @@ -138,7 +138,7 @@ for my $x (split(/,/, 'from-tag,to-tag,call-id,transport protocol,media address, for my $x (split(/,/, 'TOS,delete-delay,delay-buffer,volume,frequency,trigger-end-time,trigger-end-digits,DTMF-delay')) { defined($options{$x}) and $packet{$x} = $options{$x}; } -for my $x (split(/,/, 'trust address,symmetric,asymmetric,unidirectional,force,strict source,media handover,sip source address,reset,port latching,no rtcp attribute,full rtcp attribute,loop protect,record call,always transcode,all,SIPREC,pad crypto,generate mid,fragment,original sendrecv,symmetric codecs,asymmetric codecs,inject DTMF,detect DTMF,generate RTCP,single codec,no codec renegotiation,pierce NAT,SIP-source-address,allow transcoding,trickle ICE,reject ICE,egress')) { +for my $x (split(/,/, 'trust address,symmetric,asymmetric,unidirectional,force,strict source,media handover,sip source address,reset,port latching,no rtcp attribute,full rtcp attribute,loop protect,record call,always transcode,SIPREC,pad crypto,generate mid,fragment,original sendrecv,symmetric codecs,asymmetric codecs,inject DTMF,detect DTMF,generate RTCP,single codec,no codec renegotiation,pierce NAT,SIP-source-address,allow transcoding,trickle ICE,reject ICE,egress')) { defined($options{$x}) and push(@{$packet{flags}}, $x); } for my $x (split(/,/, 'origin,session connection,sdp version,username,session-name,zero-address')) {