I have worked hard to find informations and experiment to make outboud URI dialing usable in the real word with Asterisk. Asterisk is not very friendly with URI dialing. It seems simple at the beginning, but there is a couple of practical problems to solve to get it really working. My frustration with a lot of "channel unavailable" calls when using URI outbound calling gaves me the energy to make this small but very usefull work.
URI dialing is certainly not as important as ENUM for today public VOIP networks, but it will certainly become more popular as soon as phones will get alpha keyboards.
After this cleaning work on the outbound URI side, i can say as well that the anonymous call inbound routing works well inside freepbx 2.3, as opposite as i was thinking a few days ago.
I have only a couple of days of testing with 4 remote sites, but things feel good.
There is a bit more work to be done, specially with freepbx 2.3 integration.
Actually each extension needing URI dialing must be placed in the dial-uri context.
If the call is detected local, then it is forwarded to the from-internal context. If it is for a remote site, then it is placed with the full URI address through the macro-uridial.
I think it would be better to integrate this work inside the from-internal context, or define a new trunk type.
Last, there is some more work to be done for outboud CID replacement, but globally the following code seems to give good results and has the needed tips in it to get the magic of URI dialing working.
The following code can be included inside extensions_custom.conf. Then change your asterisk IP and domain names inside it, and place your extensions where you want URI dialing in the dial-uri context.
Then test with a softphone like X-lite 3.0. Enter the account data to connect to your asterisk box and select the "send outbound via domain" option in the account property panel.
In this case, X-lite send the full URI to your asterisk box, where it is proxied for the outbound call. Asterisk replace the extension number by an uncommon one, to avoid the frequent "407 authentication requested" error.
Then you will get a reliable URI telephone system. Leaving X-lite sending outbound calls himself is not reliable (Send outboud via target domain option). You will get a "unavailable channel" as soon as the destination has in his dialplan the extension number you have set in your X-lite proxy account.
; URI dialing : place your extensions inside this context to enable outboud URI dialing
[dial-uri]
; version 1.0 november 2007
; Olivier ADLER, FRANCE IP
; input here your Asterisk IP address
exten => _.,1,Set(AsteriskIP=192.168.0.25) ; it's a good idea to have a static IP
; change here your domain names. 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
exten => _.,n,Set(IntraNetDomain=mycompany.fr)
exten => _.,n,Set(ExtraNetDomain=remotehost.company.fr)
; for debugging purpose, set debug level to 4 to see this in the asterisk console
exten => _.,n,NoOp(Incoming Call from internal extension ${CALLERID} for ${EXTEN}@${SIPDOMAIN})
; here we are testing to see if the call is local to this asterisk machine, or not.
; we need many tests, because SIP devices do not send the same URI when calling a local extension
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
; the call is remote : we forward it with the full URI address
exten => _.,n,NoOp(@${SIPDOMAIN} is remote, forwarding...)
exten => _.,n,Macro(uridial,${EXTEN}@${SIPDOMAIN})
exten => _.,n,HangUp()
; 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. (Work to be done for outbound Caller ID replacement.)
[macro-uridial]
; this URI ID need to be appended to the calling party extension number to avoid asterisk 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 would fail.
; this is not really what we want
; appending a small text to the calling party extension number solve definitively the problem
exten => s,1,Set(URIID=URICall) ; this URI ID need to be appended to avoid asterisk authentication problems.
exten => s,2,Macro(user-callerid,SKIPTTL)
exten => s,3,GotoIf($["${ECID${CALLERID(number)}}" = ""]?5) ;check for CID override for exten
exten => s,4,Set(CALLERID(all)=${ECID${CALLERID(number)}})
exten => s,5,SetCIDNum(${CALLERID(number)}*${URIID}*) ; append the URI ID to avoid 407 errors
exten => s,6,Dial(SIP/${ARG1},120)
exten => s,n,Congestion()