summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkpfleming <kpfleming@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2008-03-21 23:30:41 +0000
committerkpfleming <kpfleming@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2008-03-21 23:30:41 +0000
commit57544543646a83e92555be35b6096928d41b721e (patch)
tree9bbfb63133ea8454d6968122a860a68ca46577fd
parent9b0ddb179b1216d03a2d0e7d884342fbef2246a0 (diff)
add MF R2 tone generation, and along the way do a lot of cleanup of the tone building and playback code
git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.4@4063 5390a7c7-147a-4af0-8ec9-7488f05a26cb
-rw-r--r--kernel/digits.h13
-rw-r--r--kernel/wcusb.c2
-rw-r--r--kernel/zaptel-base.c303
-rw-r--r--kernel/zaptel.h102
-rw-r--r--tonezone.c92
-rw-r--r--tonezone.h3
-rw-r--r--zonedata.c123
7 files changed, 456 insertions, 182 deletions
diff --git a/kernel/digits.h b/kernel/digits.h
index eba09dd..9f4ea9b 100644
--- a/kernel/digits.h
+++ b/kernel/digits.h
@@ -15,14 +15,14 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * Use DTMF/MFv1 tables
*/
#ifndef _DIGITS_H
#define _DIGITS_H
#define DEFAULT_DTMF_LENGTH 100 * ZT_CHUNKSIZE
-#define DEFAULT_MFV1_LENGTH 60 * ZT_CHUNKSIZE
+#define DEFAULT_MFR1_LENGTH 68 * ZT_CHUNKSIZE
+#define DEFAULT_MFR2_LENGTH 100 * ZT_CHUNKSIZE
#define PAUSE_LENGTH 500 * ZT_CHUNKSIZE
/* At the end of silence, the tone stops */
@@ -31,8 +31,13 @@ static struct zt_tone dtmf_silence = {
};
/* At the end of silence, the tone stops */
-static struct zt_tone mfv1_silence = {
- .tonesamples = DEFAULT_MFV1_LENGTH,
+static struct zt_tone mfr1_silence = {
+ .tonesamples = DEFAULT_MFR1_LENGTH,
+};
+
+/* At the end of silence, the tone stops */
+static struct zt_tone mfr2_silence = {
+ .tonesamples = DEFAULT_MFR2_LENGTH,
};
/* A pause in the dialing */
diff --git a/kernel/wcusb.c b/kernel/wcusb.c
index 51eaca7..15205a4 100644
--- a/kernel/wcusb.c
+++ b/kernel/wcusb.c
@@ -393,7 +393,7 @@ loop_start:
}
if (debug) printk("wcusb: got digit %d\n", d->scanned_event);
if (digit != 'z') {
- d->tone = zt_dtmf_tone(&p->chan, digit);
+ d->tone = zt_mf_tone(&p->chan, digit, p->chan.digitmode);
if (!d->tone) {
printk("wcusb: Didn't get a tone structure\n");
goto func_end;
diff --git a/kernel/zaptel-base.c b/kernel/zaptel-base.c
index f98494d..c4b4ccf 100644
--- a/kernel/zaptel-base.c
+++ b/kernel/zaptel-base.c
@@ -116,7 +116,7 @@ static char *zt_txlevelnames[] = {
EXPORT_SYMBOL(zt_transcode_fops);
EXPORT_SYMBOL(zt_init_tone_state);
-EXPORT_SYMBOL(zt_dtmf_tone);
+EXPORT_SYMBOL(zt_mf_tone);
EXPORT_SYMBOL(zt_register);
EXPORT_SYMBOL(zt_unregister);
EXPORT_SYMBOL(__zt_mulaw);
@@ -301,14 +301,17 @@ of the next sample chunk's data (next time around the world).
*/
#define DIGIT_MODE_DTMF 0
-#define DIGIT_MODE_MFV1 1
+#define DIGIT_MODE_MFR1 1
#define DIGIT_MODE_PULSE 2
+#define DIGIT_MODE_MFR2_FWD 3
+#define DIGIT_MODE_MFR2_REV 4
#include "digits.h"
static struct zt_dialparams global_dialparams = {
.dtmf_tonelen = DEFAULT_DTMF_LENGTH,
- .mfv1_tonelen = DEFAULT_MFV1_LENGTH,
+ .mfv1_tonelen = DEFAULT_MFR1_LENGTH,
+ .mfr2_tonelen = DEFAULT_MFR2_LENGTH,
};
static int zt_chan_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long data, int unit);
@@ -372,8 +375,9 @@ struct zt_zone {
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 */
+ struct zt_tone mfr1[15]; /* MFR1 tones for this zone, with desired length */
+ struct zt_tone mfr2_fwd[15]; /* MFR2 FWD tones for this zone, with desired length */
+ struct zt_tone mfr2_rev[15]; /* MFR2 REV tones for this zone, with desired length */
};
static struct zt_span *spans[ZT_MAX_SPANS];
@@ -1163,22 +1167,29 @@ static int start_tone(struct zt_chan *chan, int tone)
res = -ENOSYS;
} else /* Note that no tone zone exists at the moment */
res = -ENODATA;
- } else if (tone >= ZT_TONE_DTMF_BASE && tone <= ZT_TONE_DTMF_MAX) {
- /* ZT_SENDTONE should never be used on a channel configured for pulse dialing */
- chan->dialing = 1;
- res = 0;
- 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;
+ } else if (chan->digitmode == DIGIT_MODE_DTMF) {
+ if ((tone >= ZT_TONE_DTMF_BASE) && (tone <= ZT_TONE_DTMF_MAX)) {
+ chan->dialing = 1;
+ res = 0;
+ tone -= ZT_TONE_DTMF_BASE;
+ if (chan->curzone) {
+ /* Have a tone zone */
+ if (chan->curzone->dtmf_continuous[tone].tonesamples) {
+ chan->curtone = &chan->curzone->dtmf_continuous[tone];
+ res = 0;
+ } else {
+ /* Indicate that zone is loaded but no such tone exists */
+ res = -ENOSYS;
+ }
+ } else {
+ /* Note that no tone zone exists at the moment */
+ res = -ENODATA;
+ }
+ } else {
res = -EINVAL;
- }
+ };
+ } else {
+ res = -EINVAL;
}
if (chan->curtone)
@@ -2680,7 +2691,9 @@ static int ioctl_load_zone(unsigned long data)
enum {
REGULAR_TONE,
DTMF_TONE,
- MF_TONE,
+ MFR1_TONE,
+ MFR2_FWD_TONE,
+ MFR2_REV_TONE,
} tone_type;
if (space < sizeof(*t)) {
@@ -2716,15 +2729,23 @@ static int ioctl_load_zone(unsigned long data)
} 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 if ((td.tone >= ZT_TONE_MFR1_BASE) &&
+ (td.tone <= ZT_TONE_MFR1_MAX)) {
+ tone_type = MFR1_TONE;
+ td.tone -= ZT_TONE_MFR1_BASE;
+ t = &z->mfr1[td.tone];
+ } else if ((td.tone >= ZT_TONE_MFR2_FWD_BASE) &&
+ (td.tone <= ZT_TONE_MFR2_FWD_MAX)) {
+ tone_type = MFR2_FWD_TONE;
+ td.tone -= ZT_TONE_MFR2_FWD_BASE;
+ t = &z->mfr2_fwd[td.tone];
+ } else if ((td.tone >= ZT_TONE_MFR2_REV_BASE) &&
+ (td.tone <= ZT_TONE_MFR2_REV_MAX)) {
+ tone_type = MFR2_REV_TONE;
+ td.tone -= ZT_TONE_MFR2_REV_BASE;
+ t = &z->mfr2_rev[td.tone];
} else {
printk("Invalid tone (%d) defined\n", td.tone);
kfree(slab);
@@ -2751,14 +2772,26 @@ static int ioctl_load_zone(unsigned long data)
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];
+ case MFR1_TONE:
+ switch (td.tone + ZT_TONE_MFR1_BASE) {
+ case ZT_TONE_MFR1_KP:
+ case ZT_TONE_MFR1_ST:
+ case ZT_TONE_MFR1_STP:
+ case ZT_TONE_MFR1_ST2P:
+ case ZT_TONE_MFR1_ST3P:
+ /* signaling control tones are always 100ms */
+ t->tonesamples = 100 * ZT_CHUNKSIZE;
+ break;
+ default:
+ t->tonesamples = global_dialparams.mfv1_tonelen;
+ break;
+ }
+ t->next = &mfr1_silence;
+ break;
+ case MFR2_FWD_TONE:
+ case MFR2_REV_TONE:
+ t->tonesamples = global_dialparams.mfr2_tonelen;
+ t->next = &dtmf_silence;
break;
}
}
@@ -2790,51 +2823,134 @@ void zt_init_tone_state(struct zt_tone_state *ts, struct zt_tone *zt)
ts->modulate = zt->modulate;
}
-struct zt_tone *zt_dtmf_tone(const struct zt_chan *chan, char digit)
+struct zt_tone *zt_mf_tone(const struct zt_chan *chan, char digit, int digitmode)
{
- struct zt_tone *z;
+ unsigned int tone_index;
- switch (chan->digitmode) {
+ switch (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':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- return z + (digit - '0');
- case '*':
- return z + 10;
- case '#':
- return z + 11;
- case 'A':
- case 'B':
- case 'C':
- return z + (digit + 12 - 'A');
- case 'D':
- if (chan->digitmode == DIGIT_MODE_MFV1)
+ switch (digit) {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ tone_index = ZT_TONE_DTMF_0 + (digit - '0');
+ break;
+ case '*':
+ tone_index = ZT_TONE_DTMF_s;
+ break;
+ case '#':
+ tone_index = ZT_TONE_DTMF_p;
+ break;
+ case 'A':
+ case 'B':
+ case 'C':
+ case 'D':
+ tone_index = ZT_TONE_DTMF_A + (digit - 'A');
+ case 'W':
+ return &tone_pause;
+ default:
return NULL;
- else
- return z + (digit + 12 - 'A');
- case 'W':
- return &tone_pause;
+ }
+ return &chan->curzone->dtmf[tone_index - ZT_TONE_DTMF_BASE];
+ case DIGIT_MODE_MFR1:
+ switch (digit) {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ tone_index = ZT_TONE_MFR1_0 + (digit - '0');
+ break;
+ case '*':
+ tone_index = ZT_TONE_MFR1_KP;
+ break;
+ case '#':
+ tone_index = ZT_TONE_MFR1_ST;
+ break;
+ case 'A':
+ tone_index = ZT_TONE_MFR1_STP;
+ break;
+ case 'B':
+ tone_index = ZT_TONE_MFR1_ST2P;
+ break;
+ case 'C':
+ tone_index = ZT_TONE_MFR1_ST3P;
+ break;
+ case 'W':
+ return &tone_pause;
+ default:
+ return NULL;
+ }
+ return &chan->curzone->mfr1[tone_index - ZT_TONE_MFR1_BASE];
+ case DIGIT_MODE_MFR2_FWD:
+ switch (digit) {
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ tone_index = ZT_TONE_MFR2_FWD_1 + (digit - '1');
+ break;
+ case 'A':
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'E':
+ case 'F':
+ tone_index = ZT_TONE_MFR2_FWD_10 + (digit - 'A');
+ break;
+ case 'W':
+ return &tone_pause;
+ default:
+ return NULL;
+ }
+ return &chan->curzone->mfr2_fwd[tone_index - ZT_TONE_MFR2_FWD_BASE];
+ case DIGIT_MODE_MFR2_REV:
+ switch (digit) {
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ tone_index = ZT_TONE_MFR2_REV_1 + (digit - '1');
+ break;
+ case 'A':
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'E':
+ case 'F':
+ tone_index = ZT_TONE_MFR2_REV_10 + (digit - 'A');
+ break;
+ case 'W':
+ return &tone_pause;
+ default:
+ return NULL;
+ }
+ return &chan->curzone->mfr2_rev[tone_index - ZT_TONE_MFR2_REV_BASE];
+ default:
+ return NULL;
}
-
- return NULL;
}
static void __do_dtmf(struct zt_chan *chan)
@@ -2850,7 +2966,15 @@ static void __do_dtmf(struct zt_chan *chan)
chan->tonep = 0;
break;
case 'M':
- chan->digitmode = DIGIT_MODE_MFV1;
+ chan->digitmode = DIGIT_MODE_MFR1;
+ chan->tonep = 0;
+ break;
+ case 'F':
+ chan->digitmode = DIGIT_MODE_MFR2_FWD;
+ chan->tonep = 0;
+ break;
+ case 'R':
+ chan->digitmode = DIGIT_MODE_MFR2_REV;
chan->tonep = 0;
break;
case 'P':
@@ -2866,7 +2990,7 @@ static void __do_dtmf(struct zt_chan *chan)
return;
}
} else {
- chan->curtone = zt_dtmf_tone(chan, c);
+ chan->curtone = zt_mf_tone(chan, c, chan->digitmode);
chan->tonep = 0;
if (chan->curtone) {
zt_init_tone_state(&chan->ts, chan->curtone);
@@ -3713,6 +3837,8 @@ static int zt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd
return -EINVAL;
if ((tdp.mfv1_tonelen > 4000) || (tdp.mfv1_tonelen < 10))
return -EINVAL;
+ if ((tdp.mfr2_tonelen > 4000) || (tdp.mfr2_tonelen < 10))
+ return -EINVAL;
global_dialparams = tdp;
@@ -3724,19 +3850,28 @@ static int zt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd
if (!z)
continue;
- for (i = 0; i < sizeof(z->dtmf) / sizeof(z->dtmf[0]); i++)
+ 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;
+ /* for MFR1, we only adjust the length of the digits */
+ for (i = ZT_TONE_MFR1_0; i <= ZT_TONE_MFR1_9; i++) {
+ z->mfr1[i - ZT_TONE_MFR1_BASE].tonesamples = tdp.mfv1_tonelen * ZT_CHUNKSIZE;
+ }
- /* Special case for K/P tone */
- z->mf[10].tonesamples *= 5 / 3;
+ for (i = 0; i < sizeof(z->mfr2_fwd) / sizeof(z->mfr2_fwd[0]); i++) {
+ z->mfr2_fwd[i].tonesamples = tdp.mfr2_tonelen * ZT_CHUNKSIZE;
+ }
+
+ for (i = 0; i < sizeof(z->mfr2_rev) / sizeof(z->mfr2_rev[0]); i++) {
+ z->mfr2_rev[i].tonesamples = tdp.mfr2_tonelen * ZT_CHUNKSIZE;
+ }
}
write_unlock(&zone_lock);
dtmf_silence.tonesamples = tdp.dtmf_tonelen * ZT_CHUNKSIZE;
- mfv1_silence.tonesamples = tdp.mfv1_tonelen * ZT_CHUNKSIZE;
+ mfr1_silence.tonesamples = tdp.mfv1_tonelen * ZT_CHUNKSIZE;
+ mfr2_silence.tonesamples = tdp.mfr2_tonelen * ZT_CHUNKSIZE;
break;
case ZT_GET_DIALPARAMS:
diff --git a/kernel/zaptel.h b/kernel/zaptel.h
index b37a2c3..e0db194 100644
--- a/kernel/zaptel.h
+++ b/kernel/zaptel.h
@@ -351,7 +351,7 @@ char netdev_name[16]; /*name for the hdlc network device*/
typedef struct zt_sfconfig
{
int chan; /* Channel we're applying this to (0 to use name) */
-char name[40]; /* Name of channel to use */
+char name[40]; /* Name of channel to use */
long rxp1; /* receive tone det. p1 */
long rxp2; /* receive tone det. p2 */
long rxp3; /* receive tone det. p3 */
@@ -371,14 +371,13 @@ int readbufs; /* How many read buffers are full (read-only) */
int writebufs; /* How many write buffers are full (read-only) */
} ZT_BUFFERINFO;
-typedef struct zt_dialparams
-{
-int mfv1_tonelen; /* MF tone length (KP = this * 5/3) */
-int dtmf_tonelen; /* DTMF tone length */
-int reserved[4]; /* Reserved for future expansion -- always set to 0 */
+typedef struct zt_dialparams {
+ int mfv1_tonelen; /* MF R1 tone length for digits */
+ int dtmf_tonelen; /* DTMF tone length */
+ int mfr2_tonelen; /* MF R2 tone length */
+ int reserved[3]; /* Reserved for future expansion -- always set to 0 */
} ZT_DIAL_PARAMS;
-
typedef struct zt_dynamic_span {
char driver[20]; /* Which low-level driver to use */
char addr[40]; /* Destination address */
@@ -387,7 +386,7 @@ typedef struct zt_dynamic_span {
int spanno; /* Span number (filled in by zaptel) */
} ZT_DYNAMIC_SPAN;
-/* Define the max # of outgoing DTMF or MFv1 digits to queue in-kernel */
+/* Define the max # of outgoing DTMF, MFR1 or MFR2 digits to queue in-kernel */
#define ZT_MAX_DTMF_BUF 256
#define ZT_DIAL_OP_APPEND 1
@@ -398,10 +397,9 @@ typedef struct zt_dynamic_span {
#define ZT_LAW_MULAW 1 /* Mu-law */
#define ZT_LAW_ALAW 2 /* A-law */
-typedef struct zt_dialoperation
-{
-int op;
-char dialstr[ZT_MAX_DTMF_BUF];
+typedef struct zt_dialoperation {
+ int op;
+ char dialstr[ZT_MAX_DTMF_BUF];
} ZT_DIAL_OPERATION;
@@ -804,7 +802,9 @@ struct zt_hwgain{
#define ZT_TONE_MAX 16
#define ZT_TONE_DTMF_BASE 64
-#define ZT_TONE_MF_BASE 80
+#define ZT_TONE_MFR1_BASE 80
+#define ZT_TONE_MFR2_FWD_BASE 96
+#define ZT_TONE_MFR2_REV_BASE 112
enum {
ZT_TONE_DTMF_0 = ZT_TONE_DTMF_BASE,
@@ -828,24 +828,64 @@ enum {
#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,
+ ZT_TONE_MFR1_0 = ZT_TONE_MFR1_BASE,
+ ZT_TONE_MFR1_1,
+ ZT_TONE_MFR1_2,
+ ZT_TONE_MFR1_3,
+ ZT_TONE_MFR1_4,
+ ZT_TONE_MFR1_5,
+ ZT_TONE_MFR1_6,
+ ZT_TONE_MFR1_7,
+ ZT_TONE_MFR1_8,
+ ZT_TONE_MFR1_9,
+ ZT_TONE_MFR1_KP,
+ ZT_TONE_MFR1_ST,
+ ZT_TONE_MFR1_STP,
+ ZT_TONE_MFR1_ST2P,
+ ZT_TONE_MFR1_ST3P,
+};
+
+#define ZT_TONE_MFR1_MAX ZT_TONE_MFR1_ST3P
+
+enum {
+ ZT_TONE_MFR2_FWD_1 = ZT_TONE_MFR2_FWD_BASE,
+ ZT_TONE_MFR2_FWD_2,
+ ZT_TONE_MFR2_FWD_3,
+ ZT_TONE_MFR2_FWD_4,
+ ZT_TONE_MFR2_FWD_5,
+ ZT_TONE_MFR2_FWD_6,
+ ZT_TONE_MFR2_FWD_7,
+ ZT_TONE_MFR2_FWD_8,
+ ZT_TONE_MFR2_FWD_9,
+ ZT_TONE_MFR2_FWD_10,
+ ZT_TONE_MFR2_FWD_11,
+ ZT_TONE_MFR2_FWD_12,
+ ZT_TONE_MFR2_FWD_13,
+ ZT_TONE_MFR2_FWD_14,
+ ZT_TONE_MFR2_FWD_15,
+};
+
+#define ZT_TONE_MFR2_FWD_MAX ZT_TONE_MFR2_FWD_15
+
+enum {
+ ZT_TONE_MFR2_REV_1 = ZT_TONE_MFR2_REV_BASE,
+ ZT_TONE_MFR2_REV_2,
+ ZT_TONE_MFR2_REV_3,
+ ZT_TONE_MFR2_REV_4,
+ ZT_TONE_MFR2_REV_5,
+ ZT_TONE_MFR2_REV_6,
+ ZT_TONE_MFR2_REV_7,
+ ZT_TONE_MFR2_REV_8,
+ ZT_TONE_MFR2_REV_9,
+ ZT_TONE_MFR2_REV_10,
+ ZT_TONE_MFR2_REV_11,
+ ZT_TONE_MFR2_REV_12,
+ ZT_TONE_MFR2_REV_13,
+ ZT_TONE_MFR2_REV_14,
+ ZT_TONE_MFR2_REV_15,
};
-#define ZT_TONE_MF_MAX ZT_TONE_MF_C
+#define ZT_TONE_MFR2_REV_MAX ZT_TONE_MFR2_REV_15
#define ZT_MAX_CADENCE 16
@@ -1770,8 +1810,8 @@ void zt_alarm_notify(struct zt_span *span);
/* 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. */
-struct zt_tone *zt_dtmf_tone(const struct zt_chan *chan, char digit);
+/* Get a given MF tone struct, suitable for zt_tone_nextsample. */
+struct zt_tone *zt_mf_tone(const struct zt_chan *chan, char digit, int digitmode);
/* 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
diff --git a/tonezone.c b/tonezone.c
index 7c7d70e..f48cf88 100644
--- a/tonezone.c
+++ b/tonezone.c
@@ -234,7 +234,7 @@ struct mf_tone {
float f2; /* second freq */
};
-static struct mf_tone dtmf_dial[] = {
+static struct mf_tone dtmf_tones[] = {
{ ZT_TONE_DTMF_0, 941.0, 1336.0 },
{ ZT_TONE_DTMF_1, 697.0, 1209.0 },
{ ZT_TONE_DTMF_2, 697.0, 1336.0 },
@@ -254,22 +254,60 @@ static struct mf_tone dtmf_dial[] = {
{ 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''' */
+static struct mf_tone mfr1_tones[] = {
+ { ZT_TONE_MFR1_0, 1300.0, 1500.0 },
+ { ZT_TONE_MFR1_1, 700.0, 900.0 },
+ { ZT_TONE_MFR1_2, 700.0, 1100.0 },
+ { ZT_TONE_MFR1_3, 900.0, 1100.0 },
+ { ZT_TONE_MFR1_4, 700.0, 1300.0 },
+ { ZT_TONE_MFR1_5, 900.0, 1300.0 },
+ { ZT_TONE_MFR1_6, 1100.0, 1300.0 },
+ { ZT_TONE_MFR1_7, 700.0, 1500.0 },
+ { ZT_TONE_MFR1_8, 900.0, 1500.0 },
+ { ZT_TONE_MFR1_9, 1100.0, 1500.0 },
+ { ZT_TONE_MFR1_KP, 1100.0, 1700.0 }, /* KP */
+ { ZT_TONE_MFR1_ST, 1500.0, 1700.0 }, /* ST */
+ { ZT_TONE_MFR1_STP, 900.0, 1700.0 }, /* KP' or ST' */
+ { ZT_TONE_MFR1_ST2P, 1300.0, 1700.0 }, /* KP'' or ST'' */
+ { ZT_TONE_MFR1_ST3P, 700.0, 1700.0 }, /* KP''' or ST''' */
+ { 0, 0, 0 }
+};
+
+static struct mf_tone mfr2_fwd_tones[] = {
+ { ZT_TONE_MFR2_FWD_1, 1380.0, 1500.0 },
+ { ZT_TONE_MFR2_FWD_2, 1380.0, 1620.0 },
+ { ZT_TONE_MFR2_FWD_3, 1500.0, 1620.0 },
+ { ZT_TONE_MFR2_FWD_4, 1380.0, 1740.0 },
+ { ZT_TONE_MFR2_FWD_5, 1500.0, 1740.0 },
+ { ZT_TONE_MFR2_FWD_6, 1620.0, 1740.0 },
+ { ZT_TONE_MFR2_FWD_7, 1380.0, 1860.0 },
+ { ZT_TONE_MFR2_FWD_8, 1500.0, 1860.0 },
+ { ZT_TONE_MFR2_FWD_9, 1620.0, 1860.0 },
+ { ZT_TONE_MFR2_FWD_10, 1740.0, 1860.0 },
+ { ZT_TONE_MFR2_FWD_11, 1380.0, 1980.0 },
+ { ZT_TONE_MFR2_FWD_12, 1500.0, 1980.0 },
+ { ZT_TONE_MFR2_FWD_13, 1620.0, 1980.0 },
+ { ZT_TONE_MFR2_FWD_14, 1740.0, 1980.0 },
+ { ZT_TONE_MFR2_FWD_15, 1860.0, 1980.0 },
+ { 0, 0, 0 }
+};
+
+static struct mf_tone mfr2_rev_tones[] = {
+ { ZT_TONE_MFR2_REV_1, 1020.0, 1140.0 },
+ { ZT_TONE_MFR2_REV_2, 900.0, 1140.0 },
+ { ZT_TONE_MFR2_REV_3, 900.0, 1020.0 },
+ { ZT_TONE_MFR2_REV_4, 780.0, 1140.0 },
+ { ZT_TONE_MFR2_REV_5, 780.0, 1020.0 },
+ { ZT_TONE_MFR2_REV_6, 780.0, 900.0 },
+ { ZT_TONE_MFR2_REV_7, 660.0, 1140.0 },
+ { ZT_TONE_MFR2_REV_8, 660.0, 1020.0 },
+ { ZT_TONE_MFR2_REV_9, 660.0, 900.0 },
+ { ZT_TONE_MFR2_REV_10, 660.0, 780.0 },
+ { ZT_TONE_MFR2_REV_11, 540.0, 1140.0 },
+ { ZT_TONE_MFR2_REV_12, 540.0, 1020.0 },
+ { ZT_TONE_MFR2_REV_13, 540.0, 900.0 },
+ { ZT_TONE_MFR2_REV_14, 540.0, 780.0 },
+ { ZT_TONE_MFR2_REV_15, 540.0, 660.0 },
{ 0, 0, 0 }
};
@@ -346,15 +384,29 @@ int tone_zone_register_zone(int fd, struct tone_zone *z)
space -= res;
}
- if ((res = build_mf_tones(ptr, space, &count, dtmf_dial, z->dtmf_low_level, z->dtmf_high_level)) < 0) {
+ if ((res = build_mf_tones(ptr, space, &count, dtmf_tones, 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");
+ if ((res = build_mf_tones(ptr, space, &count, mfr1_tones, z->mfr1_level, z->mfr1_level)) < 0) {
+ fprintf(stderr, "Could not build MFR1 tones.\n");
+ return -1;
+ }
+ ptr += res;
+ space -= res;
+
+ if ((res = build_mf_tones(ptr, space, &count, mfr2_fwd_tones, z->mfr2_level, z->mfr2_level)) < 0) {
+ fprintf(stderr, "Could not build MFR2 FWD tones.\n");
+ return -1;
+ }
+ ptr += res;
+ space -= res;
+
+ if ((res = build_mf_tones(ptr, space, &count, mfr2_rev_tones, z->mfr2_level, z->mfr2_level)) < 0) {
+ fprintf(stderr, "Could not build MFR2 REV tones.\n");
return -1;
}
ptr += res;
diff --git a/tonezone.h b/tonezone.h
index f59940e..ca795f6 100644
--- a/tonezone.h
+++ b/tonezone.h
@@ -50,7 +50,8 @@ struct tone_zone {
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. */
+ int mfr1_level; /* Power level of MFR1, expressed in dBm0. */
+ int mfr2_level; /* Power level of MFR2, expressed in dBm0. */
};
extern struct tone_zone builtin_zones[];
diff --git a/zonedata.c b/zonedata.c
index 7889e70..7cb2938 100644
--- a/zonedata.c
+++ b/zonedata.c
@@ -44,7 +44,8 @@ struct tone_zone builtin_zones[] =
},
.dtmf_high_level = -10,
.dtmf_low_level = -10,
- .mf_level = -10,
+ .mfr1_level = -10,
+ .mfr2_level = -8,
},
{ .zone = 1,
.country = "au",
@@ -64,7 +65,8 @@ struct tone_zone builtin_zones[] =
},
.dtmf_high_level = -10,
.dtmf_low_level = -10,
- .mf_level = -10,
+ .mfr1_level = -10,
+ .mfr2_level = -8,
},
{ .zone = 2,
.country = "fr",
@@ -88,7 +90,8 @@ struct tone_zone builtin_zones[] =
},
.dtmf_high_level = -11,
.dtmf_low_level = -9,
- .mf_level = -7,
+ .mfr1_level = -7,
+ .mfr2_level = -8,
},
{ .zone = 3,
.country = "nl",
@@ -111,7 +114,8 @@ struct tone_zone builtin_zones[] =
},
.dtmf_high_level = -11,
.dtmf_low_level = -9,
- .mf_level = -7,
+ .mfr1_level = -7,
+ .mfr2_level = -8,
},
{ .zone = 4,
.country = "uk",
@@ -131,7 +135,8 @@ struct tone_zone builtin_zones[] =
},
.dtmf_high_level = -11,
.dtmf_low_level = -13,
- .mf_level = -7,
+ .mfr1_level = -7,
+ .mfr2_level = -8,
},
{ .zone = 5,
.country = "fi",
@@ -150,7 +155,8 @@ struct tone_zone builtin_zones[] =
},
.dtmf_high_level = -11,
.dtmf_low_level = -9,
- .mf_level = -7,
+ .mfr1_level = -7,
+ .mfr2_level = -8,
},
{ .zone = 6,
.country = "es",
@@ -169,7 +175,8 @@ struct tone_zone builtin_zones[] =
},
.dtmf_high_level = -11,
.dtmf_low_level = -13,
- .mf_level = -7,
+ .mfr1_level = -7,
+ .mfr2_level = -8,
},
{ .zone = 7,
.country = "jp",
@@ -188,7 +195,8 @@ struct tone_zone builtin_zones[] =
},
.dtmf_high_level = -7,
.dtmf_low_level = -7,
- .mf_level = -7,
+ .mfr1_level = -7,
+ .mfr2_level = -8,
},
{ .zone = 8,
.country = "no",
@@ -207,7 +215,8 @@ struct tone_zone builtin_zones[] =
},
.dtmf_high_level = -10,
.dtmf_low_level = -10,
- .mf_level = -10,
+ .mfr1_level = -10,
+ .mfr2_level = -8,
},
{ .zone = 9,
.country = "at",
@@ -228,7 +237,8 @@ struct tone_zone builtin_zones[] =
},
.dtmf_high_level = -10,
.dtmf_low_level = -10,
- .mf_level = -10,
+ .mfr1_level = -10,
+ .mfr2_level = -8,
},
{ .zone = 10,
.country = "nz",
@@ -247,7 +257,8 @@ struct tone_zone builtin_zones[] =
},
.dtmf_high_level = -11,
.dtmf_low_level = -9,
- .mf_level = -7,
+ .mfr1_level = -7,
+ .mfr2_level = -8,
},
{ .zone = 11,
.country = "it",
@@ -267,7 +278,8 @@ struct tone_zone builtin_zones[] =
},
.dtmf_high_level = -10,
.dtmf_low_level = -10,
- .mf_level = -10,
+ .mfr1_level = -10,
+ .mfr2_level = -8,
},
{ .zone = 12,
.country = "us-old",
@@ -286,7 +298,8 @@ struct tone_zone builtin_zones[] =
},
.dtmf_high_level = -10,
.dtmf_low_level = -10,
- .mf_level = -10,
+ .mfr1_level = -10,
+ .mfr2_level = -8,
},
{ .zone = 13,
.country = "gr",
@@ -305,7 +318,8 @@ struct tone_zone builtin_zones[] =
},
.dtmf_high_level = -10,
.dtmf_low_level = -10,
- .mf_level = -10,
+ .mfr1_level = -10,
+ .mfr2_level = -8,
},
{ .zone = 14,
.country = "tw",
@@ -324,7 +338,8 @@ struct tone_zone builtin_zones[] =
},
.dtmf_high_level = -11,
.dtmf_low_level = -9,
- .mf_level = -7,
+ .mfr1_level = -7,
+ .mfr2_level = -8,
},
{ .zone = 15,
.country = "cl",
@@ -343,7 +358,8 @@ struct tone_zone builtin_zones[] =
},
.dtmf_high_level = -10,
.dtmf_low_level = -10,
- .mf_level = -10,
+ .mfr1_level = -10,
+ .mfr2_level = -8,
},
{ .zone = 16,
.country = "se",
@@ -367,7 +383,8 @@ struct tone_zone builtin_zones[] =
},
.dtmf_high_level = -9,
.dtmf_low_level = -10,
- .mf_level = -7,
+ .mfr1_level = -7,
+ .mfr2_level = -8,
},
{ .zone = 17,
.country = "be",
@@ -389,7 +406,8 @@ struct tone_zone builtin_zones[] =
},
.dtmf_high_level = -10,
.dtmf_low_level = -10,
- .mf_level = -10,
+ .mfr1_level = -10,
+ .mfr2_level = -8,
},
{ .zone = 18,
.country = "sg",
@@ -411,7 +429,8 @@ struct tone_zone builtin_zones[] =
},
.dtmf_high_level = -11,
.dtmf_low_level = -9,
- .mf_level = -7,
+ .mfr1_level = -7,
+ .mfr2_level = -8,
},
{ .zone = 19,
.country = "il",
@@ -430,7 +449,8 @@ struct tone_zone builtin_zones[] =
},
.dtmf_high_level = -10,
.dtmf_low_level = -10,
- .mf_level = -10,
+ .mfr1_level = -10,
+ .mfr2_level = -8,
},
{ .zone = 20,
.country = "br",
@@ -448,7 +468,8 @@ struct tone_zone builtin_zones[] =
{ ZT_TONE_STUTTER, "350+440" } },
.dtmf_high_level = -10,
.dtmf_low_level = -12,
- .mf_level = -10,
+ .mfr1_level = -10,
+ .mfr2_level = -8,
},
{ .zone = 21,
.country = "hu",
@@ -469,7 +490,8 @@ struct tone_zone builtin_zones[] =
},
.dtmf_high_level = -10,
.dtmf_low_level = -10,
- .mf_level = -10,
+ .mfr1_level = -10,
+ .mfr2_level = -8,
},
{ .zone = 22,
.country = "lt",
@@ -492,7 +514,8 @@ struct tone_zone builtin_zones[] =
},
.dtmf_high_level = -10,
.dtmf_low_level = -10,
- .mf_level = -10,
+ .mfr1_level = -10,
+ .mfr2_level = -8,
},
{ .zone = 23,
.country = "pl",
@@ -515,7 +538,8 @@ struct tone_zone builtin_zones[] =
},
.dtmf_high_level = -10,
.dtmf_low_level = -10,
- .mf_level = -10,
+ .mfr1_level = -10,
+ .mfr2_level = -8,
},
{ .zone = 24,
.country = "za",
@@ -537,7 +561,8 @@ struct tone_zone builtin_zones[] =
},
.dtmf_high_level = -11,
.dtmf_low_level = -13,
- .mf_level = -7,
+ .mfr1_level = -7,
+ .mfr2_level = -8,
},
{ .zone = 25,
.country = "pt",
@@ -559,7 +584,8 @@ struct tone_zone builtin_zones[] =
},
.dtmf_high_level = -10,
.dtmf_low_level = -10,
- .mf_level = -10,
+ .mfr1_level = -10,
+ .mfr2_level = -8,
},
{ .zone = 26,
.country = "ee",
@@ -582,7 +608,8 @@ struct tone_zone builtin_zones[] =
},
.dtmf_high_level = -10,
.dtmf_low_level = -10,
- .mf_level = -10,
+ .mfr1_level = -10,
+ .mfr2_level = -8,
},
{ .zone = 27,
.country = "mx",
@@ -601,7 +628,8 @@ struct tone_zone builtin_zones[] =
},
.dtmf_high_level = -8,
.dtmf_low_level = -6,
- .mf_level = -7,
+ .mfr1_level = -7,
+ .mfr2_level = -8,
},
{ .zone = 28,
.country = "in",
@@ -625,7 +653,8 @@ struct tone_zone builtin_zones[] =
},
.dtmf_high_level = -10,
.dtmf_low_level = -10,
- .mf_level = -10,
+ .mfr1_level = -10,
+ .mfr2_level = -8,
},
{ .zone = 29,
.country = "de",
@@ -647,7 +676,8 @@ struct tone_zone builtin_zones[] =
},
.dtmf_high_level = -11,
.dtmf_low_level = -9,
- .mf_level = -7,
+ .mfr1_level = -7,
+ .mfr2_level = -8,
},
{ .zone = 30,
.country = "ch",
@@ -669,7 +699,8 @@ struct tone_zone builtin_zones[] =
},
.dtmf_high_level = -10,
.dtmf_low_level = -10,
- .mf_level = -10,
+ .mfr1_level = -10,
+ .mfr2_level = -8,
},
{ .zone = 31,
.country = "dk",
@@ -692,7 +723,8 @@ struct tone_zone builtin_zones[] =
},
.dtmf_high_level = -10,
.dtmf_low_level = -10,
- .mf_level = -10,
+ .mfr1_level = -10,
+ .mfr2_level = -8,
},
{ .zone = 32,
.country = "cz",
@@ -715,7 +747,8 @@ struct tone_zone builtin_zones[] =
},
.dtmf_high_level = -10,
.dtmf_low_level = -10,
- .mf_level = -10,
+ .mfr1_level = -10,
+ .mfr2_level = -8,
},
{ .zone = 33,
.country = "cn",
@@ -736,7 +769,8 @@ struct tone_zone builtin_zones[] =
},
.dtmf_high_level = -11,
.dtmf_low_level = -9,
- .mf_level = -7,
+ .mfr1_level = -7,
+ .mfr2_level = -8,
},
{ .zone = 34,
.country = "ar",
@@ -755,7 +789,8 @@ struct tone_zone builtin_zones[] =
},
.dtmf_high_level = -11,
.dtmf_low_level = -9,
- .mf_level = -7,
+ .mfr1_level = -7,
+ .mfr2_level = -8,
},
{ .zone = 35,
.country = "my",
@@ -774,7 +809,8 @@ struct tone_zone builtin_zones[] =
},
.dtmf_high_level = -10,
.dtmf_low_level = -10,
- .mf_level = -10,
+ .mfr1_level = -10,
+ .mfr2_level = -8,
},
{ .zone = 36,
.country = "th",
@@ -798,7 +834,8 @@ struct tone_zone builtin_zones[] =
},
.dtmf_high_level = -11,
.dtmf_low_level = -9,
- .mf_level = -7,
+ .mfr1_level = -7,
+ .mfr2_level = -8,
},
{ .zone = 37,
.country = "bg",
@@ -818,7 +855,8 @@ struct tone_zone builtin_zones[] =
},
.dtmf_high_level = -10,
.dtmf_low_level = -10,
- .mf_level = -10,
+ .mfr1_level = -10,
+ .mfr2_level = -8,
},
{ .zone = 38,
.country = "ve",
@@ -839,7 +877,8 @@ struct tone_zone builtin_zones[] =
},
.dtmf_high_level = -7,
.dtmf_low_level = -9,
- .mf_level = -7,
+ .mfr1_level = -7,
+ .mfr2_level = -8,
},
{ .zone = 39,
.country = "ph",
@@ -863,7 +902,8 @@ struct tone_zone builtin_zones[] =
},
.dtmf_high_level = -10,
.dtmf_low_level = -10,
- .mf_level = -10,
+ .mfr1_level = -10,
+ .mfr2_level = -8,
},
{ .zone = 40,
.country = "ru",
@@ -884,7 +924,8 @@ struct tone_zone builtin_zones[] =
},
.dtmf_high_level = -10,
.dtmf_low_level = -10,
- .mf_level = -10,
+ .mfr1_level = -10,
+ .mfr2_level = -8,
},
{ .zone = -1 }
};