[zaptel-commits] kpfleming: branch 1.4 r3490 - /branches/1.4/

SVN commits to the Zaptel project zaptel-commits at lists.digium.com
Fri Dec 14 17:47:32 CST 2007


Author: kpfleming
Date: Fri Dec 14 17:47:31 2007
New Revision: 3490

URL: http://svn.digium.com/view/zaptel?view=rev&rev=3490
Log:
(merging dtmf-twister branch plus a few fixes)

move DTMF/MF generation into tonezone.c (libtonezone) so that it can happen at runtime instead of compile time; this allows for DTMF/MF to be different on a zone-by-zone basis without requiring a recompile of Zaptel

set DTMF 'twist' for Brazil (zone 'br') to 2dB


Removed:
    branches/1.4/gendigits.c
Modified:
    branches/1.4/   (props changed)
    branches/1.4/Makefile
    branches/1.4/digits.h
    branches/1.4/tonezone.c
    branches/1.4/tonezone.h
    branches/1.4/wcusb.c
    branches/1.4/zaptel-base.c
    branches/1.4/zaptel.h
    branches/1.4/zonedata.c

Propchange: branches/1.4/
------------------------------------------------------------------------------
    automerge = yes

Propchange: branches/1.4/
------------------------------------------------------------------------------
    automerge-email = kpfleming at digium.com

Propchange: branches/1.4/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Fri Dec 14 17:47:31 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

Propchange: branches/1.4/
------------------------------------------------------------------------------
    svnmerge-integrated = /branches/1.4:1-3476

Modified: branches/1.4/Makefile
URL: http://svn.digium.com/view/zaptel/branches/1.4/Makefile?view=diff&rev=3490&r1=3489&r2=3490
==============================================================================
--- branches/1.4/Makefile (original)
+++ branches/1.4/Makefile Fri Dec 14 17:47:31 2007
@@ -311,9 +311,6 @@
 tonezone.lo: tonezone.c
 	$(CC) -c $(CFLAGS) -o $@ $^
 
-tones.h: gendigits
-	./gendigits > $@
-
 tor2fw.h: tormenta2.rbt makefw 
 	./makefw $< tor2fw > $@
 
@@ -323,10 +320,7 @@
 makefw: makefw.c
 	$(HOSTCC) -o $@ $^
 
-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 +393,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: branches/1.4/digits.h
URL: http://svn.digium.com/view/zaptel/branches/1.4/digits.h?view=diff&rev=3490&r1=3489&r2=3490
==============================================================================
--- branches/1.4/digits.h (original)
+++ branches/1.4/digits.h Fri Dec 14 17:47:31 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: branches/1.4/tonezone.c
URL: http://svn.digium.com/view/zaptel/branches/1.4/tonezone.c?view=diff&rev=3490&r1=3489&r2=3490
==============================================================================
--- branches/1.4/tonezone.c (original)
+++ branches/1.4/tonezone.c Fri Dec 14 17:47:31 2007
@@ -29,6 +29,7 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <errno.h>
+
 #include "tonezone.h"
 
 #define DEFAULT_ZT_DEV "/dev/zap/ctl"
@@ -63,15 +64,15 @@
 
 #define LEVEL -10
 
