Overview
Hangup handlers are subroutines attached to a channel that will execute when that channel hangs up. Unlike the traditional h extension, hangup handlers follow the channel. Thus hangup handlers are always run when a channel is hung up, regardless of where in the dialplan a channel is executing.
Multiple hangup handlers can be attached to a single channel. If multiple hangup handlers are attached to a channel, the hangup handlers will be executed in the order of most recently added first.
Dialplan Applications and Functions
All manipulation of a channel's hangup handlers are done using the CHANNEL function. All values manipulated for hangup handlers are write-only.
hangup_handler_push
Used to push a hangup handler onto a channel.
same => n,Set(CHANNEL(hangup_handler_push)=[[context,]exten,]priority[(arg1[,...][,argN])]);
hangup_handler_pop
Used to pop a hangup handler off a channel. Optionally, a replacement hangup handler can be added to the channel.
same => n,Set(CHANNEL(hangup_handler_pop)=[[[context,]exten,]priority[(arg1[,...][,argN])]]);
hangup_handler_wipe
Remove all hangup handlers on the channel. Optionally, a new hangup handler can be pushed onto the channel.
same => n,Set(CHANNEL(hangup_handler_wipe)=[[[context,]exten,]priority[(arg1[,...][,argN])]]);
Examples
Adding hangup handlers to a channel
In this example, three hangup handlers are added to a channel: hdlr3, hdlr2, and hdlr1. When the channel is hung up, they will be executed in the order of most recently added first - so hdlr1 will execute first, followed by hdlr2, then hdlr3.
Removing and replacing hangup handlers
In this example, three hangup handlers are added to a channel: hdlr3, hdlr2, and hdlr1. Using the CHANNEL function's hangup_handler_pop value, hdlr1 is removed from the stack of hangup handlers. Then, using the hangup_handler_pop value again, hdlr2 is replaced with hdlr4. When the channel is hung up, hdlr4 will be executed, followed by hdlr3.
CLI Commands
core show hanguphandlers <chan>
Channel Handler <chan-name> <first handler to execute> <second handler to execute> <third handler to execute>
core show hanguphandlers all
Channel Handler <chan1-name> <first handler to execute> <second handler to execute> <third handler to execute> <chan2-name> <first handler to execute> <chan3-name> <first handler to execute> <second handler to execute>
13 Comments
Gopalakrishnan N
Any example in which scenario can I use multiple handlers, will this help to kill ZOMBIE channels?
Matt Jordan
Zombie channels are an artifact of a channel masquerade - they are completely independent of the concept of a hangup handler.
Channel masquerades are a complex topic that is a result of Asterisk's bridging architecture. The notion of masquerading, when and how it occurs, has been a major focus in the development of Asterisk 12.
Hangup handlers are similar to the
h
extension - they execute logic on a channel when that channel is hung up. Unlike theh
extension however, they are associated explicitly with a channel. If a channel moves between contexts it will still safely execute its hangup handlers - while if a channel moved into a context that did not contain anh
extension, it would not execute theh
extension in the context it just left.Gopalakrishnan N
Thanks for the reply.
So I can Hangup handlers when the channels moves from one context to other context even though in two different servers right?
Matt Jordan
I'm not sure I understand your question. This has nothing to do with multiple servers or instances of Asterisk.
Does this example help?
If not, I'd suggest asking any further questions on #asterisk-users or on the asterisk-users mailing list. The wiki is not really meant for Q&A.
Gopalakrishnan N
Ok gotcha....
When am using two context and the call control if transferred from one context to other context the hangup handler properly releases the channel from that context and passes to other one...
And sorry for my Q&A, I will back to asterisk-users mailing list if any...
Thanks for your comments. I really appreciate....
Josh Kitchens
You have to use hangup_handler_pop like:
same => n,Set(CHANNEL(hangup_handler_pop)=)
using it without the '=' gives you:
[Apr 2 15:47:43] WARNING[15252][C-0000001d] pbx.c: Set requires an '=' to be a valid assignment.
and no hangup_handler is removed.
Rusty Newton
Fixed, thanks Josh.
Leonardo Santana
Is there any way to figure out what was the context which invoked the handler? Something similar to the MACRO_CONTEXT? Thx!
Rusty Newton
I don't believe so. It appears the only way would be to pass in the current context via args when pushing a handler onto the channel.
Vadim
How can I execute Hangup handlers before the 'h' extension?
Rusty Newton
The documentation says "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."
That means, there isn't a way to know when the hangup handlers will execute in relation to the h extension.
I wouldn't recommend using both hangup handlers and the h extension simultaneously unless you are sure that what they are each doing is not going to conflict with the other.
Shane Pan
Is there any reason why each Set application in the examples has a semicolon/empty comment at the end of the line?
Richard Mudgett
No reason other than possibly I'm so used to writing in C that the semicolon got stuck there by habit in the original document.