[asterisk-commits] russell: branch group/vldtmf r40480 - in /team/group/vldtmf: ./ include/aster...

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Fri Aug 18 19:09:19 MST 2006


Author: russell
Date: Fri Aug 18 21:09:18 2006
New Revision: 40480

URL: http://svn.digium.com/view/asterisk?rev=40480&view=rev
Log:
Implement some (untested) magic in ast_read() as discussed with Josh and Kevin.
This implements handling of DTMF_END frames without a BEGIN in the core instead
of in the channel drivers.  This is necessary for backwards compatability with
older versions of Asterisk, as well as any channel driver using the inband DTMF
detector until it gets updated to detect the beginning and end of a digit,
instead of just a single DTMF event.

- add a couple flags to ast_channel
  - AST_FLAG_IN_DTMF, which is set on a BEGIN, and cleared on an END
  - AST_FLAG_EMULATE_DTMF, this is when an END is received without a begin, and
    the core must emulate the length of the digit

Modified:
    team/group/vldtmf/channel.c
    team/group/vldtmf/include/asterisk/channel.h

Modified: team/group/vldtmf/channel.c
URL: http://svn.digium.com/view/asterisk/team/group/vldtmf/channel.c?rev=40480&r1=40479&r2=40480&view=diff
==============================================================================
--- team/group/vldtmf/channel.c (original)
+++ team/group/vldtmf/channel.c Fri Aug 18 21:09:18 2006
@@ -102,6 +102,9 @@
 
 AST_THREADSTORAGE(state2str_threadbuf, state2str_threadbuf_init);
 #define STATE2STR_BUFSIZE   32
+
+/* XXX 100ms ... this won't work with wideband support */
+#define AST_DEFAULT_EMULATE_DTMF_SAMPLES 800
 
 struct chanlist {
 	const struct ast_channel_tech *tech;
@@ -1894,11 +1897,10 @@
 	 */
 	ast_channel_lock(chan);
 	if (chan->masq) {
-		if (ast_do_masquerade(chan)) {
+		if (ast_do_masquerade(chan))
 			ast_log(LOG_WARNING, "Failed to perform masquerade\n");
-		} else {
+		else
 			f =  &ast_null_frame;
-		}
 		goto done;
 	}
 
@@ -1910,13 +1912,16 @@
 	}
 	prestate = chan->_state;
 
-	if (!ast_test_flag(chan, AST_FLAG_DEFER_DTMF) && !ast_strlen_zero(chan->dtmfq)) {
+	if (!ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_EMULATE_DTMF | AST_FLAG_IN_DTMF) && 
+	    !ast_strlen_zero(chan->dtmfq)) {
 		/* We have DTMF that has been deferred.  Return it now */
-		chan->dtmff.frametype = AST_FRAME_DTMF;
+		chan->dtmff.frametype = AST_FRAME_DTMF_BEGIN;
 		chan->dtmff.subclass = chan->dtmfq[0];
 		/* Drop first digit from the buffer */
 		memmove(chan->dtmfq, chan->dtmfq + 1, sizeof(chan->dtmfq) - 1);
 		f = &chan->dtmff;
+		ast_set_flag(chan, AST_FLAG_EMULATE_DTMF);
+		chan->emulate_dtmf_samples = AST_DEFAULT_EMULATE_DTMF_SAMPLES;
 		goto done;
 	}
 	
@@ -2032,7 +2037,7 @@
 			break;
 		case AST_FRAME_DTMF_END:
 			ast_log(LOG_DTMF, "DTMF end '%c' received on %s\n", f->subclass, chan->name);
-			if (ast_test_flag(chan, AST_FLAG_DEFER_DTMF)) {
+			if (ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_EMULATE_DTMF)) {
 				if (strlen(chan->dtmfq) < sizeof(chan->dtmfq) - 2)
 					chan->dtmfq[strlen(chan->dtmfq)] = f->subclass;
 				else
@@ -2040,12 +2045,30 @@
 				ast_frfree(f);
 				f = &ast_null_frame;
 			}
+			if (!ast_test_flag(chan, AST_FLAG_IN_DTMF)) {
+				f->frametype = AST_FRAME_DTMF_BEGIN;
+				ast_set_flag(chan, AST_FLAG_EMULATE_DTMF);
+				if (f->samples)
+					chan->emulate_dtmf_samples = f->samples;
+				else
+					chan->emulate_dtmf_samples = AST_DEFAULT_EMULATE_DTMF_SAMPLES;
+			} else 
+				ast_clear_flag(chan, AST_FLAG_IN_DTMF);
 			break;
 		case AST_FRAME_DTMF_BEGIN:
 			ast_log(LOG_DTMF, "DTMF begin '%c' received on %s\n", f->subclass, chan->name);
