Asterisk
  1. Asterisk
  2. ASTERISK-8685

DTMF modes are bot getting translated in P2P bridging mode

    Details

    • Type: Bug Bug
    • Status: Closed
    • Severity: Minor Minor
    • Resolution: Fixed
    • Affects Version/s: None
    • Target Release Version/s: None
    • Component/s: Core/General
    • Labels:
      None
    • SVN Revision Number:
      52506
    • Mantis ID:
      8936
    • Regression:
      No

      Description

      If 2 call-legs have different DTMF modes and P2P bridging (and probably native) is used then DTMFs are not getting translated and as such are not recognized by the peer.
      File 2833-to-inband.txt show debugging output for calls when originating peer has dtmfmode set to rfc2833 and terminating peer has dtmfmode set to inband. DTMF digits are recognized by terminating peer.
      Relevant part of sip.conf:

      [general]
      disallow=all ; First disallow all codecs
      allow=ulaw ; Allow codecs in order of preference
      [pbx2]
      type=friend
      username=pbxtest
      permit=66.114.83.0/255.255.255.192
      deny=0.0.0.0/0.0.0.0
      host=66.114.83.12
      context=pbxes
      sendrpid=yes
      dtmfmode=inband
      nat=yes
      [xyz011101]
      type=friend
      username=xyz011101
      md5secret=7c7bad2e3d3bb30bbfb413ec14755db2
      context=xyz
      host=dynamic
      dtmfmode=rfc2833
      callerid=111
      mailbox=111@xyz
      mohsuggest=xyz

      File inband-to-2833.txt show debugging output for call when originating peer has dtmfmode set to inband and terminating peer has dtmfmode set to rfc2833. DTMF digits are recognized by terminating peer.
      Relevant part of sip.conf:

      [general]
      disallow=all ; First disallow all codecs
      allow=ulaw ; Allow codecs in order of preference
      [pbx2]
      type=friend
      username=pbxtest
      permit=66.114.83.0/255.255.255.192
      deny=0.0.0.0/0.0.0.0
      host=66.114.83.12
      context=pbxes
      sendrpid=yes
      rfc2833compensate=yes
      dtmfmode=rfc2833
      nat=yes
      [xyz011101]
      ;ext_id=1599, station_id=394, Polycom IP500
      type=friend
      username=xyz011101
      md5secret=7c7bad2e3d3bb30bbfb413ec14755db2
      context=xyz
      host=dynamic
      dtmfmode=inband
      callerid=111
      mailbox=111@xyz
      mohsuggest=xyz

      The only way I could get DTMF recognized by the peer is to make dtmfmode equal on both endpoints. It's not an option on my production system and I believe pbx should translate digits anyway.
      The other way I could get it work is to completely disable native bridging (by making codecs incompatible). If generic bridging is used then everything works fine.

      1. 2833-to-inband.txt
        56 kB
      2. 2833-to-inband-8936patch.txt
        100 kB
      3. 8936.patch
        3 kB
      4. chan_sip.c.diff
        1 kB
      5. inband-to-2833.txt
        51 kB
      6. inband-to-2833-8936patch.txt
        48 kB

        Activity

        Hide
        Russell Bryant added a comment -

        This should be fixed in the 1.4 branch and trunk in revisions 52645 and 52646. Thanks!

        Show
        Russell Bryant added a comment - This should be fixed in the 1.4 branch and trunk in revisions 52645 and 52646. Thanks!
        Hide
        mdu113 added a comment -

        It still doesn't work and debug output looks identical to what I posted.
        I spend some time reading the code and if my limited understanding is correct then I guess the problem is the following line
        in chan_sip.c:
        ast_rtp_setdtmf(dialog->rtp, ast_test_flag(&dialog->flags[0], SIP_DTMF) != SIP_DTMF_INFO);
        To correspond to the following table from rtp.c:

        • --------------------------------------------------
        • DTMF Mode HAS_DTMF Accepts Begin Frames
        • ----------- ------------ -----------------------
        • Inband False True
        • RFC2833 True True
        • SIP INFO False False
        • --------------------------------------------------
          it has to be changed to
          ast_rtp_setdtmf(dialog->rtp, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
          I've attached the patch. With this patch P2P bridging is not enabled if DTMF modes don't match and as far as I can tell it works correctly.

        On a separate note, is it a good idea to completely disable native bridging in this case? Isn't it better to make sure that core always monitor channels for DTMF if their modes don't match?

        Show
        mdu113 added a comment - It still doesn't work and debug output looks identical to what I posted. I spend some time reading the code and if my limited understanding is correct then I guess the problem is the following line in chan_sip.c: ast_rtp_setdtmf(dialog->rtp, ast_test_flag(&dialog->flags [0] , SIP_DTMF) != SIP_DTMF_INFO); To correspond to the following table from rtp.c: -------------------------------------------------- DTMF Mode HAS_DTMF Accepts Begin Frames ----------- ------------ ----------------------- Inband False True RFC2833 True True SIP INFO False False -------------------------------------------------- it has to be changed to ast_rtp_setdtmf(dialog->rtp, ast_test_flag(&dialog->flags [0] , SIP_DTMF) == SIP_DTMF_RFC2833); I've attached the patch. With this patch P2P bridging is not enabled if DTMF modes don't match and as far as I can tell it works correctly. On a separate note, is it a good idea to completely disable native bridging in this case? Isn't it better to make sure that core always monitor channels for DTMF if their modes don't match?
        Hide
        Russell Bryant added a comment -

        Originally, I had thought that implementing this such that DTMF always went through the core with P2P bridging when the modes didn't match wouldn't work. But, now that I look again, I think it's a simple change. Would you mind trying my attached patch?

        Show
        Russell Bryant added a comment - Originally, I had thought that implementing this such that DTMF always went through the core with P2P bridging when the modes didn't match wouldn't work. But, now that I look again, I think it's a simple change. Would you mind trying my attached patch?
        Hide
        mdu113 added a comment -

        Still no good.
        I uploaded 2 more files with debugging output from asterisk with your patch applied.
        When translation is supposed to be from rfc2833 to inband then digits are recognized by the core (according to the log), but still are not recognized by the peer. My guess is core still doesn't replay them in outbound stream.
        When translation is supposed to be from inband to rfc2833 then digits are not recognized by the core and debug looks identical to me.
        Again looking in the code I don't see how it's supposed to recognize the inband digits. The following line in rtp.c:bridge_p2p_rtp_write():
        /* If the payload is DTMF, and we are listening for DTMF - then feed it into the core */
        if (ast_test_flag(rtp, FLAG_P2P_NEED_DTMF) && !rtpPT.isAstFormat && rtpPT.code == AST_RTP_DTMF)
        return -1;
        suggests that it will work for rfc2833 digits only.
        To recognize inband DTMF I think it should be something like the following written in human language:
        if (dtmfmode is inband and we watch for dtmf and rtp frame type is voice )
        return -1;
        This probably also means that whatever is configured in features.conf won't work with inband dtmf in P2P-bridged calls.
        What do you think?

        Show
        mdu113 added a comment - Still no good. I uploaded 2 more files with debugging output from asterisk with your patch applied. When translation is supposed to be from rfc2833 to inband then digits are recognized by the core (according to the log), but still are not recognized by the peer. My guess is core still doesn't replay them in outbound stream. When translation is supposed to be from inband to rfc2833 then digits are not recognized by the core and debug looks identical to me. Again looking in the code I don't see how it's supposed to recognize the inband digits. The following line in rtp.c:bridge_p2p_rtp_write(): /* If the payload is DTMF, and we are listening for DTMF - then feed it into the core */ if (ast_test_flag(rtp, FLAG_P2P_NEED_DTMF) && !rtpPT.isAstFormat && rtpPT.code == AST_RTP_DTMF) return -1; suggests that it will work for rfc2833 digits only. To recognize inband DTMF I think it should be something like the following written in human language: if (dtmfmode is inband and we watch for dtmf and rtp frame type is voice ) return -1; This probably also means that whatever is configured in features.conf won't work with inband dtmf in P2P-bridged calls. What do you think?
        Hide
        Russell Bryant added a comment -

        Your analysis is correct. While bridged in P2P mode, there is no DTMF detector used on the incoming audio. In fact, doing so is more than I'm willing to do to solve this bug in the release branch. However, it would certainly be a nice feature to have in the trunk. But, that's really a separate issue.

        Thanks for all of the thorough logs and analysis of the problems!

        Show
        Russell Bryant added a comment - Your analysis is correct. While bridged in P2P mode, there is no DTMF detector used on the incoming audio. In fact, doing so is more than I'm willing to do to solve this bug in the release branch. However, it would certainly be a nice feature to have in the trunk. But, that's really a separate issue. Thanks for all of the thorough logs and analysis of the problems!
        Hide
        Russell Bryant added a comment -

        I have fixed the errors in chan_sip for setting the HAS_DTMF flag on the rtp structure in 1.4 and the trunk in revisions 52952 and 52953. Thanks!

        Show
        Russell Bryant added a comment - I have fixed the errors in chan_sip for setting the HAS_DTMF flag on the rtp structure in 1.4 and the trunk in revisions 52952 and 52953. Thanks!

          People

          • Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development