chan_dahdi: Configurable dialed digit timeouts

Analog phones dial overlap dialing and it is chan_dahdi's job to read the
numbers.  It has three timeout constants that this commit converts to
channel-level configuration options:

* firstdigit_timeout: Default time (ms) to detect first digit

* interdigit_timeout: Default time (ms) to detect following digits

* matchdigit_timeout: Default time (ms) to wait in case of ambiguous
match.  This happens when the dialed digits match a number in the current
context but are also the prefix of another number.

Change-Id: Ib728fa900a4f6ae56d1ed810aba61b6593fb7213
16.0
Tzafrir Cohen 7 years ago committed by Richard Mudgett
parent e538fc8e86
commit 6301531416

@ -45,6 +45,11 @@ chan_sip
headers be retrieved from the REFER message and made accessible to the
dialplan in the hash TRANSFER_DATA.
chan_dahdi
------------------
* Timeouts for reading digits from analog phones are now configurable in
chan_dahdi.conf: firstdigit_timeout, interdigit_timeout, matchdigit_timeout.
AMI
------------------
* The ContactStatus and Status fields for the manager events ContactStatus

@ -50,6 +50,10 @@ Build System:
MALLOC_DEBUG and vice versa. Third-party pre-compiled modules no longer
need to have a special build with it enabled.
chan_dahdi:
- Timeouts for reading digits from analog phones are now configurable in
chan_dahdi.conf: firstdigit_timeout, interdigit_timeout, matchdigit_timeout.
cdr_syslog:
- The cdr_syslog module is now deprecated and by default it is no longer
built.

