[asterisk-commits] rmudgett: trunk r260231 - in /trunk: ./ channels/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Apr 29 17:44:19 CDT 2010


Author: rmudgett
Date: Thu Apr 29 17:44:14 2010
New Revision: 260231

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=260231
Log:
Merged revisions 260195 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
  r260195 | rmudgett | 2010-04-29 17:11:47 -0500 (Thu, 29 Apr 2010) | 26 lines
  
  DTMF CallerID detection problems.
  
  The code handling DTMF CallerID drops digits on long CallerID numbers and
  may timeout waiting for the first ring with shorter numbers.
  
  The DTMF emulation mode was not turned off when processing DTMF CallerID.
  When the emulation code gets behind in processing the DTMF digits it can
  skip a digit.
  
  For shorter numbers, the timeout may have been too short.  I increased it
  from 2 seconds to 4 seconds.  Four seconds is a typical time between rings
  for many countries.
  
  (closes issue #16460)
  Reported by: sum
  Patches:
        issue16460.patch uploaded by rmudgett (license 664)
        issue16460_v1.6.2.patch uploaded by rmudgett (license 664)
  Tested by: sum, rmudgett
  
  Review: https://reviewboard.asterisk.org/r/634/
  
  JIRA SWP-562
  JIRA AST-334
  JIRA SWP-901
........

Modified:
    trunk/   (props changed)
    trunk/channels/chan_dahdi.c
    trunk/channels/sig_analog.c

Propchange: trunk/
------------------------------------------------------------------------------
Binary property 'branch-1.4-merged' - no diff available.

Modified: trunk/channels/chan_dahdi.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_dahdi.c?view=diff&rev=260231&r1=260230&r2=260231
==============================================================================
--- trunk/channels/chan_dahdi.c (original)
+++ trunk/channels/chan_dahdi.c Thu Apr 29 17:44:14 2010
@@ -9700,14 +9700,25 @@
 			if (p->cid_signalling == CID_SIG_DTMF) {
 				int k = 0;
 				cs = NULL;
-				ast_debug(1, "Receiving DTMF cid on "
-					"channel %s\n", chan->name);
+				ast_debug(1, "Receiving DTMF cid on channel %s\n", chan->name);
 				dahdi_setlinear(p->subs[idx].dfd, 0);
-				res = 2000;
+				/*
+				 * We are the only party interested in the Rx stream since
+				 * we have not answered yet.  We don't need or even want DTMF
+				 * emulation.  The DTMF digits can come so fast that emulation
+				 * can drop some of them.
+				 */
+				ast_set_flag(chan, AST_FLAG_END_DTMF_ONLY);
+				res = 4000;/* This is a typical OFF time between rings. */
 				for (;;) {
 					struct ast_frame *f;
 					res = ast_waitfor(chan, res);
 					if (res <= 0) {
+						/*
+						 * We do not need to restore the dahdi_setlinear()
+						 * or AST_FLAG_END_DTMF_ONLY flag settings since we
+						 * are hanging up the channel.
+						 */
 						ast_log(LOG_WARNING, "DTMFCID timed out waiting for ring. "
 							"Exiting simple switch\n");
 						ast_hangup(chan);
@@ -9717,22 +9728,24 @@
 					if (!f)
 						break;
 					if (f->frametype == AST_FRAME_DTMF) {
-						dtmfbuf[k++] = f->subclass.integer;
+						if (k < ARRAY_LEN(dtmfbuf) - 1) {
+							dtmfbuf[k++] = f->subclass.integer;
+						}
 						ast_debug(1, "CID got digit '%c'\n", f->subclass.integer);
-						res = 2000;
+						res = 4000;/* This is a typical OFF time between rings. */
 					}
 					ast_frfree(f);
 					if (chan->_state == AST_STATE_RING ||
 						chan->_state == AST_STATE_RINGING)
 						break; /* Got ring */
 				}
+				ast_clear_flag(chan, AST_FLAG_END_DTMF_ONLY);
 				dtmfbuf[k] = '\0';
 				dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
 				/* Got cid and ring. */
 				ast_debug(1, "CID got string '%s'\n", dtmfbuf);
 				callerid_get_dtmf(dtmfbuf, dtmfcid, &flags);
-				ast_debug(1, "CID is '%s', flags %d\n",
-					dtmfcid, flags);
+				ast_debug(1, "CID is '%s', flags %d\n", dtmfcid, flags);
 				/* If first byte is NULL, we have no cid */
 				if (!ast_strlen_zero(dtmfcid))
 					number = dtmfcid;
@@ -9815,13 +9828,10 @@
 					if (p->cid_signalling == CID_SIG_V23_JP) {
 						res = dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_ONHOOK);
 						usleep(1);
-						res = 4000;
-					} else {
-
-						/* Finished with Caller*ID, now wait for a ring to make sure there really is a call coming */
-						res = 2000;
 					}
 
+					/* Finished with Caller*ID, now wait for a ring to make sure there really is a call coming */
+					res = 4000;/* This is a typical OFF time between rings. */
 					for (;;) {
 						struct ast_frame *f;
 						res = ast_waitfor(chan, res);

Modified: trunk/channels/sig_analog.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/sig_analog.c?view=diff&rev=260231&r1=260230&r2=260231
==============================================================================
--- trunk/channels/sig_analog.c (original)
+++ trunk/channels/sig_analog.c Thu Apr 29 17:44:14 2010
@@ -2119,16 +2119,27 @@
 				int i = 0;
 				int oldlinearity; 
 				cs = NULL;
-				ast_debug(1, "Receiving DTMF cid on "
-					"channel %s\n", chan->name);
+				ast_debug(1, "Receiving DTMF cid on channel %s\n", chan->name);
 
 				oldlinearity = analog_set_linear_mode(p, index, 0);
 
-				res = 2000;
+				/*
+				 * We are the only party interested in the Rx stream since
+				 * we have not answered yet.  We don't need or even want DTMF
+				 * emulation.  The DTMF digits can come so fast that emulation
+				 * can drop some of them.
+				 */
+				ast_set_flag(chan, AST_FLAG_END_DTMF_ONLY);
+				res = 4000;/* This is a typical OFF time between rings. */
 				for (;;) {
 					struct ast_frame *f;
 					res = ast_waitfor(chan, res);
 					if (res <= 0) {
+						/*
+						 * We do not need to restore the analog_set_linear_mode()
+						 * or AST_FLAG_END_DTMF_ONLY flag settings since we
+						 * are hanging up the channel.
+						 */
 						ast_log(LOG_WARNING, "DTMFCID timed out waiting for ring. "
 							"Exiting simple switch\n");
 						ast_hangup(chan);
@@ -2138,15 +2149,18 @@
 						break;
 					}
 					if (f->frametype == AST_FRAME_DTMF) {
-						dtmfbuf[i++] = f->subclass.integer;
+						if (i < ARRAY_LEN(dtmfbuf) - 1) {
+							dtmfbuf[i++] = f->subclass.integer;
+						}
 						ast_debug(1, "CID got digit '%c'\n", f->subclass.integer);
-						res = 2000;
+						res = 4000;/* This is a typical OFF time between rings. */
 					}
 					ast_frfree(f);
 					if (chan->_state == AST_STATE_RING || chan->_state == AST_STATE_RINGING) {
 						break; /* Got ring */
 					}
 				}
+				ast_clear_flag(chan, AST_FLAG_END_DTMF_ONLY);
 				dtmfbuf[i] = '\0';
 
 				analog_set_linear_mode(p, index, oldlinearity);
@@ -2154,8 +2168,7 @@
 				/* Got cid and ring. */
 				ast_debug(1, "CID got string '%s'\n", dtmfbuf);
 				callerid_get_dtmf(dtmfbuf, dtmfcid, &flags);
-				ast_debug(1, "CID is '%s', flags %d\n",
-					dtmfcid, flags);
+				ast_debug(1, "CID is '%s', flags %d\n", dtmfcid, flags);
 				/* If first byte is NULL, we have no cid */
 				if (!ast_strlen_zero(dtmfcid)) {
 					number = dtmfcid;
@@ -2207,12 +2220,10 @@
 					if (p->cid_signalling == CID_SIG_V23_JP) {
 						res = analog_on_hook(p);
 						usleep(1);
-						res = 4000;
-					} else {
-						/* Finished with Caller*ID, now wait for a ring to make sure there really is a call coming */
-						res = 2000;
-					}
-
+					}
+
+					/* Finished with Caller*ID, now wait for a ring to make sure there really is a call coming */
+					res = 4000;/* This is a typical OFF time between rings. */
 					for (;;) {
 						struct ast_frame *f;
 						res = ast_waitfor(chan, res);




More information about the asterisk-commits mailing list