Allow "auto" dtmf mode to select between RFC2833 and inband based on peer's offer...
authorMark Spencer <markster@digium.com>
Tue, 6 Sep 2005 21:04:40 +0000 (21:04 +0000)
committerMark Spencer <markster@digium.com>
Tue, 6 Sep 2005 21:04:40 +0000 (21:04 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@6518 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_sip.c
configs/sip.conf.sample

index 9ea866c..eb00e3c 100755 (executable)
@@ -489,6 +489,7 @@ struct sip_auth {
 #define SIP_DTMF_RFC2833       (0 << 16)       /* RTP DTMF */
 #define SIP_DTMF_INBAND                (1 << 16)       /* Inband audio, only for ULAW/ALAW */
 #define SIP_DTMF_INFO          (2 << 16)       /* SIP Info messages */
+#define SIP_DTMF_AUTO          (3 << 16)       /* AUTO switch between rfc2833 and in-band DTMF */
 /* NAT settings */
 #define SIP_NAT                        (3 << 18)       /* four settings, uses two bits */
 #define SIP_NAT_NEVER          (0 << 18)       /* No nat support */
@@ -1814,7 +1815,7 @@ static int create_addr_from_peer(struct sip_pvt *r, struct sip_peer *peer)
        /* Set timer T1 to RTT for this peer (if known by qualify=) */
        if (peer->maxms && peer->lastms)
                r->timer_t1 = peer->lastms;
-       if (ast_test_flag(r, SIP_DTMF) == SIP_DTMF_RFC2833)
+       if ((ast_test_flag(r, SIP_DTMF) == SIP_DTMF_RFC2833) || (ast_test_flag(r, SIP_DTMF) == SIP_DTMF_AUTO))
                r->noncodeccapability |= AST_RTP_DTMF;
        else
                r->noncodeccapability &= ~AST_RTP_DTMF;
@@ -2976,7 +2977,7 @@ static struct sip_pvt *sip_alloc(char *callid, struct sockaddr_in *sin, int useg
        /* Assign default music on hold class */
        strcpy(p->musicclass, global_musicclass);
        p->capability = global_capability;
-       if (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_RFC2833)
+       if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_RFC2833) || (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_AUTO))
                p->noncodeccapability |= AST_RTP_DTMF;
        strcpy(p->context, default_context);
 
@@ -3418,6 +3419,16 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req)
        p->peercapability = (peercapability | vpeercapability);
        p->noncodeccapability = noncodeccapability & peernoncodeccapability;
        
+       if (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_AUTO) {
+               ast_clear_flag(p, SIP_DTMF);
+               if (p->noncodeccapability & AST_RTP_DTMF) {
+                       /* XXX Would it be reasonable to drop the DSP at this point? XXX */
+                       ast_set_flag(p, SIP_DTMF_RFC2833);
+               } else {
+                       ast_set_flag(p, SIP_DTMF_INBAND);
+               }
+       }
+       
        if (debug) {
                /* shame on whoever coded this.... */
                const unsigned slen=512;
@@ -6589,7 +6600,7 @@ static int check_user_full(struct sip_pvt *p, struct sip_request *req, int sipme
                        p->jointcapability = user->capability;
                        if (p->peercapability)
                                p->jointcapability &= p->peercapability;
-                       if (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_RFC2833)
+                       if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_RFC2833) || (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_AUTO))
                                p->noncodeccapability |= AST_RTP_DTMF;
                        else
                                p->noncodeccapability &= ~AST_RTP_DTMF;
@@ -6691,7 +6702,7 @@ static int check_user_full(struct sip_pvt *p, struct sip_request *req, int sipme
                                p->jointcapability = peer->capability;
                                if (p->peercapability)
                                        p->jointcapability &= p->peercapability;
-                               if (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_RFC2833)
+                               if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_RFC2833) || (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_AUTO))
                                        p->noncodeccapability |= AST_RTP_DTMF;
                                else
                                        p->noncodeccapability &= ~AST_RTP_DTMF;
@@ -7134,6 +7145,8 @@ static const char *dtmfmode2str(int mode)
                return "info";
        case SIP_DTMF_INBAND:
                return "inband";
+       case SIP_DTMF_AUTO:
+               return "auto";
        }
        return "<error>";
 }
@@ -10834,6 +10847,8 @@ static int handle_common_options(struct ast_flags *flags, struct ast_flags *mask
                        ast_set_flag(flags, SIP_DTMF_RFC2833);
                else if (!strcasecmp(v->value, "info"))
                        ast_set_flag(flags, SIP_DTMF_INFO);
+               else if (!strcasecmp(v->value, "auto"))
+                       ast_set_flag(flags, SIP_DTMF_AUTO);
                else {
                        ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno);
                        ast_set_flag(flags, SIP_DTMF_RFC2833);
index 23cc922..3fb2150 100755 (executable)
@@ -83,6 +83,7 @@ srvlookup=yes                 ; Enable DNS SRV lookups on outbound calls
                                ; Other options: 
                                ; info : SIP INFO messages
                                ; inband : Inband audio (requires 64 kbit codec -alaw, ulaw)
+                               ; auto : Use rfc2833 if offered, inband otherwise
 
 ;compactheaders = yes          ; send compact sip headers.
 ;sipdebug = yes                        ; Turn on SIP debugging by default, from