[Asterisk-Dev] DTMF detection on modem(ISDN)

Tomaz Izanc izol at itt.nu
Mon Oct 27 04:24:39 MST 2003


how to turn off DTMF detection on  modem (isdn).
is this patch too old ?
any other way to turn off DTMF detection when the channel is open (ISDN)?
tnx.
Tomaz


patch  -p0 -d /usr/src/asterisk/asterisk/ < /usr/src/isdn-dsp.diff  -N
patching file channels/chan_modem.c
Hunk #1 FAILED at 11.
Hunk #2 FAILED at 22.
Hunk #3 FAILED at 73.
Hunk #4 FAILED at 475.
Hunk #5 FAILED at 514.
Hunk #6 FAILED at 536.
Hunk #7 FAILED at 745.
Hunk #8 FAILED at 839.
Hunk #9 FAILED at 924.
9 out of 9 hunks FAILED -- saving rejects to file channels/chan_modem.c.rej
patching file channels/chan_modem_i4l.c
Hunk #1 FAILED at 17.
Hunk #2 FAILED at 278.
Hunk #3 FAILED at 562.
3 out of 3 hunks FAILED -- saving rejects to file 
channels/chan_modem_i4l.c.rej
patching file include/asterisk/vmodem.h
Hunk #1 FAILED at 75.
1 out of 1 hunk FAILED -- saving rejects to file 
include/asterisk/vmodem.h.rej

----------------------
-------------- next part --------------
Index: channels/chan_modem.c
===================================================================
RCS file: /usr/cvsroot/asterisk/channels/chan_modem.c,v
retrieving revision 1.40
diff -u -r1.40 chan_modem.c
--- channels/chan_modem.c	11 Nov 2002 18:21:17 -0000	1.40
+++ channels/chan_modem.c	17 Jan 2003 11:40:19 -0000
@@ -11,6 +11,7 @@
  * the GNU General Public License
  */
 
+#define _GNU_SOURCE	/* for strdupa */
 #include <stdio.h>
 #include <pthread.h>
 #include <string.h>
@@ -21,6 +22,7 @@
 #include <asterisk/logger.h>
 #include <asterisk/module.h>
 #include <asterisk/pbx.h>
+#include <asterisk/dsp.h>
 #include <asterisk/options.h>
 #include <asterisk/vmodem.h>
 #include <sys/socket.h>
@@ -71,6 +73,10 @@
 
 static int stripmsd = 0;
 
+/* when no feature is given, DTMF detection is assumed */
+static int features = DSP_FEATURE_DTMF_DETECT;
+static int digitmode = DSP_DIGITMODE_DTMF;
+
 static pthread_mutex_t usecnt_lock = AST_MUTEX_INITIALIZER;
 
 /* Protect the interface list (of ast_modem_pvt's) */
@@ -469,8 +475,21 @@
 {
 	struct ast_modem_pvt *p = ast->pvt->pvt;
 	struct ast_frame *fr=NULL;
-	if (p->mc->read)
+	if (p->mc->read) {
 		fr = p->mc->read(p);
+		if (p->dsp) {
+			/* Perform busy detection. etc on the modem line */
+			fr = ast_dsp_process(ast, p->dsp, fr, 0);
+// PM2003: We do not (yet) have an indication if the channel is in or outgoing
+//			if (fr && (fr->frametype == AST_FRAME_CONTROL) && (fr->subclass == AST_CONTROL_BUSY)) {
+//				if ((ast->_state == AST_STATE_UP) && !p->outgoing) {
+//					/* Treat this as a "hangup" instead of a "busy" on the assumption that
+//					   a busy  */
+//					fr = NULL;
+//				}
+//			}
+		}
+	}
 	return fr;
 }
 
@@ -495,7 +514,7 @@
 
 	/* Block again */
 	fcntl(ast->fds[0], F_SETFL, flags);
-	return 0;
+	return res;
 }
 
 struct ast_channel *ast_modem_new(struct ast_modem_pvt *i, int state)
@@ -517,6 +536,10 @@
 		tmp->pvt->answer = modem_answer;
 		tmp->pvt->read = modem_read;
 		tmp->pvt->write = modem_write;
+		if (i->dsp) {
+			ast_dsp_reset(i->dsp);
+			ast_dsp_digitreset(i->dsp);
+		}
 		strncpy(tmp->context, i->context, sizeof(tmp->context)-1);
 		if (strlen(i->cid))
 			tmp->callerid = strdup(i->cid);
@@ -722,6 +745,13 @@
 		tmp->ministate = 0;
 		tmp->stripmsd = stripmsd;
 		tmp->dialtype = dialtype;
+		if (features) {
+			tmp->dsp = ast_dsp_new();
+			if (tmp->dsp) {
+				ast_dsp_set_features(tmp->dsp, features);
+				ast_dsp_digitmode(tmp->dsp, digitmode);
+			}
+		}
 		tmp->mode = gmode;
 		tmp->group = cur_group;
 		memset(tmp->cid, 0, sizeof(tmp->cid));
@@ -809,7 +839,7 @@
 	int start, finish,x;
 	unsigned int group = 0;
 	char *copy = strdupa(s);
