;Version("3.1.2.151")
;InformationalVersion("3.1.2.0")

[nixxis-outbound]

exten => _[a-zA-Z0-9+].,1,NoOp(outbound call to ${EXTEN})

 same => n,Set(IAXORSIP=SIP)
 same => n,Set(MONITORFILE=${SIP_HEADER(x-cr-rec)})
 same => n,Set(ACCOUNTCODE=${IF($["${SIP_HEADER(x-cr-acc)}"!=""]?${SIP_HEADER(x-cr-acc)}:${CDR(accountcode)})})
 same => n,Set(FROM=${SIP_HEADER(From)})
 same => n,Set(PROV=${SIP_HEADER(x-cr-prov)})

 same => n,SendText(CRIVRmon:${CHANNEL})

 same => n,GotoIf($["${SIP_HEADER(x-cr-iex)}" = "http"]?ivrInfoHttp:ivrInfoDone)

 same => n(ivrInfoHttp),Set(NixxisAppServerUri=${SIP_HEADER(x-cr-hsr)})
 same => n,Set(CURLOPT(httptimeout)=3)
 same => n,Set(RequestUri=${NixxisAppServerUri}/sip?action=getIvrInfo&sipid=${SIPCALLID}&version=${CUT(NixxisFileVersion,\",2)})
 same => n,Set(RawAnswer=${CURL(${RequestUri})})
 same => n,GoSub(ParseIvrInfo(${RawAnswer}))

 same => n(ivrInfoDone),Set(CDR(accountcode)=${ACCOUNTCODE})
 same => n,Set(PREDIAL=${CUT(PROV,/,2)})
 same => n,Set(PROVSPLIT=${CUT(PROV,/,1)})
 same => n,ExecIf($["${PROVSPLIT}"!=""]?Set(PROV=${PROVSPLIT}))
 same => n,Set(MONITORPATH=${NixxisRecordingPath}/${ACCOUNTCODE})
 same => n,Set(PeerName=${EXTEN})
 same => n,GoSub(ValidatePeer(${PeerName}))
 
 ;Direct sip dial in case extension is registered
 same => n,GotoIf($["${PROVSPLIT}"="" & "${PeerIp}" != "" & "${NixxisNoExtenDial}" = ""]?ExtenSipDial)

 same => n,GoSub(ValidateIaxPeer(${PeerName}))
 
 ;Direct iax dial in case extension is registered
 same => n,GotoIf($["${PROVSPLIT}"="" & "${PeerIp}" != "" & "${NixxisNoExtenDial}" = ""]?ExtenIaxDial)


 ;Dial backoffice if match found
 same => n,GotoIf($["${PROVSPLIT}"="" & ${DIALPLAN_EXISTS(${IF($["${ACCOUNTCODE}" != ""]?${ACCOUNTCODE}-)}BackOffice,${EXTEN},1)} ]?${IF($["${ACCOUNTCODE}" != ""]?${ACCOUNTCODE}-)}BackOffice,${EXTEN},1)
 

 same => n(NoBackOffice),Set(PeerName=${PROV}-${ACCOUNTCODE}-Outbound)
 same => n,GoSub(ValidatePeer(${PeerName}))
 same => n,GotoIf($["${PeerIp}" != ""]?PeerFound)

 same => n,Set(PeerName=${PROV}-${ACCOUNTCODE}-Outbound)
 same => n,GoSub(ValidateIaxPeer(${PeerName}))
 same => n,GotoIf($["${PeerIp}" != ""]?IaxPeerFound)

 same => n,Set(PeerName=${PROV}-${ACCOUNTCODE})
 same => n,GoSub(ValidatePeer(${PeerName}))
 same => n,GotoIf($["${PeerIp}" != ""]?PeerFound)

 same => n,Set(PeerName=${PROV}-${ACCOUNTCODE})
 same => n,GoSub(ValidateIaxPeer(${PeerName}))
 same => n,GotoIf($["${PeerIp}" != ""]?IaxPeerFound)

 same => n,Set(PeerName=${ACCOUNTCODE}-Outbound)
 same => n,GoSub(ValidatePeer(${PeerName}))
 same => n,GotoIf($["${PeerIp}" != ""]?PeerFound)

 same => n,Set(PeerName=${ACCOUNTCODE}-Outbound)
 same => n,GoSub(ValidateIaxPeer(${PeerName}))
 same => n,GotoIf($["${PeerIp}" != ""]?IaxPeerFound)

 same => n,Set(PeerName=${PROV})
 same => n,GoSub(ValidatePeer(${PeerName}))
 same => n,GotoIf($["${PeerIp}" != ""]?PeerFound)

 same => n,Set(PeerName=${PROV})
 same => n,GoSub(ValidateIaxPeer(${PeerName}))
 same => n,GotoIf($["${PeerIp}" != ""]?IaxPeerFound)

 same => n,Set(PeerName=${ACCOUNTCODE})
 same => n,GoSub(ValidatePeer(${PeerName}))
 same => n,GotoIf($["${PeerIp}" != ""]?PeerFound)

 same => n,Set(PeerName=${ACCOUNTCODE})
 same => n,GoSub(ValidateIaxPeer(${PeerName}))
 same => n,GotoIf($["${PeerIp}" != ""]?IaxPeerFound)


 same => n,Verbose(1,    -- No outbound peer found)
 same => n,Congestion()

 same => n(IaxPeerFound),Set(IAXORSIP=IAX2)

 same => n(PeerFound),NoOp(Set CLI data from header ${SIP_HEADER(From)})
 same => n,Set(CALLERIDEXPR="[+]?([0-9]+)")
 same => n,Set(ReceivedCLI=${CALLERID(name)})
 same => n,ExecIf($[!("${ReceivedCLI}"~=${CALLERIDEXPR})]?Set(ReceivedCLI=${CALLERID(num)})
 same => n,Set(PrefixCLI=${CUT(ReceivedCLI,#,2)})
 same => n,ExecIf($["${PrefixCLI}"!=""]?Set(ReceivedCLI=${CUT(ReceivedCLI,#,3)})
 same => n,Set(SendCLI=$["${ReceivedCLI}" : ${CALLERIDEXPR}])
 same => n,GotoIf($["${SendCLI}"!=""]?ForwardCLI)
 same => n,Set(SendCLI=)
 same => n,Set(PrefixCLI=31)
 same => n(ForwardCLI),Set(CALLERID(name)=${SendCLI})
 same => n,Set(CALLERID(num)=${SendCLI})
 same => n,GotoIf($["${PrefixCLI}"!="31"]?checkmon)
 same => n,Set(CALLERID(num-pres)=prohib)
 ;same => n,SIPAddHeader(P-Asserted-Identity: <sip:${CALLERID(num)}@1.2.3.4>)
 ;same => n,SIPAddHeader(Privacy:id)
 
 same => n(checkmon),GotoIf($["${MONITORFILE}" != ""]?mon:dial)
 same => n(mon),ExecIf($["${NixxisRecordingProcessing}" = "" ]?MixMonitor(${MONITORPATH}/${MONITORFILE}.wav):MixMonitor(${MONITORPATH}/${MONITORFILE}.wav,,${NixxisRecordingProcessing} "^{MIXMONITOR_FILENAME}"))

 same => n(dial),NoOp(Preparing outbound call to ${EXTEN})

 same => n,ExecIf($["${ManifoneCarrier_camp}"!=""]?SIPAddHeader(X-MANITERM-CAMPAIGN:${ManifoneCarrier_camp}))
 same => n,ExecIf($["${ManifoneCarrier_dst}"!=""]?SIPAddHeader(X-MANITERM-DST-FOR-CAMPAIGN:${ManifoneCarrier_dst}))
 same => n,ExecIf($["${ManifoneCarrier_amd}"!=""]?SIPAddHeader(X-MANITERM-AMD:${ManifoneCarrier_amd}))

 same => n,GotoIf($["${PREDIAL}" = ""]?DefaultDial)
 same => n,Goto(${PREDIAL},${EXTEN},1)

 ; The DefaultDial and SipDial priority names are used to get back here from the pre-dial extension, don't change !

 same => n(DefaultDial),GotoIf(${DIALPLAN_EXISTS(${PeerName}-Dial)}?${PeerName}-Dial,${EXTEN},1)

 same => n(SipDial),NoOp(outbound call to ${EXTEN} via ${PeerName})
 same => n,Dial(${IAXORSIP}/${PeerName}/${EXTEN},120)

 same => n,GotoIf($["${BackupCarrier}" = ""]?hangup)
 same => n,Set(PeerName=${BackupCarrier})
 same => n,Set(BackupCarrier=)
 same => n,GotoIf($["${DIALSTATUS}" = "CHANUNAVAIL"]?PeerFound)
 same => n,GotoIf($["${DIALSTATUS}" = "CONGESTION"]?PeerFound)

 same => n(hangup),NoOp(Continue after We lost the AppServer....)
 same => n,HangUp()

 same => n(ExtenSipDial),NoOp(outbound call to SIP extension ${EXTEN})
 same => n,Dial(SIP/${EXTEN})
 same => n,HangUp()

 same => n(ExtenIaxDial),NoOp(outbound call to IAX extension ${EXTEN})
 same => n,Dial(IAX/${EXTEN})
 same => n,HangUp()

 same => n(ValidatePeer),ExecIf($["${PeerName}" != ""]?Set(PeerIp=${SIPPEER(${PeerName})})
 same => n,Set(PeerStatus=${SIPPEER(${PeerName},status)})
 same => n,ExecIf($["${PeerIp}" = "(null)"]?Set(PeerIp=))
 same => n,ExecIf($["${PeerStatus}" = "UNREACHABLE"]?Set(PeerIp=))
 same => n,Return


 same => n(ValidateIaxPeer),ExecIf($["${PeerName}" != ""]?Set(PeerIp=${IAXPEER(${PeerName})})
 same => n,Set(PeerStatus=${IAXPEER(${PeerName},status)})
 same => n,ExecIf($["${PeerIp}" = "(null)"]?Set(PeerIp=))
 same => n,ExecIf($["${PeerStatus}" = "UNREACHABLE"]?Set(PeerIp=))
 same => n,Return

 same => n(ParseIvrInfo),NoOp(Parsing IvrInfo)
 same => n,While($["${SET(AnswerPart=${SHIFT(ARG1,&)})}" != ""])
 same => n,Set(PartName=${CUT(AnswerPart,=,1)})
 same => n,Set(PartValue=${AnswerPart:$[${LEN(${PartName})}+1]})
 same => n,ExecIf($["${PartName}" = "x-cr-acc"]?Set(ACCOUNTCODE=${PartValue}))
 same => n,ExecIf($["${PartName}" = "x-cr-rec"]?Set(MONITORFILE=${PartValue}))
 same => n,ExecIf($["${PartName}" = "x-cr-prov"]?Set(PROV=${PartValue}))
 same => n,ExecIf($["${PartName}" = "x-cr-lan"]?Set(LAN=${PartValue}))
 same => n,ExecIf($["${PartName}" = "x-cr-carrier"]?Set(CR_CARRIER=${PartValue}))
 same => n,EndWhile
 same => n,GotoIf($["${CR_CARRIER}"=""]?IvrInfoParsed)
 same => n,Set(CrCarrierName=${SHIFT(CR_CARRIER,\;)})
 same => n,While($["${SET(Var=${SHIFT(CR_CARRIER,\;)})}"!=""])
 same => n,Set(Param=${CUT(Var,=,1)})
 same => n,ExecIf($[${LEN(${Param})}<${LEN(${Var})}]?Set(${CrCarrierName}_${Param}=${Var:$[${LEN(${Param})}+1]}))
 same => n,EndWhile
 same => n(IvrInfoParsed),Return