@ -615,15 +615,6 @@ static int pridebugfd = -1;
static char pridebugfilename[1024] = "";
#endif
/*! \brief Wait up to 16 seconds for first digit (FXO logic) */
static int firstdigittimeout = 16000;
/*! \brief How long to wait for following digits (FXO logic) */
static int gendigittimeout = 8000;
/*! \brief How long to wait for an extra digit, if there is an ambiguous match */
static int matchdigittimeout = 3000;
/*! \brief Protect the interface list (of dahdi_pvt's) */
AST_MUTEX_DEFINE_STATIC(iflock);
@ -977,6 +968,9 @@ static struct dahdi_chan_conf dahdi_chan_conf_default(void)
.buf_no = numbufs,
.usefaxbuffers = 0,
.cc_params = ast_cc_config_params_init(),
.firstdigit_timeout = ANALOG_FIRST_DIGIT_TIMEOUT,
.interdigit_timeout = ANALOG_INTER_DIGIT_TIMEOUT,
.matchdigit_timeout = ANALOG_MATCH_DIGIT_TIMEOUT,
},
.timing = {
.prewinktime = -1,
@ -3326,6 +3320,19 @@ static int my_have_progressdetect(void *pvt)
}
}
#define gen_pvt_field_callback(type, field) \
static type my_get_##field(void *pvt) \
{ \
struct dahdi_pvt *p = pvt; \
return p->field; \
}
gen_pvt_field_callback(int, firstdigit_timeout);
gen_pvt_field_callback(int, interdigit_timeout);
gen_pvt_field_callback(int, matchdigit_timeout);
#undef gen_pvt_field_callback
struct analog_callback analog_callbacks =
{
.play_tone = my_play_tone,
@ -3394,6 +3401,9 @@ struct analog_callback analog_callbacks =
.answer_polarityswitch = my_answer_polarityswitch,
.hangup_polarityswitch = my_hangup_polarityswitch,
.have_progressdetect = my_have_progressdetect,
.get_firstdigit_timeout = my_get_firstdigit_timeout,
.get_matchdigit_timeout = my_get_matchdigit_timeout,
.get_interdigit_timeout = my_get_interdigit_timeout,
};
/*! Round robin search locations. */
@ -9555,9 +9565,9 @@ static void *analog_ss_thread(void *data)
dtmfbuf[len] = '\0';
while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, ast_channel_context(chan), dtmfbuf, 1, p->cid_num)) {
if (ast_exists_extension(chan, ast_channel_context(chan), dtmfbuf, 1, p->cid_num)) {
timeout = matchdigittimeout;
timeout = p->matchdigit_timeout;
} else {
timeout = gendigittimeout;
timeout = p->interdigit_timeout;
}
res = ast_waitfordigit(chan, timeout);
if (res < 0) {
@ -9725,7 +9735,7 @@ static void *analog_ss_thread(void *data)
case SIG_FXOGS:
case SIG_FXOKS:
/* Read the first digit */
timeout = firstdigittimeout;
timeout = p->firstdigit_timeout;
/* If starting a threeway call, never timeout on the first digit so someone
can use flash-hook as a "hold" feature */
if (p->subs[SUB_THREEWAY].owner)
@ -9800,8 +9810,8 @@ static void *analog_ss_thread(void *data)
}
} else {
/* It's a match, but they just typed a digit, and there is an ambiguous match,
so just set the timeout to matchdigittimeout and wait some more */
timeout = matchdigittimeout;
so just set the timeout to matchdigit_timeout and wait some more */
timeout = p->matchdigit_timeout;
}
} else if (res == 0) {
ast_debug(1, "not enough digits (and no ambiguous match)...\n");
@ -9821,7 +9831,7 @@ static void *analog_ss_thread(void *data)
len = 0;
ioctl(p->subs[idx].dfd,DAHDI_CONFDIAG,&len);
memset(exten, 0, sizeof(exten));
timeout = firstdigittimeout;
timeout = p->firstdigit_timeout;
} else if (!strcmp(exten, pickupexten)) {
/* Scan all channels and see if there are any
@ -9866,7 +9876,7 @@ static void *analog_ss_thread(void *data)
}
len = 0;
memset(exten, 0, sizeof(exten));
timeout = firstdigittimeout;
timeout = p->firstdigit_timeout;
} else if (p->callreturn && !strcmp(exten, "*69")) {
res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL);
break;
@ -9938,7 +9948,7 @@ static void *analog_ss_thread(void *data)
}
len = 0;
memset(exten, 0, sizeof(exten));
timeout = firstdigittimeout;
timeout = p->firstdigit_timeout;
} else if (!strcmp(exten, "*0")) {
struct ast_channel *nbridge =
p->subs[SUB_THREEWAY].owner;
@ -9986,7 +9996,7 @@ static void *analog_ss_thread(void *data)
break;
}
if (!timeout)
timeout = gendigittimeout;
timeout = p->interdigit_timeout;
if (len && !ast_ignore_pattern(ast_channel_context(chan), exten))
tone_zone_play_tone(p->subs[idx].dfd, -1);
}
@ -12501,6 +12511,9 @@ static struct dahdi_pvt *mkintf(int channel, const struct dahdi_chan_conf *conf,
tmp->waitfordialtone = conf->chan.waitfordialtone;
tmp->dialtone_detect = conf->chan.dialtone_detect;
tmp->faxdetect_timeout = conf->chan.faxdetect_timeout;
tmp->firstdigit_timeout = conf->chan.firstdigit_timeout;
tmp->interdigit_timeout = conf->chan.interdigit_timeout;
tmp->matchdigit_timeout = conf->chan.matchdigit_timeout;
tmp->cancallforward = conf->chan.cancallforward;
tmp->dtmfrelax = conf->chan.dtmfrelax;
tmp->callwaiting = tmp->permcallwaiting;
@ -17713,6 +17726,21 @@ static int process_dahdi(struct dahdi_chan_conf *confp, const char *cat, struct
if (sscanf(v->value, "%30u", &confp->chan.faxdetect_timeout) != 1) {
confp->chan.faxdetect_timeout = 0;
}
} else if (!strcasecmp(v->name, "firstdigit_timeout")) {
if (sscanf(v->value, "%30d", &confp->chan.firstdigit_timeout) != 1
|| confp->chan.firstdigit_timeout <= 0) {
confp->chan.firstdigit_timeout = ANALOG_FIRST_DIGIT_TIMEOUT;
}
} else if (!strcasecmp(v->name, "interdigit_timeout")) {
if (sscanf(v->value, "%30d", &confp->chan.interdigit_timeout) != 1
|| confp->chan.interdigit_timeout <= 0) {
confp->chan.interdigit_timeout = ANALOG_INTER_DIGIT_TIMEOUT;
}
} else if (!strcasecmp(v->name, "matchdigit_timeout")) {
if (sscanf(v->value, "%30d", &confp->chan.matchdigit_timeout) != 1
|| confp->chan.matchdigit_timeout <= 0) {
confp->chan.matchdigit_timeout = ANALOG_MATCH_DIGIT_TIMEOUT;
}
} else if (!strcasecmp(v->name, "echocancel")) {
process_echocancel(confp, v->value, v->lineno);
} else if (!strcasecmp(v->name, "echotraining")) {

@ -617,6 +617,21 @@ struct dahdi_pvt {
* \note Set from the "faxdetect_timeout" value read in from chan_dahdi.conf
*/
unsigned int faxdetect_timeout;
/*!
* \brief Time (ms) to detect first digit (in an analog phone)
* \note Set from the "firstdigit_timeout" value read in from chan_dahdi.conf
*/
int firstdigit_timeout;
/*!
* \brief Time (ms) to detect following digits (in an analog phone)
* \note Set from the "interdigit_timeout" value read in from chan_dahdi.conf
*/
int interdigit_timeout;
/*!
* \brief Time (ms) to wait, in case of ambiguous match (in an analog phone)
* \note Set from the "matchdigit_timeout" value read in from chan_dahdi.conf
*/
int matchdigit_timeout;
struct timeval waitingfordt; /*!< Time we started waiting for dialtone */
struct timeval flashtime; /*!< Last flash-hook time */
/*! \brief Opaque DSP configuration structure. */

@ -62,9 +62,6 @@
#define POLARITY_IDLE 0
#define POLARITY_REV 1
#define MIN_MS_SINCE_FLASH ( (2000) ) /*!< 2000 ms */
static int analog_matchdigittimeout = 3000;
static int analog_gendigittimeout = 8000;
static int analog_firstdigittimeout = 16000;
static char analog_defaultcic[64] = "";
static char analog_defaultozz[64] = "";
@ -219,6 +216,21 @@ static int analog_have_progressdetect(struct analog_pvt *p)
return 0;
}
#define gen_analog_field_callback(type, callback_name, def_value) \
static type analog_get_##callback_name(struct analog_pvt *p) \
{ \
if (!analog_callbacks.get_##callback_name) { \
return def_value; \
} \
return analog_callbacks.get_##callback_name(p->chan_pvt); \
}
gen_analog_field_callback(int, firstdigit_timeout, ANALOG_FIRST_DIGIT_TIMEOUT);
gen_analog_field_callback(int, interdigit_timeout, ANALOG_INTER_DIGIT_TIMEOUT);
gen_analog_field_callback(int, matchdigit_timeout, ANALOG_MATCH_DIGIT_TIMEOUT);
#undef gen_analog_field_callback
enum analog_cid_start analog_str_to_cidstart(const char *value)
{
if (!strcasecmp(value, "ring")) {
@ -1886,9 +1898,9 @@ static void *__analog_ss_thread(void *data)
dtmfbuf[len] = '\0';
while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, ast_channel_context(chan), dtmfbuf, 1, p->cid_num)) {
if (ast_exists_extension(chan, ast_channel_context(chan), dtmfbuf, 1, p->cid_num)) {
timeout = analog_matchdigittimeout;
timeout = analog_get_matchdigit_timeout(p);
} else {
timeout = analog_gendigittimeout;
timeout = analog_get_interdigit_timeout(p);
}
res = ast_waitfordigit(chan, timeout);
if (res < 0) {
@ -2074,7 +2086,7 @@ static void *__analog_ss_thread(void *data)
case ANALOG_SIG_FXOGS:
case ANALOG_SIG_FXOKS:
/* Read the first digit */
timeout = analog_firstdigittimeout;
timeout = analog_get_firstdigit_timeout(p);
/* If starting a threeway call, never timeout on the first digit so someone
can use flash-hook as a "hold" feature */
if (p->subs[ANALOG_SUB_THREEWAY].owner) {
@ -2155,7 +2167,7 @@ static void *__analog_ss_thread(void *data)
} else {
/* It's a match, but they just typed a digit, and there is an ambiguous match,
so just set the timeout to analog_matchdigittimeout and wait some more */
timeout = analog_matchdigittimeout;
timeout = analog_get_matchdigit_timeout(p);
}
} else if (res == 0) {
ast_debug(1, "not enough digits (and no ambiguous match)...\n");
@ -2174,7 +2186,7 @@ static void *__analog_ss_thread(void *data)
}
len = 0;
memset(exten, 0, sizeof(exten));
timeout = analog_firstdigittimeout;
timeout = analog_get_firstdigit_timeout(p);
} else if (!strcmp(exten, pickupexten)) {
/* Scan all channels and see if there are any
@ -2219,7 +2231,7 @@ static void *__analog_ss_thread(void *data)
}
len = 0;
memset(exten, 0, sizeof(exten));
timeout = analog_firstdigittimeout;
timeout = analog_get_firstdigit_timeout(p);
} else if (p->callreturn && !strcmp(exten, "*69")) {
res = 0;
if (!ast_strlen_zero(p->lastcid_num)) {
@ -2305,7 +2317,7 @@ static void *__analog_ss_thread(void *data)
}
len = 0;
memset(exten, 0, sizeof(exten));
timeout = analog_firstdigittimeout;
timeout = analog_get_firstdigit_timeout(p);
} else if (!strcmp(exten, "*0")) {
struct ast_channel *nbridge = p->subs[ANALOG_SUB_THREEWAY].owner;
struct analog_pvt *pbridge = NULL;
@ -2348,7 +2360,7 @@ static void *__analog_ss_thread(void *data)
break;
}
if (!timeout) {
timeout = analog_gendigittimeout;
timeout = analog_get_interdigit_timeout(p);
}
if (len && !ast_ignore_pattern(ast_channel_context(chan), exten)) {
analog_play_tone(p, idx, -1);

@ -34,6 +34,13 @@
#define READ_SIZE 160
#define RING_PATTERNS 3
/*! \brief Default time (ms) to detect first digit */
#define ANALOG_FIRST_DIGIT_TIMEOUT 16000
/*! \brief Default time (ms) to detect following digits */
#define ANALOG_INTER_DIGIT_TIMEOUT 8000
/*! \brief Default time (ms) to wait, in case of ambiguous match */
#define ANALOG_MATCH_DIGIT_TIMEOUT 3000
/* Signalling types supported */
enum analog_sigtype {
ANALOG_SIG_NONE = -1,
@ -237,6 +244,9 @@ struct analog_callback {
const char *(* const get_orig_dialstring)(void *pvt);
int (* const have_progressdetect)(void *pvt);
int (* const get_firstdigit_timeout)(void *pvt);
int (* const get_interdigit_timeout)(void *pvt);
int (* const get_matchdigit_timeout)(void *pvt);
};
/*! Global analog callbacks to the upper layer. */

@ -1137,6 +1137,21 @@ pickupgroup=1
;
;faxbuffers=>6,full
;
; When FXO signalling (FXS device, e.g. analog phone) is used, overlap dialing
; is typically used. Asterisk has several configurable (per-channel) timeouts
; to know how long to wait for the next digit. All the values are in
; milliseconds.
; * firstdigit_timeout: a longer timeout before any digit is dialed.
; By default: 16 seconds.
; * interdigit_timeout: timeout for next digits, if the current number dialed
; does not match a number in the current context. Default: 8 seconds.
; * matchdigit_timeout: timeout for next digits, if the current number dialed
; matches a number in the current context. Default: 3 seconds.
;
;firstdigit_timeout=16000
;interdigit_timeout=8000
;matchdigit_timeout=3000
;
; Configure the default number of DAHDI buffers and the transmit policy to use.
; This can be used to eliminate data drops when scheduling jitter prevents
; Asterisk from writing to a DAHDI channel regularly. Most users will probably

Loading…
Cancel
Save