-	char *stringp=NULL;
+	char *stringp;
 	if (!copy) {
 		ast_log(LOG_ERROR, "Out of memory\n");
 		return 0;
@@ -894,6 +924,42 @@
 				gmode = MODEM_MODE_WAIT_ANSWER;
 			else
 				ast_log(LOG_WARNING, "Unknown mode: %s\n", v->value);
+		} else if (!strcasecmp(v->name, "features")) {
+			char *piece, *stringp = strdupa(v->value);
+			piece = strsep(&stringp, ",");
+			features = 0;
+			digitmode = 0;
+			while(piece && *piece) {
+				if (!strcasecmp(piece,"dtmf")) {
+					features |= DSP_FEATURE_DTMF_DETECT;
+					digitmode |= DSP_DIGITMODE_DTMF;
+					digitmode &= ~DSP_DIGITMODE_MF;
+				} else if (!strcasecmp(piece,"mf")) {
+					features |= DSP_FEATURE_DTMF_DETECT;
+					digitmode &= ~DSP_DIGITMODE_DTMF;
+					digitmode |= DSP_DIGITMODE_MF;
+				} else if (!strcasecmp(piece,"noquelch")) {
+					features |= DSP_FEATURE_DTMF_DETECT;
+					digitmode |= DSP_DIGITMODE_NOQUELCH;
+					/* no mode given? use DTMF */
+					if (!(digitmode & (DSP_DIGITMODE_DTMF|DSP_DIGITMODE_MF)))
+						digitmode = DSP_DIGITMODE_DTMF;
+				} else if (!strcasecmp(piece,"relax")) {
+					features |= DSP_FEATURE_DTMF_DETECT;
+					digitmode |= DSP_DIGITMODE_RELAXDTMF;
+					/* no mode given? use DTMF */
+					if (!(digitmode & (DSP_DIGITMODE_DTMF|DSP_DIGITMODE_MF)))
+						digitmode = DSP_DIGITMODE_DTMF;
+				} else if (!strcasecmp(piece,"busydetect"))
+					features |= DSP_FEATURE_BUSY_DETECT;
+				else if (!strcasecmp(piece,"callprogress"))
+					features |= DSP_FEATURE_CALL_PROGRESS;
+				else {
+					ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'.\n", v->value,piece);
+					return -1;
+				}
+				piece = strsep(&stringp, ",");
+			}
 		} else if (!strcasecmp(v->name, "stripmsd")) {
 			stripmsd = atoi(v->value);
 		} else if (!strcasecmp(v->name, "type")) {
Index: channels/chan_modem_i4l.c
===================================================================
RCS file: /usr/cvsroot/asterisk/channels/chan_modem_i4l.c,v
retrieving revision 1.28
diff -u -r1.28 chan_modem_i4l.c
--- channels/chan_modem_i4l.c	29 Nov 2002 02:14:13 -0000	1.28
+++ channels/chan_modem_i4l.c	17 Jan 2003 11:40:19 -0000
@@ -17,6 +17,7 @@
 #include <stdlib.h>
 #include <errno.h>
 #include <unistd.h>
+#include <fcntl.h>
 #include <sys/ioctl.h>
 #include <asterisk/lock.h>
 #include <asterisk/vmodem.h>
@@ -277,6 +278,9 @@
 	case '9':
 	case '*':
 	case '#':
+		if (p->dsp)	/* VAD active, let it handle the detection */
+			return &p->fr;
+
 		ast_log(LOG_DEBUG, "DTMF: '%c' (%d)\n", esc, esc);
 		p->fr.frametype=AST_FRAME_DTMF;
 		p->fr.subclass=esc;
@@ -558,7 +562,26 @@
 	read(p->fd, dummy, sizeof(dummy));
 	if (ast_modem_send(p, "ATH", 0)) {
 		ast_log(LOG_WARNING, "Unable to hang up\n");
-		return -1;
+		/* last resort: close modem device and open it again.
+		 * Note: we very much assume the modem does NOT forget
+		 * its settings when closing/opening it. No AT&D3! */
+		close(p->fd);
+		p->fd = open(p->dev, O_RDWR | O_NONBLOCK);
+		if (p->fd < 0) {
+			ast_log(LOG_WARNING, "Unable to open '%s'\n", p->dev);
+			return -1;
+		}
+		p->f = fdopen(p->fd, "w+");
+		setvbuf(p->f, NULL, _IONBF,0);
+		if (p->f == NULL) {
+			ast_log(LOG_WARNING, "Unable to open '%s'\n", p->dev);
+			return -1;
+		}
+		if (ast_modem_send(p, "ATH", 0)) {
+			ast_log(LOG_WARNING, "Really unable to hang up\n");
+			return -1;
+		}
+		/* end-of-last-resort */
 	}
 	if (ast_modem_expect(p, "OK", 5)) {
 		ast_log(LOG_WARNING, "Final 'OK' not received\n");
Index: include/asterisk/vmodem.h
===================================================================
RCS file: /usr/cvsroot/asterisk/include/asterisk/vmodem.h,v
retrieving revision 1.12
diff -u -r1.12 vmodem.h
--- include/asterisk/vmodem.h	20 Oct 2002 20:16:32 -0000	1.12
+++ include/asterisk/vmodem.h	17 Jan 2003 11:40:19 -0000
@@ -75,6 +75,8 @@
 	char dev[256];					
 	/*! Frame */
 	struct ast_frame fr;			
+	/* Call progress and DTMF/MF tone detection */
+	struct ast_dsp* dsp;
 	
 	char offset[AST_FRIENDLY_OFFSET];
 	/*! Outgoing buffer */



More information about the asterisk-dev mailing list