<p>Sarah Autumn has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/16151">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">sig_analog: Changes to improve electromechanical signalling compatibility<br><br>This changeset is intended to address compatibility issues encountered<br>when interfacing Asterisk to electromechanical telephone switches that<br>implement ANI-B, ANI-C, or ANI-D.<br><br>In particular the behaviours that this impacts include:<br><br> - FGC-CAMA did not work at all when using MF signaling. Modified the<br>   switch case block to send calls to the correct part of the<br>   signaling-handling state machine.<br><br> - For FGC-CAMA operation, the delay between called number ST and<br>   second wink for ANI spill has been made configurable; previously<br>   all calls were made to wait for one full second.<br><br> - After the ANI spill, previous behavior was to require a 'ST' tone<br>   to advance the call.  This has been changed to allow 'STP' 'ST2P'<br>   or 'ST3P' as well, for compatibility with ANI-D.<br><br> - For calls with an ANI failure, No. 1 Crossbar switches will send<br>   forward a single-digit failure code, with no calling number digits<br>   and no ST pulse to terminate the spill.  I've made the ANI timeout<br>   configurable so to reduce dead air time on calls with ANI fail.<br><br> - ANI info digits configurable.  Modern digital switches will send 2<br>   digits, but ANI-B sends only a single info digit.  This caused the<br>   ANI reported by Asterisk to be misaligned.<br><br> - Changed a confusing log message to be more informative.<br><br>Change-Id: Ib7e27d987aee4ed9bc3663c57ef413e21b404256<br>---<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>4 files changed, 81 insertions(+), 9 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/51/16151/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c</span><br><span>index 2c7b673..74c76f7 100644</span><br><span>--- a/channels/chan_dahdi.c</span><br><span>+++ b/channels/chan_dahdi.c</span><br><span>@@ -953,6 +953,10 @@</span><br><span>                    .parkinglot = "",</span><br><span>                  .transfertobusy = 1,</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+                      .ani_info_digits = 2,</span><br><span style="color: hsl(120, 100%, 40%);">+                 .ani_wink_time = 1000,</span><br><span style="color: hsl(120, 100%, 40%);">+                        .ani_timeout = 10000,</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>                      .cid_signalling = CID_SIG_BELL,</span><br><span>                      .cid_start = CID_START_RING,</span><br><span>                         .dahditrcallerid = 0,</span><br><span>@@ -12839,6 +12843,9 @@</span><br><span> </span><br><span>          tmp->polarityonanswerdelay = conf->chan.polarityonanswerdelay;</span><br><span>                 tmp->answeronpolarityswitch = conf->chan.answeronpolarityswitch;</span><br><span style="color: hsl(120, 100%, 40%);">+                tmp->ani_info_digits = conf->chan.ani_info_digits;</span><br><span style="color: hsl(120, 100%, 40%);">+              tmp->ani_wink_time = conf->chan.ani_wink_time;</span><br><span style="color: hsl(120, 100%, 40%);">+          tmp->ani_timeout = conf->chan.ani_timeout;</span><br><span>             tmp->hanguponpolarityswitch = conf->chan.hanguponpolarityswitch;</span><br><span>               tmp->sendcalleridafter = conf->chan.sendcalleridafter;</span><br><span>                 ast_cc_copy_config_params(tmp->cc_params, conf->chan.cc_params);</span><br><span>@@ -12944,6 +12951,9 @@</span><br><span>                             analog_p->channel = tmp->channel;</span><br><span>                              analog_p->polarityonanswerdelay = conf->chan.polarityonanswerdelay;</span><br><span>                            analog_p->answeronpolarityswitch = conf->chan.answeronpolarityswitch;</span><br><span style="color: hsl(120, 100%, 40%);">+                           analog_p->ani_info_digits = conf->chan.ani_info_digits;</span><br><span style="color: hsl(120, 100%, 40%);">+                         analog_p->ani_timeout = conf->chan.ani_timeout;</span><br><span style="color: hsl(120, 100%, 40%);">+                         analog_p->ani_wink_time = conf->chan.ani_wink_time;</span><br><span>                            analog_p->hanguponpolarityswitch = conf->chan.hanguponpolarityswitch;</span><br><span>                          analog_p->permcallwaiting = conf->chan.callwaiting; /* permcallwaiting possibly modified in analog_config_complete */</span><br><span>                          analog_p->callreturn = conf->chan.callreturn;</span><br><span>@@ -18241,6 +18251,12 @@</span><br><span>                       confp->chan.polarityonanswerdelay = atoi(v->value);</span><br><span>            } else if (!strcasecmp(v->name, "answeronpolarityswitch")) {</span><br><span>                    confp->chan.answeronpolarityswitch = ast_true(v->value);</span><br><span style="color: hsl(120, 100%, 40%);">+                } else if (!strcasecmp(v->name, "ani_info_digits")) {</span><br><span style="color: hsl(120, 100%, 40%);">+                    confp->chan.ani_info_digits = atoi(v->value);</span><br><span style="color: hsl(120, 100%, 40%);">+           } else if (!strcasecmp(v->name, "ani_wink_time")) {</span><br><span style="color: hsl(120, 100%, 40%);">+                      confp->chan.ani_wink_time = atoi(v->value);</span><br><span style="color: hsl(120, 100%, 40%);">+             } else if (!strcasecmp(v->name, "ani_timeout")) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        confp->chan.ani_timeout = atoi(v->value);</span><br><span>              } else if (!strcasecmp(v->name, "hanguponpolarityswitch")) {</span><br><span>                    confp->chan.hanguponpolarityswitch = ast_true(v->value);</span><br><span>               } else if (!strcasecmp(v->name, "sendcalleridafter")) {</span><br><span>diff --git a/channels/chan_dahdi.h b/channels/chan_dahdi.h</span><br><span>index f98ebdc..94e05a0 100644</span><br><span>--- a/channels/chan_dahdi.h</span><br><span>+++ b/channels/chan_dahdi.h</span><br><span>@@ -182,6 +182,22 @@</span><br><span>          */</span><br><span>  unsigned int answeronpolarityswitch:1;</span><br><span>       /*!</span><br><span style="color: hsl(120, 100%, 40%);">+    * \brief INTEGER, number of ANI INFO digits on a CAMA trunk.</span><br><span style="color: hsl(120, 100%, 40%);">+  * older switches use 1 INFO digit, newer switches use 2 INFO digits</span><br><span style="color: hsl(120, 100%, 40%);">+   * \note Set from the "ani_info_digits" value read in from chan_dahdi.conf</span><br><span style="color: hsl(120, 100%, 40%);">+   */</span><br><span style="color: hsl(120, 100%, 40%);">+   unsigned int ani_info_digits:8;</span><br><span style="color: hsl(120, 100%, 40%);">+       /*!</span><br><span style="color: hsl(120, 100%, 40%);">+    * \brief INTEGER, length of ANI failure timeout in ms.</span><br><span style="color: hsl(120, 100%, 40%);">+        * \note Set from the "ani_timeout" value read in from chan_dahdi.conf</span><br><span style="color: hsl(120, 100%, 40%);">+       */</span><br><span style="color: hsl(120, 100%, 40%);">+   unsigned int ani_timeout:16;</span><br><span style="color: hsl(120, 100%, 40%);">+  /*!</span><br><span style="color: hsl(120, 100%, 40%);">+    * \brief INTEGER, length of time to wait before sending ANI wink in ms. </span><br><span style="color: hsl(120, 100%, 40%);">+      * \note Set from the "ani_wink_time" value read in from chan_dahdi.conf</span><br><span style="color: hsl(120, 100%, 40%);">+     */</span><br><span style="color: hsl(120, 100%, 40%);">+   unsigned int ani_wink_time:16;</span><br><span style="color: hsl(120, 100%, 40%);">+        /*!</span><br><span>   * \brief TRUE if busy detection is enabled.</span><br><span>          * (Listens for the beep-beep busy pattern.)</span><br><span>          * \note Set from the "busydetect" value read in from chan_dahdi.conf</span><br><span>diff --git a/channels/sig_analog.c b/channels/sig_analog.c</span><br><span>index 4356e02..0433298 100644</span><br><span>--- a/channels/sig_analog.c</span><br><span>+++ b/channels/sig_analog.c</span><br><span>@@ -1864,7 +1864,6 @@</span><br><span>                                     if (p->sig == ANALOG_SIG_E911) {</span><br><span>                                          analog_off_hook(p);</span><br><span>                                  }</span><br><span style="color: hsl(0, 100%, 40%);">-                                       res = analog_my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "#", 3000);</span><br><span>                             }</span><br><span>                            if (res < 1) {</span><br><span>                                    analog_dsp_reset_and_flush_digits(p);</span><br><span>@@ -1927,21 +1926,58 @@</span><br><span>                      goto quit;</span><br><span>           }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-           if (p->sig == ANALOG_SIG_FGC_CAMA) {</span><br><span style="color: hsl(120, 100%, 40%);">+               if (p->sig == ANALOG_SIG_FGC_CAMA || p->sig == ANALOG_SIG_FGC_CAMAMF) {</span><br><span style="color: hsl(120, 100%, 40%);">+                 /* This if block is where we process ANI for CAMA */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>                       char anibuf[100];</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-                   if (ast_safe_sleep(chan,1000) == -1) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        /* cnoffset is the point at which we pull the calling number out</span><br><span style="color: hsl(120, 100%, 40%);">+                       * of anibuf. Must be the number of ani_info_digits + 1 to account</span><br><span style="color: hsl(120, 100%, 40%);">+                     * for the KP, which is considered a digit.  */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                     /* The 1XB with ANI-B will send a full 10 digits</span><br><span style="color: hsl(120, 100%, 40%);">+                      *  or 2 digits in case of ANI failure.</span><br><span style="color: hsl(120, 100%, 40%);">+                        * (CD-95811-01 Section II, page 10)</span><br><span style="color: hsl(120, 100%, 40%);">+                   * 10 digit string example:  *08320123#</span><br><span style="color: hsl(120, 100%, 40%);">+                        * 2 digit string example:   *2</span><br><span style="color: hsl(120, 100%, 40%);">+                        * KP (*) and ST (#) are considered to be digits */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                  int cnoffset = p->ani_info_digits + 1;</span><br><span style="color: hsl(120, 100%, 40%);">+                     ast_debug(1, "cnoffset: %d\n", cnoffset);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                 /* This is how long to wait before the wink to start ANI spill</span><br><span style="color: hsl(120, 100%, 40%);">+                         * Pulled from chan_dahdi.conf, default is 1000ms */</span><br><span style="color: hsl(120, 100%, 40%);">+                  if (ast_safe_sleep(chan,p->ani_wink_time) == -1) {</span><br><span>                                ast_hangup(chan);</span><br><span>                            goto quit;</span><br><span>                   }</span><br><span>                    analog_off_hook(p);</span><br><span style="color: hsl(120, 100%, 40%);">+                   ast_debug(1, "Sent wink to signal ANI start\n");</span><br><span>                   analog_dsp_set_digitmode(p, ANALOG_DIGITMODE_MF);</span><br><span style="color: hsl(0, 100%, 40%);">-                       res = analog_my_getsigstr(chan, anibuf, "#", 10000);</span><br><span style="color: hsl(0, 100%, 40%);">-                  if ((res > 0) && (strlen(anibuf) > 2)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                          if (anibuf[strlen(anibuf) - 1] == '#') {</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                    /* ani_timeout is configured in chan_dahdi.conf. default is 10000ms.</span><br><span style="color: hsl(120, 100%, 40%);">+                   * ST, STP, ST2P, ST3P can all signal transmission complete, regardless of timeout */</span><br><span style="color: hsl(120, 100%, 40%);">+                 res = analog_my_getsigstr(chan, anibuf, "#ABC", p->ani_timeout);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                       /* so we can work with the ani buffer */</span><br><span style="color: hsl(120, 100%, 40%);">+                      pbx_builtin_setvar_helper(chan, "ANIBUF", anibuf);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                        /* as long as we get a terminating pulse OR the length of ANI buffer is at least >=2, we can treat</span><br><span style="color: hsl(120, 100%, 40%);">+                  * this as a complete spill for the purposes of setting anistart */</span><br><span style="color: hsl(120, 100%, 40%);">+                   if ((res > 0) || (strlen(anibuf) >= 2)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                               char anistart[2] = "X";</span><br><span style="color: hsl(120, 100%, 40%);">+                             if (strchr("#ABC", anibuf[strlen(anibuf) - 1])) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                   anistart[0] = anibuf[strlen(anibuf) - 1];</span><br><span>                                    anibuf[strlen(anibuf) - 1] = 0;</span><br><span>                              }</span><br><span style="color: hsl(0, 100%, 40%);">-                               ast_set_callerid(chan, anibuf + 2, NULL, anibuf + 2);</span><br><span style="color: hsl(120, 100%, 40%);">+                         ast_set_callerid(chan, anibuf + cnoffset, NULL, anibuf + cnoffset);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                         anibuf[cnoffset] = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                               /* so we can work with the different start pulses as used in ANI-D */</span><br><span style="color: hsl(120, 100%, 40%);">+                         pbx_builtin_setvar_helper(chan, "ANISTART", anistart);</span><br><span style="color: hsl(120, 100%, 40%);">+                              /* so we can use our ANI INFO digits in our dialplan */</span><br><span style="color: hsl(120, 100%, 40%);">+                               pbx_builtin_setvar_helper(chan, "ANI2", anibuf + 1);</span><br><span>                       }</span><br><span>                    analog_dsp_set_digitmode(p, ANALOG_DIGITMODE_DTMF);</span><br><span>          }</span><br><span>@@ -2023,7 +2059,7 @@</span><br><span>                                    ast_copy_string(exten, "911", sizeof(exten));</span><br><span>                              }</span><br><span>                    } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                                ast_log(LOG_WARNING, "Got a non-E911/FGC CAMA input on channel %d.  Assuming E&M Wink instead\n", p->channel);</span><br><span style="color: hsl(120, 100%, 40%);">+                               ast_log(LOG_WARNING, "A KP was expected to start signaling for Feature Group C CAMA-MF, but we got something else. Received: %s on channel %d\n", exten, p->channel);</span><br><span>                   }</span><br><span>            }</span><br><span>            if (p->sig == ANALOG_SIG_FEATB) {</span><br><span>@@ -2035,7 +2071,7 @@</span><br><span>                                 s1 = strsep(&stringp, "#");</span><br><span>                            ast_copy_string(exten, exten2 + 1, sizeof(exten));</span><br><span>                   } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                                ast_log(LOG_WARNING, "Got a non-Feature Group B input on channel %d.  Assuming E&M Wink instead\n", p->channel);</span><br><span style="color: hsl(120, 100%, 40%);">+                             ast_log(LOG_WARNING, "A KP was expected to start signaling for Feature Group B, but we got something else. Received: %s on channel %d\n", exten, p->channel);</span><br><span>                   }</span><br><span>            }</span><br><span>            if ((p->sig == ANALOG_SIG_FEATDMF) || (p->sig == ANALOG_SIG_FEATDMF_TA)) {</span><br><span>diff --git a/channels/sig_analog.h b/channels/sig_analog.h</span><br><span>index 3b9dcf5..488be36 100644</span><br><span>--- a/channels/sig_analog.h</span><br><span>+++ b/channels/sig_analog.h</span><br><span>@@ -277,6 +277,10 @@</span><br><span>     int msgstate;</span><br><span> </span><br><span>    /* XXX: Option Variables - Set by allocator of private structure */</span><br><span style="color: hsl(120, 100%, 40%);">+   unsigned int ani_info_digits:8;                 /* Older switches use 1 INFO digit, newer switches use 2 */</span><br><span style="color: hsl(120, 100%, 40%);">+   unsigned int ani_timeout:16;                    /* Time in ms before we give up waiting for ANI spill */</span><br><span style="color: hsl(120, 100%, 40%);">+      unsigned int ani_wink_time:16;                  /* Safe wait time before we wink to start ANI spill */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>     unsigned int answeronpolarityswitch:1;</span><br><span>       unsigned int callreturn:1;</span><br><span>   unsigned int cancallforward:1;</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/16151">change 16151</a>. To unsubscribe, or for help writing mail filters, 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/c/asterisk/+/16151"/><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-Change-Id: Ib7e27d987aee4ed9bc3663c57ef413e21b404256 </div>
<div style="display:none"> Gerrit-Change-Number: 16151 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Sarah Autumn <sarah@endlesstemple.org> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>