From 57544543646a83e92555be35b6096928d41b721e Mon Sep 17 00:00:00 2001 From: kpfleming Date: Fri, 21 Mar 2008 23:30:41 +0000 Subject: 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 --- kernel/digits.h | 13 ++- kernel/wcusb.c | 2 +- kernel/zaptel-base.c | 303 +++++++++++++++++++++++++++++++++++++-------------- kernel/zaptel.h | 102 +++++++++++------ tonezone.c | 92 ++++++++++++---- tonezone.h | 3 +- zonedata.c | 123 ++++++++++++++------- 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 } }; -- cgit v1.2.3