[svn-commits] russell: branch group/vldtmf r39457 - /team/group/vldtmf/channels/chan_zap.c

svn-commits at lists.digium.com svn-commits at lists.digium.com
Tue Aug 8 21:50:40 MST 2006


Author: russell
Date: Tue Aug  8 23:50:40 2006
New Revision: 39457

URL: http://svn.digium.com/view/asterisk?rev=39457&view=rev
Log:
Implement variable length DTMF generation on zap channels.  If the version of
zaptel running doesn't support the updated ioctl, it will fall back to the
method used previously.

Modified:
    team/group/vldtmf/channels/chan_zap.c

Modified: team/group/vldtmf/channels/chan_zap.c
URL: http://svn.digium.com/view/asterisk/team/group/vldtmf/channels/chan_zap.c?rev=39457&r1=39456&r2=39457&view=diff
==============================================================================
--- team/group/vldtmf/channels/chan_zap.c (original)
+++ team/group/vldtmf/channels/chan_zap.c Tue Aug  8 23:50:40 2006
@@ -690,6 +690,7 @@
 #endif	
 	int polarity;
 	int dsp_features;
+	int begindigit;
 } *iflist = NULL, *ifend = NULL;
 
 static struct ast_channel *zt_request(const char *type, int format, void *data, int *cause);
@@ -1004,50 +1005,128 @@
 	return 0;
 }
 
-static int zt_digit_begin(struct ast_channel *ast, char digit)
-{
-	/* XXX Implement me, plz, kthx */
-	return 0;
-}
-static int zt_digit_end(struct ast_channel *ast, char digit)
+static int digit_to_dtmfindex(char digit)
+{
+	if (isdigit(digit))
+		return ZT_TONE_DTMF_BASE + (digit - '0');
+	else if (digit >= 'A' && digit <= 'D')
+		return ZT_TONE_DTMF_A + (digit - 'A');
+	else if (digit >= 'a' && digit <= 'd')
+		return ZT_TONE_DTMF_A + (digit - 'a');
+	else if (digit == 's' || digit == 'S')
+		return ZT_TONE_DTMF_s;
+	else if (digit == 'p' || digit == 'P')
+		return ZT_TONE_DTMF_p;
+	else
+		return -1;
+}
+
+static char dtmfindex_to_digit(int dtmfindex)
+{
+	if (dtmfindex >= ZT_TONE_DTMF_BASE && dtmfindex <= ZT_TONE_DTMF_9)
+		return '0' + (dtmfindex - ZT_TONE_DTMF_BASE);
+	else if (dtmfindex >= ZT_TONE_DTMF_A && dtmfindex <= ZT_TONE_DTMF_D)
+		return 'A' + (dtmfindex - ZT_TONE_DTMF_A);
+	else if (dtmfindex == ZT_TONE_DTMF_s)
+		return 's';
+	else if (dtmfindex == ZT_TONE_DTMF_p)
+		return 'p';
+	else
+		return 'x';
+}
+
+static int zt_digit_begin(struct ast_channel *chan, char digit)
+{
+	struct zt_pvt *pvt;
+	int index;
+	int dtmf = -1;
+
+	pvt = chan->tech_pvt;
+
+	ast_mutex_lock(&pvt->lock);
+
+	index = zt_get_index(chan, pvt, 0);
+
+	if ((index != SUB_REAL) || !pvt->owner)
+		goto out;
+
+#ifdef HAVE_PRI
+	if (pvt->sig != SIG_PRI)
+		goto out;
+#endif
+	dtmf = digit_to_dtmfindex(digit);
+
+	if (dtmf == -1)
+		goto out;
+
+	if (!ioctl(pvt->subs[SUB_REAL].zfd, ZT_SENDTONE, &dtmf)) {
+		pvt->dialing = 1;
+		pvt->begindigit = dtmf;
+	} else
+		pvt->begindigit = 0;
+
+out:
+	ast_mutex_unlock(&pvt->lock);
+
+	return 0; /* Tell Asterisk not to generate inband indications */
+}
+
+static int zt_digit_end(struct ast_channel *chan, char digit)
 {
 	ZT_DIAL_OPERATION zo;
-	struct zt_pvt *p;
+	struct zt_pvt *pvt;
 	int res = 0;
 	int index;
-	p = ast->tech_pvt;
-	ast_mutex_lock(&p->lock);
-	index = zt_get_index(ast, p, 0);
-	if ((index == SUB_REAL) && p->owner) {
+
+	pvt = chan->tech_pvt;
+
+	ast_mutex_lock(&pvt->lock);
+	
+	index = zt_get_index(chan, pvt, 0);
+
+	if ((index != SUB_REAL) || !pvt->owner)
+		goto out;
+
 #ifdef HAVE_PRI
-		if ((p->sig == SIG_PRI) && (ast->_state == AST_STATE_DIALING) && !p->proceeding) {
-			if (p->setup_ack) {
-				if (!pri_grab(p, p->pri)) {
-					pri_information(p->pri->pri,p->call,digit);
-					pri_rel(p->pri);
-				} else
-					ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
-			} else if (strlen(p->dialdest) < sizeof(p->dialdest) - 1) {
-				ast_log(LOG_DEBUG, "Queueing digit '%c' since setup_ack not yet received\n", digit);
-				res = strlen(p->dialdest);
-				p->dialdest[res++] = digit;
-				p->dialdest[res] = '\0';
-			}
-		} else {
+	if ((pvt->sig == SIG_PRI) && (chan->_state == AST_STATE_DIALING) && !pvt->proceeding) {
+		if (pvt->setup_ack) {
+			if (!pri_grab(pvt, pvt->pri)) {
+				pri_information(pvt->pri->pri, pvt->call, digit);
+				pri_rel(pvt->pri);
+			} else
+				ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", pvt->span);
+		} else if (strlen(pvt->dialdest) < sizeof(pvt->dialdest) - 1) {
+			ast_log(LOG_DEBUG, "Queueing digit '%c' since setup_ack not yet received\n", digit);
+			res = strlen(pvt->dialdest);
+			pvt->dialdest[res++] = digit;
+			pvt->dialdest[res] = '\0';
+		}
+	} else {
 #else
-		{
+	{
 #endif
+		if (!pvt->begindigit) {
 			zo.op = ZT_DIAL_OP_APPEND;
 			zo.dialstr[0] = 'T';
 			zo.dialstr[1] = digit;
 			zo.dialstr[2] = 0;
-			if ((res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &zo)))
+			if ((res = ioctl(pvt->subs[SUB_REAL].zfd, ZT_DIAL, &zo)))
 				ast_log(LOG_WARNING, "Couldn't dial digit %c\n", digit);
 			else
-				p->dialing = 1;
-		}
-	}
-	ast_mutex_unlock(&p->lock);
+				pvt->dialing = 1;
+		} else {
+			if (pvt->begindigit != digit_to_dtmfindex(digit)) {
+				ast_log(LOG_WARNING, "We already started playing dtmf index '%c', but asked to end digit '%c'!  :(\n",
+					dtmfindex_to_digit(pvt->begindigit), digit);
+			}
+			res = ioctl(pvt->subs[SUB_REAL].zfd, ZT_SENDTONE, -1);
+			pvt->begindigit = 0;
+		}
+	}
+
+out:
+	ast_mutex_unlock(&pvt->lock);
+
 	return res;
 }
 



More information about the svn-commits mailing list