<p>Joshua Colp <strong>merged</strong> this change.</p><p><a href="https://gerrit.asterisk.org/8637">View Change</a></p><div style="white-space:pre-wrap">Approvals:
Matthew Fredrickson: Looks good to me, approved
Joshua Colp: Approved for Submit
</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">chan_dahdi: Configurable dialed digit timeouts<br><br>Analog phones dial overlap dialing and it is chan_dahdi's job to read the<br>numbers. It has three timeout constants that this commit converts to<br>channel-level configuration options:<br><br>* firstdigit_timeout: Default time (ms) to detect first digit<br><br>* interdigit_timeout: Default time (ms) to detect following digits<br><br>* matchdigit_timeout: Default time (ms) to wait in case of ambiguous<br>match. This happens when the dialed digits match a number in the current<br>context but are also the prefix of another number.<br><br>Change-Id: Ib728fa900a4f6ae56d1ed810aba61b6593fb7213<br>---<br>M CHANGES<br>M UPGRADE.txt<br>M channels/chan_dahdi.c<br>M channels/chan_dahdi.h<br>M channels/sig_analog.c<br>M channels/sig_analog.h<br>M configs/samples/chan_dahdi.conf.sample<br>7 files changed, 118 insertions(+), 29 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/CHANGES b/CHANGES<br>index 19c8f86..7b67f8d 100644<br>--- a/CHANGES<br>+++ b/CHANGES<br>@@ -45,6 +45,11 @@<br> headers be retrieved from the REFER message and made accessible to the<br> dialplan in the hash TRANSFER_DATA.<br> <br>+chan_dahdi<br>+------------------<br>+ * Timeouts for reading digits from analog phones are now configurable in<br>+ chan_dahdi.conf: firstdigit_timeout, interdigit_timeout, matchdigit_timeout.<br>+<br> AMI<br> ------------------<br> * The ContactStatus and Status fields for the manager events ContactStatus<br>diff --git a/UPGRADE.txt b/UPGRADE.txt<br>index 108c10a..154a9b7 100644<br>--- a/UPGRADE.txt<br>+++ b/UPGRADE.txt<br>@@ -50,6 +50,10 @@<br> MALLOC_DEBUG and vice versa. Third-party pre-compiled modules no longer<br> need to have a special build with it enabled.<br> <br>+chan_dahdi:<br>+ - Timeouts for reading digits from analog phones are now configurable in<br>+ chan_dahdi.conf: firstdigit_timeout, interdigit_timeout, matchdigit_timeout.<br>+<br> cdr_syslog:<br> - The cdr_syslog module is now deprecated and by default it is no longer<br> built.<br>diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c<br>index 37e2774..7c54cf3 100644<br>--- a/channels/chan_dahdi.c<br>+++ b/channels/chan_dahdi.c<br>@@ -615,15 +615,6 @@<br> static char pridebugfilename[1024] = "";<br> #endif<br> <br>-/*! \brief Wait up to 16 seconds for first digit (FXO logic) */<br>-static int firstdigittimeout = 16000;<br>-<br>-/*! \brief How long to wait for following digits (FXO logic) */<br>-static int gendigittimeout = 8000;<br>-<br>-/*! \brief How long to wait for an extra digit, if there is an ambiguous match */<br>-static int matchdigittimeout = 3000;<br>-<br> /*! \brief Protect the interface list (of dahdi_pvt's) */<br> AST_MUTEX_DEFINE_STATIC(iflock);<br> <br>@@ -977,6 +968,9 @@<br> .buf_no = numbufs,<br> .usefaxbuffers = 0,<br> .cc_params = ast_cc_config_params_init(),<br>+ .firstdigit_timeout = ANALOG_FIRST_DIGIT_TIMEOUT,<br>+ .interdigit_timeout = ANALOG_INTER_DIGIT_TIMEOUT,<br>+ .matchdigit_timeout = ANALOG_MATCH_DIGIT_TIMEOUT,<br> },<br> .timing = {<br> .prewinktime = -1,<br>@@ -3326,6 +3320,19 @@<br> }<br> }<br> <br>+#define gen_pvt_field_callback(type, field) \<br>+ static type my_get_##field(void *pvt) \<br>+ { \<br>+ struct dahdi_pvt *p = pvt; \<br>+ return p->field; \<br>+ }<br>+<br>+gen_pvt_field_callback(int, firstdigit_timeout);<br>+gen_pvt_field_callback(int, interdigit_timeout);<br>+gen_pvt_field_callback(int, matchdigit_timeout);<br>+<br>+#undef gen_pvt_field_callback<br>+<br> struct analog_callback analog_callbacks =<br> {<br> .play_tone = my_play_tone,<br>@@ -3394,6 +3401,9 @@<br> .answer_polarityswitch = my_answer_polarityswitch,<br> .hangup_polarityswitch = my_hangup_polarityswitch,<br> .have_progressdetect = my_have_progressdetect,<br>+ .get_firstdigit_timeout = my_get_firstdigit_timeout,<br>+ .get_matchdigit_timeout = my_get_matchdigit_timeout,<br>+ .get_interdigit_timeout = my_get_interdigit_timeout,<br> };<br> <br> /*! Round robin search locations. */<br>@@ -9555,9 +9565,9 @@<br> dtmfbuf[len] = '\0';<br> while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, ast_channel_context(chan), dtmfbuf, 1, p->cid_num)) {<br> if (ast_exists_extension(chan, ast_channel_context(chan), dtmfbuf, 1, p->cid_num)) {<br>- timeout = matchdigittimeout;<br>+ timeout = p->matchdigit_timeout;<br> } else {<br>- timeout = gendigittimeout;<br>+ timeout = p->interdigit_timeout;<br> }<br> res = ast_waitfordigit(chan, timeout);<br> if (res < 0) {<br>@@ -9725,7 +9735,7 @@<br> case SIG_FXOGS:<br> case SIG_FXOKS:<br> /* Read the first digit */<br>- timeout = firstdigittimeout;<br>+ timeout = p->firstdigit_timeout;<br> /* If starting a threeway call, never timeout on the first digit so someone<br> can use flash-hook as a "hold" feature */<br> if (p->subs[SUB_THREEWAY].owner)<br>@@ -9800,8 +9810,8 @@<br> }<br> } else {<br> /* It's a match, but they just typed a digit, and there is an ambiguous match,<br>- so just set the timeout to matchdigittimeout and wait some more */<br>- timeout = matchdigittimeout;<br>+ so just set the timeout to matchdigit_timeout and wait some more */<br>+ timeout = p->matchdigit_timeout;<br> }<br> } else if (res == 0) {<br> ast_debug(1, "not enough digits (and no ambiguous match)...\n");<br>@@ -9821,7 +9831,7 @@<br> len = 0;<br> ioctl(p->subs[idx].dfd,DAHDI_CONFDIAG,&len);<br> memset(exten, 0, sizeof(exten));<br>- timeout = firstdigittimeout;<br>+ timeout = p->firstdigit_timeout;<br> <br> } else if (!strcmp(exten, pickupexten)) {<br> /* Scan all channels and see if there are any<br>@@ -9866,7 +9876,7 @@<br> }<br> len = 0;<br> memset(exten, 0, sizeof(exten));<br>- timeout = firstdigittimeout;<br>+ timeout = p->firstdigit_timeout;<br> } else if (p->callreturn && !strcmp(exten, "*69")) {<br> res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL);<br> break;<br>@@ -9938,7 +9948,7 @@<br> }<br> len = 0;<br> memset(exten, 0, sizeof(exten));<br>- timeout = firstdigittimeout;<br>+ timeout = p->firstdigit_timeout;<br> } else if (!strcmp(exten, "*0")) {<br> struct ast_channel *nbridge =<br> p->subs[SUB_THREEWAY].owner;<br>@@ -9986,7 +9996,7 @@<br> break;<br> }<br> if (!timeout)<br>- timeout = gendigittimeout;<br>+ timeout = p->interdigit_timeout;<br> if (len && !ast_ignore_pattern(ast_channel_context(chan), exten))<br> tone_zone_play_tone(p->subs[idx].dfd, -1);<br> }<br>@@ -12501,6 +12511,9 @@<br> tmp->waitfordialtone = conf->chan.waitfordialtone;<br> tmp->dialtone_detect = conf->chan.dialtone_detect;<br> tmp->faxdetect_timeout = conf->chan.faxdetect_timeout;<br>+ tmp->firstdigit_timeout = conf->chan.firstdigit_timeout;<br>+ tmp->interdigit_timeout = conf->chan.interdigit_timeout;<br>+ tmp->matchdigit_timeout = conf->chan.matchdigit_timeout;<br> tmp->cancallforward = conf->chan.cancallforward;<br> tmp->dtmfrelax = conf->chan.dtmfrelax;<br> tmp->callwaiting = tmp->permcallwaiting;<br>@@ -17713,6 +17726,21 @@<br> if (sscanf(v->value, "%30u", &confp->chan.faxdetect_timeout) != 1) {<br> confp->chan.faxdetect_timeout = 0;<br> }<br>+ } else if (!strcasecmp(v->name, "firstdigit_timeout")) {<br>+ if (sscanf(v->value, "%30d", &confp->chan.firstdigit_timeout) != 1<br>+ || confp->chan.firstdigit_timeout <= 0) {<br>+ confp->chan.firstdigit_timeout = ANALOG_FIRST_DIGIT_TIMEOUT;<br>+ }<br>+ } else if (!strcasecmp(v->name, "interdigit_timeout")) {<br>+ if (sscanf(v->value, "%30d", &confp->chan.interdigit_timeout) != 1<br>+ || confp->chan.interdigit_timeout <= 0) {<br>+ confp->chan.interdigit_timeout = ANALOG_INTER_DIGIT_TIMEOUT;<br>+ }<br>+ } else if (!strcasecmp(v->name, "matchdigit_timeout")) {<br>+ if (sscanf(v->value, "%30d", &confp->chan.matchdigit_timeout) != 1<br>+ || confp->chan.matchdigit_timeout <= 0) {<br>+ confp->chan.matchdigit_timeout = ANALOG_MATCH_DIGIT_TIMEOUT;<br>+ }<br> } else if (!strcasecmp(v->name, "echocancel")) {<br> process_echocancel(confp, v->value, v->lineno);<br> } else if (!strcasecmp(v->name, "echotraining")) {<br>diff --git a/channels/chan_dahdi.h b/channels/chan_dahdi.h<br>index ab5c1eb..c22ed01 100644<br>--- a/channels/chan_dahdi.h<br>+++ b/channels/chan_dahdi.h<br>@@ -617,6 +617,21 @@<br> * \note Set from the "faxdetect_timeout" value read in from chan_dahdi.conf<br> */<br> unsigned int faxdetect_timeout;<br>+ /*!<br>+ * \brief Time (ms) to detect first digit (in an analog phone)<br>+ * \note Set from the "firstdigit_timeout" value read in from chan_dahdi.conf<br>+ */<br>+ int firstdigit_timeout;<br>+ /*!<br>+ * \brief Time (ms) to detect following digits (in an analog phone)<br>+ * \note Set from the "interdigit_timeout" value read in from chan_dahdi.conf<br>+ */<br>+ int interdigit_timeout;<br>+ /*!<br>+ * \brief Time (ms) to wait, in case of ambiguous match (in an analog phone)<br>+ * \note Set from the "matchdigit_timeout" value read in from chan_dahdi.conf<br>+ */<br>+ int matchdigit_timeout;<br> struct timeval waitingfordt; /*!< Time we started waiting for dialtone */<br> struct timeval flashtime; /*!< Last flash-hook time */<br> /*! \brief Opaque DSP configuration structure. */<br>diff --git a/channels/sig_analog.c b/channels/sig_analog.c<br>index 110942c..53f9fb2 100644<br>--- a/channels/sig_analog.c<br>+++ b/channels/sig_analog.c<br>@@ -62,9 +62,6 @@<br> #define POLARITY_IDLE 0<br> #define POLARITY_REV 1<br> #define MIN_MS_SINCE_FLASH ( (2000) ) /*!< 2000 ms */<br>-static int analog_matchdigittimeout = 3000;<br>-static int analog_gendigittimeout = 8000;<br>-static int analog_firstdigittimeout = 16000;<br> static char analog_defaultcic[64] = "";<br> static char analog_defaultozz[64] = "";<br> <br>@@ -218,6 +215,21 @@<br> /* Don't have progress detection. */<br> return 0;<br> }<br>+<br>+#define gen_analog_field_callback(type, callback_name, def_value) \<br>+ static type analog_get_##callback_name(struct analog_pvt *p) \<br>+ { \<br>+ if (!analog_callbacks.get_##callback_name) { \<br>+ return def_value; \<br>+ } \<br>+ return analog_callbacks.get_##callback_name(p->chan_pvt); \<br>+ }<br>+<br>+gen_analog_field_callback(int, firstdigit_timeout, ANALOG_FIRST_DIGIT_TIMEOUT);<br>+gen_analog_field_callback(int, interdigit_timeout, ANALOG_INTER_DIGIT_TIMEOUT);<br>+gen_analog_field_callback(int, matchdigit_timeout, ANALOG_MATCH_DIGIT_TIMEOUT);<br>+<br>+#undef gen_analog_field_callback<br> <br> enum analog_cid_start analog_str_to_cidstart(const char *value)<br> {<br>@@ -1886,9 +1898,9 @@<br> dtmfbuf[len] = '\0';<br> while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, ast_channel_context(chan), dtmfbuf, 1, p->cid_num)) {<br> if (ast_exists_extension(chan, ast_channel_context(chan), dtmfbuf, 1, p->cid_num)) {<br>- timeout = analog_matchdigittimeout;<br>+ timeout = analog_get_matchdigit_timeout(p);<br> } else {<br>- timeout = analog_gendigittimeout;<br>+ timeout = analog_get_interdigit_timeout(p);<br> }<br> res = ast_waitfordigit(chan, timeout);<br> if (res < 0) {<br>@@ -2074,7 +2086,7 @@<br> case ANALOG_SIG_FXOGS:<br> case ANALOG_SIG_FXOKS:<br> /* Read the first digit */<br>- timeout = analog_firstdigittimeout;<br>+ timeout = analog_get_firstdigit_timeout(p);<br> /* If starting a threeway call, never timeout on the first digit so someone<br> can use flash-hook as a "hold" feature */<br> if (p->subs[ANALOG_SUB_THREEWAY].owner) {<br>@@ -2155,7 +2167,7 @@<br> } else {<br> /* It's a match, but they just typed a digit, and there is an ambiguous match,<br> so just set the timeout to analog_matchdigittimeout and wait some more */<br>- timeout = analog_matchdigittimeout;<br>+ timeout = analog_get_matchdigit_timeout(p);<br> }<br> } else if (res == 0) {<br> ast_debug(1, "not enough digits (and no ambiguous match)...\n");<br>@@ -2174,7 +2186,7 @@<br> }<br> len = 0;<br> memset(exten, 0, sizeof(exten));<br>- timeout = analog_firstdigittimeout;<br>+ timeout = analog_get_firstdigit_timeout(p);<br> <br> } else if (!strcmp(exten, pickupexten)) {<br> /* Scan all channels and see if there are any<br>@@ -2219,7 +2231,7 @@<br> }<br> len = 0;<br> memset(exten, 0, sizeof(exten));<br>- timeout = analog_firstdigittimeout;<br>+ timeout = analog_get_firstdigit_timeout(p);<br> } else if (p->callreturn && !strcmp(exten, "*69")) {<br> res = 0;<br> if (!ast_strlen_zero(p->lastcid_num)) {<br>@@ -2305,7 +2317,7 @@<br> }<br> len = 0;<br> memset(exten, 0, sizeof(exten));<br>- timeout = analog_firstdigittimeout;<br>+ timeout = analog_get_firstdigit_timeout(p);<br> } else if (!strcmp(exten, "*0")) {<br> struct ast_channel *nbridge = p->subs[ANALOG_SUB_THREEWAY].owner;<br> struct analog_pvt *pbridge = NULL;<br>@@ -2348,7 +2360,7 @@<br> break;<br> }<br> if (!timeout) {<br>- timeout = analog_gendigittimeout;<br>+ timeout = analog_get_interdigit_timeout(p);<br> }<br> if (len && !ast_ignore_pattern(ast_channel_context(chan), exten)) {<br> analog_play_tone(p, idx, -1);<br>diff --git a/channels/sig_analog.h b/channels/sig_analog.h<br>index 42e00c0..3b9dcf5 100644<br>--- a/channels/sig_analog.h<br>+++ b/channels/sig_analog.h<br>@@ -34,6 +34,13 @@<br> #define READ_SIZE 160<br> #define RING_PATTERNS 3<br> <br>+/*! \brief Default time (ms) to detect first digit */<br>+#define ANALOG_FIRST_DIGIT_TIMEOUT 16000<br>+/*! \brief Default time (ms) to detect following digits */<br>+#define ANALOG_INTER_DIGIT_TIMEOUT 8000<br>+/*! \brief Default time (ms) to wait, in case of ambiguous match */<br>+#define ANALOG_MATCH_DIGIT_TIMEOUT 3000<br>+<br> /* Signalling types supported */<br> enum analog_sigtype {<br> ANALOG_SIG_NONE = -1,<br>@@ -237,6 +244,9 @@<br> <br> const char *(* const get_orig_dialstring)(void *pvt);<br> int (* const have_progressdetect)(void *pvt);<br>+ int (* const get_firstdigit_timeout)(void *pvt);<br>+ int (* const get_interdigit_timeout)(void *pvt);<br>+ int (* const get_matchdigit_timeout)(void *pvt);<br> };<br> <br> /*! Global analog callbacks to the upper layer. */<br>diff --git a/configs/samples/chan_dahdi.conf.sample b/configs/samples/chan_dahdi.conf.sample<br>index 3c5e18d..d24c22b 100644<br>--- a/configs/samples/chan_dahdi.conf.sample<br>+++ b/configs/samples/chan_dahdi.conf.sample<br>@@ -1137,6 +1137,21 @@<br> ;<br> ;faxbuffers=>6,full<br> ;<br>+; When FXO signalling (FXS device, e.g. analog phone) is used, overlap dialing<br>+; is typically used. Asterisk has several configurable (per-channel) timeouts<br>+; to know how long to wait for the next digit. All the values are in<br>+; milliseconds.<br>+; * firstdigit_timeout: a longer timeout before any digit is dialed.<br>+; By default: 16 seconds.<br>+; * interdigit_timeout: timeout for next digits, if the current number dialed<br>+; does not match a number in the current context. Default: 8 seconds.<br>+; * matchdigit_timeout: timeout for next digits, if the current number dialed<br>+; matches a number in the current context. Default: 3 seconds.<br>+;<br>+;firstdigit_timeout=16000<br>+;interdigit_timeout=8000<br>+;matchdigit_timeout=3000<br>+;<br> ; Configure the default number of DAHDI buffers and the transmit policy to use.<br> ; This can be used to eliminate data drops when scheduling jitter prevents<br> ; Asterisk from writing to a DAHDI channel regularly. Most users will probably<br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/8637">change 8637</a>. To unsubscribe, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/8637"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: Ib728fa900a4f6ae56d1ed810aba61b6593fb7213 </div>
<div style="display:none"> Gerrit-Change-Number: 8637 </div>
<div style="display:none"> Gerrit-PatchSet: 4 </div>
<div style="display:none"> Gerrit-Owner: Tzafrir Cohen <tzafrir.cohen@xorcom.com> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins2 </div>
<div style="display:none"> Gerrit-Reviewer: Joshua Colp <jcolp@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Matthew Fredrickson <creslin@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Oron Peled <oron.peled@xorcom.com> </div>
<div style="display:none"> Gerrit-Reviewer: Richard Mudgett <rmudgett@digium.com> </div>