<html>
<head>
    <base href="https://wiki.asterisk.org/wiki">
            <link rel="stylesheet" href="/wiki/s/en/2172/18/9/_/styles/combined.css?spaceKey=AST&amp;forWysiwyg=true" type="text/css">
    </head>
<body style="background: white;" bgcolor="white" class="email-body">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
    <h2><a href="https://wiki.asterisk.org/wiki/display/AST/Hangup+handlers">Hangup handlers</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://wiki.asterisk.org/wiki/display/~rmudgett">Richard Mudgett</a>
    </h4>
        <div id="versionComment">
        <b>Comment:</b>
        Hangup handlers are always executed if they are attached to a channel.  Changed CHANNEL(hangup_handler).  Added AMI events generated for hangup handlers.<br />
    </div>
        <br/>
                         <h4>Changes (19)</h4>
                                 
    
<div id="page-diffs">
                    <table class="diff" cellpadding="0" cellspacing="0">
    
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >Call transfers, call pickup, and call parking can result in channels on both sides of a bridge containing hangup handlers. <br> <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">Hangup handlers can also be attached to any call leg because of pre-dial routines.  However, attaching a hangup handler to a channel using pre-dial does not necessarily mean it will get executed.  If you attached a hangup handler to all outgoing legs of a Dial or FollowMe using the pre-dial feature, only the winning outgoing call leg will have its hangup handlers run.   <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">Hangup handlers can also be attached to any call leg because of pre-dial routines. <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">The restriction on losing calls not having their hangup handlers executed may be removed.  The call pickup scenario has the picked up ringing channel run its hangup handlers after the masquerade.  Although, it would be easy to have that situation just discard those handlers instead. <br> <br></td></tr>
            <tr><td class="diff-unchanged" >h2. When hangup handlers are executed <br> <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">Hangup handler execution will be evaluated under the following circumstances: <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">Any hangup handlers associated with a channel are always executed when the channel is hung up. <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">1) When the incoming call PBX reaches the end of dialplan.  This is normal PBX thread termination. <br> <br>2) When the bridge between a channel and its peer call leg is broken.  The hangup handlers on both sides of the bridge will be evaluated for possible execution as appropriate for the circumstances of the bridge. <br> <br></td></tr>
            <tr><td class="diff-unchanged" >{note} <br>Adding a hangup handler in the h extension or during a hangup handler execution is undefined behavior.   <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >{warning} <br> <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">h2. Add hangup handlers to a channel <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">h2. Manipulating hangup handlers on a channel <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-changed-lines" >Hangup handlers pass the saved handler string to the Gosub application to execute. <span class="diff-added-words"style="background-color: #dfd;"> The syntax is intentionally the same as the Gosub application.  If context or exten are not supplied then the current values from the channel pushing the hangup handler are inserted before storing on the hangup handler stack.</span> <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">{noformat:title=Add a hangup handler to a channel} <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">{noformat:title=Push a hangup handler onto a channel} <br></td></tr>
            <tr><td class="diff-changed-lines" >same =&gt; <span class="diff-changed-words">n,Set(CHANNEL(hangup_handler<span class="diff-added-chars"style="background-color: #dfd;">_push</span>)=[[context,]exten,]priority[(arg1[,...][,argN])]);</span> <br></td></tr>
            <tr><td class="diff-unchanged" >{noformat} <br> <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">The syntax is intentionally the same as the Gosub application.  If context or exten are not supplied then the current values from the channel adding the hangup handler are inserted before saving. <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">{noformat:title=Pop a hangup handler off a channel and optionally push a replacement} <br>same =&gt; n,Set(CHANNEL(hangup_handler_pop)=[[[context,]exten,]priority[(arg1[,...][,argN])]]); <br>{noformat} <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">{noformat:title=Pop all hangup handlers off a channel and optionally push a replacement} <br>same =&gt; n,Set(CHANNEL(hangup_handler_replace)=[[[context,]exten,]priority[(arg1[,...][,argN])]]); <br>{noformat} <br> <br></td></tr>
            <tr><td class="diff-unchanged" >{noformat:title=Cascading hangup handlers} <br></td></tr>
            <tr><td class="diff-changed-lines" >same =&gt; <span class="diff-changed-words">n,Set(CHANNEL(hangup_handler<span class="diff-added-chars"style="background-color: #dfd;">_push</span>)=hdlr3,s,1(args));</span> <br></td></tr>
            <tr><td class="diff-changed-lines" >same =&gt; <span class="diff-changed-words">n,Set(CHANNEL(hangup_handler<span class="diff-added-chars"style="background-color: #dfd;">_push</span>)=hdlr2,s,1(args));</span> <br></td></tr>
            <tr><td class="diff-changed-lines" >same =&gt; <span class="diff-changed-words">n,Set(CHANNEL(hangup_handler<span class="diff-added-chars"style="background-color: #dfd;">_push</span>)=hdlr1,s,1(args));</span> <br></td></tr>
            <tr><td class="diff-unchanged" >{noformat} <br> <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">h2. AMI events <br> <br>The hangup handler AMI events are output as part of the AMI dialplan permission class. <br> <br>The AMI event HangupHandlerPush is generated whenever a hangup handler is pushed on the stack by the CHANNEL() function. <br>The AMI event HangupHandlerPop is generated whenever a hangup handler is popped off the stack by the CHANNEL() function. <br>The AMI event HangupHandlerRun is generated as a hangup handler is about to be executed. <br> <br></td></tr>
            <tr><td class="diff-unchanged" >h2. CLI commands <br> <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
    
            </table>
    </div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        

