Hello, colleagues.
We have the following dialplan, used both for AMI calls and regular calls. If AMI is executed, the first leg of the call lands in ami-originate, and from there, upon the agent’s answer, it goes to orig-answer-channel.
Then, the call proceeds with the second leg to sub-outbound, where we perform a ChannelRedirect for the LocalChannel, after which the call continues through the same sub-outbound context as usual.
At the end of the call, there is a check on DIALSTATUS. If the status is “CONGESTION” or “CHANUNAVAIL”, we attempt to call again through the next trunk. Otherwise, we go to sub-no-answered-call-finished, where, depending on the status, we play the appropriate message about the called party being busy or unavailable and then end the call by entering hangup_handler = outbound-hangup-handler.
[ami-originate]
exten => _X!,1,NoOp(Init dial from AMI)
same => n,NoCDR()
same => n,Set(MASTER_CHANNEL(destinationChannel)=${originalCalledNumber})
same => n,Dial(PJSIP/${EXTEN},60,TtU(orig-answer-channel),s,1))
[orig-answer-channel]
exten => s,1,NoOp(Set source channel)
same => n,NoOP(${CHANNEL(name)})
same => n,Set(MASTER_CHANNEL(sourceChannel)=${CHANNEL})
same => n,Return()
[sub-outbound]
exten => _.,1,NoOp(Call attempt via outbound route)
same => n,ExecIf($[ “${sourceChannel}x” != “x” ]?NoCDR())
same => n,ExecIf($[ “${sourceChannel}x” != “x” ]?ChannelRedirect(${sourceChannel},${ARG1},${destinationChannel},1))
same => n,ExecIf($[ “${sourceChannel}x” != “x” ]?Set(amiFirstPart=yes))
same => n,ExecIf($[ “${sourceChannel}x” != “x” ]?Hangup())
same => n,Set(CHANNEL(hangup_handler_push)=outbound-hangup-handler,s,1)
same => n,Dial(PJSIP/1234567@ProviderName,60,TU(sub-record-call,s,1))
same => n,GotoIf($[$[ “${ARG2}” = “yes” ] & $[ “${DIALSTATUS}” = “CONGESTION” | “${DIALSTATUS}” = “CHANUNAVAIL” ]]?return:callend)
same => n(return),HangupCauseClear()
same => n,Return()
same => n(callend),GoSub(sub-no-answered-call-finished,s-${DIALSTATUS},1)
exten => h,1,NoOp(Hangup first leg AMI call)
same => n,Hangup()
[outbound-hangup-handler]
exten => s,1,NoOp()
same => n,GotoIf($[ “${amiFirstPart}” = “yes” ]?callend)
same => n,Set(CDR(last_call_attempt)=yes)
same => n(callend),Return()
[sub-no-answered-call-finished]
exten => s-BUSY,1,Playback(is-curntly-busy)
exten => s-BUSY,n,Playtones(busy)
exten => s-BUSY,n,Wait(3)
exten => s-BUSY,n,Hangup()
We encountered the following problem: When making a call through AMI Originate, if the called party hangs up (the caller receives a “busy” signal), the last executed Hangup application does not appear in the CDR.
If the call is made directly, everything works correctly. If the AMI call ends successfully, everything also works correctly. We also noticed that with an AMI call, the required record sometimes appears in the CDR, but it seems random—twice it appeared, then 50 times it didn’t.
In cases where the record does not appear, the Set(CDR(last_call_attempt)=yes) does not execute, and the CDR logic breaks down.
Sometimes we do receive a hangup in the CDR if party A hangs up the phone, and during regular calls, we always receive it, no matter who hangs up first.
Could you please explain why there might be issues with the last_application = Hangup not appearing in the CDR intermittently?