Search code examples
asteriskasteriskami

Asterisk AMI Originate - add hangup_handler for first leg


We use Asterisk AMI Originate for outbound calls (our software), so after successfully connecting to the first leg (external), we can use dialplan to Dial the second leg (internal) and handle the hangup.

Now we are using AMI in our software to pick up Hangup Event on the first leg/channel (if we have not established a connection - busy, noanswer, etc). Is it possible to set the hangup_handler for the first channel in AMI Originate (similar to Asterisk Application Originate, which has option b, where you can set the hangup_handler)?

-- Edited

I was able to do it through Local channels, but I think it's a bit complicated, maybe there is another way?

channel originate Local/0123456789@to_caller extension ivm_100@process_ivm

dialplan:

[to_caller]
exten => _X.,1,Log(VERBOSE,OUTGOING CALL)
same => n,NoCDR()
; remember about variable inheritance https://asteriskfaqs.org/2021/02/23/asterisk-users/channel-variable-inheritance.html
; can set here same variables
same => n,Set(CALLERID(num)=0123456789) 
same => n,Set(CALLERID(name)=${CALLERID(num)})
same => n,Set(__clrCID=${CALLERID(num)})
;end test
same => n,Dial(SIP/${EXTEN},30,b(set_hangup_handler,s,1)U(remove_hangup_handler,s,1)))

[set_hangup_handler]
exten => s,1,Set(CHANNEL(hangup_handler_push)=to_caller_hangup_handler,s,1)
;test variables in new channel
same => n,NoOp(clrCID: ${clrCID})
; need to set CALLERID for new channel
same => n,Set(CALLERID(num)=${clrCID})
same => n,Set(CALLERID(name)=${CALLERID(num)})
;end test
same => n,Return()

[remove_hangup_handler]
exten => s,1,NoOp(Remove hangup_handler)
same => n,Set(CHANNEL(hangup_handler_pop)=)
same => n,Set(MASTER_CHANNEL(clrFCH)=${CHANNEL(name)})
same => n,Return()

[to_caller_hangup_handler]
exten => s,1,NoOp(TO_CALLER_HANGUP_HANDLER First Call Leg)
same => n,NoOp(Data: CHANNEL: ${CHANNEL}, SIP Cause - ${HANGUPCAUSE}, Technology Cause Code "${HANGUPCAUSE(${CHANNEL},tech)}", Asterisk Cause Code "${HANGUPCAUSE(${CHANNEL},ast)}")
same => n,Return()

[process_ivm]
exten => _ivm.,1,NoOp(Process dialplan IVM)
same => n,NoCDR()
same => n,ChannelRedirect(${clrFCH},ivms,${EXTEN},1) ; redirect from Local to real channel
same => n,Hangup() ; hangup Local channel

exten => h,1,NoOp(Hangup Local channel)

[ivms]
; here is main logic when DIALSTATUS will be ANSWER

Solution

  • One more asterisk software made without asterisk expert in team...

    First, to make a hangup event you don't need AMI or handler, much simpler is to use CEL or beanstalk integration.

    Second, AMI is not designed to really control anything in dialplan. It is more about events/commands.

    Third, if you still want you do handler for dialout leg, you should use Local/ channel dialling, not SIP. Check source code of any modern opensource solution. For example, vicidial.org

    After that in dialplan, you can setup any handler and see how it affect your reability and perfomance.