-static int build_tone(char *data, int size, struct tone_zone_sound *t, int *count)
+static int build_tone(void *data, int size, struct tone_zone_sound *t, int *count)
 {
 	char *dup, *s;
 	struct zt_tone_def *td=NULL;
 	int firstnobang = -1;
 	int freq1, freq2, time;
-	int used = 0;
 	int modulate = 0;
 	float gain;
+	int used = 0;
 	dup = strdup(t->data);
 	s = strtok(dup, ",");
 	while(s && strlen(s)) {
@@ -125,11 +126,11 @@
 #if 0
 		printf("Using %d samples for %d and %d\n", time * 8, freq1, freq2);
 #endif
-		if (size < sizeof(struct zt_tone_def)) {
-			fprintf(stderr, "Not enough space for samples\n");
+		if (size < sizeof(*td)) {
+			fprintf(stderr, "Not enough space for tones\n");
 			return -1;
 		}
-		td = (struct zt_tone_def *)data;
+		td = data;
 
 		/* Bring it down -8 dbm */
 		gain = pow(10.0, (LEVEL - 3.14) / 20.0) * 65536.0 / 2.0;
@@ -144,9 +145,9 @@
 
 		td->modulate = modulate;
 
-		data += (sizeof(struct zt_tone_def));
-		used += (sizeof(struct zt_tone_def));
-		size -= (sizeof(struct zt_tone_def));
+		data += sizeof(*td);
+		used += sizeof(*td);
+		size -= sizeof(*td);
 		td->tone = t->toneid;
 		if (time) {
 			/* We should move to the next tone */
@@ -157,7 +158,7 @@
 			td->next = *count;
 			td->samples = 8000;
 		}
-		(*count)++;
+		*count += 1;
 		s = strtok(NULL, ",");
 	}
 	if (td && time) {
@@ -203,85 +204,187 @@
 }
 
 #ifdef TONEZONE_DRIVER
-static void dump_tone_zone(void *data)
+static void dump_tone_zone(void *data, int size)
 {
 	struct zt_tone_def_header *z;
 	struct zt_tone_def *td;
 	int x;
-	int len=0;
+	int len = sizeof(*z);
+
 	z = data;
 	data += sizeof(*z);
 	printf("Header: %d tones, %d bytes of data, zone %d (%s)\n", 
-		z->count, z->size, z->zone, z->name);
-	for (x=0;x < z->count; x++) {
+		z->count, size, z->zone, z->name);
+	for (x = 0; x < z->count; x++) {
 		td = data;
-		printf("Tone Fragment %d: %d bytes, %s tone, next is %d, %d samples total\n",
-			x, td->size, tone_name(td->tone), td->next, td->samples);
+		printf("Tone Fragment %d: tone is %d, next is %d, %d samples\n",
+			x, td->tone, td->next, td->samples);
 		data += sizeof(*td);
-		data += td->size;
-		len += td->size;
+		len += sizeof(*td);
 	}
 	printf("Total measured bytes of data: %d\n", len);
 }
 #endif
+
+/* Tone frequency tables */
+struct mf_tone {
+	int	tone;
+	float   f1;     /* first freq */
+	float   f2;     /* second freq */
+};
+ 
+static struct mf_tone dtmf_dial[] = {
+	{ ZT_TONE_DTMF_0, 941.0, 1336.0 },
+	{ ZT_TONE_DTMF_1, 697.0, 1209.0 },
+	{ ZT_TONE_DTMF_2, 697.0, 1336.0 },
+	{ ZT_TONE_DTMF_3, 697.0, 1477.0 },
+	{ ZT_TONE_DTMF_4, 770.0, 1209.0 },
+	{ ZT_TONE_DTMF_5, 770.0, 1336.0 },
+	{ ZT_TONE_DTMF_6, 770.0, 1477.0 },
+	{ ZT_TONE_DTMF_7, 852.0, 1209.0 },
+	{ ZT_TONE_DTMF_8, 852.0, 1336.0 },
+	{ ZT_TONE_DTMF_9, 852.0, 1477.0 },
+	{ ZT_TONE_DTMF_s, 941.0, 1209.0 },
+	{ ZT_TONE_DTMF_p, 941.0, 1477.0 },
+	{ ZT_TONE_DTMF_A, 697.0, 1633.0 },
+	{ ZT_TONE_DTMF_B, 770.0, 1633.0 },
+	{ ZT_TONE_DTMF_C, 852.0, 1633.0 },
+	{ ZT_TONE_DTMF_D, 941.0, 1633.0 },
+	{ 0, 0, 0 }
+};
+ 
+static struct mf_tone mf_dial[] = {
+	{ ZT_TONE_MF_0, 1300.0, 1500.0 },
+	{ ZT_TONE_MF_1, 700.0, 900.0 },
+	{ ZT_TONE_MF_2, 700.0, 1100.0 },
+	{ ZT_TONE_MF_3, 900.0, 1100.0 },
+	{ ZT_TONE_MF_4, 700.0, 1300.0 },
+	{ ZT_TONE_MF_5, 900.0, 1300.0 },
+	{ ZT_TONE_MF_6, 1100.0, 1300.0 },
+	{ ZT_TONE_MF_7, 700.0, 1500.0 },
+	{ ZT_TONE_MF_8, 900.0, 1500.0 },
+	{ ZT_TONE_MF_9, 1100.0, 1500.0 },
+	{ ZT_TONE_MF_s, 1100.0, 1700.0 },	/* KP */
+	{ ZT_TONE_MF_p, 1500.0, 1700.0 },	/* ST */
+	{ ZT_TONE_MF_A, 900.0, 1700.0 },	/* ST' */
+	{ ZT_TONE_MF_B, 1300.0, 1700.0 },	/* ST'' */
+	{ ZT_TONE_MF_C, 700.0, 1700.0 },	/* ST''' */
+	{ 0, 0, 0 }
+};
+
+static int build_mf_tones(void *data, int size, int *count, struct mf_tone *tone, int low_tone_level, int high_tone_level)
+{
+	struct zt_tone_def *td;
+	float gain;
+	int used = 0;
+
+	while (tone->tone) {
+		if (size < sizeof(*td)) {
+			fprintf(stderr, "Not enough space for samples\n");
+			return -1;
+		}
+		td = data;
+		data += sizeof(*td);
+		used += sizeof(*td);
+		size -= sizeof(*td);
+		td->tone = tone->tone;
+		*count += 1;
+
+		/* Bring it down 6 dBm */
+		gain = pow(10.0, (low_tone_level - 3.14) / 20.0) * 65536.0 / 2.0;
+		td->fac1 = 2.0 * cos(2.0 * M_PI * (tone->f1 / 8000.0)) * 32768.0;
+		td->init_v2_1 = sin(-4.0 * M_PI * (tone->f1 / 8000.0)) * gain;
+		td->init_v3_1 = sin(-2.0 * M_PI * (tone->f1 / 8000.0)) * gain;
+		
+		gain = pow(10.0, (high_tone_level - 3.14) / 20.0) * 65536.0 / 2.0;
+		td->fac2 = 2.0 * cos(2.0 * M_PI * (tone->f2 / 8000.0)) * 32768.0;
+		td->init_v2_2 = sin(-4.0 * M_PI * (tone->f2 / 8000.0)) * gain;
+		td->init_v3_2 = sin(-2.0 * M_PI * (tone->f2 / 8000.0)) * gain;
+
+		tone++;
+	}
+
+	return used;
+}
 
 int tone_zone_register_zone(int fd, struct tone_zone *z)
 {
 	char buf[MAX_SIZE];
 	int res;
-	int count=0;
+	int count = 0;
 	int x;
-	int used = 0;
-	int iopenedit = 0;
 	int space = MAX_SIZE;
-	char *ptr = buf;
+	void *ptr = buf;
+	int iopenedit = 1;
 	struct zt_tone_def_header *h;
+
+	h = ptr;
+	ptr += sizeof(*h);
+	space -= sizeof(*h);
+	h->zone = z->zone;
+
+	strncpy(h->name, z->description, sizeof(h->name) - 1);
+
+	for (x = 0; x < ZT_MAX_CADENCE; x++) 
+		h->ringcadence[x] = z->ringcadence[x];
+
+	for (x = 0; x < ZT_TONE_MAX; x++) {
+		if (!strlen(z->tones[x].data))
+			continue;
+
+#if 0
+		printf("Tone: %d, string: %s\n", z->tones[x].toneid, z->tones[x].data);
+#endif			
+		if ((res = build_tone(ptr, space, &z->tones[x], &count)) < 0) {
+			fprintf(stderr, "Tone %d not built.\n", x);
+			return -1;
+		}
+		ptr += res;
+		space -= res;
+	}
+
+	if ((res = build_mf_tones(ptr, space, &count, dtmf_dial, z->dtmf_low_level, z->dtmf_high_level)) < 0) {
+		fprintf(stderr, "Could not build DTMF tones.\n");
+		return -1;
+	}
+	ptr += res;
+	space -= res;
+
+	if ((res = build_mf_tones(ptr, space, &count, mf_dial, z->mf_level, z->mf_level)) < 0) {
+		fprintf(stderr, "Could not build MF tones.\n");
+		return -1;
+	}
+	ptr += res;
+	space -= res;
+
+	h->count = count;
+
 	if (fd < 0) {
-		fd = open(DEFAULT_ZT_DEV, O_RDWR);
-		iopenedit=1;
-		if (fd < 0) {
+		if ((fd = open(DEFAULT_ZT_DEV, O_RDWR)) < 0) {
 			fprintf(stderr, "Unable to open %s and fd not provided\n", DEFAULT_ZT_DEV);
 			return -1;
 		}
-	}
-	h = (struct zt_tone_def_header *)ptr;
-	ptr += sizeof(struct zt_tone_def_header);
-	space -= sizeof(struct zt_tone_def_header);
-	used += sizeof(struct zt_tone_def_header);
-	/*
-	 * Fill in ring cadence 
-	 */
-	for (x=0;x<ZT_MAX_CADENCE;x++) 
-		h->ringcadence[x] = z->ringcadence[x];
-	/* Put in an appropriate method for a kernel ioctl */
-	for (x=0;x<ZT_TONE_MAX;x++) {
-		if (strlen(z->tones[x].data)) {
-			/* It's a real tone */
-#if 0
-			printf("Tone: %d, string: %s\n", z->tones[x].toneid, z->tones[x].data);
-#endif			
-			res = build_tone(ptr, space, &z->tones[x], &count);
-			if (res < 0) {
-				fprintf(stderr, "Tone not built.\n");
-				if (iopenedit)
-					close(fd);
-				return -1;
-			}
-			ptr += res;
-			used += res;
-			space -= res;
-		}
-	}
-	h->count = count;
-	h->zone = z->zone;
-	strncpy(h->name, z->description, sizeof(h->name));
+		iopenedit = 1;
+	}
+
 	x = z->zone;
-	ioctl(fd, ZT_FREEZONE, &x);
-	res = ioctl(fd, ZT_LOADZONE, h);
-	if (res) 
+	if ((res = ioctl(fd, ZT_FREEZONE, &x))) {
+		fprintf(stderr, "ioctl(ZT_FREEZONE) failed: %s\n", strerror(errno));
+		return res;
+	}
+
+#if defined(TONEZONE_DRIVER)
+	dump_tone_zone(h, MAX_SIZE - space);
+#endif
+
+	if ((res = ioctl(fd, ZT_LOADZONE, h))) {
 		fprintf(stderr, "ioctl(ZT_LOADZONE) failed: %s\n", strerror(errno));
+		return res;
+	}
+
 	if (iopenedit)
 		close(fd);
+
 	return res;
 }
 

Modified: branches/1.4/tonezone.h
URL: http://svn.digium.com/view/zaptel/branches/1.4/tonezone.h?view=diff&rev=3490&r1=3489&r2=3490
==============================================================================
--- branches/1.4/tonezone.h (original)
+++ branches/1.4/tonezone.h Fri Dec 14 17:47:31 2007
@@ -41,11 +41,16 @@
 };
 
 struct tone_zone {
-	int zone;					/* Zone number */
+	int zone;				/* Zone number */
 	char country[10];			/* Country code */
-	char description[40];		/* Description */
+	char description[40];			/* Description */
 	int ringcadence[ZT_MAX_CADENCE];	/* Ring cadence */
 	struct tone_zone_sound tones[ZT_TONE_MAX];
+	int dtmf_high_level;			/* Power level of high frequency component
+						   of DTMF, expressed in dBm0. */
+	int dtmf_low_level;			/* Power level of low frequency component
+						   of DTMF, expressed in dBm0. */
+	int mf_level;				/* Power level of MF, expressed in dBm0. */
 };
 
 extern struct tone_zone builtin_zones[];

Modified: branches/1.4/wcusb.c
URL: http://svn.digium.com/view/zaptel/branches/1.4/wcusb.c?view=diff&rev=3490&r1=3489&r2=3490
==============================================================================
--- branches/1.4/wcusb.c (original)
+++ branches/1.4/wcusb.c Fri Dec 14 17:47:31 2007
@@ -393,7 +393,7 @@
 			}
 			if (debug) printk("wcusb: got digit %d\n", d->scanned_event);
 			if (digit != 'z') {
-				d->tone = zt_dtmf_tone(digit, 0);
+				d->tone = zt_dtmf_tone(&p->chan, digit);
 				if (!d->tone) {
 					printk("wcusb: Didn't get a tone structure\n");
 					goto func_end;

Modified: branches/1.4/zaptel-base.c
URL: http://svn.digium.com/view/zaptel/branches/1.4/zaptel-base.c?view=diff&rev=3490&r1=3489&r2=3490
==============================================================================
--- branches/1.4/zaptel-base.c (original)
+++ branches/1.4/zaptel-base.c Fri Dec 14 17:47:31 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,8 +303,10 @@
 
 #include "digits.h"
 
-static struct zt_tone *dtmf_tones_continuous = NULL;
-static struct zt_tone *mfv1_tones_continuous = NULL;
+static struct zt_dialparams global_dialparams = {
+	.dtmf_tonelen = DEFAULT_DTMF_LENGTH,
+	.mfv1_tonelen = DEFAULT_MFV1_LENGTH,
+};
 
 static int zt_chan_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long data, int unit);
 
@@ -363,6 +366,10 @@
 	   of zt_tones to generate what we
 	   want.  Use NULL if the tone is
 	   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[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];
@@ -1074,13 +1081,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;
 }
 