+			ast_set_flag(chan, AST_FLAG_IN_DTMF);
 			break;
 		case AST_FRAME_VOICE:
-			if (dropaudio) {
+			if (dropaudio || ast_test_flag(chan, AST_FLAG_IN_DTMF)) {
+				ast_frfree(f);
+				f = &ast_null_frame;
+			} else if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF)) {
+				if (f->samples >= chan->emulate_dtmf_samples) {
+					chan->emulate_dtmf_samples = 0;
+					ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF);
+				} else
+					chan->emulate_dtmf_samples -= f->samples;
 				ast_frfree(f);
 				f = &ast_null_frame;
 			} else if (!(f->subclass & chan->nativeformats)) {

Modified: team/group/vldtmf/include/asterisk/channel.h
URL: http://svn.digium.com/view/asterisk/team/group/vldtmf/include/asterisk/channel.h?rev=40480&r1=40479&r2=40480&view=diff
==============================================================================
--- team/group/vldtmf/include/asterisk/channel.h (original)
+++ team/group/vldtmf/include/asterisk/channel.h Fri Aug 18 21:09:18 2006
@@ -422,7 +422,10 @@
 	struct ast_channel_spy_list *spies;		/*!< Chan Spy stuff */
 	struct ast_channel_whisper_buffer *whisper;	/*!< Whisper Paging buffer */
 	AST_LIST_ENTRY(ast_channel) chan_list;		/*!< For easy linking */
+	
 	struct ast_jb jb;				/*!< The jitterbuffer state  */
+
+	unsigned int emulate_dtmf_samples;		/*!< Number of samples left to emulate DTMF for */
 
 	/*! \brief Data stores on the channel */
 	AST_LIST_HEAD_NOLOCK(datastores, ast_datastore) datastores;
@@ -441,29 +444,34 @@
 /*! \brief ast_channel flags */
 enum {
 	/*! Queue incoming dtmf, to be released when this flag is turned off */
-	AST_FLAG_DEFER_DTMF =  (1 << 1),
+	AST_FLAG_DEFER_DTMF =   (1 << 1),
 	/*! write should be interrupt generator */
-	AST_FLAG_WRITE_INT =   (1 << 2),
+	AST_FLAG_WRITE_INT =    (1 << 2),
 	/*! a thread is blocking on this channel */
-	AST_FLAG_BLOCKING =    (1 << 3),
+	AST_FLAG_BLOCKING =     (1 << 3),
 	/*! This is a zombie channel */
-	AST_FLAG_ZOMBIE =      (1 << 4),
+	AST_FLAG_ZOMBIE =       (1 << 4),
 	/*! There is an exception pending */
-	AST_FLAG_EXCEPTION =   (1 << 5),
+	AST_FLAG_EXCEPTION =    (1 << 5),
 	/*! Listening to moh XXX anthm promises me this will disappear XXX */
-	AST_FLAG_MOH =         (1 << 6),
+	AST_FLAG_MOH =          (1 << 6),
 	/*! This channel is spying on another channel */
-	AST_FLAG_SPYING =      (1 << 7),
+	AST_FLAG_SPYING =       (1 << 7),
 	/*! This channel is in a native bridge */
-	AST_FLAG_NBRIDGE =     (1 << 8),
+	AST_FLAG_NBRIDGE =      (1 << 8),
 	/*! the channel is in an auto-incrementing dialplan processor,
 	 *  so when ->priority is set, it will get incremented before
 	 *  finding the next priority to run */
-	AST_FLAG_IN_AUTOLOOP = (1 << 9),
+	AST_FLAG_IN_AUTOLOOP =  (1 << 9),
 	/*! This is an outgoing call */
-	AST_FLAG_OUTGOING =    (1 << 10),
+	AST_FLAG_OUTGOING =     (1 << 10),
 	/*! This channel is being whispered on */
-	AST_FLAG_WHISPER =     (1 << 11),
+	AST_FLAG_WHISPER =      (1 << 11),
+	/*! A DTMF_BEGIN frame has been read from this channel, but not yet an END */
+	AST_FLAG_IN_DTMF =      (1 << 12),
+	/*! A DTMF_END was received when not IN_DTMF, so the length of the digit is 
+	 *  currently being emulated */
+	AST_FLAG_EMULATE_DTMF = (1 << 13),
 };
 
 /*! \brief ast_bridge_config flags */



More information about the asterisk-commits mailing list