<p>Tzafrir Cohen has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/8637">View Change</a></p><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<br>the numbers. It has three timeout constants, that this commit convert to<br>channel-level configuration options.<br><br>* firstdigit_timeout: delay before the first digit is dialed<br>* gendigit_timeout: the delay after a digit has been dialed, if current<br>  digit does not match an extension in the current dialplan context.<br>* matchdigit_timeout: the delay after a digit has been dialed, if current<br>  digit matches an extension in the current dialplan context.<br><br>Change-Id: Ib728fa900a4f6ae56d1ed810aba61b6593fb7213<br>---<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>6 files changed, 105 insertions(+), 29 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/37/8637/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/UPGRADE.txt b/UPGRADE.txt<br>index 108c10a..a604af9 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, gendigit_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..e39184b 100644<br>--- a/channels/chan_dahdi.c<br>+++ b/channels/chan_dahdi.c<br>@@ -554,6 +554,10 @@<br> #define CALLPROGRESS_FAX_INCOMING     4<br> #define CALLPROGRESS_FAX            (CALLPROGRESS_FAX_INCOMING | CALLPROGRESS_FAX_OUTGOING)<br> <br>+#define DEFAULT_FIRST_DIGIT_TIMEOUT        16000<br>+#define DEFAULT_GEN_DIGIT_TIMEOUT       8000<br>+#define DEFAULT_MATCH_DIGIT_TIMEOUT      3000<br>+<br> #define NUM_CADENCE_MAX 25<br> static int num_cadence = 4;<br> static int user_has_defined_cadences = 0;<br>@@ -614,15 +618,6 @@<br> static int pridebugfd = -1;<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>@@ -977,6 +972,9 @@<br>                      .buf_no = numbufs,<br>                    .usefaxbuffers = 0,<br>                   .cc_params = ast_cc_config_params_init(),<br>+                    .firstdigit_timeout = DEFAULT_FIRST_DIGIT_TIMEOUT,<br>+                   .gendigit_timeout = DEFAULT_GEN_DIGIT_TIMEOUT,<br>+                       .matchdigit_timeout = DEFAULT_MATCH_DIGIT_TIMEOUT,<br>            },<br>            .timing = {<br>                   .prewinktime = -1,<br>@@ -3326,6 +3324,22 @@<br>    }<br> }<br> <br>+#define get_pvt_field_callback(type, field, def_value) \<br>+  static type my_get_##field(void *pvt) \<br>+      { \<br>+          struct dahdi_pvt *p = pvt; \<br>+         if (!p) { \<br>+                  return def_value; \<br>+          } \<br>+          return p->field; \<br>+        }<br>+<br>+get_pvt_field_callback(int, firstdigit_timeout, 0);<br>+get_pvt_field_callback(int, matchdigit_timeout, 0);<br>+get_pvt_field_callback(int, gendigit_timeout, 0);<br>+<br>+#undef get_pvt_field_callback<br>+<br> struct analog_callback analog_callbacks =<br> {<br>    .play_tone = my_play_tone,<br>@@ -3394,6 +3408,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_gendigit_timeout = my_get_gendigit_timeout,<br> };<br> <br> /*! Round robin search locations. */<br>@@ -9555,9 +9572,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->gendigit_timeout;<br>                                     }<br>                                     res = ast_waitfordigit(chan, timeout);<br>                                        if (res < 0) {<br>@@ -9725,7 +9742,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 +9817,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 +9838,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 +9883,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 +9955,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 +10003,7 @@<br>                               break;<br>                        }<br>                     if (!timeout)<br>-                                timeout = gendigittimeout;<br>+                           timeout = p->gendigit_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 +12518,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->gendigit_timeout = conf->chan.gendigit_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 +17733,18 @@<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, "%30u", &confp->chan.firstdigit_timeout) != 1) {<br>+                            confp->chan.firstdigit_timeout = DEFAULT_FIRST_DIGIT_TIMEOUT;<br>+                     }<br>+            } else if (!strcasecmp(v->name, "gendigit_timeout")) {<br>+                  if (sscanf(v->value, "%30u", &confp->chan.gendigit_timeout) != 1) {<br>+                              confp->chan.gendigit_timeout = DEFAULT_GEN_DIGIT_TIMEOUT;<br>+                 }<br>+            } else if (!strcasecmp(v->name, "matchdigit_timeout")) {<br>+                        if (sscanf(v->value, "%30u", &confp->chan.matchdigit_timeout) != 1) {<br>+                            confp->chan.matchdigit_timeout = DEFAULT_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..40e2e78 100644<br>--- a/channels/chan_dahdi.h<br>+++ b/channels/chan_dahdi.h<br>@@ -617,6 +617,20 @@<br>     * \note Set from the "faxdetect_timeout" value read in from chan_dahdi.conf<br>         */<br>   unsigned int faxdetect_timeout;<br>+      /*! \brief Time (ms) to wait for 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 wait for following digits in an analog phone<br>+  * \note Set from the "gendigit_timeout" value read in from chan_dahdi.conf<br>+         */<br>+  int gendigit_timeout;<br>+<br>+     /*! \brief Time (ms) to wait for an extra digit, if there is an ambiguous match<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..76b623e 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,18 @@<br>  /* Don't have progress detection. */<br>      return 0;<br> }<br>+<br>+#define analog_get_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>+analog_get_field_callback(int, firstdigit_timeout, 0);<br>+analog_get_field_callback(int, matchdigit_timeout, 0);<br>+analog_get_field_callback(int, gendigit_timeout, 0);<br> <br> enum analog_cid_start analog_str_to_cidstart(const char *value)<br> {<br>@@ -1886,9 +1895,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_gendigit_timeout(p);<br>                                     }<br>                                     res = ast_waitfordigit(chan, timeout);<br>                                        if (res < 0) {<br>@@ -2074,7 +2083,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 +2164,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 +2183,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 +2228,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 +2314,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 +2357,7 @@<br>                             break;<br>                        }<br>                     if (!timeout) {<br>-                              timeout = analog_gendigittimeout;<br>+                            timeout = analog_get_gendigit_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..8557039 100644<br>--- a/channels/sig_analog.h<br>+++ b/channels/sig_analog.h<br>@@ -237,6 +237,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_matchdigit_timeout)(void *pvt);<br>+     int (* const get_gendigit_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..6d2e5eb 100644<br>--- a/configs/samples/chan_dahdi.conf.sample<br>+++ b/configs/samples/chan_dahdi.conf.sample<br>@@ -1137,6 +1137,20 @@<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>+; * gendigit_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>+;firstdigit_timeout=16000<br>+;gendigit_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: newchange </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: 1 </div>
<div style="display:none"> Gerrit-Owner: Tzafrir Cohen <tzafrir.cohen@xorcom.com> </div>