--- res_agi.c	(revision 207352)
+++ res_agi.c	(working copy)
@@ -686,13 +686,21 @@
 		
 		
 			
+			
+			
+			
+			
 		
 		
 			Waits up to timeout milliseconds for channel to
 			receive a DTMF digit. Returns -1 on channel failure, 0
 			if no digit is received in the timeout, or the numerical value of the ascii of the digit if
 			one is received. Use -1 for the timeout value if
-			you desire the call to block indefinitely.
+			you desire the call to block indefinitely.
+
+			If 'voicefile' is specified it is played as long 'previously die chars' (default '#') are
+			not typed in or as long as any of 'escape chars' (default '1234567890*#ABCD') is pressed a
+			'maxdigit' (default 1) times .
 		
 	
 	
@@ -1602,14 +1610,97 @@
 
 static int handle_waitfordigit(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
 {
-	int res, to;
+    int res;
+	int to;
+	char *valid_dtmf_digits = AST_DIGIT_ANY;
+	char *previously_die_on = "#";
+	char *digits = NULL;
+	char *escape_digits = NULL;
+	char *voicefile = NULL;
+	int maxdigits = 1;
 
-	if (argc != 4)
+	if (argc < 4)
 		return RESULT_SHOWUSAGE;
 	if (sscanf(argv[3], "%d", &to) != 1)
 		return RESULT_SHOWUSAGE;
-	res = ast_waitfordigit_full(chan, to, agi->audio, agi->ctrl);
-	ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
+
+	if (chan->_state != AST_STATE_UP) {
+		/* Answer the chan */
+		res = ast_answer(chan);
+	}
+
+	if (argc >= 5) {
+		// soundfile specified
+
+		if (argc >= 6)
+		{
+			// escape characters defined
+			valid_dtmf_digits = (char *) argv[5];
+		}
+
+		if (argc >= 7) {
+			//  maxdigits
+			if (sscanf(argv[6], "%d", &maxdigits) != 1)
+		        return RESULT_SHOWUSAGE;
+		}
+
+		if (argc >= 8) {
+			// escape before escape chars on
+			previously_die_on = (char *) argv[7];
+		}
+		
+		voicefile = (char *) argv[4];
+		res = ast_streamfile(chan, voicefile, chan->language);
+		if (res < 0)
+			return RESULT_FAILURE;
+		
+		// allocate space for the digits (2 chars per digit + \0 - ||...)
+		digits = (char *)ast_malloc(maxdigits * 2 + 1);
+		ast_copy_string(digits, "", 1);
+
+		// catenate the escape digits together with previously die digits
+		escape_digits = (char *)ast_malloc(strlen(valid_dtmf_digits) + strlen(previously_die_on)+ 1);
+		ast_copy_string(escape_digits, valid_dtmf_digits, sizeof(valid_dtmf_digits));
+		strcat(escape_digits, previously_die_on);
+
+		if (chan->stream)
+		{
+			int dtmf_count = 0;
+			do {
+				char buf[3];
+				res = ast_waitstream_full(chan, escape_digits, agi->audio, agi->ctrl);
+
+				if (res > 0) {
+					if (strchr(previously_die_on, res) != NULL) {
+						// previously die character found - end loop
+						
+						ast_log(LOG_DEBUG, "prev die digit %c pressed\n", res);
+						break;
+					} else {
+						// chars in valid_dtmf_digits found
+						
+						ast_log(LOG_DEBUG, "dtmf turn=%d of %d | res=%d\n", dtmf_count, maxdigits, res);
+						sprintf(buf, "%c|", res);
+						strcat(digits, buf);
+						dtmf_count++;
+					}
+				}
+			} while ( strchr(previously_die_on, res) == NULL && dtmf_count < maxdigits && chan->stream);
+			ast_stopstream(chan);
+			
+			ast_agi_send(agi->fd, chan, "200 result=%s\n", digits);
+		} else {
+			res = ast_waitfordigit_full(chan, to, agi->audio, agi->ctrl);
+			ast_agi_send(agi->fd, chan, "200 result=%c\n", res);
+		}
+	} else {
+		res = ast_waitfordigit_full(chan, to, agi->audio, agi->ctrl);
+		ast_agi_send(agi->fd, chan, "200 result=%c\n", res);
+	}
+	
+	ast_free(escape_digits);
+	ast_free(digits);
+	
 	return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
 }