diff --git a/README.md b/README.md index b12596db5..69f70d87b 100644 --- a/README.md +++ b/README.md @@ -1256,6 +1256,14 @@ Optionally included keys are: Add `a=mid` attributes to the outgoing SDP if they were not already present. + - `original sendrecv` + + With this flag present, *rtpengine* will leave the media direction attributes + (`sendrecv`, `recvonly`, `sendonly`, and `inactive`) from the received SDP body + unchanged. Normally *rtpengine* would consume these attributes and insert its + own version of them based on other media parameters (e.g. a media section with + a zero IP address would come out as `sendonly` or `inactive`). + * `replace` Similar to the `flags` list. Controls which parts of the SDP body should be rewritten. diff --git a/daemon/call_interfaces.c b/daemon/call_interfaces.c index 2b28f7990..0826744cf 100644 --- a/daemon/call_interfaces.c +++ b/daemon/call_interfaces.c @@ -674,6 +674,9 @@ static void call_ng_flags_flags(struct sdp_ng_flags *out, str *s, void *dummy) { case CSH_LOOKUP("loop-protect"): out->loop_protect = 1; break; + case CSH_LOOKUP("original-sendrecv"): + out->original_sendrecv = 1; + break; case CSH_LOOKUP("always-transcode"): out->always_transcode = 1; break; diff --git a/daemon/sdp.c b/daemon/sdp.c index f0fb9e3ad..b70bcd21b 100644 --- a/daemon/sdp.c +++ b/daemon/sdp.c @@ -1627,15 +1627,19 @@ static int process_session_attributes(struct sdp_chopper *chop, struct sdp_attri goto strip; case ATTR_EXTMAP: - case ATTR_INACTIVE: - case ATTR_SENDONLY: - case ATTR_RECVONLY: - case ATTR_SENDRECV: case ATTR_FINGERPRINT: case ATTR_SETUP: case ATTR_IGNORE: goto strip; + case ATTR_INACTIVE: + case ATTR_SENDONLY: + case ATTR_RECVONLY: + case ATTR_SENDRECV: + if (!flags->original_sendrecv) + goto strip; + break; + case ATTR_GROUP: if (attr->u.group.semantics == GROUP_BUNDLE) goto strip; @@ -1697,16 +1701,21 @@ static int process_media_attributes(struct sdp_chopper *chop, struct sdp_media * case ATTR_RTCP_MUX: if (flags->ice_force_relay) break; - // fall thru - case ATTR_INACTIVE: - case ATTR_SENDONLY: - case ATTR_RECVONLY: - case ATTR_SENDRECV: + goto strip; + case ATTR_IGNORE: case ATTR_END_OF_CANDIDATES: // we strip it here and re-insert it later case ATTR_MID: goto strip; + case ATTR_INACTIVE: + case ATTR_SENDONLY: + case ATTR_RECVONLY: + case ATTR_SENDRECV: + if (!flags->original_sendrecv) + goto strip; + break; + case ATTR_RTPMAP: case ATTR_FMTP: case ATTR_PTIME: @@ -2096,14 +2105,16 @@ int sdp_replace(struct sdp_chopper *chop, GQueue *sessions, struct call_monologu if (!sdp_media->port_num || !ps->selected_sfd) goto next; - if (MEDIA_ARESET2(call_media, SEND, RECV)) - chopper_append_c(chop, "a=sendrecv\r\n"); - else if (MEDIA_ISSET(call_media, SEND)) - chopper_append_c(chop, "a=sendonly\r\n"); - else if (MEDIA_ISSET(call_media, RECV)) - chopper_append_c(chop, "a=recvonly\r\n"); - else - chopper_append_c(chop, "a=inactive\r\n"); + if (!flags->original_sendrecv) { + if (MEDIA_ARESET2(call_media, SEND, RECV)) + chopper_append_c(chop, "a=sendrecv\r\n"); + else if (MEDIA_ISSET(call_media, SEND)) + chopper_append_c(chop, "a=sendonly\r\n"); + else if (MEDIA_ISSET(call_media, RECV)) + chopper_append_c(chop, "a=recvonly\r\n"); + else + chopper_append_c(chop, "a=inactive\r\n"); + } if (call_media->protocol && call_media->protocol->rtp) { if (MEDIA_ISSET(call_media, RTCP_MUX) diff --git a/include/call_interfaces.h b/include/call_interfaces.h index dc7cc0a8a..c903ea8d4 100644 --- a/include/call_interfaces.h +++ b/include/call_interfaces.h @@ -64,6 +64,7 @@ struct sdp_ng_flags { fragment:1, record_call:1, loop_protect:1, + original_sendrecv:1, always_transcode:1, asymmetric_codecs:1, supports_load_limit:1, diff --git a/utils/rtpengine-ng-client b/utils/rtpengine-ng-client index 37f3d58a2..5dc38e28a 100755 --- a/utils/rtpengine-ng-client +++ b/utils/rtpengine-ng-client @@ -64,6 +64,7 @@ GetOptions( 'pad-crypto' => \$options{'pad crypto'}, 'generate-mid' => \$options{'generate mid'}, 'fragment' => \$options{'fragment'}, + 'original-sendrecv' => \$options{'original sendrecv'}, ) or die; my $cmd = shift(@ARGV) or die; @@ -76,7 +77,7 @@ for my $x (split(/,/, 'from-tag,to-tag,call-id,transport protocol,media address, for my $x (split(/,/, 'TOS,delete-delay')) { defined($options{$x}) and $packet{$x} = $options{$x}; } -for my $x (split(/,/, 'trust address,symmetric,asymmetric,force,strict source,media handover,sip source address,reset,port latching,no rtcp attribute,full rtcp attribute,loop protect,record call,always transcode,all,pad crypto,generate mid,fragment')) { +for my $x (split(/,/, 'trust address,symmetric,asymmetric,force,strict source,media handover,sip source address,reset,port latching,no rtcp attribute,full rtcp attribute,loop protect,record call,always transcode,all,pad crypto,generate mid,fragment,original sendrecv')) { defined($options{$x}) and push(@{$packet{flags}}, $x); } for my $x (split(/,/, 'origin,session connection')) {