<p>N A has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/19747">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">sig_analog: Add Called Subscriber Held capability.<br><br>This adds support for Called Subscriber Held for FXS<br>lines, which allows users to go on hook when receiving<br>a call and resume the call later from another phone on<br>the same line, without disconnecting the call. This is<br>a convenience mechanism that most real PSTN telephone<br>switches support.<br><br>ASTERISK-30372 #close<br><br>Change-Id: Iaac4384f73bd0f354d01b1f53e168b385dcbdbd4<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>M configs/samples/chan_dahdi.conf.sample<br>A doc/CHANGES-staging/csh.txt<br>6 files changed, 84 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/47/19747/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 5607eb0..ffb9aa8 100644</span><br><span>--- a/channels/chan_dahdi.c</span><br><span>+++ b/channels/chan_dahdi.c</span><br><span>@@ -12806,6 +12806,7 @@</span><br><span> tmp->usedistinctiveringdetection = usedistinctiveringdetection;</span><br><span> tmp->callwaitingcallerid = conf->chan.callwaitingcallerid;</span><br><span> tmp->threewaycalling = conf->chan.threewaycalling;</span><br><span style="color: hsl(120, 100%, 40%);">+ tmp->calledsubscriberheld = conf->chan.calledsubscriberheld; /* Not used in chan_dahdi.c, just analog pvt, but must exist on the DAHDI pvt anyways */</span><br><span> tmp->adsi = conf->chan.adsi;</span><br><span> tmp->use_smdi = conf->chan.use_smdi;</span><br><span> tmp->permhidecallerid = conf->chan.hidecallerid;</span><br><span>@@ -13103,6 +13104,7 @@</span><br><span> 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 style="color: hsl(120, 100%, 40%);">+ analog_p->calledsubscriberheld = conf->chan.calledsubscriberheld; /* Only actual used in analog pvt, not DAHDI pvt */</span><br><span> analog_p->callreturn = conf->chan.callreturn;</span><br><span> analog_p->cancallforward = conf->chan.cancallforward;</span><br><span> analog_p->canpark = conf->chan.canpark;</span><br><span>@@ -18192,6 +18194,8 @@</span><br><span> confp->chan.busycount = atoi(v->value);</span><br><span> } else if (!strcasecmp(v->name, "busypattern")) {</span><br><span> parse_busy_pattern(v, &confp->chan.busy_cadence);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (!strcasecmp(v->name, "calledsubscriberheld")) {</span><br><span style="color: hsl(120, 100%, 40%);">+ confp->chan.calledsubscriberheld = ast_true(v->value);</span><br><span> } else if (!strcasecmp(v->name, "callprogress")) {</span><br><span> confp->chan.callprogress &= ~CALLPROGRESS_PROGRESS;</span><br><span> if (ast_true(v->value))</span><br><span>diff --git a/channels/chan_dahdi.h b/channels/chan_dahdi.h</span><br><span>index de813f2..170da0e 100644</span><br><span>--- a/channels/chan_dahdi.h</span><br><span>+++ b/channels/chan_dahdi.h</span><br><span>@@ -204,6 +204,13 @@</span><br><span> */</span><br><span> unsigned int busydetect:1;</span><br><span> /*!</span><br><span style="color: hsl(120, 100%, 40%);">+ * \brief TRUE if Called Subscriber held is enabled.</span><br><span style="color: hsl(120, 100%, 40%);">+ * This allows a single incoming call to hold a DAHDI channel up,</span><br><span style="color: hsl(120, 100%, 40%);">+ * allowing a recipient to hang up an extension and pick up another</span><br><span style="color: hsl(120, 100%, 40%);">+ * phone on the same line without disconnecting the call.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int calledsubscriberheld:1;</span><br><span style="color: hsl(120, 100%, 40%);">+ /*!</span><br><span> * \brief TRUE if call return is enabled.</span><br><span> * (*69, if your dialplan doesn't catch this first)</span><br><span> * \note Set from the "callreturn" 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 b694a96..d77b0c4 100644</span><br><span>--- a/channels/sig_analog.c</span><br><span>+++ b/channels/sig_analog.c</span><br><span>@@ -805,6 +805,11 @@</span><br><span> return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /* If line is being held, definitely not (don't allow call waitings to an on-hook phone) */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (p->cshactive) {</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* If no owner definitely available */</span><br><span> if (!p->owner) {</span><br><span> offhook = analog_is_off_hook(p);</span><br><span>@@ -2892,6 +2897,34 @@</span><br><span> analog_get_and_handle_alarms(p);</span><br><span> cause_code->ast_cause = AST_CAUSE_NETWORK_OUT_OF_ORDER;</span><br><span> case ANALOG_EVENT_ONHOOK:</span><br><span style="color: hsl(120, 100%, 40%);">+ if (p->calledsubscriberheld && (p->sig == ANALOG_SIG_FXOLS || p->sig == ANALOG_SIG_FXOGS || p->sig == ANALOG_SIG_FXOKS) && idx == ANALOG_SUB_REAL) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_debug(4, "Channel state on %s is %d\n", ast_channel_name(ast), ast_channel_state(ast));</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Called Subscriber Held: don't let the called party hang up on an incoming call immediately (if it's the only call). */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (p->subs[ANALOG_SUB_CALLWAIT].owner || p->subs[ANALOG_SUB_THREEWAY].owner) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_debug(2, "Letting this call hang up normally, since it's not the only call\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (!p->owner || !p->subs[ANALOG_SUB_REAL].owner || ast_channel_state(ast) != AST_STATE_UP) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_debug(2, "Called Subscriber Held does not apply: channel state is %d\n", ast_channel_state(ast));</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (!p->owner || !p->subs[ANALOG_SUB_REAL].owner || strcmp(ast_channel_appl(p->subs[ANALOG_SUB_REAL].owner), "AppDial")) {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Called Subscriber held only applies to incoming calls, not outgoing calls.</span><br><span style="color: hsl(120, 100%, 40%);">+ * We can't use p->outgoing because that is always true, for both incoming and outgoing calls, so it's not accurate.</span><br><span style="color: hsl(120, 100%, 40%);">+ * We can check the channel application/data instead.</span><br><span style="color: hsl(120, 100%, 40%);">+ * For incoming calls to the channel, it will look like: AppDial / (Outgoing Line)</span><br><span style="color: hsl(120, 100%, 40%);">+ * We only want this behavior for regular calls anyways (and not, say, Queue),</span><br><span style="color: hsl(120, 100%, 40%);">+ * so this would actually work great. But accessing ast_channel_appl can cause a crash if there are no calls left,</span><br><span style="color: hsl(120, 100%, 40%);">+ * so this check must occur AFTER we confirm the channel state *is* still UP.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_debug(2, "Called Subscriber Held does not apply: not an incoming call\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (analog_is_off_hook(p)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_log(LOG_WARNING, "Got ONHOOK but channel %d is off hook?\n", p->channel); /* Shouldn't happen */</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_verb(3, "Holding incoming call %s for channel %d\n", ast_channel_name(ast), p->channel);</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Inhibit dahdi_hangup from getting called, and do nothing else now.</span><br><span style="color: hsl(120, 100%, 40%);">+ * When the DAHDI channel goes off hook again, it'll just get reconnected with the incoming call,</span><br><span style="color: hsl(120, 100%, 40%);">+ * to which, as far as its concerned, nothing has happened. */</span><br><span style="color: hsl(120, 100%, 40%);">+ p->cshactive = 1; /* Keep track that this DAHDI channel is currently being held by an incoming call. */</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span> ast_queue_control_data(ast, AST_CONTROL_PVT_CAUSE_CODE, cause_code, data_size);</span><br><span> ast_channel_hangupcause_hash_set(ast, cause_code, data_size);</span><br><span> switch (p->sig) {</span><br><span>@@ -3768,6 +3801,7 @@</span><br><span> case ANALOG_SIG_FXOKS:</span><br><span> res = analog_off_hook(i);</span><br><span> i->fxsoffhookstate = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ i->cshactive = 0;</span><br><span> if (res && (errno == EBUSY)) {</span><br><span> break;</span><br><span> }</span><br><span>diff --git a/channels/sig_analog.h b/channels/sig_analog.h</span><br><span>index 7e9acda..f332d4f 100644</span><br><span>--- a/channels/sig_analog.h</span><br><span>+++ b/channels/sig_analog.h</span><br><span>@@ -282,6 +282,7 @@</span><br><span> unsigned int ani_wink_time:16; /* Safe wait time before we wink to start ANI spill */</span><br><span> </span><br><span> unsigned int answeronpolarityswitch:1;</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int calledsubscriberheld:1; /*!< TRUE if a single incoming call can hold an FXS channel */</span><br><span> unsigned int callreturn:1;</span><br><span> unsigned int cancallforward:1;</span><br><span> unsigned int canpark:1;</span><br><span>@@ -320,6 +321,7 @@</span><br><span> </span><br><span> /* XXX: All variables after this are internal */</span><br><span> unsigned int callwaiting:1; /*!< TRUE if call waiting is enabled. (Active option) */</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int cshactive:1; /*!< TRUE if FXS channel is currently held by an incoming call */</span><br><span> unsigned int dialednone:1;</span><br><span> unsigned int dialing:1; /*!< TRUE if in the process of dialing digits or sending something */</span><br><span> unsigned int dnd:1; /*!< TRUE if Do-Not-Disturb is enabled. */</span><br><span>diff --git a/configs/samples/chan_dahdi.conf.sample b/configs/samples/chan_dahdi.conf.sample</span><br><span>index 6b29549..c01465e 100644</span><br><span>--- a/configs/samples/chan_dahdi.conf.sample</span><br><span>+++ b/configs/samples/chan_dahdi.conf.sample</span><br><span>@@ -746,6 +746,18 @@</span><br><span> ;</span><br><span> callwaitingcallerid=yes</span><br><span> ;</span><br><span style="color: hsl(120, 100%, 40%);">+; Whether or not to allow users to go on-hook when receiving an incoming call</span><br><span style="color: hsl(120, 100%, 40%);">+; without disconnecting it. Users can later resume the call from any phone</span><br><span style="color: hsl(120, 100%, 40%);">+; on the same physical phone line (the same DAHDI channel).</span><br><span style="color: hsl(120, 100%, 40%);">+; This setting only has an effect on FXS (FXO-signalled) channels where there</span><br><span style="color: hsl(120, 100%, 40%);">+; is only a single incoming call to the DAHDI channel, using the Dial application.</span><br><span style="color: hsl(120, 100%, 40%);">+; (This is a convenience mechanism to avoid users wishing to resume a conversation</span><br><span style="color: hsl(120, 100%, 40%);">+; at a different phone from leaving a phone off the hook, resuming elsewhere,</span><br><span style="color: hsl(120, 100%, 40%);">+; and forgetting to restore the original phone on hook afterwards.)</span><br><span style="color: hsl(120, 100%, 40%);">+; Default is no.</span><br><span style="color: hsl(120, 100%, 40%);">+;</span><br><span style="color: hsl(120, 100%, 40%);">+;calledsubscriberheld=yes</span><br><span style="color: hsl(120, 100%, 40%);">+;</span><br><span> ; Support three-way calling</span><br><span> ;</span><br><span> threewaycalling=yes</span><br><span>diff --git a/doc/CHANGES-staging/csh.txt b/doc/CHANGES-staging/csh.txt</span><br><span>new file mode 100644</span><br><span>index 0000000..c16b207</span><br><span>--- /dev/null</span><br><span>+++ b/doc/CHANGES-staging/csh.txt</span><br><span>@@ -0,0 +1,7 @@</span><br><span style="color: hsl(120, 100%, 40%);">+Subject: sig_analog</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+Called Subscriber Held is now supported for analog FXS</span><br><span style="color: hsl(120, 100%, 40%);">+channels, using the calledsubscriberheld option. This</span><br><span style="color: hsl(120, 100%, 40%);">+allows a station user to go on hook when receiving an</span><br><span style="color: hsl(120, 100%, 40%);">+incoming call and resume from another phone on the same</span><br><span style="color: hsl(120, 100%, 40%);">+line by going on hook, without disconnecting the call.</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/19747">change 19747</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/+/19747"/><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: Iaac4384f73bd0f354d01b1f53e168b385dcbdbd4 </div>
<div style="display:none"> Gerrit-Change-Number: 19747 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: N A <asterisk@phreaknet.org> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>