<h1><a name="Hanguphandlers-Summary"></a>1. Summary</h1>

<p>Hangup handlers - Ability to attach subroutines to a channel that runs dialplan when the channel hangs up.</p>

<h1><a name="Hanguphandlers-Description"></a>2. Description</h1>

<p>Hangup handlers are an alternative to the h extension.  They can be used in addition to the h extension.  The idea is to attach a Gosub routine to a channel that will execute when the call hangs up.  Whereas which h extension gets executed depends on the location of dialplan execution when the call hangs up, hangup handlers are attached to the call channel.  You can attach multiple handlers that will execute in the order of most recently added first.</p>

<div class='panelMacro'><table class='noteMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="/wiki/images/icons/emoticons/warning.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>Please note that when the hangup handlers execute in relation to the h extension is not defined.  They could execute before or after the h extension.</td></tr></table></div>

<div class='panelMacro'><table class='noteMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="/wiki/images/icons/emoticons/warning.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>Need to investigate CDR handling issues.</td></tr></table></div>

<p>Call transfers, call pickup, and call parking can result in channels on both sides of a bridge containing hangup handlers.</p>

<p>Hangup handlers can also be attached to any call leg because of pre-dial routines.</p>

<h2><a name="Hanguphandlers-Whenhanguphandlersareexecuted"></a>2.1. When hangup handlers are executed</h2>

<p>Any hangup handlers associated with a channel are always executed when the channel is hung up.</p>

<div class='panelMacro'><table class='noteMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="/wiki/images/icons/emoticons/warning.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>Adding a hangup handler in the h extension or during a hangup handler execution is undefined behavior.</td></tr></table></div>

<div class='panelMacro'><table class='warningMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="/wiki/images/icons/emoticons/forbidden.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>As always, hangup handlers like the h extension need to execute quickly because they are in the hangup sequence path of the call leg.  Specific channel driver protocols like ISDN and SIP may not be able to handle excessive delays completing the hangup sequence.</td></tr></table></div>

<h2><a name="Hanguphandlers-Manipulatinghanguphandlersonachannel"></a>2.2. Manipulating hangup handlers on a channel</h2>

