Outbound URI dialing from asterisk. Not as simple... Working and compatible with freepbx 2.3.1

After many frustrations with Asterisk outbound URI dialing, i’ve decided to write something to get URI dialing possible with Asterisk.

This work is based on some previous works and ideas from other peoples i’ve found on Internet, and on some freepbx dialplan samples.

I hope it will open the door to URI dialing with Asterisk, as it was a nightmare before. Asterisk is not URI dialing friendly. Neither at the calling party side (URIs are not directly parsed in the dialplan), neither at the called party side (authentication problems giving failed calls).

This code try to solve those problems. After a couple of days of testing, things seem right.

It must be copied inside the extensions_custom.conf file.

; URI dialing : place your extensions inside this context to enable outbound URI dialing

[dial-uri]

; version 1.1 november 2007
; Olivier ADLER, FRANCE IP.

; Set here your proxy Asterisk IP address
; This address is sent by some phones in the domain part of the URI.
; The call will be considered local if this address is detected in the destination URI.

exten => _.,1,Set(AsteriskIP=192.168.0.50)

; Change your domain names here. Some phones don’t use that. you can leave defaults in this case
; You can define two domain names, Intranet and Extranet for example
; Or repeat the same name if you have only one
; As soon as an URI address with such a domain name will be detected, the call will be considered local

exten => _.,n,Set(IntraNetDomain=mycompany.fr)
exten => _.,n,Set(ExtraNetDomain=mycompany.fr)

; Define here the URI trunk caller id. Will be used if there is no outbound caller id defined for the calling extension. No need to change it.

exten => _.,n,Set(TRUNKOUTCID=“Appel URI”)

; Set console debug level to 4 to see those logs in the asterisk console
exten => _.,n,NoOp(Incoming Call from internal extension ${CALLERID} for ${EXTEN}@${SIPDOMAIN})

; Tests to see if the call destination is local or not
; We need many tests, because SIP devices do have different URI formats for local calls

exten => _.,n,GotoIf($[${LEN(${SIPDOMAIN})} = 0]?local) ; if there is no domain in the URI, the call is considered local
exten => _.,n,GotoIf($[${SIPDOMAIN} = ${IntraNetDomain}]?local) ; the call is considered local (for our Intranet)
exten => _.,n,GotoIf($[${SIPDOMAIN} = ${IntraNetDomain}:5060]?local) ; the same with a port number appending
exten => _.,n,GotoIf($[${SIPDOMAIN} = ${ExtraNetDomain}]?local) ; the call is considered local (for our Extranet)
exten => _.,n,GotoIf($[${SIPDOMAIN} = ${ExtraNetDomain}:5060]?local) ; the same with a port number appending
exten => _.,n,GotoIf($[${SIPDOMAIN} = ${AsteriskIP}]?local) ; for phones appending the proxy IP adress
exten => _.,n,GotoIf($[${SIPDOMAIN} = ${AsteriskIP}:5060]?local) ; same with port number appending

; If the call destination is not local then we forward it to the remote domain

exten => _.,n,NoOp(@${SIPDOMAIN} is remote, forwarding…)
exten => _.,n,Macro(uridial,${EXTEN}@${SIPDOMAIN})
exten => _.,n,HangUp()

; If the call is local, we send it to the from-internal context

exten => _.,n(local),Goto(from-internal,${EXTEN},1)
exten => h,1,HangUp()

; This macro place the uri call.
[macro-uridial]

exten => s,1,Macro(user-callerid,SKIPTTL)
exten => s,n,Macro(uri-outbound-callerid)
exten => s,n,Dial(SIP/${ARG1},120)
exten => s,n,Congestion()

; This macro choose the right outbound callerid for dial-uri calls

[macro-uri-outbound-callerid]

exten => s,1,Set(USEROUTCID=${DB(AMPUSER/${CALLERID(number)}/outboundcid)}) ; Get the outbound CID number for the calling extension

exten => s,n,GotoIf($["${USEROUTCID:1:2}" != “”]?setcid) ; If defined, use it for the outbound call CID

exten => s,n,Set(CALLERID(all)=${TRUNKOUTCID}) ; If extension outbound CID is not defined, use the URI trunk CID instead

exten => s,n,Goto(report) ; log a report to the console

exten => s,n(setcid),Set(CALLERID(all)=${USEROUTCID})

; The calling party extension number must not exist in the destination dialplan to avoid authentication problems.
; If asterisk receive a call with a calling party extension number present in his dialplan, he will try to authenticate.
; There are good chances that the passwords will be different, and the call will fail.
; This is not really what we want.
; Appending a small text to the calling party extension number solve definitely the problem

exten => s,n,SetCIDNum(${CALLERID(number)}URI)

exten => s,n,GotoIf($[“x${CALLERID(name)}”!=“xhidden”]?report:hidecid) ; check CID blocking for extension
exten => s,n(hidecid),SetCallerPres(prohib_passed_screen) ; Only works with ISDN (T1/E1/BRI)

exten => s,n(report),NoOp(CallerID set to ${CALLERID(all)})