diff --git a/dsp.c b/dsp.c index ad90ff65034c418fa2c19818d979f954a84e18e1..3ea3cf235f1a777ff1fa66b24cc659b30066eb22 100755 --- a/dsp.c +++ b/dsp.c @@ -50,9 +50,11 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") /* Number of goertzels for progress detect */ #define GSAMP_SIZE_NA 183 /* North America - 350, 440, 480, 620, 950, 1400, 1800 Hz */ #define GSAMP_SIZE_CR 188 /* Costa Rica, Brazil - Only care about 425 Hz */ +#define GSAMP_SIZE_UK 160 /* UK disconnect goertzel feed - shoud trigger 400hz */ #define PROG_MODE_NA 0 #define PROG_MODE_CR 1 +#define PROG_MODE_UK 2 /* For US modes */ #define HZ_350 0 @@ -66,6 +68,9 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") /* For CR/BR modes */ #define HZ_425 0 +/* For UK mode */ +#define HZ_400 0 + static struct progalias { char *name; int mode; @@ -74,6 +79,7 @@ static struct progalias { { "ca", PROG_MODE_NA }, { "cr", PROG_MODE_CR }, { "br", PROG_MODE_CR }, + { "uk", PROG_MODE_UK }, }; static struct progress { @@ -82,6 +88,7 @@ static struct progress { } modes[] = { { GSAMP_SIZE_NA, { 350, 440, 480, 620, 950, 1400, 1800 } }, /* North America */ { GSAMP_SIZE_CR, { 425 } }, + { GSAMP_SIZE_UK, { 400 } }, }; #define DEFAULT_THRESHOLD 512 @@ -100,6 +107,8 @@ static struct progress { #define TONE_THRESH 10.0 /* How much louder the tone should be than channel energy */ #define TONE_MIN_THRESH 1e8 /* How much tone there should be at least to attempt */ #define COUNT_THRESH 3 /* Need at least 50ms of stuff to count it */ +#define UK_HANGUP_THRESH 60 /* This is the threshold for the UK */ + #define MAX_DTMF_DIGITS 128 @@ -1009,6 +1018,7 @@ static int __ast_dsp_call_progress(struct ast_dsp *dsp, short *s, int len) int pass; int newstate = DSP_TONE_STATE_SILENCE; int res = 0; + int thresh = (dsp->progmode == PROG_MODE_UK) ? UK_HANGUP_THRESH : COUNT_THRESH; while(len) { /* Take the lesser of the number of samples we need and what we have */ pass = len; @@ -1060,12 +1070,17 @@ static int __ast_dsp_call_progress(struct ast_dsp *dsp, short *s, int len) } else newstate = DSP_TONE_STATE_SILENCE; break; + case PROG_MODE_UK: + if (hz[HZ_400] > TONE_MIN_THRESH * TONE_THRESH) { + newstate = DSP_TONE_STATE_HUNGUP; + } + break; default: ast_log(LOG_WARNING, "Can't process in unknown prog mode '%d'\n", dsp->progmode); } if (newstate == dsp->tstate) { dsp->tcount++; - if (dsp->tcount == COUNT_THRESH) { + if (dsp->tcount == thresh) { if ((dsp->features & DSP_PROGRESS_BUSY) && dsp->tstate == DSP_TONE_STATE_BUSY) { res = AST_CONTROL_BUSY; @@ -1081,6 +1096,10 @@ static int __ast_dsp_call_progress(struct ast_dsp *dsp, short *s, int len) dsp->tstate == DSP_TONE_STATE_SPECIAL3) { res = AST_CONTROL_CONGESTION; dsp->features &= ~DSP_FEATURE_CALL_PROGRESS; + } else if ((dsp->features & DSP_FEATURE_CALL_PROGRESS) && + dsp->tstate == DSP_TONE_STATE_HUNGUP) { + res = AST_CONTROL_HANGUP; + dsp->features &= ~DSP_FEATURE_CALL_PROGRESS; } } } else { @@ -1478,6 +1497,7 @@ struct ast_frame *ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp, case AST_CONTROL_BUSY: case AST_CONTROL_RINGING: case AST_CONTROL_CONGESTION: + case AST_CONTROL_HANGUP: memset(&dsp->f, 0, sizeof(dsp->f)); dsp->f.frametype = AST_FRAME_CONTROL; dsp->f.subclass = res; diff --git a/include/asterisk/dsp.h b/include/asterisk/dsp.h index ca6ab7da8798ee4357add11042b8b5813c5cb63c..d335b18bf2b19e338affbd04eee07a59b9f5fb2e 100755 --- a/include/asterisk/dsp.h +++ b/include/asterisk/dsp.h @@ -41,6 +41,7 @@ #define DSP_TONE_STATE_SPECIAL1 5 #define DSP_TONE_STATE_SPECIAL2 6 #define DSP_TONE_STATE_SPECIAL3 7 +#define DSP_TONE_STATE_HUNGUP 8 struct ast_dsp;