@@ -1130,10 +1135,14 @@
 		/* ZT_SENDTONE should never be used on a channel configured for pulse dialing */
 		chan->dialing = 1;
 		res = 0;
-		if (chan->digitmode == DIGIT_MODE_DTMF)
-			chan->curtone = dtmf_tones_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);
+		if ((chan->digitmode == DIGIT_MODE_DTMF) &&
+		    (tone >= ZT_TONE_DTMF_BASE) &&
+		    (tone <= ZT_TONE_DTMF_MAX))
+			chan->curtone = &chan->curzone->dtmf_continuous[tone - ZT_TONE_DTMF_BASE];
+		else if ((chan->digitmode == DIGIT_MODE_MFV1) &&
+			 (tone >= ZT_TONE_MF_BASE) &&
+			 (tone <= ZT_TONE_MF_MAX))
+			chan->curtone = &chan->curzone->mf_continuous[tone - ZT_TONE_MF_BASE];
 		else {
 			chan->dialing = 0;
 			res = -EINVAL;
@@ -2563,84 +2572,112 @@
 
 /* No bigger than 32k for everything per tone zone */
 #define MAX_SIZE 32768
-/* No more than 64 subtones */
-#define MAX_TONES 64
-
-static int
-ioctl_load_zone(unsigned long data)
-{
-	struct zt_tone *samples[MAX_TONES];
-	short next[MAX_TONES];
+/* No more than 128 subtones */
+#define MAX_TONES 128
+
+/* The tones to be loaded can (will) be a mix of regular tones,
+   DTMF tones and MF tones. We need to load DTMF and MF tones
+   a bit differently than regular tones because their storage
+   format is much simpler (an array structure field of the zone
+   structure, rather an array of pointers).
+*/
+static int ioctl_load_zone(unsigned long data)
+{
+	struct zt_tone *samples[MAX_TONES] = { NULL, };
+	short next[MAX_TONES] = { 0, };
 	struct zt_tone_def_header th;
+	struct zt_tone_def td;
+	struct zt_zone *z;
+	struct zt_tone *t;
 	void *slab, *ptr;
-	long size;
-	struct zt_zone *z;
-	struct zt_tone_def td;
-	struct zt_tone *t;
 	int x;
-	int space;
+	size_t space;
+	size_t size;
 	int res;
 	
-	/* XXX Unnecessary XXX */
-	memset(samples, 0, sizeof(samples));
-	/* XXX Unnecessary XXX */
-	memset(next, 0, sizeof(next));
-	if (copy_from_user(&th, (struct zt_tone_def_header *)data, sizeof(th)))
+	if (copy_from_user(&th, (struct zt_tone_def_header *) data, sizeof(th)))
 		return -EFAULT;
+
+	data += sizeof(th);
+
 	if ((th.count < 0) || (th.count > MAX_TONES)) {
 		printk("Too many tones included\n");
 		return -EINVAL;
 	}
-	space = size = sizeof(struct zt_zone) +
-			th.count * sizeof(struct zt_tone);
-	if ((size > MAX_SIZE) || (size < 0))
+
+	space = size = sizeof(*z) + th.count * sizeof(*t);
+
+	if (size > MAX_SIZE)
 		return -E2BIG;
-	ptr = slab = (char *)kmalloc(size, GFP_KERNEL);
-	if (!slab)
+
+	if (!(z = ptr = slab = kmalloc(size, GFP_KERNEL)))
 		return -ENOMEM;
-	/* Zero it out for simplicity */
+
 	memset(slab, 0, size);
-	/* Grab the zone */
-	z = (struct zt_zone *)slab;
+
+	ptr += sizeof(*z);
+	space -= sizeof(*z);
+
 	strncpy(z->name, th.name, sizeof(z->name) - 1);
-	for (x=0;x<ZT_MAX_CADENCE;x++)
+
+	for (x = 0; x < ZT_MAX_CADENCE; x++)
 		z->ringcadence[x] = th.ringcadence[x];
-	data += sizeof(struct zt_tone_def_header);
-	ptr += sizeof(struct zt_zone);
-	space -= sizeof(struct zt_zone);
-	for (x=0;x<th.count;x++) {
-		if (space < sizeof(struct zt_tone)) {
-			/* Check space for zt_tone struct */
+
+	for (x = 0; x < th.count; x++) {
+		enum {
+			REGULAR_TONE,
+			DTMF_TONE,
+			MF_TONE,
+		} tone_type;
+
+		if (space < sizeof(*t)) {
 			kfree(slab);
 			printk("Insufficient tone zone space\n");
 			return -EINVAL;
 		}
-		if (copy_from_user(&td, (struct zt_tone_def *)data, sizeof(struct zt_tone_def))) {
+
+		if (copy_from_user(&td, (struct zt_tone_def *) data, sizeof(td))) {
 			kfree(slab);
 			return -EFAULT;
 		}
-		/* Index the current sample */
-		samples[x] = t = (struct zt_tone *)ptr;
-		/* Remember which sample is next */
-		next[x] = td.next;
-		/* Make sure the "next" one is sane */
-		if ((next[x] >= th.count) || (next[x] < 0)) {
-			printk("Invalid 'next' pointer: %d\n", next[x]);
+
+		data += sizeof(td);
+
+		if ((td.tone >= 0) && (td.tone < ZT_TONE_MAX)) {
+			tone_type = REGULAR_TONE;
+
+			t = samples[x] = ptr;
+
+			space -= sizeof(*t);
+			ptr += sizeof(*t);
+
+			/* Remember which sample is next */
+			next[x] = td.next;
+			
+			/* Make sure the "next" one is sane */
+			if ((next[x] >= th.count) || (next[x] < 0)) {
+				printk("Invalid 'next' pointer: %d\n", next[x]);
+				kfree(slab);
+				return -EINVAL;
+			}
+		} else if ((td.tone >= ZT_TONE_DTMF_BASE) &&
+			   (td.tone <= ZT_TONE_DTMF_MAX)) {
+			tone_type = DTMF_TONE;
+
+			td.tone -= ZT_TONE_DTMF_BASE;
+			t = &z->dtmf[td.tone];
+		} else if ((td.tone >= ZT_TONE_MF_BASE) &&
+			   (td.tone <= ZT_TONE_MF_MAX)) {
+			tone_type = MF_TONE;
+
+			td.tone -= ZT_TONE_MF_BASE;
+			t = &z->mf[td.tone];
+		} else {
+			printk("Invalid tone (%d) defined\n", td.tone);
 			kfree(slab);
 			return -EINVAL;
 		}
-		if (td.tone >= ZT_TONE_MAX) {
-			printk("Too many tones defined\n");
-			/* Make sure it's sane */
-			kfree(slab);
-			return -EINVAL;
-		}
-		/* Update pointers to account for zt_tone header */
-		space -= sizeof(struct zt_tone);
-		ptr += sizeof(struct zt_tone);
-		data += sizeof(struct zt_tone_def);
-		/* Fill in tonedata, datalen, and tonesamples fields */
-		t->tonesamples = td.samples;
+
 		t->fac1 = td.fac1;
 		t->init_v2_1 = td.init_v2_1;
 		t->init_v3_1 = td.init_v3_1;
@@ -2648,18 +2685,39 @@
 		t->init_v2_2 = td.init_v2_2;
 		t->init_v3_2 = td.init_v3_2;
 		t->modulate = td.modulate;
-		t->next = NULL;					/* XXX Unnecessary XXX */
-		if (!z->tones[td.tone])
-			z->tones[td.tone] = t;
-	}
-	for (x=0;x<th.count;x++) 
-		/* Set "next" pointers */
-		samples[x]->next = samples[next[x]];
-
-	/* Actually register zone */
-	res = zt_register_tone_zone(th.zone, z);
-	if (res)
+
+		switch (tone_type) {
+		case REGULAR_TONE:
+			t->tonesamples = td.samples;
+			if (!z->tones[td.tone])
+				z->tones[td.tone] = t;
+			break;
+		case DTMF_TONE:
+			t->tonesamples = global_dialparams.dtmf_tonelen;
+			t->next = &dtmf_silence;
+			z->dtmf_continuous[td.tone] = *t;
+			z->dtmf_continuous[td.tone].next = &z->dtmf_continuous[td.tone];
+			break;
+		case MF_TONE:
+			t->tonesamples = global_dialparams.mfv1_tonelen;
+			t->next = &mfv1_silence;
+			/* Special case for K/P tone */
+			if (td.tone == 10)
+				t->tonesamples *= 5 / 3;
+			z->mf_continuous[td.tone] = *t;
+			z->mf_continuous[td.tone].next = &z->mf_continuous[td.tone];
+			break;
+		}
+	}
+
+	for (x = 0; x < th.count; x++) {
+		if (samples[x] && next[x])
+			samples[x]->next = samples[next[x]];
+	}
+
+	if ((res = zt_register_tone_zone(th.zone, z)))
 		kfree(slab);
+
 	return res;
 }
 
@@ -2674,15 +2732,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':
@@ -2693,7 +2758,7 @@
 	case '7':
 	case '8':
 	case '9':
-		return z + (int)(digit - '0');
+		return z + (digit - '0');
 	case '*':
 		return z + 10;
 	case '#':
@@ -2703,66 +2768,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;
@@ -2770,6 +2817,7 @@
 			}
 		}
 	}
+
 	/* Notify userspace process if there is nothing left */
 	chan->dialing = 0;
 	__qevent(chan, ZT_EVENT_DIALCOMPLETE);
@@ -3567,43 +3615,70 @@
 		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 0
+		if (j == default_zone) {
+			write_unlock(&zone_lock);
+			/* XXX: possibly a better return code here */
+			return -EINVAL;
+		}
+#endif
 		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;
+
+		global_dialparams = tdp;
+
+		/* 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 < sizeof(z->dtmf) / sizeof(z->dtmf[0]); i++)
+				z->dtmf[i].tonesamples = tdp.dtmf_tonelen * ZT_CHUNKSIZE;
+
+			for (i = 0; i < sizeof(z->mf) / sizeof(z->mf[0]); 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.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)))
+		tdp = global_dialparams;
+		if (copy_to_user((struct zt_dialparams *) data, &tdp, sizeof(tdp)))
 			return -EFAULT;
 		break;
 	case ZT_GETVERSION:
@@ -3687,6 +3762,7 @@
 	unsigned long flags, flagso;
 	int i, j, k, rv;
 	int ret, c;
+	char *s;
 	
 	if (!chan)
 		return -EINVAL;
@@ -3702,10 +3778,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;
@@ -3719,17 +3797,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;
@@ -7144,7 +7220,6 @@
 
 static int __init zt_init(void) {
 	int res = 0;
-	int i = 0;
 
 #ifdef CONFIG_PROC_FS
 	proc_entries[0] = proc_mkdir("zaptel", NULL);
@@ -7178,26 +7253,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();
@@ -7222,16 +7277,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: branches/1.4/zaptel.h
URL: http://svn.digium.com/view/zaptel/branches/1.4/zaptel.h?view=diff&rev=3490&r1=3489&r2=3490
==============================================================================
--- branches/1.4/zaptel.h (original)
+++ branches/1.4/zaptel.h Fri Dec 14 17:47:31 2007
@@ -518,7 +518,7 @@
 #define	ZT_DEFAULTZONE		_IOW (ZT_CODE, 24, int)
 
 /*
- * Load a tone zone from a ZT_tone_def_header, see
+ * Load a tone zone from a zt_tone_def_header, see
  * below...
  */
 #define ZT_LOADZONE		_IOW (ZT_CODE, 25, struct zt_tone_def_header)
@@ -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,
@@ -790,6 +788,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
 
 #define ZT_TONEDETECT_ON	(1 << 0)		/* Detect tones */
@@ -855,7 +873,7 @@
 	int zone;		/* Which zone we are loading */
 	int ringcadence[ZT_MAX_CADENCE];	/* Ring cadence in ms (0=on, 1=off, ends with 0 value) */
 	char name[40];		/* Informational name of zone */
-	/* Immediately follow the ZT_tone_def_header by ZT_tone_def's */
+	/* Immediately follow the zt_tone_def_header by zt_tone_def's */
 };
 
 struct zt_tone_def {		/* Structure for zone programming */
@@ -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

Modified: branches/1.4/zonedata.c
URL: http://svn.digium.com/view/zaptel/branches/1.4/zonedata.c?view=diff&rev=3490&r1=3489&r2=3490
==============================================================================
--- branches/1.4/zonedata.c (original)
+++ branches/1.4/zonedata.c Fri Dec 14 17:47:31 2007
@@ -25,620 +25,866 @@
  */
 #include "tonezone.h"
 
-struct tone_zone builtin_zones[]  =
+struct tone_zone builtin_zones[] =
 {
-	{ 0, "us", "United States / North America", { 2000, 4000 }, 
-	  {
-		  { ZT_TONE_DIALTONE, "350+440" },
-		  { ZT_TONE_BUSY, "480+620/500,0/500" },
-		  { ZT_TONE_RINGTONE, "440+480/2000,0/4000" },
-		  { ZT_TONE_CONGESTION, "480+620/250,0/250" },
-		  { ZT_TONE_CALLWAIT, "440/300,0/10000" },
-		  { ZT_TONE_DIALRECALL, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" },
-		  { ZT_TONE_RECORDTONE, "1400/500,0/15000" },
-		  { ZT_TONE_INFO, "!950/330,!1400/330,!1800/330,0" },
-		  { ZT_TONE_STUTTER, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" },
-	  },
-	},
-	{ 1, "au", "Australia", {  400, 200, 400, 2000 },
-	  {
-		  { ZT_TONE_DIALTONE, "413+438" },		
-		  { ZT_TONE_BUSY, "425/375,0/375" },
-		  { ZT_TONE_RINGTONE, "413+438/400,0/200,413+438/400,0/2000" },
-		  /* XXX Congestion: Should reduce by 10 db every other cadence XXX */
-		  { ZT_TONE_CONGESTION, "425/375,0/375,420/375,0/375" }, 
-		  { ZT_TONE_CALLWAIT, "425/100,0/200,425/200,0/4400" },
-		  { ZT_TONE_DIALRECALL, "413+428" },
-		  { ZT_TONE_RECORDTONE, "!425/1000,!0/15000,425/360,0/15000" },
-		  { ZT_TONE_INFO, "425/2500,0/500" },
-		  { ZT_TONE_STUTTER, "413+438/100,0/40" },
-	  },
-	},
-	{ 2, "fr", "France", { 1500, 3500 },
-	  {
-		  /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */
-		  /* Dialtone can also be 440+330 */
-		  { ZT_TONE_DIALTONE, "440" },
-		  { ZT_TONE_BUSY, "440/500,0/500" },
-		  { ZT_TONE_RINGTONE, "440/1500,0/3500" },
-		  /* CONGESTION - not specified */
-		  { ZT_TONE_CONGESTION, "440/250,0/250" },
-		  { ZT_TONE_CALLWAIT, "440/300,0/10000" },
-		  /* DIALRECALL - not specified */
-		  { ZT_TONE_DIALRECALL, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" },
-		  /* RECORDTONE - not specified */
-		  { ZT_TONE_RECORDTONE, "1400/500,0/15000" },
-		  { ZT_TONE_INFO, "!950/330,!1400/330,!1800/330,0" },
-		  { ZT_TONE_STUTTER, "!440/100,!0/100,!440/100,!0/100,!440/100,!0/100,!440/100,!0/100,!440/100,!0/100,!440/100,!0/100,440" },
-	  },
-	},
-	{ 3, "nl", "Netherlands", { 1000, 4000 },
-	  {
-		  /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */
-		  /* Most of these 425's can also be 450's */
-		  { ZT_TONE_DIALTONE, "425" },
-		  { ZT_TONE_BUSY, "425/500,0/500" },
-		  { ZT_TONE_RINGTONE, "425/1000,0/4000" },
-		  { ZT_TONE_CONGESTION, "425/250,0/250" },
-		  { ZT_TONE_CALLWAIT, "425/500,0/9500" },
-		  /* DIALRECALL - not specified */
-		  { ZT_TONE_DIALRECALL, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" },
-		  /* RECORDTONE - not specified */
-		  { ZT_TONE_RECORDTONE, "1400/500,0/15000" },
-		  { ZT_TONE_INFO, "950/330,1400/330,1800/330,0/1000" },
-		  { ZT_TONE_STUTTER, "425/500,0/50" },
-	  },
-	},
-	{ 4, "uk", "United Kingdom", { 400, 200, 400, 2000 },
-	  {
-		  /* From British Telecom SIN350 v1.2 */
-		  { ZT_TONE_DIALTONE, "350+440" },
-		  { ZT_TONE_BUSY, "400/375,0/375" },
-		  { ZT_TONE_RINGTONE, "400+450/400,0/200,400+450/400,0/2000" },
-		  { ZT_TONE_CONGESTION, "400/400,0/350,400/225,0/525" },
-		  { ZT_TONE_CALLWAIT, "400/100,0/4000" },
-		  { ZT_TONE_DIALRECALL, "350+440" },
-		  { ZT_TONE_RECORDTONE, "1400/500,0/60000" },
-		  { ZT_TONE_INFO, "950/330,0/15,1400/330,0/15,1800/330,0/1000" },
-		  { ZT_TONE_STUTTER, "350+440/750,440/750" },
-	  },
-	},
-	{ 5, "fi", "Finland", { 1000, 4000 },
-	  {
-		  { ZT_TONE_DIALTONE, "425" },
-		  { ZT_TONE_BUSY, "425/300,0/300" },
-		  { ZT_TONE_RINGTONE, "425/1000,0/4000" },
-		  { ZT_TONE_CONGESTION, "425/200,0/200" },
-		  { ZT_TONE_CALLWAIT, "425/150,0/150,425/150,0/8000" },
-		  { ZT_TONE_DIALRECALL, "425/650,0/25" },
-		  { ZT_TONE_RECORDTONE, "1400/500,0/15000" },
-		  { ZT_TONE_INFO, "950/650,0/325,950/325,0/30,1400/1300,0/2600" },
-		  { ZT_TONE_STUTTER, "425/650,0/25" },
-	  },
-	},
-	{ 6,"es","Spain", { 1500, 3000},
-	  {
-		  { ZT_TONE_DIALTONE, "425" },
-		  { ZT_TONE_BUSY, "425/200,0/200" },
-		  { ZT_TONE_RINGTONE, "425/1500,0/3000" },
-		  { ZT_TONE_CONGESTION, "425/200,0/200,425/200,0/200,425/200,0/600" },
-		  { ZT_TONE_CALLWAIT, "425/175,0/175,425/175,0/3500" },
-		  { ZT_TONE_DIALRECALL, "!425/200,!0/200,!425/200,!0/200,!425/200,!0/200,425" },
-		  { ZT_TONE_RECORDTONE, "1400/500,0/15000" },
-		  { ZT_TONE_INFO, "950/330,0/1000" },
-		  { ZT_TONE_STUTTER, "425/500,0/50" },
-	  },
-	},
-	{ 7,"jp","Japan", { 1000, 2000 },
-	  {
-		  { ZT_TONE_DIALTONE, "400" },
-		  { ZT_TONE_BUSY, "400/500,0/500" },
-		  { ZT_TONE_RINGTONE, "400+15/1000,0/2000" },
-		  { ZT_TONE_CONGESTION, "400/500,0/500" },
-		  { ZT_TONE_CALLWAIT, "400+16/500,0/8000" },
-		  { ZT_TONE_DIALRECALL, "!400/200,!0/200,!400/200,!0/200,!400/200,!0/200,400" },
-		  { ZT_TONE_RECORDTONE, "1400/500,0/15000" },
-		  { ZT_TONE_INFO, "!950/330,!1400/330,!1800/330,0" },
-		  { ZT_TONE_STUTTER, "!400/100,!0/100,!400/100,!0/100,!400/100,!0/100,!400/100,!0/100,!400/100,!0/100,!400/100,!0/100,400" },
-	  },
-	},
-	{ 8,"no","Norway", { 1000, 4000 },
-	  {
-		  { ZT_TONE_DIALTONE, "425" },
-		  { ZT_TONE_BUSY, "425/500,0/500" },
-		  { ZT_TONE_RINGTONE, "425/1000,0/4000" },
-		  { ZT_TONE_CONGESTION, "425/200,0/200" },
-		  { ZT_TONE_CALLWAIT, "425/200,0/600,425/200,0/10000" },
-		  { ZT_TONE_DIALRECALL, "470/400,425/400" },
-		  { ZT_TONE_RECORDTONE, "1400/400,0/15000" },
-		  { ZT_TONE_INFO, "!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,0" },
-		  { ZT_TONE_STUTTER, "470/400,425/400" },
-	  },
-	},
-	{ 9, "at", "Austria", { 1000, 5000 },
-	  {
-		  /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */
-		  { ZT_TONE_DIALTONE, "420" },

[... 1342 lines stripped ...]



More information about the zaptel-commits mailing list