#include ext-radius.conf

[general]
static=yes
autofallthrough=yes

[forbidden]
exten =>          h,1,Hangup(21)
exten => _[0-9a-zA-Z*+#]!,1,NoOp(-- No context for host ${CHANNEL(recvip)} --)
same =>             n,Log(NOTICE,UC from ${CALLERID(name)} ${CALLERID(num)}@${CHANNEL(recvip)} to ${EXTEN})
same =>             n,Hangup(21)

[h323-id]
exten => _[#+*0-9]!,1,NoOp(-- H323 ID --)
same =>             n,Set(ID=${SIP_HEADER(h323-conf-id)})
same =>             n,ExecIf($[ "${ID}" = "" ]?Set(ID=${RAND(300000000,2000000000)}-${RAND(300000000,2000000000)}-${RAND(300000000,2000000000)}-${RAND(300000000,2000000000)}))
same =>             n,Set(H323_ID=${ID}) 
same =>             n,Set(H323_ID_HEX=${MATH(${CUT(ID,,1)}+0,hex)} ${MATH(${CUT(ID,,2)}+0,hex)} ${MATH(${CUT(ID,,3)}+0,hex)} ${MATH(${CUT(ID,,4)}+0,hex)})
same =>             n,SIPAddHeader(h323-conf-id: ${H323_ID})
same =>             n,Set(CDR(h323id)=${H323_ID_HEX})
same =>             n,Return()

[fromhost]
exten =>   _[*0-9]!,1,NoOp(-- Inbound Authentication for customer IP --)
same =>             n,Set(CDR(CustomerType)=IpAuth)
same =>             n,Set(CDR(accountcode)=${CHANNEL(recvip)})
same =>             n,Gosub(h323-id,${EXTEN},1)
same =>             n,Set(MYCALLID=${SIPCALLID})
same =>             n,AGI(/var/lib/asterisk/agi-bin/agi-rad-auth.pl,Routing=SIP&AuthorizeBy=Account&Password=cisco&H323_ID=${H323_ID}&CustomerType=IpAuth&H323_RADDR=${CHANNEL(recvip)})
same =>             n,Set(CDR(disconnect-reason)=${h323-return-code})
same =>             n,Goto(rad-auth,${VERIFIED_EXTEN},1)

[fromnode]
exten =>   _[*0-9]!,1,NoOp(-- Inbound Authentication --)
same =>             n,Set(CDR(CustomerType)=PeerAuth)
same =>             n,Set(CDR(accountcode)=${CHANNEL(recvip)})
same =>             n,Gosub(h323-id,${EXTEN},1)
same =>             n,Set(MYCALLID=${SIPCALLID})
same =>             n,AGI(/var/lib/asterisk/agi-bin/agi-rad-auth.pl,Routing=SIP&AuthorizeBy=Account&Password=cisco&H323_ID=${H323_ID}&CustomerType=PeerAuth&H323_RADDR=${CHANNEL(recvip)})
same =>             n,Set(CDR(disconnect-reason)=${h323-return-code})
same =>             n,Goto(rad-auth,${VERIFIED_EXTEN},1)

[fromaccount]
exten => _[#+*0-9]!,1,NoOp(-- SIP Authentication --)
same =>             n,Set(CDR(CustomerType)=SipAuth)
same =>             n,Set(CDR(accountcode)=${SIP_Username})
same =>             n,Gosub(h323-id,${EXTEN},1)
same =>             n,Set(SIP_Authorization=${SIP_HEADER(Proxy-Authorization)})
same =>             n,Execif($[ "${SIP_Authorization}" = "" ]?Set(SIP_Authorization=${SIP_HEADER(Authorization)}))
same =>             n,AGI(/var/lib/asterisk/agi-bin/agi-rad-auth.pl,Routing=SIP&AuthorizeBy=SIP&IfFailed=DoNotHangup&H323_ID=${H323_ID}&CustomerType=SipAuth&H323_RADDR=${CHANNEL(recvip)})
same =>             n,Goto(rad-auth,${VERIFIED_EXTEN},1)

[rad-auth]
exten =>   _[*0-9]!,1,NoOp()
same =>             n,Set(RECVIP=${CHANNEL(recvip)})
same =>             n,Set(PBCLD=${PBCLD})
same =>             n,Set(CDR(disconnect-reason)=${h323-return-code})
same =>             n,GotoIf($[ "${h323-return-code}" = "1" ]?invalid_account,${EXTEN},1)
same =>             n,GotoIf($[ "${h323-return-code}" = "2" ]?wrong_passwd,${EXTEN},1)
same =>             n,GotoIf($[ "${h323-return-code}" = "3" ]?in_use,${EXTEN},1)
same =>             n,GotoIf($[ "${h323-return-code}" = "4" ]?zero_balance,${EXTEN},1)
same =>             n,GotoIf($[ "${h323-return-code}" = "5" ]?account_expired,${EXTEN},1)
same =>             n,GotoIf($[ "${h323-return-code}" = "6" ]?credit_limit,${EXTEN},1)
same =>             n,GotoIf($[ "${h323-return-code}" = "7" ]?user_denied,${EXTEN},1)
same =>             n,GotoIf($[ "${h323-return-code}" = "8" ]?not_avail,${EXTEN},1)
same =>             n,GotoIf($[ "${h323-return-code}" = "9" ]?no-route-exists-to-dest,${EXTEN},1)
same =>             n,GotoIf($[ "${h323-return-code}" = "10" ]?retries,${EXTEN},1)
same =>             n,GotoIf($[ "${h323-return-code}" = "12" ]?insufficient_balance,${EXTEN},1)
same =>             n,GotoIf($[ "${h323-return-code}" = "14" ]?Not-Found-2,${EXTEN},1)
same =>             n,GotoIf($[ "${h323-return-code}" = "0" | "${h323-return-code}" = "13" ]?welcome-msg,${EXTEN},1)
same =>             n,Goto(cannot-complete-temp-error,${EXTEN},1)

[welcome-msg]
exten => _[*0-9]!,1,NoOp()
exten => _[*0-9]!,n,ExecIf($[ ${XTOT} < 1 ]?Gosub(check_ua,${EXTEN},1))
exten => _[*0-9]!,n,GotoIf($[ ${XTOT} < 1 & "${multipleUA}" = "0" ]?telephone-number-temp-disconnected,${EXTEN},1)
exten => _[*0-9]!,n,Set(User_Agent=${SIP_HEADER(User-Agent)})
exten => _[*0-9]!,n,Set(CDR(User-Agent)=User-Agent:${User_Agent})
exten => _[*0-9]!,n,Progress
;exten => _[*0-9]!,n,Wait(0.5)
exten => _[*0-9]!,n,ExecIf($[ "${h323-return-code}" = "13" ]?Playback(free-calls,noanswer):Playback(beep,noanswer))
exten => _[*0-9]!,n,Goto(routing,${EXTEN},1)

[MyRoute]
exten => _[*0-9]!,1,NoOp()
exten => _[*0-9]!,n,ExecIf($[ "${ActivePrivacy}" = "1" ]?SetCallerPres(prohib_not_screened)) ; this might not be needed --- needs further testing
exten => _[*0-9]!,n,Set(multipleUA=0)
exten => _[*0-9]!,n,GotoIf($["${connid}" = ""]?MyRoute-error,${EXTEN},1)
exten => _[*0-9]!,n,MYSQL(Query resultid ${connid} CALL set_route('${PBCLD}','${CHANNEL(recvip)}'))
exten => _[*0-9]!,n,MYSQL(Query resultid ${connid} SELECT get_route('${PBCLD}'))
exten => _[*0-9]!,n,MYSQL(Fetch fetchid ${resultid} myROUTE)
exten => _[*0-9]!,n,GotoIf($[ "${myROUTE}"="NULL" | "${myROUTE}"="" ]?MyRoute-error,${EXTEN},1)
exten => _[*0-9]!,n,MYSQL(Clear ${resultid})
exten => _[*0-9]!,n,MYSQL(Disconnect ${connid})
exten => _[*0-9]!,n,Set(VDNID=${PBCLD})
exten => _[*0-9]!,n,Set(ROUTEIP=${NAS_IP_Address})
exten => _[*0-9]!,n,Dial(${myROUTE},30,${CALL_LIMIT})
exten => _[*0-9]!,n,Hangup(${HANGUPCAUSE})
exten => _[*0-9]!,n,Set(CDR(Hangupcause)=Hangupcause:${HANGUPCAUSE})

[MyRoute-error]
exten => _[*0-9]!,1,NoOp()
exten => _[*0-9]!,n,Dial(SIP/${PBCLD},30,${CALL_LIMIT})
exten => _[*0-9]!,n,Hangup(${HANGUPCAUSE})
exten => _[*0-9]!,n,Set(CDR(Hangupcause)=Hangupcause:${HANGUPCAUSE})

[check_ua]
exten => _[*0-9]!,1,NoOp()
exten => _[*0-9]!,n,MYSQL(Connect connid localhost ${dbuser} ${dbpass} ${dbname})
exten => _[*0-9]!,n,GotoIf($["${connid}" = ""]?error)
exten => _[*0-9]!,n,MYSQL(Query resultid ${connid} SELECT 1 FROM multiple_ua WHERE username='${PBCLD}' LIMIT 1)
exten => _[*0-9]!,n,MYSQL(Fetch fetchid ${resultid} multipleUA)
exten => _[*0-9]!,n,ExecIf($[ "${multipleUA}"="NULL" | "${multipleUA}"="" ]?Set(multipleUA=0))
exten => _[*0-9]!,n,MYSQL(Clear ${resultid})
exten => _[*0-9]!,n,ExecIf($[ "${multipleUA}" = "0" ]?MYSQL(Disconnect ${connid}))
exten => _[*0-9]!,n(error),Return()

[routing]
exten => _[*0-9]!,1,NoOp()
exten => _[*0-9]!,n,ExecIf($[ "${CALLERID(name)}" = "Anonymous" | "${CALLERID(name)}" = "anonymous"]?Set(ActivePrivacy=1))
exten => _[*0-9]!,n,ExecIf($[ "${multipleUA}" = "0" ]?Gosub(check_ua,${EXTEN},1))
exten => _[*0-9]!,n,GotoIf($[ "${multipleUA}" = "1" ]?MyRoute,${EXTEN},1)
exten => _[*0-9]!,n(loop),NoOp()
exten => _[*0-9]!,n,GotoIf($[ "${II}" = "1" | "${II}" = "0"]?SingleRoute)
exten => _[*0-9]!,n,Playback(the-next,noanswer)
exten => _[*0-9]!,n(SingleRoute),Set(KK=0)
exten => _[*0-9]!,n,Set(SUM_ROUTE=${XSUM_${II}})
exten => _[*0-9]!,n(loop1),NoOp()
exten => _[*0-9]!,n,Set(TARGET_ROUTE=${XROUTE_${II}_${KK}})
exten => _[*0-9]!,n,Set(TARGET_EXPIRE=${XEXP_${II}_${KK}})
exten => _[*0-9]!,n,Set(TARGET_CLI=${XCLI_${II}_${KK}})
exten => _[*0-9]!,n,Set(CALLERID(all)=${TARGET_CLI} <${TARGET_CLI}>)
exten => _[*0-9]!,n,Set(MYDNID=${CUT(TARGET_ROUTE,@,1)})
exten => _[*0-9]!,n,Set(VDNID=${CUT(MYDNID,/,2)})
exten => _[*0-9]!,n,Set(ROUTEIP=${CUT(TARGET_ROUTE,@,2)})
exten => _[*0-9]!,n,GotoIf($[ "${ROUTEIP}" = "" ]?not_avail,${EXTEN},1)
exten => _[*0-9]!,n,GotoIf($[ "${ActivePrivacy}" != "1" ]?noprivacy)
exten => _[*0-9]!,n,GotoIf($[ "${ROUTEIP}" != "${NAS_IP_Address}" ]?extprivacy)
exten => _[*0-9]!,n,SetCallerPres(prohib_not_screened) ; this might not be needed --- needs further testing
exten => _[*0-9]!,n,Goto(noprivacy)
exten => _[*0-9]!,n(extprivacy),NoOp()
exten => _[*0-9]!,n,SIPAddHeader(Remote-Party-ID:"${CALLERID(num)}" <sip:${CALLERID(num)}@${NAS_IP_Address}>\;privacy=full\;screen=yes)
exten => _[*0-9]!,n(noprivacy),NoOp()
exten => _[*0-9]!,n,Dial(${IF($[ "${ROUTEIP}" = "${NAS_IP_Address}"]?${MYDNID}:${TARGET_ROUTE})},${TARGET_EXPIRE},${CALL_LIMIT})
exten => _[*0-9]!,n,Set(HANGUPCAUSE2=${HANGUPCAUSE})
exten => _[*0-9]!,n,Execif($[ "${ROUTEIP}" = "${NAS_IP_Address}" & "${HANGUPCAUSE2}" = "20"]?Set(HANGUPCAUSE2=126))
exten => _[*0-9]!,n,Set(CDR(Hangupcause)=Hangupcause:${HANGUPCAUSE2})
exten => _[*0-9]!,n,Set(KK=$[${KK}+1])
exten => _[*0-9]!,n,GotoIf($[ "${DIALSTATUS}" = "BUSY" | "${DIALSTATUS}" = "NOANSWER" | "${DIALSTATUS}" = "CANCEL" ]?end1)
exten => _[*0-9]!,n,GotoIf($[${KK} < ${SUM_ROUTE} ]?loop1:end1)
exten => _[*0-9]!,n(end1),NoOp()
exten => _[*0-9]!,n,Set(II=$[${II}+1])
exten => _[*0-9]!,n,GotoIf($[${II} <= ${XTOT} ]?loop:end)
exten => _[*0-9]!,n(end),NoOp()
exten => _[*0-9]!,n,Goto(Error-Info,${EXTEN},1)

[Error-Info]
exten => _[*0-9]!,1,NoOp()
exten => _[*0-9]!,n,GotoIf($[ ${XTOT} > 1 ]?Ter)
exten => _[*0-9]!,n,GotoIf($[ "${HANGUPCAUSE2}" = "17" ]?currentlybusy,${EXTEN},1)
exten => _[*0-9]!,n,GotoIf($[ "${HANGUPCAUSE2}" = "126" ]?not_avail,${EXTEN},1)
exten => _[*0-9]!,n,GotoIf($[ "${HANGUPCAUSE2}" = "28" ]?ISUP28,${EXTEN},1)
exten => _[*0-9]!,n,GotoIf($[ "${HANGUPCAUSE2}" = "1" | "${HANGUPCAUSE2}" = "3" | "${HANGUPCAUSE2}" = "27" | "${HANGUPCAUSE2}" = "31" | "${HANGUPCAUSE2}" = "88" | "${HANGUPCAUSE2}" = "95" | "${HANGUPCAUSE2}" = "111" ]?Not-Found,${EXTEN},1)
exten => _[*0-9]!,n,GotoIf($[ ${HANGUPCAUSE2} >= 90 ]?cannot-complete-temp-error,${EXTEN},1)
exten => _[*0-9]!,n,GotoIf($[ "${DIALSTATUS}" = "CANCEL" ]?cancelled,${EXTEN},1)
exten => _[*0-9]!,n,GotoIf($[ "${HANGUPCAUSE2}" = "34" | "${HANGUPCAUSE2}" = "38" | "${HANGUPCAUSE2}" = "41" | "${HANGUPCAUSE2}" = "42" | "${HANGUPCAUSE2}" = "47" ]?all-outgoing-lines-unavailable,${EXTEN},1)
exten => _[*0-9]!,n,GotoIf($[ "${DIALSTATUS}" = "CHANUNAVAIL" ]?an-error-has-occured,${EXTEN},1)
exten => _[*0-9]!,n,GotoIf($[ "${DIALSTATUS}" = "CONGESTION" ]?cannot-complete-otherend-error,${EXTEN},1)
exten => _[*0-9]!,n(Ter),Hangup(${HANGUPCAUSE2})

[ISUP28]
exten => _[*0-9]!,1,SET(error_message="incomplete-num")
exten => _[*0-9]!,n,Gosub(playerror,${EXTEN},1)
exten => _[*0-9]!,n,Hangup(${HANGUPCAUSE2})

[currentlybusy]
exten => _[*0-9]!,1,SET(error_message="the-number-u-dialed&is-curntly-busy")
exten => _[*0-9]!,n,Gosub(playerror,${EXTEN},1)
exten => _[*0-9]!,n,Hangup(${HANGUPCAUSE2})

[user_denied]
exten => _[*0-9]!,1,SET(error_message="user_denied")
exten => _[*0-9]!,n,Gosub(playerror,${EXTEN},1)
exten => _[*0-9]!,n,Hangup(${HANGUPCAUSE2})

[cannot-complete-otherend-error]
exten => _[*0-9]!,1,SET(error_message="cannot-complete-otherend-error")
exten => _[*0-9]!,n,Gosub(playerror,${EXTEN},1)
exten => _[*0-9]!,n,Hangup(${HANGUPCAUSE2})

[cancelled]
exten => _[*0-9]!,1,SET(error_message="cancelled")
exten => _[*0-9]!,n,Gosub(playerror,${EXTEN},1)
exten => _[*0-9]!,n,Hangup(${HANGUPCAUSE2})

[not_avail]
exten => _[*0-9]!,1,SET(error_message="not_avail")
exten => _[*0-9]!,n,Gosub(playerror,${EXTEN},1)
exten => _[*0-9]!,n,Hangup(${HANGUPCAUSE2})

[invalid_account]
exten => _[*0-9]!,1,SET(error_message="invalid_account")
exten => _[*0-9]!,n,Gosub(playerror,${EXTEN},1)
exten => _[*0-9]!,n,Hangup(${HANGUPCAUSE2})

[wrong_passwd]
exten => _[*0-9]!,1,SET(error_message="wrong_passwd")
exten => _[*0-9]!,n,Gosub(playerror,${EXTEN},1)
exten => _[*0-9]!,n,Hangup(${HANGUPCAUSE2})

[account_expired]
exten => _[*0-9]!,1,SET(error_message="account_expired")
exten => _[*0-9]!,n,Gosub(playerror,${EXTEN},1)
exten => _[*0-9]!,n,Hangup(${HANGUPCAUSE2})

[credit_limit]
exten => _[*0-9]!,1,SET(error_message="credit_limit")
exten => _[*0-9]!,n,Gosub(playerror,${EXTEN},1)
exten => _[*0-9]!,n,Hangup(${HANGUPCAUSE2})

[zero_balance]
exten => _[*0-9]!,1,SET(error_message="zero_balance")
exten => _[*0-9]!,n,Gosub(playerror,${EXTEN},1)
exten => _[*0-9]!,n,Hangup(${HANGUPCAUSE2})

[in_use]
exten => _[*0-9]!,1,SET(error_message="simul-call-limit-reached")
exten => _[*0-9]!,n,Gosub(playerror,${EXTEN},1)
exten => _[*0-9]!,n,Hangup(${HANGUPCAUSE2})

[insufficient_balance]
exten => _[*0-9]!,1,SET(error_message="insufficient_balance")
exten => _[*0-9]!,n,Gosub(playerror,${EXTEN},1)
exten => _[*0-9]!,n,Hangup(${HANGUPCAUSE2})

[retries]
exten => _[*0-9]!,1,SET(error_message="retries")
exten => _[*0-9]!,n,Gosub(playerror,${EXTEN},1)
exten => _[*0-9]!,n,Hangup(${HANGUPCAUSE2})

[cannot-complete-temp-error]
exten => _[*0-9]!,1,SET(error_message="cannot-complete-temp-error")
exten => _[*0-9]!,n,Gosub(playerror,${EXTEN},1)
exten => _[*0-9]!,n,Hangup(${HANGUPCAUSE2})

[no-route-exists-to-dest]
exten => _[*0-9]!,1,SET(error_message="no-route-exists-to-dest")
exten => _[*0-9]!,n,Gosub(playerror,${EXTEN},1)
exten => _[*0-9]!,n,Hangup(${HANGUPCAUSE2})

[Not-Found]
exten => _[*0-9]!,1,NoOp()
exten => _[*0-9]!,n,Set(NotFoundContext=Not-Found-${IF($[ ${CUT(TARGET_ROUTE,@,2)} = ${NAS_IP_Address}]?1:2)})
exten => _[*0-9]!,n,Goto(${NotFoundContext},${EXTEN},1)

[Not-Found-1]
exten => _[*0-9]!,1,SET(error_message="not-found")
exten => _[*0-9]!,n,Gosub(playerror,${EXTEN},1)
exten => _[*0-9]!,n,Hangup(${HANGUPCAUSE2})

[Not-Found-2]
exten => _[*0-9]!,1,SET(error_message="you-dialed-wrong-number")
exten => _[*0-9]!,n,Gosub(playerror,${EXTEN},1)
exten => _[*0-9]!,n,Hangup(${HANGUPCAUSE2})

[telephone-number-temp-disconnected]
exten => _[*0-9]!,1,SET(error_message="the-number-u-dialed&temp-disconnected")
exten => _[*0-9]!,n,Gosub(playerror,${EXTEN},1)
exten => _[*0-9]!,n,Hangup(${HANGUPCAUSE2})

[all-outgoing-lines-unavailable]
exten => _[*0-9]!,1,SET(error_message="all-outgoing-lines-unavailable")
exten => _[*0-9]!,n,Gosub(playerror,${EXTEN},1)
exten => _[*0-9]!,n,Hangup(${HANGUPCAUSE2})

[an-error-has-occured]
exten => _[*0-9]!,1,SET(error_message="an-error-has-occured")
exten => _[*0-9]!,n,Gosub(playerror,${EXTEN},1)
exten => _[*0-9]!,n,Hangup(${HANGUPCAUSE2})

[playerror]
exten => _[*0-9]!,1,Set(COUNTER=0)
exten => _[*0-9]!,n,Progress()
exten => _[*0-9]!,n,Wait(0.5)
exten => _[*0-9]!,n(loop),Wait(1)
exten => _[*0-9]!,n,Playback(beeperr,noanswer)
exten => _[*0-9]!,n,Playback(${error_message},noanswer)
exten => _[*0-9]!,n,Set(COUNTER=$[${COUNTER} + 1])
exten => _[*0-9]!,n,GotoIf($[${COUNTER}<=5]?loop)
exten => _[*0-9]!,n,Return
