mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-01 18:09:41 +00:00
Add an option, waitfordialtone, for UK analog lines which do not end a call
until the originating line hangs up. (closes issue #12382) Reported by: one47 Patches: zap-waitfordialtone-trunk.080901.patch uploaded by one47 (license 23) zap-waitfordialtone-bra-1.4.21.2.patch uploaded by fleed (license 463) Tested by: fleed git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@159317 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
5
CHANGES
5
CHANGES
@@ -32,6 +32,11 @@ Skinny Changes
|
||||
Please have a look at configs/skinny.conf.sample and change your skinny.conf
|
||||
accordingly.
|
||||
|
||||
DAHDI Changes
|
||||
-------------
|
||||
* The UK option waitfordialtone has been added for use with BT analog
|
||||
lines.
|
||||
|
||||
Dialplan Functions
|
||||
------------------
|
||||
* Added a new dialplan function, CURLOPT, which permits setting various
|
||||
|
@@ -712,6 +712,8 @@ static struct dahdi_pvt {
|
||||
int busy_tonelength;
|
||||
int busy_quietlength;
|
||||
int callprogress;
|
||||
int waitfordialtone;
|
||||
struct timeval waitingfordt; /*!< Time we started waiting for dialtone */
|
||||
struct timeval flashtime; /*!< Last flash-hook time */
|
||||
struct ast_dsp *dsp;
|
||||
int cref; /*!< Call reference number */
|
||||
@@ -2182,6 +2184,7 @@ static int dahdi_call(struct ast_channel *ast, char *rdest, int timeout)
|
||||
ast_mutex_unlock(&p->lock);
|
||||
return -1;
|
||||
}
|
||||
p->waitingfordt.tv_sec = 0;
|
||||
p->dialednone = 0;
|
||||
if ((p->radio || (p->oprmode < 0))) /* if a radio channel, up immediately */
|
||||
{
|
||||
@@ -2405,6 +2408,20 @@ static int dahdi_call(struct ast_channel *ast, char *rdest, int timeout)
|
||||
p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0';
|
||||
} else
|
||||
p->echobreak = 0;
|
||||
|
||||
/* waitfordialtone ? */
|
||||
#ifdef HAVE_PRI
|
||||
if (!p->pri) {
|
||||
#endif
|
||||
if( p->waitfordialtone && CANPROGRESSDETECT(p) && p->dsp ) {
|
||||
ast_log(LOG_DEBUG, "Defer dialling for %dms or dialtone\n", p->waitfordialtone);
|
||||
gettimeofday(&p->waitingfordt,NULL);
|
||||
ast_setstate(ast, AST_STATE_OFFHOOK);
|
||||
break;
|
||||
}
|
||||
#ifdef HAVE_PRI
|
||||
}
|
||||
#endif
|
||||
if (!res) {
|
||||
if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop)) {
|
||||
int saveerr = errno;
|
||||
@@ -3446,6 +3463,7 @@ static int dahdi_hangup(struct ast_channel *ast)
|
||||
p->callwaitcas = 0;
|
||||
p->callwaiting = p->permcallwaiting;
|
||||
p->hidecallerid = p->permhidecallerid;
|
||||
p->waitingfordt.tv_sec = 0;
|
||||
p->dialing = 0;
|
||||
p->rdnis[0] = '\0';
|
||||
update_conf(p);
|
||||
@@ -5183,6 +5201,7 @@ static struct ast_frame *dahdi_handle_event(struct ast_channel *ast)
|
||||
case DAHDI_EVENT_HOOKCOMPLETE:
|
||||
if (p->inalarm) break;
|
||||
if ((p->radio || (p->oprmode < 0))) break;
|
||||
if (p->waitingfordt.tv_sec) break;
|
||||
switch (mysig) {
|
||||
case SIG_FXSLS: /* only interesting for FXS */
|
||||
case SIG_FXSGS:
|
||||
@@ -5639,8 +5658,8 @@ static struct ast_frame *dahdi_read(struct ast_channel *ast)
|
||||
p->subs[idx].f.data.ptr = NULL;
|
||||
p->subs[idx].f.datalen= 0;
|
||||
}
|
||||
if (p->dsp && (!p->ignoredtmf || p->callwaitcas || p->busydetect || p->callprogress) && !idx) {
|
||||
/* Perform busy detection. etc on the dahdi line */
|
||||
if (p->dsp && (!p->ignoredtmf || p->callwaitcas || p->busydetect || p->callprogress || p->waitingfordt.tv_sec) && !idx) {
|
||||
/* Perform busy detection etc on the dahdi line */
|
||||
int mute;
|
||||
|
||||
f = ast_dsp_process(ast, p->dsp, &p->subs[idx].f);
|
||||
@@ -5671,6 +5690,35 @@ static struct ast_frame *dahdi_read(struct ast_channel *ast)
|
||||
#endif
|
||||
/* DSP clears us of being pulse */
|
||||
p->pulsedial = 0;
|
||||
} else if (p->waitingfordt.tv_sec) {
|
||||
if (ast_tvdiff_ms(ast_tvnow(), p->waitingfordt) >= p->waitfordialtone ) {
|
||||
p->waitingfordt.tv_sec = 0;
|
||||
ast_log(LOG_WARNING, "Never saw dialtone on channel %d\n", p->channel);
|
||||
f=NULL;
|
||||
} else if (f->frametype == AST_FRAME_VOICE) {
|
||||
f->frametype = AST_FRAME_NULL;
|
||||
f->subclass = 0;
|
||||
if ((ast_dsp_get_tstate(p->dsp) == DSP_TONE_STATE_DIALTONE || ast_dsp_get_tstate(p->dsp) == DSP_TONE_STATE_RINGING) && ast_dsp_get_tcount(p->dsp) > 9) {
|
||||
p->waitingfordt.tv_sec = 0;
|
||||
p->dsp_features &= ~DSP_FEATURE_WAITDIALTONE;
|
||||
ast_dsp_set_features(p->dsp, p->dsp_features);
|
||||
ast_log(LOG_DEBUG, "Got 10 samples of dialtone!\n");
|
||||
if (!ast_strlen_zero(p->dop.dialstr)) { /* Dial deferred digits */
|
||||
res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop);
|
||||
if (res < 0) {
|
||||
ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel);
|
||||
p->dop.dialstr[0] = '\0';
|
||||
return NULL;
|
||||
} else {
|
||||
ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr);
|
||||
p->dialing = 1;
|
||||
p->dop.dialstr[0] = '\0';
|
||||
p->dop.op = DAHDI_DIAL_OP_REPLACE;
|
||||
ast_setstate(ast, AST_STATE_DIALING);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else
|
||||
@@ -6094,6 +6142,8 @@ static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpb
|
||||
features |= DSP_FEATURE_BUSY_DETECT;
|
||||
if ((i->callprogress & CALLPROGRESS_PROGRESS) && CANPROGRESSDETECT(i))
|
||||
features |= DSP_FEATURE_CALL_PROGRESS;
|
||||
if ((i->waitfordialtone) && CANPROGRESSDETECT(i))
|
||||
features |= DSP_FEATURE_WAITDIALTONE;
|
||||
if ((!i->outgoing && (i->callprogress & CALLPROGRESS_FAX_INCOMING)) ||
|
||||
(i->outgoing && (i->callprogress & CALLPROGRESS_FAX_OUTGOING))) {
|
||||
features |= DSP_FEATURE_FAX_DETECT;
|
||||
@@ -8809,6 +8859,7 @@ static struct dahdi_pvt *mkintf(int channel, const struct dahdi_chan_conf *conf,
|
||||
tmp->busy_tonelength = conf->chan.busy_tonelength;
|
||||
tmp->busy_quietlength = conf->chan.busy_quietlength;
|
||||
tmp->callprogress = conf->chan.callprogress;
|
||||
tmp->waitfordialtone = conf->chan.waitfordialtone;
|
||||
tmp->cancallforward = conf->chan.cancallforward;
|
||||
tmp->dtmfrelax = conf->chan.dtmfrelax;
|
||||
tmp->callwaiting = tmp->permcallwaiting;
|
||||
@@ -12471,6 +12522,7 @@ static char *dahdi_show_channel(struct ast_cli_entry *e, int cmd, struct ast_cli
|
||||
} else {
|
||||
ast_cli(a->fd, "\tnone\n");
|
||||
}
|
||||
ast_cli(a->fd, "Wait for dialtone: %dms\n", tmp->waitfordialtone);
|
||||
if (tmp->master)
|
||||
ast_cli(a->fd, "Master Channel: %d\n", tmp->master->channel);
|
||||
for (x = 0; x < MAX_SLAVES; x++) {
|
||||
@@ -13917,6 +13969,8 @@ static int process_dahdi(struct dahdi_chan_conf *confp, const char *cat, struct
|
||||
confp->chan.callprogress &= ~CALLPROGRESS_PROGRESS;
|
||||
if (ast_true(v->value))
|
||||
confp->chan.callprogress |= CALLPROGRESS_PROGRESS;
|
||||
} else if (!strcasecmp(v->name, "waitfordialtone")) {
|
||||
confp->chan.waitfordialtone = atoi(v->value);
|
||||
} else if (!strcasecmp(v->name, "faxdetect")) {
|
||||
confp->chan.callprogress &= ~CALLPROGRESS_FAX;
|
||||
if (!strcasecmp(v->value, "incoming")) {
|
||||
|
@@ -361,6 +361,13 @@ usecallerid=yes
|
||||
;
|
||||
;hidecallerid=yes
|
||||
;
|
||||
; On UK analog lines, the caller hanging up determines the end of calls. So
|
||||
; Asterisk hanging up the line may or may not end a call (DAHDI could just as
|
||||
; easily be re-attaching to a prior incoming call that was not yet hung up).
|
||||
; This option changes the hangup to wait for a dialtone on the line, before
|
||||
; marking the line as once again available for use with outgoing calls.
|
||||
;waitfordialtone=yes
|
||||
;
|
||||
; The following option enables receiving MWI on FXO lines. The default
|
||||
; value is no. When this is enabled, and MWI notification indicates on or off,
|
||||
; the script specified by the mwimonitornotify option is executed. Also, an
|
||||
|
@@ -41,6 +41,7 @@
|
||||
#define DSP_PROGRESS_BUSY (1 << 18) /*!< Enable busy tone detection */
|
||||
#define DSP_PROGRESS_CONGESTION (1 << 19) /*!< Enable congestion tone detection */
|
||||
#define DSP_FEATURE_CALL_PROGRESS (DSP_PROGRESS_TALK | DSP_PROGRESS_RINGING | DSP_PROGRESS_BUSY | DSP_PROGRESS_CONGESTION)
|
||||
#define DSP_FEATURE_WAITDIALTONE (1 << 20) /*!< Enable dial tone detection */
|
||||
|
||||
#define DSP_FAXMODE_DETECT_CNG (1 << 0)
|
||||
#define DSP_FAXMODE_DETECT_CED (1 << 1)
|
||||
|
155
main/dsp.c
155
main/dsp.c
@@ -82,7 +82,9 @@ enum freq_index {
|
||||
HZ_425 = 0,
|
||||
|
||||
/*! For UK mode */
|
||||
HZ_400 = 0
|
||||
HZ_350UK = 0,
|
||||
HZ_400UK,
|
||||
HZ_440UK
|
||||
};
|
||||
|
||||
static struct progalias {
|
||||
@@ -102,7 +104,7 @@ static struct progress {
|
||||
} modes[] = {
|
||||
{ GSAMP_SIZE_NA, { 350, 440, 480, 620, 950, 1400, 1800 } }, /*!< North America */
|
||||
{ GSAMP_SIZE_CR, { 425 } }, /*!< Costa Rica, Brazil */
|
||||
{ GSAMP_SIZE_UK, { 400 } }, /*!< UK */
|
||||
{ GSAMP_SIZE_UK, { 350, 400, 440 } }, /*!< UK */
|
||||
};
|
||||
|
||||
/*!\brief This value is the minimum threshold, calculated by averaging all
|
||||
@@ -322,9 +324,10 @@ static inline void goertzel_update(goertzel_state_t *s, short *samps, int count)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0;i<count;i++)
|
||||
for (i = 0; i < count; i++) {
|
||||
goertzel_sample(s, samps[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static inline float goertzel_result(goertzel_state_t *s)
|
||||
@@ -511,11 +514,12 @@ static void ast_digit_detect_init(digit_detect_state_t *s, int mf)
|
||||
s->lost_digits = 0;
|
||||
s->digits[0] = '\0';
|
||||
|
||||
if (mf)
|
||||
if (mf) {
|
||||
ast_mf_detect_init(&s->td.mf);
|
||||
else
|
||||
} else {
|
||||
ast_dtmf_detect_init(&s->td.dtmf);
|
||||
}
|
||||
}
|
||||
|
||||
static int tone_detect(struct ast_dsp *dsp, tone_detect_state_t *s, int16_t *amp, int samples)
|
||||
{
|
||||
@@ -536,8 +540,9 @@ static int tone_detect(struct ast_dsp *dsp, tone_detect_state_t *s, int16_t *amp
|
||||
for (start = 0; start < samples; start = end) {
|
||||
/* Process in blocks. */
|
||||
limit = samples - start;
|
||||
if (limit > s->samples_pending)
|
||||
if (limit > s->samples_pending) {
|
||||
limit = s->samples_pending;
|
||||
}
|
||||
end = start + limit;
|
||||
|
||||
for (i = limit, ptr = amp ; i > 0; i--, ptr++) {
|
||||
@@ -567,8 +572,9 @@ static int tone_detect(struct ast_dsp *dsp, tone_detect_state_t *s, int16_t *amp
|
||||
hit = 1;
|
||||
}
|
||||
|
||||
if (s->hit_count)
|
||||
if (s->hit_count) {
|
||||
s->hit_count++;
|
||||
}
|
||||
|
||||
if (hit == s->last_hit) {
|
||||
if (!hit) {
|
||||
@@ -653,10 +659,11 @@ static int dtmf_detect(struct ast_dsp *dsp, digit_detect_state_t *s, int16_t amp
|
||||
hit = 0;
|
||||
for (sample = 0; sample < samples; sample = limit) {
|
||||
/* DTMF_GSIZE is optimised to meet the DTMF specs. */
|
||||
if ((samples - sample) >= (DTMF_GSIZE - s->td.dtmf.current_sample))
|
||||
if ((samples - sample) >= (DTMF_GSIZE - s->td.dtmf.current_sample)) {
|
||||
limit = sample + (DTMF_GSIZE - s->td.dtmf.current_sample);
|
||||
else
|
||||
} else {
|
||||
limit = samples;
|
||||
}
|
||||
/* The following unrolled loop takes only 35% (rough estimate) of the
|
||||
time of a rolled loop on the machine on which it was developed */
|
||||
for (j = sample; j < limit; j++) {
|
||||
@@ -684,12 +691,14 @@ static int dtmf_detect(struct ast_dsp *dsp, digit_detect_state_t *s, int16_t amp
|
||||
|
||||
for (best_row = best_col = 0, i = 1; i < 4; i++) {
|
||||
row_energy[i] = goertzel_result (&s->td.dtmf.row_out[i]);
|
||||
if (row_energy[i] > row_energy[best_row])
|
||||
if (row_energy[i] > row_energy[best_row]) {
|
||||
best_row = i;
|
||||
}
|
||||
col_energy[i] = goertzel_result (&s->td.dtmf.col_out[i]);
|
||||
if (col_energy[i] > col_energy[best_col])
|
||||
if (col_energy[i] > col_energy[best_col]) {
|
||||
best_col = i;
|
||||
}
|
||||
}
|
||||
hit = 0;
|
||||
/* Basic signal level test and the twist test */
|
||||
if (row_energy[best_row] >= DTMF_THRESHOLD &&
|
||||
@@ -800,10 +809,11 @@ static int mf_detect(struct ast_dsp *dsp, digit_detect_state_t *s, int16_t amp[]
|
||||
for (sample = 0; sample < samples; sample = limit) {
|
||||
/* 80 is optimised to meet the MF specs. */
|
||||
/* XXX So then why is MF_GSIZE defined as 120? */
|
||||
if ((samples - sample) >= (MF_GSIZE - s->td.mf.current_sample))
|
||||
if ((samples - sample) >= (MF_GSIZE - s->td.mf.current_sample)) {
|
||||
limit = sample + (MF_GSIZE - s->td.mf.current_sample);
|
||||
else
|
||||
} else {
|
||||
limit = samples;
|
||||
}
|
||||
/* The following unrolled loop takes only 35% (rough estimate) of the
|
||||
time of a rolled loop on the machine on which it was developed */
|
||||
for (j = sample; j < limit; j++) {
|
||||
@@ -930,18 +940,21 @@ static inline int pair_there(float p1, float p2, float i1, float i2, float e)
|
||||
{
|
||||
/* See if p1 and p2 are there, relative to i1 and i2 and total energy */
|
||||
/* Make sure absolute levels are high enough */
|
||||
if ((p1 < TONE_MIN_THRESH) || (p2 < TONE_MIN_THRESH))
|
||||
if ((p1 < TONE_MIN_THRESH) || (p2 < TONE_MIN_THRESH)) {
|
||||
return 0;
|
||||
}
|
||||
/* Amplify ignored stuff */
|
||||
i2 *= TONE_THRESH;
|
||||
i1 *= TONE_THRESH;
|
||||
e *= TONE_THRESH;
|
||||
/* Check first tone */
|
||||
if ((p1 < i1) || (p1 < i2) || (p1 < e))
|
||||
if ((p1 < i1) || (p1 < i2) || (p1 < e)) {
|
||||
return 0;
|
||||
}
|
||||
/* And second */
|
||||
if ((p2 < i1) || (p2 < i2) || (p2 < e))
|
||||
if ((p2 < i1) || (p2 < i2) || (p2 < e)) {
|
||||
return 0;
|
||||
}
|
||||
/* Guess it's there... */
|
||||
return 1;
|
||||
}
|
||||
@@ -956,11 +969,13 @@ static int __ast_dsp_call_progress(struct ast_dsp *dsp, short *s, int len)
|
||||
while (len) {
|
||||
/* Take the lesser of the number of samples we need and what we have */
|
||||
pass = len;
|
||||
if (pass > dsp->gsamp_size - dsp->gsamps)
|
||||
if (pass > dsp->gsamp_size - dsp->gsamps) {
|
||||
pass = dsp->gsamp_size - dsp->gsamps;
|
||||
}
|
||||
for (x = 0; x < pass; x++) {
|
||||
for (y=0;y<dsp->freqcount;y++)
|
||||
for (y = 0; y < dsp->freqcount; y++) {
|
||||
goertzel_sample(&dsp->freqs[y], s[x]);
|
||||
}
|
||||
dsp->genergy += s[x] * s[x];
|
||||
}
|
||||
s += pass;
|
||||
@@ -968,8 +983,9 @@ static int __ast_dsp_call_progress(struct ast_dsp *dsp, short *s, int len)
|
||||
len -= pass;
|
||||
if (dsp->gsamps == dsp->gsamp_size) {
|
||||
float hz[7];
|
||||
for (y=0;y<7;y++)
|
||||
for (y = 0; y < 7; y++) {
|
||||
hz[y] = goertzel_result(&dsp->freqs[y]);
|
||||
}
|
||||
switch (dsp->progmode) {
|
||||
case PROG_MODE_NA:
|
||||
if (pair_there(hz[HZ_480], hz[HZ_620], hz[HZ_350], hz[HZ_440], dsp->genergy)) {
|
||||
@@ -984,24 +1000,29 @@ static int __ast_dsp_call_progress(struct ast_dsp *dsp, short *s, int len)
|
||||
if (dsp->tstate == DSP_TONE_STATE_SPECIAL1)
|
||||
newstate = DSP_TONE_STATE_SPECIAL2;
|
||||
} else if (hz[HZ_1800] > TONE_MIN_THRESH * TONE_THRESH) {
|
||||
if (dsp->tstate == DSP_TONE_STATE_SPECIAL2)
|
||||
if (dsp->tstate == DSP_TONE_STATE_SPECIAL2) {
|
||||
newstate = DSP_TONE_STATE_SPECIAL3;
|
||||
}
|
||||
} else if (dsp->genergy > TONE_MIN_THRESH * TONE_THRESH) {
|
||||
newstate = DSP_TONE_STATE_TALKING;
|
||||
} else
|
||||
} else {
|
||||
newstate = DSP_TONE_STATE_SILENCE;
|
||||
}
|
||||
break;
|
||||
case PROG_MODE_CR:
|
||||
if (hz[HZ_425] > TONE_MIN_THRESH * TONE_THRESH) {
|
||||
newstate = DSP_TONE_STATE_RINGING;
|
||||
} else if (dsp->genergy > TONE_MIN_THRESH * TONE_THRESH) {
|
||||
newstate = DSP_TONE_STATE_TALKING;
|
||||
} else
|
||||
} else {
|
||||
newstate = DSP_TONE_STATE_SILENCE;
|
||||
}
|
||||
break;
|
||||
case PROG_MODE_UK:
|
||||
if (hz[HZ_400] > TONE_MIN_THRESH * TONE_THRESH) {
|
||||
if (hz[HZ_400UK] > TONE_MIN_THRESH * TONE_THRESH) {
|
||||
newstate = DSP_TONE_STATE_HUNGUP;
|
||||
} else if (pair_there(hz[HZ_350UK], hz[HZ_440UK], hz[HZ_400UK], hz[HZ_400UK], dsp->genergy)) {
|
||||
newstate = DSP_TONE_STATE_DIALTONE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -1009,8 +1030,9 @@ static int __ast_dsp_call_progress(struct ast_dsp *dsp, short *s, int len)
|
||||
}
|
||||
if (newstate == dsp->tstate) {
|
||||
dsp->tcount++;
|
||||
if (dsp->ringtimeout)
|
||||
if (dsp->ringtimeout) {
|
||||
dsp->ringtimeout++;
|
||||
}
|
||||
switch (dsp->tstate) {
|
||||
case DSP_TONE_STATE_RINGING:
|
||||
if ((dsp->features & DSP_PROGRESS_RINGING) &&
|
||||
@@ -1061,8 +1083,9 @@ static int __ast_dsp_call_progress(struct ast_dsp *dsp, short *s, int len)
|
||||
}
|
||||
|
||||
/* Reset goertzel */
|
||||
for (x=0;x<7;x++)
|
||||
for (x = 0; x < 7; x++) {
|
||||
dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
|
||||
}
|
||||
dsp->gsamps = 0;
|
||||
dsp->genergy = 0.0;
|
||||
}
|
||||
@@ -1090,11 +1113,13 @@ static int __ast_dsp_silence_noise(struct ast_dsp *dsp, short *s, int len, int *
|
||||
int x;
|
||||
int res = 0;
|
||||
|
||||
if (!len)
|
||||
if (!len) {
|
||||
return 0;
|
||||
}
|
||||
accum = 0;
|
||||
for (x=0;x<len; x++)
|
||||
for (x = 0; x < len; x++) {
|
||||
accum += abs(s[x]);
|
||||
}
|
||||
accum /= len;
|
||||
if (accum < dsp->threshold) {
|
||||
/* Silent */
|
||||
@@ -1121,23 +1146,27 @@ static int __ast_dsp_silence_noise(struct ast_dsp *dsp, short *s, int len, int *
|
||||
dsp->historicsilence[DSP_HISTORY - 1] = dsp->totalsilence;
|
||||
/* check if the previous sample differs only by BUSY_PERCENT from the one before it */
|
||||
if (silence1 < silence2) {
|
||||
if (silence1 + silence1*BUSY_PERCENT/100 >= silence2)
|
||||
if (silence1 + silence1 * BUSY_PERCENT / 100 >= silence2) {
|
||||
dsp->busymaybe = 1;
|
||||
else
|
||||
dsp->busymaybe = 0;
|
||||
} else {
|
||||
if (silence1 - silence1*BUSY_PERCENT/100 <= silence2)
|
||||
dsp->busymaybe = 1;
|
||||
else
|
||||
dsp->busymaybe = 0;
|
||||
}
|
||||
} else {
|
||||
if (silence1 - silence1 * BUSY_PERCENT / 100 <= silence2) {
|
||||
dsp->busymaybe = 1;
|
||||
} else {
|
||||
dsp->busymaybe = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
dsp->totalsilence = 0;
|
||||
}
|
||||
if (totalsilence)
|
||||
if (totalsilence) {
|
||||
*totalsilence = dsp->totalsilence;
|
||||
if (totalnoise)
|
||||
}
|
||||
if (totalnoise) {
|
||||
*totalnoise = dsp->totalnoise;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -1148,8 +1177,9 @@ int ast_dsp_busydetect(struct ast_dsp *dsp)
|
||||
int avgsilence = 0, hitsilence = 0;
|
||||
#endif
|
||||
int avgtone = 0, hittone = 0;
|
||||
if (!dsp->busymaybe)
|
||||
if (!dsp->busymaybe) {
|
||||
return res;
|
||||
}
|
||||
for (x = DSP_HISTORY - dsp->busycount; x < DSP_HISTORY; x++) {
|
||||
#ifndef BUSYDETECT_TONEONLY
|
||||
avgsilence += dsp->historicsilence[x];
|
||||
@@ -1163,21 +1193,25 @@ int ast_dsp_busydetect(struct ast_dsp *dsp)
|
||||
for (x = DSP_HISTORY - dsp->busycount; x < DSP_HISTORY; x++) {
|
||||
#ifndef BUSYDETECT_TONEONLY
|
||||
if (avgsilence > dsp->historicsilence[x]) {
|
||||
if (avgsilence - (avgsilence*BUSY_PERCENT/100) <= dsp->historicsilence[x])
|
||||
if (avgsilence - (avgsilence * BUSY_PERCENT / 100) <= dsp->historicsilence[x]) {
|
||||
hitsilence++;
|
||||
}
|
||||
} else {
|
||||
if (avgsilence + (avgsilence*BUSY_PERCENT/100) >= dsp->historicsilence[x])
|
||||
if (avgsilence + (avgsilence * BUSY_PERCENT / 100) >= dsp->historicsilence[x]) {
|
||||
hitsilence++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (avgtone > dsp->historicnoise[x]) {
|
||||
if (avgtone - (avgtone*BUSY_PERCENT/100) <= dsp->historicnoise[x])
|
||||
if (avgtone - (avgtone * BUSY_PERCENT / 100) <= dsp->historicnoise[x]) {
|
||||
hittone++;
|
||||
}
|
||||
} else {
|
||||
if (avgtone + (avgtone*BUSY_PERCENT/100) >= dsp->historicnoise[x])
|
||||
if (avgtone + (avgtone * BUSY_PERCENT / 100) >= dsp->historicnoise[x]) {
|
||||
hittone++;
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifndef BUSYDETECT_TONEONLY
|
||||
if ((hittone >= dsp->busycount - 1) && (hitsilence >= dsp->busycount - 1) &&
|
||||
(avgtone >= BUSY_MIN && avgtone <= BUSY_MAX) &&
|
||||
@@ -1187,12 +1221,14 @@ int ast_dsp_busydetect(struct ast_dsp *dsp)
|
||||
#endif
|
||||
#ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE
|
||||
if (avgtone > avgsilence) {
|
||||
if (avgtone - avgtone*BUSY_PERCENT/100 <= avgsilence)
|
||||
if (avgtone - avgtone*BUSY_PERCENT/100 <= avgsilence) {
|
||||
res = 1;
|
||||
}
|
||||
} else {
|
||||
if (avgtone + avgtone*BUSY_PERCENT/100 >= avgsilence)
|
||||
if (avgtone + avgtone*BUSY_PERCENT/100 >= avgsilence) {
|
||||
res = 1;
|
||||
}
|
||||
}
|
||||
#else
|
||||
res = 1;
|
||||
#endif
|
||||
@@ -1277,10 +1313,12 @@ struct ast_frame *ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp,
|
||||
int len;
|
||||
struct ast_frame *outf = NULL;
|
||||
|
||||
if (!af)
|
||||
if (!af) {
|
||||
return NULL;
|
||||
if (af->frametype != AST_FRAME_VOICE)
|
||||
}
|
||||
if (af->frametype != AST_FRAME_VOICE) {
|
||||
return af;
|
||||
}
|
||||
|
||||
odata = af->data.ptr;
|
||||
len = af->datalen;
|
||||
@@ -1292,13 +1330,15 @@ struct ast_frame *ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp,
|
||||
break;
|
||||
case AST_FORMAT_ULAW:
|
||||
shortdata = alloca(af->datalen * 2);
|
||||
for (x = 0;x < len; x++)
|
||||
for (x = 0;x < len; x++) {
|
||||
shortdata[x] = AST_MULAW(odata[x]);
|
||||
}
|
||||
break;
|
||||
case AST_FORMAT_ALAW:
|
||||
shortdata = alloca(af->datalen * 2);
|
||||
for (x = 0; x < len; x++)
|
||||
for (x = 0; x < len; x++) {
|
||||
shortdata[x] = AST_ALAW(odata[x]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ast_log(LOG_WARNING, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(af->subclass));
|
||||
@@ -1408,6 +1448,8 @@ struct ast_frame *ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp,
|
||||
ast_log(LOG_WARNING, "Don't know how to represent call progress message %d\n", res);
|
||||
}
|
||||
}
|
||||
} else if ((dsp->features & DSP_FEATURE_WAITDIALTONE)) {
|
||||
res = __ast_dsp_call_progress(dsp, shortdata, len);
|
||||
}
|
||||
|
||||
done:
|
||||
@@ -1420,18 +1462,21 @@ done:
|
||||
case AST_FORMAT_SLINEAR:
|
||||
break;
|
||||
case AST_FORMAT_ULAW:
|
||||
for (x = 0; x < len; x++)
|
||||
for (x = 0; x < len; x++) {
|
||||
odata[x] = AST_LIN2MU((unsigned short) shortdata[x]);
|
||||
}
|
||||
break;
|
||||
case AST_FORMAT_ALAW:
|
||||
for (x = 0; x < len; x++)
|
||||
for (x = 0; x < len; x++) {
|
||||
odata[x] = AST_LIN2A((unsigned short) shortdata[x]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (outf) {
|
||||
if (chan)
|
||||
if (chan) {
|
||||
ast_queue_frame(chan, af);
|
||||
}
|
||||
ast_frfree(af);
|
||||
ast_set_flag(outf, AST_FRFLAG_FROM_DSP);
|
||||
return outf;
|
||||
@@ -1504,10 +1549,12 @@ void ast_dsp_set_threshold(struct ast_dsp *dsp, int threshold)
|
||||
|
||||
void ast_dsp_set_busy_count(struct ast_dsp *dsp, int cadences)
|
||||
{
|
||||
if (cadences < 4)
|
||||
if (cadences < 4) {
|
||||
cadences = 4;
|
||||
if (cadences > DSP_HISTORY)
|
||||
}
|
||||
if (cadences > DSP_HISTORY) {
|
||||
cadences = DSP_HISTORY;
|
||||
}
|
||||
dsp->busycount = cadences;
|
||||
}
|
||||
|
||||
@@ -1555,8 +1602,9 @@ void ast_dsp_reset(struct ast_dsp *dsp)
|
||||
|
||||
dsp->totalsilence = 0;
|
||||
dsp->gsamps = 0;
|
||||
for (x=0;x<4;x++)
|
||||
for (x = 0; x < 4; x++) {
|
||||
dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
|
||||
}
|
||||
memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
|
||||
memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));
|
||||
dsp->ringtimeout= 0;
|
||||
@@ -1632,8 +1680,9 @@ static int _dsp_init(int reload)
|
||||
if (value && sscanf(value, "%d", &thresholds[THRESHOLD_SILENCE]) != 1) {
|
||||
ast_log(LOG_WARNING, "%s: '%s' is not a valid silencethreshold value\n", CONFIG_FILE_NAME, value);
|
||||
thresholds[THRESHOLD_SILENCE] = 256;
|
||||
} else if (!value)
|
||||
} else if (!value) {
|
||||
thresholds[THRESHOLD_SILENCE] = 256;
|
||||
}
|
||||
|
||||
ast_config_destroy(cfg);
|
||||
}
|
||||
|
Reference in New Issue
Block a user