aboutsummaryrefslogtreecommitdiffstats
path: root/channels
diff options
context:
space:
mode:
authormarkster <markster@f38db490-d61c-443f-a65b-d21fe96a405b>2005-09-06 21:04:40 +0000
committermarkster <markster@f38db490-d61c-443f-a65b-d21fe96a405b>2005-09-06 21:04:40 +0000
commit054df857925f00c4fc914fe2c08e4744e15d24fa (patch)
tree68df632763ea6defbe265eee54d99b295f1b2dd3 /channels
parentcaf70cc4c20aae79a388d66e7cf14c2367c1a639 (diff)
Allow "auto" dtmf mode to select between RFC2833 and inband based on peer's offer or answer.
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@6518 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channels')
-rwxr-xr-xchannels/chan_sip.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 9ea866c34..eb00e3c01 100755
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -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);