[zaptel-commits] kpfleming: branch kpfleming/dtmf-twister r3480 - /team/kpfleming/dtmf-twister/
SVN commits to the Zaptel project
zaptel-commits at lists.digium.com
Fri Dec 14 11:12:13 CST 2007
Author: kpfleming
Date: Fri Dec 14 11:12:13 2007
New Revision: 3480
URL: http://svn.digium.com/view/zaptel?view=rev&rev=3480
Log:
checkpoint where tone playback code has all been updated (but no code to feed int generated tones yet):
remove tones.h and gendigits from svn:ignore as they will be going away
remove tones.h from Makefile
improve digits.h to use C99-style initializers and define default tone lengths in terms of ZT_CHUNKSIZE instead of hardcoded value
add ZT_TONE_MF_* values to zaptel.h to support sending MF tones via ZT_SENDTONE
change zt_dtmf_tone() to take a zt_chan pointer so it can get the curzone from the channel
set txdialbuf in the zt_chan to uppercase on receipt from userspace so the code using the buffer doens't have to check for both upper and lowercase characters
cleanup and simplify zt_dtmf_tone() and __do_dtmf()
don't allow a tonezone to be set with ZT_DEFAULTZONE if it hasn't been loaded
don't allow a tonezone to be freed with ZT_FREEZONE it if is the default zone
when setting tone length with ZT_SET_DIALPARAMS, do it for all loaded zones
use the default zone for tone length to be returned by ZT_GET_DIALPARAMS
clean up and fix one possible buffer overflow in ZT_DIAL_OP_APPEND
remove dtmf_tones_continuous and mf_tones_continuous global arrays
Modified:
team/kpfleming/dtmf-twister/ (props changed)
team/kpfleming/dtmf-twister/Makefile
team/kpfleming/dtmf-twister/digits.h
team/kpfleming/dtmf-twister/zaptel-base.c
team/kpfleming/dtmf-twister/zaptel.h
Propchange: team/kpfleming/dtmf-twister/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Fri Dec 14 11:12:13 2007
@@ -1,49 +1,47 @@
-sethdlc-new
-ztdiag
-zttool
-ztspeed
-ztmonitor
-ztcfg
-zonedata.lo
-torisatool
-tor2fw.h
-radfw.h
-tonezone.lo
-tones.h
-makefw
-libtonezone.so.1.0
-gendigits
-fxstest
-zttest
-fxotune
-patlooptest
-hdlcstress
-ztcfg-dude
-hdlctest
-timertest
-pattest
-hdlcgen
-usbfxstest
-patgen
-hdlcverify
+*.a
*.ko
*.mod.c
+*.so
.*.cmd
.tmp_versions
-*.so
-*.a
+Module.symvers
+Modules.symvers
+README.html
+autom4te.cache
+config.log
+config.status
+fw2h
+fxotune
+fxstest
+hdlcgen
+hdlcstress
+hdlctest
+hdlcverify
+libtonezone.so.1.0
+makefw
+makeopts
+menuselect-tree
+menuselect.makedeps
+menuselect.makeopts
+missing
+patgen
+patlooptest
+pattest
+radfw.h
+sethdlc-new
+timertest
+tonezone.lo
+tor2fw.h
+torisatool
+usbfxstest
version.h
vpm450m_fw.h
-fw2h
-autom4te.cache
-missing
-makeopts
-menuselect.makeopts
-menuselect.makedeps
-config.log
-config.status
-menuselect-tree
-Modules.symvers
-Module.symvers
-README.html
+zonedata.lo
+ztcfg
+ztcfg-dude
+ztdiag
+ztmonitor
ztscan
+ztspeed
+zttest
+zttool
Modified: team/kpfleming/dtmf-twister/Makefile
URL: http://svn.digium.com/view/zaptel/team/kpfleming/dtmf-twister/Makefile?view=diff&rev=3480&r1=3479&r2=3480
==============================================================================
--- team/kpfleming/dtmf-twister/Makefile (original)
+++ team/kpfleming/dtmf-twister/Makefile Fri Dec 14 11:12:13 2007
@@ -311,9 +311,6 @@
tonezone.lo: tonezone.c
$(CC) -c $(CFLAGS) -o $@ $^
-tones.h: gendigits
- ./gendigits > $@
-
tor2fw.h: tormenta2.rbt makefw
./makefw $< tor2fw > $@
@@ -326,7 +323,7 @@
gendigits: gendigits.c
$(HOSTCC) -o $@ $^ -lm
-prereq: config.status tones.h tor2fw.h radfw.h version.h
+prereq: config.status tor2fw.h radfw.h version.h
zttool.o: zaptel.h
zttool.o: CFLAGS+=$(NEWT_INCLUDE)
@@ -399,8 +396,6 @@
$(filter-out zaptel.o,$(BUILD_TOPDIR_MODULES:%=%.o)) zaptel-base.o: %.o: %.c zaptel.h
$(CC) $(KFLAGS) -o $@ -c $<
-
-zaptel.c: tones.h
endif
stackcheck: checkstack modules
Modified: team/kpfleming/dtmf-twister/digits.h
URL: http://svn.digium.com/view/zaptel/team/kpfleming/dtmf-twister/digits.h?view=diff&rev=3480&r1=3479&r2=3480
==============================================================================
--- team/kpfleming/dtmf-twister/digits.h (original)
+++ team/kpfleming/dtmf-twister/digits.h Fri Dec 14 11:12:13 2007
@@ -1,5 +1,5 @@
/*
- * Zapata Telephony Telephony
+ * Zapata Telephony
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -17,25 +17,27 @@
*
* Use DTMF/MFv1 tables
*/
+
#ifndef _DIGITS_H
#define _DIGITS_H
-#define DEFAULT_DTMF_LENGTH 100 * 8
-#define DEFAULT_MFV1_LENGTH 60 * 8
-#define PAUSE_LENGTH 500 * 8
+#define DEFAULT_DTMF_LENGTH 100 * ZT_CHUNKSIZE
+#define DEFAULT_MFV1_LENGTH 60 * ZT_CHUNKSIZE
+#define PAUSE_LENGTH 500 * ZT_CHUNKSIZE
/* At the end of silence, the tone stops */
-static struct zt_tone dtmf_silence =
- { 0, 0, 0, 0, 0, 0, DEFAULT_DTMF_LENGTH, NULL };
+static struct zt_tone dtmf_silence = {
+ .tonesamples = DEFAULT_DTMF_LENGTH,
+};
/* At the end of silence, the tone stops */
-static struct zt_tone mfv1_silence =
- { 0, 0, 0, 0, 0, 0, DEFAULT_MFV1_LENGTH, NULL };
+static struct zt_tone mfv1_silence = {
+ .tonesamples = DEFAULT_MFV1_LENGTH,
+};
/* A pause in the dialing */
-static struct zt_tone tone_pause =
- { 0, 0, 0, 0, 0, 0, PAUSE_LENGTH, NULL };
-
-#include "tones.h"
+static struct zt_tone tone_pause = {
+ .tonesamples = PAUSE_LENGTH,
+};
#endif
Modified: team/kpfleming/dtmf-twister/zaptel-base.c
URL: http://svn.digium.com/view/zaptel/team/kpfleming/dtmf-twister/zaptel-base.c?view=diff&rev=3480&r1=3479&r2=3480
==============================================================================
--- team/kpfleming/dtmf-twister/zaptel-base.c (original)
+++ team/kpfleming/dtmf-twister/zaptel-base.c Fri Dec 14 11:12:13 2007
@@ -45,6 +45,7 @@
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/version.h>
+#include <linux/ctype.h>
#include <linux/kmod.h>
#ifdef CONFIG_DEVFS_FS
#include <linux/devfs_fs_kernel.h>
@@ -302,9 +303,6 @@
#include "digits.h"
-static struct zt_tone *dtmf_tones_continuous = NULL;
-static struct zt_tone *mfv1_tones_continuous = NULL;
-
static int zt_chan_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long data, int unit);
#if defined(CONFIG_ZAPTEL_MMX) || defined(ECHO_CAN_FP)
@@ -365,7 +363,8 @@
unavailable */
struct zt_tone dtmf[16]; /* DTMF tones for this zone, with desired length */
struct zt_tone dtmf_continuous[16]; /* DTMF tones for this zone, continuous play */
- struct zt_tone mf[16]; /* MF tones for this zone, with desired length */
+ struct zt_tone mf[15]; /* MF tones for this zone, with desired length */
+ struct zt_tone mf_continuous[15]; /* MF tones for this zone, continuous play */
};
static struct zt_span *spans[ZT_MAX_SPANS];
@@ -1077,13 +1076,11 @@
static int free_tone_zone(int num)
{
struct zt_zone *z;
- if ((num < 0) || (num >= ZT_TONE_ZONE_MAX))
- return -EINVAL;
- write_lock(&zone_lock);
+
z = tone_zones[num];
tone_zones[num] = NULL;
- write_unlock(&zone_lock);
kfree(z);
+
return 0;
}
@@ -1134,9 +1131,9 @@
chan->dialing = 1;
res = 0;
if (chan->digitmode == DIGIT_MODE_DTMF)
- chan->curtone = dtmf_tones_continuous + (tone - ZT_TONE_DTMF_BASE);
+ chan->curtone = chan->curzone->dtmf_continuous + (tone - ZT_TONE_DTMF_BASE);
else if (chan->digitmode == DIGIT_MODE_MFV1 && tone != ZT_TONE_DTMF_MAX) /* No 'D' */
- chan->curtone = mfv1_tones_continuous + (tone - ZT_TONE_DTMF_BASE);
+ chan->curtone = chan->curzone->mf_continuous + (tone - ZT_TONE_DTMF_BASE);
else {
chan->dialing = 0;
res = -EINVAL;
@@ -2569,8 +2566,7 @@
/* No more than 64 subtones */
#define MAX_TONES 64
-static int
-ioctl_load_zone(unsigned long data)
+static int ioctl_load_zone(unsigned long data)
{
struct zt_tone *samples[MAX_TONES];
short next[MAX_TONES];
@@ -2677,15 +2673,22 @@
ts->modulate = zt->modulate;
}
-struct zt_tone *zt_dtmf_tone(char digit, int mf)
+struct zt_tone *zt_dtmf_tone(const struct zt_chan *chan, char digit)
{
struct zt_tone *z;
- if (!mf)
- z = dtmf_tones;
- else
- z = mfv1_tones;
- switch(digit) {
+ switch (chan->digitmode) {
+ case DIGIT_MODE_DTMF:
+ z = &chan->curzone->dtmf[0];
+ break;
+ case DIGIT_MODE_MFV1:
+ z = &chan->curzone->mf[0];
+ break;
+ default:
+ z = NULL;
+ }
+
+ switch (digit) {
case '0':
case '1':
case '2':
@@ -2696,7 +2699,7 @@
case '7':
case '8':
case '9':
- return z + (int)(digit - '0');
+ return z + (digit - '0');
case '*':
return z + 10;
case '#':
@@ -2706,66 +2709,48 @@
case 'C':
return z + (digit + 12 - 'A');
case 'D':
- if (!mf)
- return z + ( digit + 12 - 'A');
- return NULL;
- case 'a':
- case 'b':
- case 'c':
- return z + (digit + 12 - 'a');
- case 'd':
- if (!mf)
- return z + ( digit + 12 - 'a');
- return NULL;
+ if (chan->digitmode == DIGIT_MODE_MFV1)
+ return NULL;
+ else
+ return z + (digit + 12 - 'A');
case 'W':
- case 'w':
return &tone_pause;
}
+
return NULL;
}
static void __do_dtmf(struct zt_chan *chan)
{
char c;
+
/* Called with chan->lock held */
- while (strlen(chan->txdialbuf)) {
- c = chan->txdialbuf[0];
- /* Skooch */
+ while ((c = chan->txdialbuf[0])) {
memmove(chan->txdialbuf, chan->txdialbuf + 1, sizeof(chan->txdialbuf) - 1);
- switch(c) {
+ switch (c) {
case 'T':
- case 't':
chan->digitmode = DIGIT_MODE_DTMF;
chan->tonep = 0;
break;
case 'M':
- case 'm':
chan->digitmode = DIGIT_MODE_MFV1;
chan->tonep = 0;
break;
case 'P':
- case 'p':
chan->digitmode = DIGIT_MODE_PULSE;
chan->tonep = 0;
break;
default:
- if (chan->digitmode == DIGIT_MODE_PULSE)
- {
- if ((c >= '0') && (c <= '9') && (chan->txhooksig == ZT_TXSIG_OFFHOOK))
- {
- chan->pdialcount = c - '0';
- /* a '0' is ten pulses */
- if (!chan->pdialcount) chan->pdialcount = 10;
- zt_rbs_sethook(chan, ZT_TXSIG_ONHOOK,
- ZT_TXSTATE_PULSEBREAK, chan->pulsebreaktime);
+ if ((c != 'W') && (chan->digitmode == DIGIT_MODE_PULSE)) {
+ if ((c >= '0') && (c <= '9') && (chan->txhooksig == ZT_TXSIG_OFFHOOK)) {
+ chan->pdialcount = (c == '0') ? 10 : c - '0';
+ zt_rbs_sethook(chan, ZT_TXSIG_ONHOOK, ZT_TXSTATE_PULSEBREAK,
+ chan->pulsebreaktime);
return;
}
} else {
- case 'w':
- case 'W':
- chan->curtone = zt_dtmf_tone(c, (chan->digitmode == DIGIT_MODE_MFV1));
+ chan->curtone = zt_dtmf_tone(chan, c);
chan->tonep = 0;
- /* All done */
if (chan->curtone) {
zt_init_tone_state(&chan->ts, chan->curtone);
return;
@@ -2773,6 +2758,7 @@
}
}
}
+
/* Notify userspace process if there is nothing left */
chan->dialing = 0;
__qevent(chan, ZT_EVENT_DIALCOMPLETE);
@@ -3570,43 +3556,71 @@
return res;
case ZT_DEFAULTZONE:
if (get_user(j,(int *)data))
- return -EFAULT; /* get conf # */
- if ((j < 0) || (j >= ZT_TONE_ZONE_MAX)) return (-EINVAL);
+ return -EFAULT;
+ if ((j < 0) || (j >= ZT_TONE_ZONE_MAX))
+ return -EINVAL;
write_lock(&zone_lock);
+ if (!tone_zones[j]) {
+ write_unlock(&zone_lock);
+ return -EINVAL;
+ }
default_zone = j;
write_unlock(&zone_lock);
- return 0;
+ break;
case ZT_LOADZONE:
return ioctl_load_zone(data);
case ZT_FREEZONE:
- get_user(j,(int *)data); /* get conf # */
- if ((j < 0) || (j >= ZT_TONE_ZONE_MAX)) return (-EINVAL);
+ get_user(j, (int *) data);
+ if ((j < 0) || (j >= ZT_TONE_ZONE_MAX))
+ return -EINVAL;
+ write_lock(&zone_lock);
+ if (j == default_zone) {
+ write_unlock(&zone_lock);
+ /* XXX: possibly a better return code here */
+ return -EINVAL;
+ }
free_tone_zone(j);
- return 0;
+ write_unlock(&zone_lock);
+ break;
case ZT_SET_DIALPARAMS:
- if (copy_from_user(&tdp, (struct zt_dialparams *)data, sizeof(tdp)))
+ if (copy_from_user(&tdp, (struct zt_dialparams *) data, sizeof(tdp)))
return -EFAULT;
if ((tdp.dtmf_tonelen > 4000) || (tdp.dtmf_tonelen < 10))
return -EINVAL;
if ((tdp.mfv1_tonelen > 4000) || (tdp.mfv1_tonelen < 10))
return -EINVAL;
- for (i=0;i<16;i++)
- dtmf_tones[i].tonesamples = tdp.dtmf_tonelen * ZT_CHUNKSIZE;
+
+ /* update the lengths in all currently loaded zones */
+ write_lock(&zone_lock);
+ for (j = 0; j < sizeof(tone_zones) / sizeof(tone_zones[0]); j++) {
+ struct zt_zone *z = tone_zones[j];
+
+ if (!z)
+ continue;
+
+ for (i = 0; i < 16; i++)
+ z->dtmf[i].tonesamples = tdp.dtmf_tonelen * ZT_CHUNKSIZE;
+
+ for (i = 0; i < 15; i++)
+ z->mf[i].tonesamples = tdp.mfv1_tonelen * ZT_CHUNKSIZE;
+
+ /* Special case for K/P tone */
+ z->mf[10].tonesamples *= 5 / 3;
+ }
+ write_unlock(&zone_lock);
+
dtmf_silence.tonesamples = tdp.dtmf_tonelen * ZT_CHUNKSIZE;
- for (i=0;i<15;i++)
- mfv1_tones[i].tonesamples = tdp.mfv1_tonelen * ZT_CHUNKSIZE;
mfv1_silence.tonesamples = tdp.mfv1_tonelen * ZT_CHUNKSIZE;
- /* Special case for K/P tone */
- mfv1_tones[10].tonesamples = tdp.mfv1_tonelen * ZT_CHUNKSIZE * 5 / 3;
+
break;
case ZT_GET_DIALPARAMS:
- tdp.dtmf_tonelen = dtmf_tones[0].tonesamples / ZT_CHUNKSIZE;
- tdp.mfv1_tonelen = mfv1_tones[0].tonesamples / ZT_CHUNKSIZE;
+ tdp.dtmf_tonelen = tone_zones[default_zone]->dtmf[0].tonesamples / ZT_CHUNKSIZE;
+ tdp.mfv1_tonelen = tone_zones[default_zone]->mf[0].tonesamples / ZT_CHUNKSIZE;
tdp.reserved[0] = 0;
tdp.reserved[1] = 0;
tdp.reserved[2] = 0;
tdp.reserved[3] = 0;
- if (copy_to_user((struct zt_dialparams *)data, &tdp, sizeof(tdp)))
+ if (copy_to_user((struct zt_dialparams *) data, &tdp, sizeof(tdp)))
return -EFAULT;
break;
case ZT_GETVERSION:
@@ -3690,6 +3704,7 @@
unsigned long flags, flagso;
int i, j, k, rv;
int ret, c;
+ char *s;
if (!chan)
return -EINVAL;
@@ -3705,10 +3720,12 @@
if (copy_from_user(&stack.tdo, (struct zt_dialoperation *)data, sizeof(stack.tdo)))
return -EFAULT;
rv = 0;
- /* Force proper NULL termination */
+ /* Force proper NULL termination and uppercase entry */
stack.tdo.dialstr[ZT_MAX_DTMF_BUF - 1] = '\0';
+ for (s = stack.tdo.dialstr; *s; s++)
+ *s = toupper(*s);
spin_lock_irqsave(&chan->lock, flags);
- switch(stack.tdo.op) {
+ switch (stack.tdo.op) {
case ZT_DIAL_OP_CANCEL:
chan->curtone = NULL;
chan->dialing = 0;
@@ -3722,17 +3739,15 @@
__do_dtmf(chan);
break;
case ZT_DIAL_OP_APPEND:
- if (strlen(stack.tdo.dialstr) + strlen(chan->txdialbuf) >= ZT_MAX_DTMF_BUF)
- {
+ if (strlen(stack.tdo.dialstr) + strlen(chan->txdialbuf) >= (ZT_MAX_DTMF_BUF - 1)) {
rv = -EBUSY;
break;
- }
- strncpy(chan->txdialbuf + strlen(chan->txdialbuf), stack.tdo.dialstr, ZT_MAX_DTMF_BUF - strlen(chan->txdialbuf));
- if (!chan->dialing)
- {
+ }
+ strncpy(chan->txdialbuf + strlen(chan->txdialbuf), stack.tdo.dialstr, ZT_MAX_DTMF_BUF - strlen(chan->txdialbuf) - 1);
+ if (!chan->dialing) {
chan->dialing = 1;
__do_dtmf(chan);
- }
+ }
break;
default:
rv = -EINVAL;
@@ -7147,7 +7162,6 @@
static int __init zt_init(void) {
int res = 0;
- int i = 0;
#ifdef CONFIG_PROC_FS
proc_entries[0] = proc_mkdir("zaptel", NULL);
@@ -7181,26 +7195,6 @@
}
#endif /* CONFIG_DEVFS_FS */
- if (!(dtmf_tones_continuous = kmalloc(sizeof(dtmf_tones), GFP_KERNEL))) {
- printk(KERN_ERR "Zaptel: THERE IS A CRISIS IN THE BATCAVE!"
- " Unable to allocate memory for continuous DTMF tones list!\n");
- return -ENOMEM;
- }
-
- if (!(mfv1_tones_continuous = kmalloc(sizeof(mfv1_tones), GFP_KERNEL))) {
- printk(KERN_ERR "Zaptel: THERE IS A CRISIS IN THE BATCAVE!"
- " Unable to allocate memory for continuous MFV1 tones list!\n");
- return -ENOMEM;
- }
-
- memcpy(dtmf_tones_continuous, dtmf_tones, sizeof(dtmf_tones));
- for (i = 0; i < (sizeof(dtmf_tones) / sizeof(dtmf_tones[0])); i++)
- dtmf_tones_continuous[i].next = dtmf_tones_continuous + i;
-
- memcpy(mfv1_tones_continuous, mfv1_tones, sizeof(mfv1_tones));
- for (i = 0; i < (sizeof(mfv1_tones) / sizeof(mfv1_tones[0])); i++)
- mfv1_tones_continuous[i].next = mfv1_tones_continuous + i;
-
printk(KERN_INFO "Zapata Telephony Interface Registered on major %d\n", ZT_MAJOR);
printk(KERN_INFO "Zaptel Version: %s\n", ZAPTEL_VERSION);
echo_can_init();
@@ -7225,16 +7219,6 @@
for (x = 0; x < ZT_TONE_ZONE_MAX; x++) {
if (tone_zones[x])
kfree(tone_zones[x]);
- }
-
- if (dtmf_tones_continuous) {
- kfree(dtmf_tones_continuous);
- dtmf_tones_continuous = NULL;
- }
-
- if (mfv1_tones_continuous) {
- kfree(mfv1_tones_continuous);
- mfv1_tones_continuous = NULL;
}
#ifdef CONFIG_DEVFS_FS
Modified: team/kpfleming/dtmf-twister/zaptel.h
URL: http://svn.digium.com/view/zaptel/team/kpfleming/dtmf-twister/zaptel.h?view=diff&rev=3480&r1=3479&r2=3480
==============================================================================
--- team/kpfleming/dtmf-twister/zaptel.h (original)
+++ team/kpfleming/dtmf-twister/zaptel.h Fri Dec 14 11:12:13 2007
@@ -765,10 +765,8 @@
#define ZT_TONE_MAX 16
#define ZT_TONE_DTMF_BASE 64
-
-/*
- * These must be in the same order as the dtmf_tones array in tones.h
- */
+#define ZT_TONE_MF_BASE 80
+
enum {
ZT_TONE_DTMF_0 = ZT_TONE_DTMF_BASE,
ZT_TONE_DTMF_1,
@@ -789,6 +787,26 @@
};
#define ZT_TONE_DTMF_MAX ZT_TONE_DTMF_D
+
+enum {
+ ZT_TONE_MF_0 = ZT_TONE_MF_BASE,
+ ZT_TONE_MF_1,
+ ZT_TONE_MF_2,
+ ZT_TONE_MF_3,
+ ZT_TONE_MF_4,
+ ZT_TONE_MF_5,
+ ZT_TONE_MF_6,
+ ZT_TONE_MF_7,
+ ZT_TONE_MF_8,
+ ZT_TONE_MF_9,
+ ZT_TONE_MF_s,
+ ZT_TONE_MF_p,
+ ZT_TONE_MF_A,
+ ZT_TONE_MF_B,
+ ZT_TONE_MF_C,
+};
+
+#define ZT_TONE_MF_MAX ZT_TONE_MF_C
#define ZT_MAX_CADENCE 16
@@ -1675,9 +1693,8 @@
/* Initialize a tone state */
void zt_init_tone_state(struct zt_tone_state *ts, struct zt_tone *zt);
-/* Get a given DTMF or MF tone struct, suitable for zt_tone_nextsample.
- Set 'mf' to 0 for DTMF or 1 for MFv1 */
-struct zt_tone *zt_dtmf_tone(char digit, int mf);
+/* Get a given DTMF or MF tone struct, suitable for zt_tone_nextsample. */
+struct zt_tone *zt_dtmf_tone(const struct zt_chan *chan, char digit);
/* Echo cancel a receive and transmit chunk for a given channel. This
should be called by the low-level driver as close to the interface
More information about the zaptel-commits
mailing list