aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGES5
-rw-r--r--channels/chan_dahdi.c58
-rw-r--r--configs/chan_dahdi.conf.sample7
-rw-r--r--include/asterisk/dsp.h1
-rw-r--r--main/dsp.c191
5 files changed, 189 insertions, 73 deletions
diff --git a/CHANGES b/CHANGES
index 78f0080b8..2f84e4cce 100644
--- a/CHANGES
+++ b/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
diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c
index 053e6755f..75734d8fe 100644
--- a/channels/chan_dahdi.c
+++ b/channels/chan_dahdi.c
@@ -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")) {
diff --git a/configs/chan_dahdi.conf.sample b/configs/chan_dahdi.conf.sample
index 01da859c9..85087c504 100644
--- a/configs/chan_dahdi.conf.sample
+++ b/configs/chan_dahdi.conf.sample
@@ -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
diff --git a/include/asterisk/dsp.h b/include/asterisk/dsp.h
index 5193ff4dd..5a599cc4b 100644
--- a/include/asterisk/dsp.h
+++ b/include/asterisk/dsp.h
@@ -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)
diff --git a/main/dsp.c b/main/dsp.c
index 6963bda2c..6c0b013e4 100644
--- a/main/dsp.c
+++ b/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,8 +324,9 @@ 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]);
+ }
}
@@ -481,8 +484,8 @@ static void ast_dtmf_detect_init (dtmf_detect_state_t *s)
s->lasthit = 0;
s->current_hit = 0;
for (i = 0; i < 4; i++) {
- goertzel_init (&s->row_out[i], dtmf_row[i], DTMF_GSIZE);
- goertzel_init (&s->col_out[i], dtmf_col[i], DTMF_GSIZE);
+ goertzel_init(&s->row_out[i], dtmf_row[i], DTMF_GSIZE);
+ goertzel_init(&s->col_out[i], dtmf_col[i], DTMF_GSIZE);
s->energy = 0.0;
}
s->current_sample = 0;
@@ -511,10 +514,11 @@ 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) {
@@ -651,12 +657,13 @@ 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) {
+ 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,30 +691,32 @@ 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 &&
col_energy[best_col] >= DTMF_THRESHOLD &&
- col_energy[best_col] < row_energy[best_row]*DTMF_REVERSE_TWIST &&
- col_energy[best_col]*DTMF_NORMAL_TWIST > row_energy[best_row]) {
+ col_energy[best_col] < row_energy[best_row] * DTMF_REVERSE_TWIST &&
+ col_energy[best_col] * DTMF_NORMAL_TWIST > row_energy[best_row]) {
/* Relative peak test */
for (i = 0; i < 4; i++) {
if ((i != best_col &&
- col_energy[i]*DTMF_RELATIVE_PEAK_COL > col_energy[best_col]) ||
+ col_energy[i] * DTMF_RELATIVE_PEAK_COL > col_energy[best_col]) ||
(i != best_row
- && row_energy[i]*DTMF_RELATIVE_PEAK_ROW > row_energy[best_row])) {
+ && row_energy[i] * DTMF_RELATIVE_PEAK_ROW > row_energy[best_row])) {
break;
}
}
/* ... and fraction of total energy test */
if (i >= 4 &&
- (row_energy[best_row] + col_energy[best_col]) > DTMF_TO_TOTAL_ENERGY*s->td.dtmf.energy) {
+ (row_energy[best_row] + col_energy[best_col]) > DTMF_TO_TOTAL_ENERGY * s->td.dtmf.energy) {
/* Got a hit */
hit = dtmf_positions[(best_row << 2) + best_col];
}
@@ -758,7 +767,7 @@ static int dtmf_detect(struct ast_dsp *dsp, digit_detect_state_t *s, int16_t amp
}
/* Reinitialise the detector for the next block */
- for (i = 0; i < 4; i++) {
+ for (i = 0; i < 4; i++) {
goertzel_reset(&s->td.dtmf.row_out[i]);
goertzel_reset(&s->td.dtmf.col_out[i]);
}
@@ -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++) {
@@ -838,7 +848,7 @@ static int mf_detect(struct ast_dsp *dsp, digit_detect_state_t *s, int16_t amp[]
second_best = 0;
}
/*endif*/
- for (i=2;i<6;i++) {
+ for (i = 2; i < 6; i++) {
energy[i] = goertzel_result(&s->td.mf.tone_out[i]);
if (energy[i] >= energy[best]) {
second_best = best;
@@ -851,10 +861,10 @@ static int mf_detect(struct ast_dsp *dsp, digit_detect_state_t *s, int16_t amp[]
hit = 0;
if (energy[best] >= BELL_MF_THRESHOLD && energy[second_best] >= BELL_MF_THRESHOLD
&& energy[best] < energy[second_best]*BELL_MF_TWIST
- && energy[best]*BELL_MF_TWIST > energy[second_best]) {
+ && energy[best] * BELL_MF_TWIST > energy[second_best]) {
/* Relative peak test */
hit = -1;
- for (i=0;i<6;i++) {
+ for (i = 0; i < 6; i++) {
if (i != best && i != second_best) {
if (energy[i]*BELL_MF_RELATIVE_PEAK >= energy[second_best]) {
/* The best two are not clearly the best */
@@ -871,7 +881,7 @@ static int mf_detect(struct ast_dsp *dsp, digit_detect_state_t *s, int16_t amp[]
best = second_best;
second_best = i;
}
- best = best*5 + second_best - 1;
+ best = best * 5 + second_best - 1;
hit = bell_mf_positions[best];
/* Look for two successive similar results */
/* The logic in the next test is:
@@ -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 (x = 0; x < pass; x++) {
+ 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,18 +1113,20 @@ 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 */
- dsp->totalsilence += len/8;
+ dsp->totalsilence += len / 8;
if (dsp->totalnoise) {
/* Move and save history */
- memmove(dsp->historicnoise + DSP_HISTORY - dsp->busycount, dsp->historicnoise + DSP_HISTORY - dsp->busycount +1, dsp->busycount*sizeof(dsp->historicnoise[0]));
+ memmove(dsp->historicnoise + DSP_HISTORY - dsp->busycount, dsp->historicnoise + DSP_HISTORY - dsp->busycount + 1, dsp->busycount * sizeof(dsp->historicnoise[0]));
dsp->historicnoise[DSP_HISTORY - 1] = dsp->totalnoise;
/* we don't want to check for busydetect that frequently */
#if 0
@@ -1112,32 +1137,36 @@ static int __ast_dsp_silence_noise(struct ast_dsp *dsp, short *s, int len, int *
res = 1;
} else {
/* Not silent */
- dsp->totalnoise += len/8;
+ dsp->totalnoise += len / 8;
if (dsp->totalsilence) {
int silence1 = dsp->historicsilence[DSP_HISTORY - 1];
int silence2 = dsp->historicsilence[DSP_HISTORY - 2];
/* Move and save history */
- memmove(dsp->historicsilence + DSP_HISTORY - dsp->busycount, dsp->historicsilence + DSP_HISTORY - dsp->busycount + 1, dsp->busycount*sizeof(dsp->historicsilence[0]));
+ memmove(dsp->historicsilence + DSP_HISTORY - dsp->busycount, dsp->historicsilence + DSP_HISTORY - dsp->busycount + 1, dsp->busycount * sizeof(dsp->historicsilence[0]));
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
+ } else {
dsp->busymaybe = 0;
+ }
} else {
- if (silence1 - silence1*BUSY_PERCENT/100 <= silence2)
+ if (silence1 - silence1 * BUSY_PERCENT / 100 <= silence2) {
dsp->busymaybe = 1;
- else
+ } else {
dsp->busymaybe = 0;
+ }
}
}
dsp->totalsilence = 0;
}
- if (totalsilence)
+ if (totalsilence) {
*totalsilence = dsp->totalsilence;
- if (totalnoise)
+ }
+ if (totalnoise) {
*totalnoise = dsp->totalnoise;
+ }
return res;
}
@@ -1148,9 +1177,10 @@ 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++) {
+ }
+ for (x = DSP_HISTORY - dsp->busycount; x < DSP_HISTORY; x++) {
#ifndef BUSYDETECT_TONEONLY
avgsilence += dsp->historicsilence[x];
#endif
@@ -1160,22 +1190,26 @@ int ast_dsp_busydetect(struct ast_dsp *dsp)
avgsilence /= dsp->busycount;
#endif
avgtone /= dsp->busycount;
- for (x=DSP_HISTORY - dsp->busycount;x<DSP_HISTORY;x++) {
+ 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
@@ -1187,11 +1221,13 @@ 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;
@@ -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);
}