[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