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