<p>Hangup handlers pass the saved handler string to the Gosub application to execute.  The syntax is intentionally the same as the Gosub application.  If context or exten are not supplied then the current values from the channel pushing the hangup handler are inserted before storing on the hangup handler stack.</p>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedHeader panelHeader" style="border-bottom-width: 1px;"><b>Push a hangup handler onto a channel</b></div><div class="preformattedContent panelContent">
<pre>same =&gt; n,Set(CHANNEL(hangup_handler_push)=[[context,]exten,]priority[(arg1[,...][,argN])]);
</pre>
</div></div>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedHeader panelHeader" style="border-bottom-width: 1px;"><b>Pop a hangup handler off a channel and optionally push a replacement</b></div><div class="preformattedContent panelContent">
<pre>same =&gt; n,Set(CHANNEL(hangup_handler_pop)=[[[context,]exten,]priority[(arg1[,...][,argN])]]);
</pre>
</div></div>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedHeader panelHeader" style="border-bottom-width: 1px;"><b>Pop all hangup handlers off a channel and optionally push a replacement</b></div><div class="preformattedContent panelContent">
<pre>same =&gt; n,Set(CHANNEL(hangup_handler_replace)=[[[context,]exten,]priority[(arg1[,...][,argN])]]);
</pre>
</div></div>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedHeader panelHeader" style="border-bottom-width: 1px;"><b>Cascading hangup handlers</b></div><div class="preformattedContent panelContent">
<pre>same =&gt; n,Set(CHANNEL(hangup_handler_push)=hdlr3,s,1(args));
same =&gt; n,Set(CHANNEL(hangup_handler_push)=hdlr2,s,1(args));
same =&gt; n,Set(CHANNEL(hangup_handler_push)=hdlr1,s,1(args));
</pre>
</div></div>

<h2><a name="Hanguphandlers-AMIevents"></a>2.3. AMI events</h2>

<p>The hangup handler AMI events are output as part of the AMI dialplan permission class.</p>

<p>The AMI event HangupHandlerPush is generated whenever a hangup handler is pushed on the stack by the CHANNEL() function.<br/>
The AMI event HangupHandlerPop is generated whenever a hangup handler is popped off the stack by the CHANNEL() function.<br/>
The AMI event HangupHandlerRun is generated as a hangup handler is about to be executed.</p>

<h2><a name="Hanguphandlers-CLIcommands"></a>2.4. CLI commands</h2>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedHeader panelHeader" style="border-bottom-width: 1px;"><b>Single channel</b></div><div class="preformattedContent panelContent">
<pre>core show hanguphandlers &lt;chan&gt;
</pre>
</div></div>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedHeader panelHeader" style="border-bottom-width: 1px;"><b>Output</b></div><div class="preformattedContent panelContent">
<pre>Channel       Handler
&lt;chan-name&gt;   &lt;first handler to execute&gt;
              &lt;second handler to execute&gt;
              &lt;third handler to execute&gt;
</pre>
</div></div>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedHeader panelHeader" style="border-bottom-width: 1px;"><b>All channels</b></div><div class="preformattedContent panelContent">
<pre>core show hanguphandlers all
</pre>
</div></div>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedHeader panelHeader" style="border-bottom-width: 1px;"><b>Output</b></div><div class="preformattedContent panelContent">
<pre>Channel       Handler
&lt;chan1-name&gt;  &lt;first handler to execute&gt;
              &lt;second handler to execute&gt;
              &lt;third handler to execute&gt;
&lt;chan2-name&gt;  &lt;first handler to execute&gt;
&lt;chan3-name&gt;  &lt;first handler to execute&gt;
              &lt;second handler to execute&gt;
</pre>
</div></div>

    </div>
        <div id="commentsSection" class="wiki-content pageSection">
        <div style="float: right;" class="grey">
                        <a href="https://wiki.asterisk.org/wiki/users/removespacenotification.action?spaceKey=AST">Stop watching space</a>
            <span style="padding: 0px 5px;">|</span>
                <a href="https://wiki.asterisk.org/wiki/users/editmyemailsettings.action">Change email notification preferences</a>
</div>
        <a href="https://wiki.asterisk.org/wiki/display/AST/Hangup+handlers">View Online</a>
        |
        <a href="https://wiki.asterisk.org/wiki/pages/diffpagesbyversion.action?pageId=19726432&revisedVersion=4&originalVersion=3">View Changes</a>
                |
        <a href="https://wiki.asterisk.org/wiki/display/AST/Hangup+handlers?showComments=true&amp;showCommentArea=true#addcomment">Add Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>