New Feature for chan_dahdi. 4 length pattern matching.
In chan_dahdi.conf, the user can now use length 4 patterns in addition to the usual length 2 patterns. The s ntax remains the same and the method used to track the pattern history will only change when using the length 4 patterns. (closes issue SWP-3250) Code: jrose rmudgett git-svn-id: http://svn.digium.com/svn/asterisk/trunk@312384 f38db490-d61c-443f-a65b-d21fe96a405b
This commit is contained in:
parent
c855ea7dcb
commit
8f809d2963
5
CHANGES
5
CHANGES
|
@ -28,6 +28,11 @@ Asterisk HTTP Server
|
|||
--------------------------
|
||||
* The HTTP Server can bind to IPv6 addresses.
|
||||
|
||||
chan_dahdi
|
||||
--------------------------
|
||||
* Busy tone patterns featuring 2 silence and 2 tone lengths can now be used
|
||||
with busydetect. usage example: busypattern=200,200,200,600
|
||||
|
||||
CLI Changes
|
||||
--------------------------
|
||||
* New 'gtalk show settings' command showing the current settings loaded from
|
||||
|
|
|
@ -1115,15 +1115,10 @@ struct dahdi_pvt {
|
|||
*/
|
||||
int busycount;
|
||||
/*!
|
||||
* \brief Length of "busy" tone on time.
|
||||
* \note Set from the "busypattern" value read in from chan_dahdi.conf
|
||||
* \brief Busy cadence pattern description.
|
||||
* \note Set from the "busypattern" value read from chan_dahdi.conf
|
||||
*/
|
||||
int busy_tonelength;
|
||||
/*!
|
||||
* \brief Length of "busy" tone off time.
|
||||
* \note Set from the "busypattern" value read in from chan_dahdi.conf
|
||||
*/
|
||||
int busy_quietlength;
|
||||
struct ast_dsp_busy_pattern busy_cadence;
|
||||
/*!
|
||||
* \brief Bitmapped call progress detection flags. CALLPROGRESS_xxx values.
|
||||
* \note Bits set from the "callprogress" and "faxdetect" values read in from chan_dahdi.conf
|
||||
|
@ -9542,7 +9537,7 @@ static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpb
|
|||
ast_dsp_set_call_progress_zone(i->dsp, progzone);
|
||||
if (i->busydetect && CANBUSYDETECT(i)) {
|
||||
ast_dsp_set_busy_count(i->dsp, i->busycount);
|
||||
ast_dsp_set_busy_pattern(i->dsp, i->busy_tonelength, i->busy_quietlength);
|
||||
ast_dsp_set_busy_pattern(i->dsp, &i->busy_cadence);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12615,8 +12610,7 @@ static struct dahdi_pvt *mkintf(int channel, const struct dahdi_chan_conf *conf,
|
|||
}
|
||||
tmp->busydetect = conf->chan.busydetect;
|
||||
tmp->busycount = conf->chan.busycount;
|
||||
tmp->busy_tonelength = conf->chan.busy_tonelength;
|
||||
tmp->busy_quietlength = conf->chan.busy_quietlength;
|
||||
tmp->busy_cadence = conf->chan.busy_cadence;
|
||||
tmp->callprogress = conf->chan.callprogress;
|
||||
tmp->waitfordialtone = conf->chan.waitfordialtone;
|
||||
tmp->cancallforward = conf->chan.cancallforward;
|
||||
|
@ -15120,7 +15114,7 @@ static char *dahdi_show_channel(struct ast_cli_entry *e, int cmd, struct ast_cli
|
|||
ast_cli(a->fd, " Busy Detector Debug: Enabled\n");
|
||||
#endif
|
||||
ast_cli(a->fd, " Busy Count: %d\n", tmp->busycount);
|
||||
ast_cli(a->fd, " Busy Pattern: %d,%d\n", tmp->busy_tonelength, tmp->busy_quietlength);
|
||||
ast_cli(a->fd, " Busy Pattern: %d,%d,%d,%d\n", tmp->busy_cadence.pattern[0], tmp->busy_cadence.pattern[1], (tmp->busy_cadence.length == 4) ? tmp->busy_cadence.pattern[2] : 0, (tmp->busy_cadence.length == 4) ? tmp->busy_cadence.pattern[3] : 0);
|
||||
}
|
||||
ast_cli(a->fd, "TDD: %s\n", tmp->tdd ? "yes" : "no");
|
||||
ast_cli(a->fd, "Relax DTMF: %s\n", tmp->dtmfrelax ? "yes" : "no");
|
||||
|
@ -16664,6 +16658,40 @@ static unsigned long dahdi_display_text_option(const char *value)
|
|||
/*! process_dahdi() - No warnings on non-existing cofiguration keywords */
|
||||
#define PROC_DAHDI_OPT_NOWARN (1 << 1)
|
||||
|
||||
static void parse_busy_pattern(struct ast_variable *v, struct ast_dsp_busy_pattern *busy_cadence)
|
||||
{
|
||||
int count_pattern = 0;
|
||||
int norval = 0;
|
||||
char *temp = NULL;
|
||||
|
||||
for (; ;) {
|
||||
/* Scans the string for the next value in the pattern. If none, it checks to see if any have been entered so far. */
|
||||
if(!sscanf(v->value, "%30d", &norval) && count_pattern == 0) { ast_log(LOG_ERROR, "busypattern= expects either busypattern=tonelength,quietlength or busypattern=t1length, q1length, t2length, q2length at line %d.\n", v->lineno);
|
||||
break;
|
||||
}
|
||||
|
||||
busy_cadence->pattern[count_pattern] = norval;
|
||||
|
||||
count_pattern++;
|
||||
if (count_pattern == 4) {
|
||||
break;
|
||||
}
|
||||
|
||||
temp = strchr(v->value, ',');
|
||||
if (temp == NULL) {
|
||||
break;
|
||||
}
|
||||
v->value = temp + 1;
|
||||
}
|
||||
busy_cadence->length = count_pattern;
|
||||
|
||||
if (count_pattern % 2 != 0) {
|
||||
/* The pattern length must be divisible by two */
|
||||
ast_log(LOG_ERROR, "busypattern= expects either busypattern=tonelength,quietlength or busypattern=t1length, q1length, t2length, q2length at line %d.\n", v->lineno);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static int process_dahdi(struct dahdi_chan_conf *confp, const char *cat, struct ast_variable *v, int reload, int options)
|
||||
{
|
||||
struct dahdi_pvt *tmp;
|
||||
|
@ -16789,9 +16817,7 @@ static int process_dahdi(struct dahdi_chan_conf *confp, const char *cat, struct
|
|||
} else if (!strcasecmp(v->name, "busycount")) {
|
||||
confp->chan.busycount = atoi(v->value);
|
||||
} else if (!strcasecmp(v->name, "busypattern")) {
|
||||
if (sscanf(v->value, "%30d,%30d", &confp->chan.busy_tonelength, &confp->chan.busy_quietlength) != 2) {
|
||||
ast_log(LOG_ERROR, "busypattern= expects busypattern=tonelength,quietlength at line %d.\n", v->lineno);
|
||||
}
|
||||
parse_busy_pattern(v, &confp->chan.busy_cadence);
|
||||
} else if (!strcasecmp(v->name, "callprogress")) {
|
||||
confp->chan.callprogress &= ~CALLPROGRESS_PROGRESS;
|
||||
if (ast_true(v->value))
|
||||
|
|
|
@ -59,6 +59,13 @@
|
|||
|
||||
struct ast_dsp;
|
||||
|
||||
struct ast_dsp_busy_pattern {
|
||||
/*! Number of elements. */
|
||||
int length;
|
||||
/*! Pattern elements in on/off time durations. */
|
||||
int pattern[4];
|
||||
};
|
||||
|
||||
enum threshold {
|
||||
/* Array offsets */
|
||||
THRESHOLD_SILENCE = 0,
|
||||
|
@ -76,7 +83,7 @@ void ast_dsp_set_threshold(struct ast_dsp *dsp, int threshold);
|
|||
void ast_dsp_set_busy_count(struct ast_dsp *dsp, int cadences);
|
||||
|
||||
/*! \brief Set expected lengths of the busy tone */
|
||||
void ast_dsp_set_busy_pattern(struct ast_dsp *dsp, int tonelength, int quietlength);
|
||||
void ast_dsp_set_busy_pattern(struct ast_dsp *dsp, const struct ast_dsp_busy_pattern *cadence);
|
||||
|
||||
/*! \brief Scans for progress indication in audio */
|
||||
int ast_dsp_call_progress(struct ast_dsp *dsp, struct ast_frame *inf);
|
||||
|
|
68
main/dsp.c
68
main/dsp.c
|
@ -378,8 +378,7 @@ struct ast_dsp {
|
|||
int ringtimeout;
|
||||
int busymaybe;
|
||||
int busycount;
|
||||
int busy_tonelength;
|
||||
int busy_quietlength;
|
||||
struct ast_dsp_busy_pattern busy_cadence;
|
||||
int historicnoise[DSP_HISTORY];
|
||||
int historicsilence[DSP_HISTORY];
|
||||
goertzel_state_t freqs[7];
|
||||
|
@ -1183,9 +1182,14 @@ int ast_dsp_busydetect(struct ast_dsp *dsp)
|
|||
int avgsilence = 0, hitsilence = 0;
|
||||
#endif
|
||||
int avgtone = 0, hittone = 0;
|
||||
if (!dsp->busymaybe) {
|
||||
return res;
|
||||
|
||||
/* if we have a 4 length pattern, the way busymaybe is set doesn't help us. */
|
||||
if (dsp->busy_cadence.length != 4) {
|
||||
if (!dsp->busymaybe) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
for (x = DSP_HISTORY - dsp->busycount; x < DSP_HISTORY; x++) {
|
||||
#ifndef BUSYDETECT_TONEONLY
|
||||
avgsilence += dsp->historicsilence[x];
|
||||
|
@ -1239,23 +1243,60 @@ int ast_dsp_busydetect(struct ast_dsp *dsp)
|
|||
res = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* If we have a 4-length pattern, we can go ahead and just check it in a different way. */
|
||||
if (dsp->busy_cadence.length == 4) {
|
||||
int x;
|
||||
int errors = 0;
|
||||
int errors_max = ((4 * dsp->busycount) / 100.0) * BUSY_PAT_PERCENT;
|
||||
|
||||
for (x = DSP_HISTORY - (dsp->busycount); x < DSP_HISTORY; x += 2) {
|
||||
int temp_error;
|
||||
temp_error = abs(dsp->historicnoise[x] - dsp->busy_cadence.pattern[0]);
|
||||
if ((temp_error * 100) / dsp->busy_cadence.pattern[0] > BUSY_PERCENT) {
|
||||
errors++;
|
||||
}
|
||||
|
||||
temp_error = abs(dsp->historicnoise[x + 1] - dsp->busy_cadence.pattern[2]);
|
||||
if ((temp_error * 100) / dsp->busy_cadence.pattern[2] > BUSY_PERCENT) {
|
||||
errors++;
|
||||
}
|
||||
|
||||
temp_error = abs(dsp->historicsilence[x] - dsp->busy_cadence.pattern[1]);
|
||||
if ((temp_error * 100) / dsp->busy_cadence.pattern[1] > BUSY_PERCENT) {
|
||||
errors++;
|
||||
}
|
||||
|
||||
temp_error = abs(dsp->historicsilence[x + 1] - dsp->busy_cadence.pattern[3]);
|
||||
if ((temp_error * 100) / dsp->busy_cadence.pattern[3] > BUSY_PERCENT) {
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
|
||||
ast_debug(5, "errors = %d max = %d\n", errors, errors_max);
|
||||
|
||||
if (errors <= errors_max) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we know the expected busy tone length, check we are in the range */
|
||||
if (res && (dsp->busy_tonelength > 0)) {
|
||||
if (abs(avgtone - dsp->busy_tonelength) > (dsp->busy_tonelength*BUSY_PAT_PERCENT/100)) {
|
||||
if (res && (dsp->busy_cadence.pattern[0] > 0)) {
|
||||
if (abs(avgtone - dsp->busy_cadence.pattern[0]) > (dsp->busy_cadence.pattern[0]*BUSY_PAT_PERCENT/100)) {
|
||||
#ifdef BUSYDETECT_DEBUG
|
||||
ast_debug(5, "busy detector: avgtone of %d not close enough to desired %d\n",
|
||||
avgtone, dsp->busy_tonelength);
|
||||
avgtone, dsp->busy_cadence.pattern[0]);
|
||||
#endif
|
||||
res = 0;
|
||||
}
|
||||
}
|
||||
#ifndef BUSYDETECT_TONEONLY
|
||||
/* If we know the expected busy tone silent-period length, check we are in the range */
|
||||
if (res && (dsp->busy_quietlength > 0)) {
|
||||
if (abs(avgsilence - dsp->busy_quietlength) > (dsp->busy_quietlength*BUSY_PAT_PERCENT/100)) {
|
||||
if (res && (dsp->busy_cadence.pattern[1] > 0)) {
|
||||
if (abs(avgsilence - dsp->busy_cadence.pattern[1]) > (dsp->busy_cadence.pattern[1] * BUSY_PAT_PERCENT / 100)) {
|
||||
#ifdef BUSYDETECT_DEBUG
|
||||
ast_debug(5, "busy detector: avgsilence of %d not close enough to desired %d\n",
|
||||
avgsilence, dsp->busy_quietlength);
|
||||
avgsilence, dsp->busy_cadence.pattern[1]);
|
||||
#endif
|
||||
res = 0;
|
||||
}
|
||||
|
@ -1571,11 +1612,10 @@ void ast_dsp_set_busy_count(struct ast_dsp *dsp, int cadences)
|
|||
dsp->busycount = cadences;
|
||||
}
|
||||
|
||||
void ast_dsp_set_busy_pattern(struct ast_dsp *dsp, int tonelength, int quietlength)
|
||||
void ast_dsp_set_busy_pattern(struct ast_dsp *dsp, const struct ast_dsp_busy_pattern *cadence)
|
||||
{
|
||||
dsp->busy_tonelength = tonelength;
|
||||
dsp->busy_quietlength = quietlength;
|
||||
ast_debug(1, "dsp busy pattern set to %d,%d\n", tonelength, quietlength);
|
||||
dsp->busy_cadence = *cadence;
|
||||
ast_debug(1, "dsp busy pattern set to %d,%d,%d,%d\n", cadence->pattern[0], cadence->pattern[1], (cadence->length == 4) ? cadence->pattern[2] : 0, (cadence->length == 4) ? cadence->pattern[3] : 0);
|
||||
}
|
||||
|
||||
void ast_dsp_digitreset(struct ast_dsp *dsp)
|
||||
|
|
Reference in New Issue