<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>