diff --git a/channels/chan_sip.c b/channels/chan_sip.c index f76d7806dc2b707b19fd96d3b4ca79cb0345e48f..ffc2cc15e7de0708eba010a17a4612c253c3b1e3 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -28025,6 +28025,10 @@ static int handle_common_options(struct ast_flags *flags, struct ast_flags *mask } else if (!strcasecmp(word, "nonat")) { ast_set_flag(&flags[0], SIP_DIRECT_MEDIA); ast_clear_flag(&flags[0], SIP_DIRECT_MEDIA_NAT); + } else if (!strcasecmp(word, "outgoing")) { + ast_set_flag(&flags[0], SIP_DIRECT_MEDIA); + ast_set_flag(&mask[2], SIP_PAGE3_DIRECT_MEDIA_OUTGOING); + ast_set_flag(&flags[2], SIP_PAGE3_DIRECT_MEDIA_OUTGOING); } else { ast_log(LOG_WARNING, "Unknown directmedia mode '%s' on line %d\n", v->value, v->lineno); } @@ -30706,6 +30710,18 @@ static int sip_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *i ast_format_cap_copy(p->redircaps, cap); changed = 1; } + + if (ast_test_flag(&p->flags[2], SIP_PAGE3_DIRECT_MEDIA_OUTGOING) && !p->outgoing_call) { + /* We only wish to withhold sending the initial direct media reinvite on the incoming dialog. + * Further direct media reinvites beyond the initial should be sent. In order to allow further + * direct media reinvites to be sent, we clear this flag. + */ + ast_clear_flag(&p->flags[2], SIP_PAGE3_DIRECT_MEDIA_OUTGOING); + sip_pvt_unlock(p); + ast_channel_unlock(chan); + return 0; + } + if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER) && !ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) { if (ast_channel_state(chan) != AST_STATE_UP) { /* We are in early state */ if (p->do_history) diff --git a/channels/sip/include/sip.h b/channels/sip/include/sip.h index cd061b7bec7eba7f44ac135041deac8e4e5a992f..958fe9af277387e24304296a378e06f5eae2c838 100644 --- a/channels/sip/include/sip.h +++ b/channels/sip/include/sip.h @@ -368,9 +368,11 @@ #define SIP_PAGE3_SRTP_TAG_32 (1 << 1) /*!< DP: Use a 32bit auth tag in INVITE not 80bit */ #define SIP_PAGE3_NAT_AUTO_RPORT (1 << 2) /*!< DGP: Set SIP_NAT_FORCE_RPORT when NAT is detected */ #define SIP_PAGE3_NAT_AUTO_COMEDIA (1 << 3) /*!< DGP: Set SIP_PAGE2_SYMMETRICRTP when NAT is detected */ +#define SIP_PAGE3_DIRECT_MEDIA_OUTGOING (1 << 4) /*!< DP: Only send direct media reinvites on outgoing calls */ #define SIP_PAGE3_FLAGS_TO_COPY \ - (SIP_PAGE3_SNOM_AOC | SIP_PAGE3_SRTP_TAG_32 | SIP_PAGE3_NAT_AUTO_RPORT | SIP_PAGE3_NAT_AUTO_COMEDIA) + (SIP_PAGE3_SNOM_AOC | SIP_PAGE3_SRTP_TAG_32 | SIP_PAGE3_NAT_AUTO_RPORT | SIP_PAGE3_NAT_AUTO_COMEDIA | \ + SIP_PAGE3_DIRECT_MEDIA_OUTGOING) #define CHECK_AUTH_BUF_INITLEN 256 diff --git a/configs/sip.conf.sample b/configs/sip.conf.sample index 0705ad05285ae5b116403e312273eb8efa9d6b68..e92bba9fee21e9c2c19bcb840df2baa529dcab05 100644 --- a/configs/sip.conf.sample +++ b/configs/sip.conf.sample @@ -936,6 +936,13 @@ srvlookup=yes ; Enable DNS SRV lookups on outbound calls ; instead of INVITE. This can be combined with 'nonat', as ; 'directmedia=update,nonat'. It implies 'yes'. +;directmedia=outgoing ; When sending directmedia reinvites, do not send an immediate + ; reinvite on an incoming call leg. This option is useful when + ; peered with another SIP user agent that is known to send + ; immediate direct media reinvites upon call establishment. Setting + ; the option in this situation helps to prevent potential glares. + ; Setting this option implies 'yes'. + ;directrtpsetup=yes ; Enable the new experimental direct RTP setup. This sets up ; the call directly with media peer-2-peer without re-invites. ; Will not work for video and cases where the callee sends