<p>Jenkins2 <strong>merged</strong> this change.</p><p><a href="https://gerrit.asterisk.org/5842">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Joshua Colp: Looks good to me, but someone else must approve
  Matthew Fredrickson: Looks good to me, approved
  Jenkins2: Approved for Submit

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">res_pjsip:  Add DTMF INFO Failback mode<br><br>The existing auto dtmf mode reverts to inband if 4733 fails to be<br>negotiated.  This patch adds a new mode auto_info which will<br>switch to INFO instead of inband if 4733 is not available.<br><br>ASTERISK-27066 #close<br><br>Change-Id: Id185b11e84afd9191a2f269e8443019047765e91<br>---<br>M CHANGES<br>M channels/chan_pjsip.c<br>A contrib/ast-db-manage/config/versions/164abbd708c_add_auto_info_to_endpoint_dtmf_mode.py<br>M include/asterisk/res_pjsip.h<br>M res/res_pjsip.c<br>M res/res_pjsip/pjsip_configuration.c<br>M res/res_pjsip_sdp_rtp.c<br>7 files changed, 121 insertions(+), 18 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/CHANGES b/CHANGES<br>index 1b87dbf..c2a9c8f 100644<br>--- a/CHANGES<br>+++ b/CHANGES<br>@@ -25,6 +25,10 @@<br>    whether to notify dialog-info state 'early' or 'confirmed' on Ringing<br>    when already INUSE.<br> <br>+ * The endpoint option 'dtmf_mode' has a new option 'auto_dtmf' added. This<br>+   mode works similar to 'auto' except uses DTMF INFO as fallback instead of<br>+   INBAND.<br>+<br> res_agi<br> ------------------<br>  * The EAGI() application will now look for a dialplan variable named<br>diff --git a/channels/chan_pjsip.c b/channels/chan_pjsip.c<br>index 486a237..d1691b8 100644<br>--- a/channels/chan_pjsip.c<br>+++ b/channels/chan_pjsip.c<br>@@ -1708,14 +1708,20 @@<br>                }<br> <br>          ast_rtp_instance_dtmf_begin(media->rtp, digit);<br>-                break;<br>+          break;<br>        case AST_SIP_DTMF_AUTO:<br>-                       if (!media || !media->rtp || (ast_rtp_instance_dtmf_mode_get(media->rtp) == AST_RTP_DTMF_MODE_INBAND)) {<br>-                        return -1;<br>-                }<br>+             if (!media || !media->rtp || (ast_rtp_instance_dtmf_mode_get(media->rtp) == AST_RTP_DTMF_MODE_INBAND)) {<br>+                       return -1;<br>+           }<br> <br>-                ast_rtp_instance_dtmf_begin(media->rtp, digit);<br>-                break;<br>+           ast_rtp_instance_dtmf_begin(media->rtp, digit);<br>+           break;<br>+       case AST_SIP_DTMF_AUTO_INFO:<br>+         if (!media || !media->rtp || (ast_rtp_instance_dtmf_mode_get(media->rtp) == AST_RTP_DTMF_MODE_NONE)) {<br>+                 return -1;<br>+           }<br>+            ast_rtp_instance_dtmf_begin(media->rtp, digit);<br>+           break;<br>        case AST_SIP_DTMF_NONE:<br>               break;<br>        case AST_SIP_DTMF_INBAND:<br>@@ -1816,6 +1822,20 @@<br>     int res = 0;<br> <br>       switch (channel->session->endpoint->dtmf) {<br>+ case AST_SIP_DTMF_AUTO_INFO:<br>+ {<br>+            if (!media || !media->rtp) {<br>+                      return -1;<br>+           }<br>+            if (ast_rtp_instance_dtmf_mode_get(media->rtp) != AST_RTP_DTMF_MODE_NONE) {<br>+                       ast_debug(3, "Told to send end of digit on Auto-Info channel %s RFC4733 negotiated so using it.\n", ast_channel_name(ast));<br>+                        ast_rtp_instance_dtmf_end_with_duration(media->rtp, digit, duration);<br>+                     break;<br>+               }<br>+            /* If RFC_4733 was not negotiated, fail through to the DTMF_INFO processing */<br>+               ast_debug(3, "Told to send end of digit on Auto-Info channel %s RFC4733 NOT negotiated using INFO instead.\n", ast_channel_name(ast));<br>+     }<br>+<br>  case AST_SIP_DTMF_INFO:<br>       {<br>             struct info_dtmf_data *dtmf_data = info_dtmf_data_alloc(channel->session, digit, duration);<br>@@ -1848,14 +1868,15 @@<br>               }<br> <br>          ast_rtp_instance_dtmf_end_with_duration(media->rtp, digit, duration);<br>-                break;<br>-        case AST_SIP_DTMF_AUTO:<br>-                if (!media || !media->rtp || (ast_rtp_instance_dtmf_mode_get(media->rtp) == AST_RTP_DTMF_MODE_INBAND)) {<br>-                        return -1;<br>-                }<br>+                break;<br>+       case AST_SIP_DTMF_AUTO:<br>+              if (!media || !media->rtp || (ast_rtp_instance_dtmf_mode_get(media->rtp) == AST_RTP_DTMF_MODE_INBAND)) {<br>+                        return -1;<br>+          }<br> <br>-                ast_rtp_instance_dtmf_end_with_duration(media->rtp, digit, duration);<br>-                break;<br>+             ast_rtp_instance_dtmf_end_with_duration(media->rtp, digit, duration);<br>+             break;<br>+<br> <br>  case AST_SIP_DTMF_NONE:<br>               break;<br>diff --git a/contrib/ast-db-manage/config/versions/164abbd708c_add_auto_info_to_endpoint_dtmf_mode.py b/contrib/ast-db-manage/config/versions/164abbd708c_add_auto_info_to_endpoint_dtmf_mode.py<br>new file mode 100644<br>index 0000000..dbc8ce9<br>--- /dev/null<br>+++ b/contrib/ast-db-manage/config/versions/164abbd708c_add_auto_info_to_endpoint_dtmf_mode.py<br>@@ -0,0 +1,57 @@<br>+"""Add auto_info to endpoint dtmf_mode<br>+<br>+Revision ID: 164abbd708c<br>+Revises: 86bb1efa278d<br>+Create Date: 2017-06-19 13:55:15.354706<br>+<br>+"""<br>+<br>+# revision identifiers, used by Alembic.<br>+revision = '164abbd708c'<br>+down_revision = '86bb1efa278d'<br>+<br>+from alembic import op<br>+import sqlalchemy as sa<br>+<br>+OLD_ENUM = ['rfc4733', 'inband', 'info', 'auto']<br>+NEW_ENUM = ['rfc4733', 'inband', 'info', 'auto', 'auto_info']<br>+<br>+old_type = sa.Enum(*OLD_ENUM, name='pjsip_dtmf_mode_values_v2')<br>+new_type = sa.Enum(*NEW_ENUM, name='pjsip_dtmf_mode_values_v3')<br>+<br>+def upgrade():<br>+    context = op.get_context()<br>+<br>+    # Upgrading to this revision WILL clear your directmedia values.<br>+    if context.bind.dialect.name != 'postgresql':<br>+        op.alter_column('ps_endpoints', 'dtmf_mode',<br>+                        type_=new_type,<br>+                        existing_type=old_type)<br>+    else:<br>+        enum = ENUM('rfc4733', 'inband', 'info', 'auto', 'auto_info',<br>+                    name='pjsip_dtmf_mode_values_v3')<br>+        enum.create(op.get_bind(), checkfirst=False)<br>+<br>+        op.execute('ALTER TABLE ps_endpoints ALTER COLUMN dtmf_mode TYPE'<br>+                   ' pjsip_dtmf_mode_values_v3 USING'<br>+                   ' dtmf_mode::text::pjsip_dtmf_mode_values_v3')<br>+<br>+        ENUM(name="pjsip_dtmf_mode_values_v2").drop(op.get_bind(), checkfirst=False)<br>+<br>+def downgrade():<br>+    context = op.get_context()<br>+<br>+    if context.bind.dialect.name != 'postgresql':<br>+        op.alter_column('ps_endpoints', 'dtmf_mode',<br>+                        type_=old_type,<br>+                        existing_type=new_type)<br>+    else:<br>+        enum = ENUM('rfc4733', 'inband', 'info', 'auto',<br>+                    name='pjsip_dtmf_mode_values_v2')<br>+        enum.create(op.get_bind(), checkfirst=False)<br>+<br>+        op.execute('ALTER TABLE ps_endpoints ALTER COLUMN dtmf_mode TYPE'<br>+                   ' pjsip_dtmf_mode_values USING'<br>+                   ' dtmf_mode::text::pjsip_dtmf_mode_values_v2')<br>+<br>+        ENUM(name="pjsip_dtmf_mode_values_v3").drop(op.get_bind(), checkfirst=False)<br>diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h<br>index 04e0c65..b5a0288 100644<br>--- a/include/asterisk/res_pjsip.h<br>+++ b/include/asterisk/res_pjsip.h<br>@@ -363,6 +363,8 @@<br>         AST_SIP_DTMF_INFO,<br>    /*! Use SIP 4733 if supported by the other side or INBAND if not */<br>   AST_SIP_DTMF_AUTO,<br>+   /*! Use SIP 4733 if supported by the other side or INFO DTMF (blech) if not */<br>+       AST_SIP_DTMF_AUTO_INFO,<br> };<br> <br> /*!<br>diff --git a/res/res_pjsip.c b/res/res_pjsip.c<br>index f79ebfd..057ae33 100644<br>--- a/res/res_pjsip.c<br>+++ b/res/res_pjsip.c<br>@@ -229,6 +229,9 @@<br>                                                       <enum name="auto"><br>                                                            <para>DTMF is sent as RFC 4733 if the other side supports it or as INBAND if not.</para><br>                                                  </enum><br>+                                                        <enum name="auto_info"><br>+                                                              <para>DTMF is sent as RFC 4733 if the other side supports it or as SIP INFO if not.</para><br>+                                                       </enum><br>                                                 </enumlist><br>                                     </description><br>                          </configOption><br>diff --git a/res/res_pjsip/pjsip_configuration.c b/res/res_pjsip/pjsip_configuration.c<br>index d2d1a0c..9604ff2 100644<br>--- a/res/res_pjsip/pjsip_configuration.c<br>+++ b/res/res_pjsip/pjsip_configuration.c<br>@@ -373,6 +373,8 @@<br>               endpoint->dtmf = AST_SIP_DTMF_RFC_4733;<br>    } else if (!strcasecmp(var->value, "inband")) {<br>          endpoint->dtmf = AST_SIP_DTMF_INBAND;<br>+     } else if (!strcasecmp(var->value, "auto_info")) {<br>+              endpoint->dtmf = AST_SIP_DTMF_AUTO_INFO;<br>   } else if (!strcasecmp(var->value, "info")) {<br>            endpoint->dtmf = AST_SIP_DTMF_INFO;<br>        } else if (!strcasecmp(var->value, "auto")) {<br>@@ -397,8 +399,11 @@<br>              *buf = "inband"; break;<br>     case AST_SIP_DTMF_INFO :<br>              *buf = "info"; break;<br>-       case AST_SIP_DTMF_AUTO :<br>+    case AST_SIP_DTMF_AUTO :<br>              *buf = "auto"; break;<br>+      case AST_SIP_DTMF_AUTO_INFO :<br>+                *buf = "auto_info";<br>+                break;<br>        default:<br>              *buf = "none";<br>      }<br>diff --git a/res/res_pjsip_sdp_rtp.c b/res/res_pjsip_sdp_rtp.c<br>index d39842f..a6bd2d7 100644<br>--- a/res/res_pjsip_sdp_rtp.c<br>+++ b/res/res_pjsip_sdp_rtp.c<br>@@ -246,7 +246,7 @@<br>           ice->stop(session_media->rtp);<br>  }<br> <br>- if (session->endpoint->dtmf == AST_SIP_DTMF_RFC_4733 || session->endpoint->dtmf == AST_SIP_DTMF_AUTO) {<br>+  if (session->endpoint->dtmf == AST_SIP_DTMF_RFC_4733 || session->endpoint->dtmf == AST_SIP_DTMF_AUTO || session->endpoint->dtmf == AST_SIP_DTMF_AUTO_INFO) {<br>                ast_rtp_instance_dtmf_mode_set(session_media->rtp, AST_RTP_DTMF_MODE_RFC2833);<br>             ast_rtp_instance_set_prop(session_media->rtp, AST_RTP_PROPERTY_DTMF, 1);<br>   } else if (session->endpoint->dtmf == AST_SIP_DTMF_INBAND) {<br>@@ -269,7 +269,7 @@<br> }<br> <br> static void get_codecs(struct ast_sip_session *session, const struct pjmedia_sdp_media *stream, struct ast_rtp_codecs *codecs,<br>-       struct ast_sip_session_media *session_media)<br>+        struct ast_sip_session_media *session_media)<br> {<br>      pjmedia_sdp_attr *attr;<br>       pjmedia_sdp_rtpmap *rtpmap;<br>@@ -335,6 +335,16 @@<br>     if (!tel_event && (session->endpoint->dtmf == AST_SIP_DTMF_AUTO)) {<br>             ast_rtp_instance_dtmf_mode_set(session_media->rtp, AST_RTP_DTMF_MODE_INBAND);<br>      }<br>+<br>+ if (session->endpoint->dtmf == AST_SIP_DTMF_AUTO_INFO) {<br>+               if  (tel_event) {<br>+                    ast_rtp_instance_dtmf_mode_set(session_media->rtp, AST_RTP_DTMF_MODE_RFC2833);<br>+            } else {<br>+                     ast_rtp_instance_dtmf_mode_set(session_media->rtp, AST_RTP_DTMF_MODE_NONE);<br>+               }<br>+    }<br>+<br>+<br>       /* Get the packetization, if it exists */<br>     if ((attr = pjmedia_sdp_media_find_attr2(stream, "ptime", NULL))) {<br>                 unsigned long framing = pj_strtoul(pj_strltrim(&attr->value));<br>@@ -429,7 +439,8 @@<br>                    ast_set_read_format(session->channel, ast_channel_readformat(session->channel));<br>                        ast_set_write_format(session->channel, ast_channel_writeformat(session->channel));<br>              }<br>-            if ((session->endpoint->dtmf == AST_SIP_DTMF_AUTO)<br>+<br>+          if ( ((session->endpoint->dtmf == AST_SIP_DTMF_AUTO) || (session->endpoint->dtmf == AST_SIP_DTMF_AUTO_INFO) )<br>                 && (ast_rtp_instance_dtmf_mode_get(session_media->rtp) == AST_RTP_DTMF_MODE_RFC2833)<br>               && (session->dsp)) {<br>                   dsp_features = ast_dsp_get_features(session->dsp);<br>@@ -1149,7 +1160,7 @@<br>  pj_str_t stmp;<br>        pjmedia_sdp_attr *attr;<br>       int index = 0;<br>-       int noncodec = (session->endpoint->dtmf == AST_SIP_DTMF_RFC_4733 || session->endpoint->dtmf == AST_SIP_DTMF_AUTO) ? AST_RTP_DTMF : 0;<br>+    int noncodec = (session->endpoint->dtmf == AST_SIP_DTMF_RFC_4733 || session->endpoint->dtmf == AST_SIP_DTMF_AUTO || session->endpoint->dtmf == AST_SIP_DTMF_AUTO_INFO) ? AST_RTP_DTMF : 0;<br>  int min_packet_size = 0, max_packet_size = 0;<br>         int rtp_code;<br>         RAII_VAR(struct ast_format_cap *, caps, NULL, ao2_cleanup);<br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/5842">change 5842</a>. To unsubscribe, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/5842"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 13 </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: Id185b11e84afd9191a2f269e8443019047765e91 </div>
<div style="display:none"> Gerrit-Change-Number: 5842 </div>
<div style="display:none"> Gerrit-PatchSet: 4 </div>
<div style="display:none"> Gerrit-Owner: Torrey Searle <tsearle@gmail.com> </div>
<div style="display:none"> Gerrit-Reviewer: Alexei Gradinari <alex2grad@gmail.com> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins2 </div>
<div style="display:none"> Gerrit-Reviewer: Joshua Colp <jcolp@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Matthew Fredrickson <creslin@digium.com> </div>