Asterisk tips SIP URI Dial

Incoming SIP URI Calls to your server

To allow incoming SIP URL calls to your server, you need to add some DNS entries to your DNS zone file for your domain, and configure sip.conf to point unauthenticated requests to the right context in your dialplan (extensions.conf) Examples here work with asterisk 1.2.x (and probably 1.4.x)

DNS Zone file example

(In this case my asterisk server is called and I have a service alias for pointing to it.)
Here is what the top of a BIND zone file might look like. I have included all of it so you can see where the SRV records go.

@ IN SOA (
2007051600 ; serial
8h ; refresh
1h ; retry
1w ; expire
5m ) ; neg cache time


; Mail server

IN MX 10

; A record for SIP server (clients that do not support SRV lookups)
; Note that if you do this, if people expect to web browse to ""
; and the web server is not the same box, then your asterisk server will need
; a web server on it that just redirects clients to


; Definition of DNS SRV record:
; _Service._Proto.Name TTL Class SRV Priority Weight Port Target

; _sip._tcp IN SRV 1 0 5060 boris
_sip._udp IN SRV 1 0 5060 boris

; SIP Server (called here..)

boris A


In sip.conf, the default context for incoming calls needs to be pointed to a context that can handle your SIP URI requests.
This must NOT be the same context that your internal SIP clients are in, otherwise you will create an insecure system, allowing anybody to dial outside lines from your asterisk server.

sip.conf example. Bits relevent to SIP URI Dial


srvlookup=yes ;optional if you want to force a particular domain.


callerid="Jeremy Perkins" <501>
... etc ...

callerid="Alice Jones" <502>
... etc...

extensions.conf example

Now, when a call comes in from an unathenticated user, it will land in the context [from-sip]. This context needs to contain the local parts of the SIP URIs you want to handle.

Extensions.conf example (incoming call processing)

(make your window wide to see this without wrapping)

include => sip-direct
; include a separate context here pointing to your extensions if you want
; to also support "" etc.
;; include => local-extensions

exten => t,1,Hangup
exten => i,1,Congestion
exten => s,1,Congestion
exten => h,1,Hangup


; In this case, from-client is a context that is aware of what 501 and 502 are and does a Dial(SIP/${EXTEN})
; do NOT "include =>" the same context here that your phones are in, or you will create an insecure system.

exten => jeremy,1,Goto(from-client,501,1)
exten => alice,1,Goto(from-client,502,1)
;; You could put these in a separate #include file if there are lots of them.
;; #include /etc/asterisk/SITE/sip-usernames.conf


;; This is and example of the context that your phones are in.
;; Only point to this from outside, not include it.
;; This context probably looks something like this. It might also just already be the default context, which
;; includes only internal extensions.

include => local-extensions
include => dial-pstn
include => bunch-of-other-stuff
include => dial-uri

exten => s,1,Congestion
exten => i,1,Hangup
exten => t,1,Hangup
exten => h,1,Hangup


;; example of what local extensions might look like already:

exten => _5XX,1,Dial(SIP/${EXTEN},20,tr)
exten => _5XX,n,GotoIf($["${DIALSTATUS}" = "CHANUNAVAIL"]?700)
exten => _5XX,n,GotoIf($["${DIALSTATUS}" = "UNKNOWN"]?i,1)
exten => _5XX,n,GotoIf($["${DIALSTATUS}" = "ANSWER"]?t,1)
exten => _5XX,n,GotoIf($["${DIALSTATUS}" = "BUSY"]?800)
exten => _5XX,n,GotoIf($["${DIALSTATUS}" = "CONGESTION"]?700)
exten => _5XX,n,GotoIf($["${DIALSTATUS}" = "NOANSWER"]?700)
exten => _5XX,n,Hangup

;; If unavailable, jump to voicemail etc...
exten => _5XX,700,Voicemail(u${EXTEN})
exten => _5XX,n,Hangup

;; If busy jump to voicemail etc...
exten => _5XX,800,Voicemail(b${EXTEN})
exten => _5XX,n,Hangup

exten => s,1,Congestion
exten => i,1,Hangup
exten => t,1,Hangup
exten => h,1,Hangup

Outgoing SIP URI Dial (from your clients to outside)

In the context that your phones are in (in this example local-extensions), you need to have something that knows how to do the SIP dialout, and also you will need, in sip.conf, srvlookup=yes

Then your phones/clients will be able to dial a SIP address like "".

extensions.conf (outgoing call processing)


include => local-extensions
;; note that dial-uri should probably be the last include => as it might catch other stuff you don't want...
include => dial-uri

...etc ...

exten => _[a-z].,1,Macro(uridial,${EXTEN}@${SIPDOMAIN})
exten => _[A-Z].,1,Macro(uridial,${EXTEN}@${SIPDOMAIN})
exten => _X.,1,Macro(uridial,${EXTEN}@${SIPDOMAIN})

;; Cut out the ";user=phone...." bits at the end of SIP URI that some clients add
exten => s,1,Set(dialuri=${CUT(ARG1,\;,1)})
;; You may or may not need to append your domain name depending if you have
;; fromdomain= enabled in sip.conf. (otherwise you end up with "")
;;exten => s,n,Set(CALLERID(number)=${CALLERID(number)}
;; corrrect outgoing caller ID from DB name:
exten => s,n,ExecIf($["${DB(${CALLERID(number)}/user_sipname)}" != ""],Set,CALLERID(number)=${DB(${CALLERID(number)}/user_sipname)})
exten => s,n,NoOp(Calling SIP URI ${dialuri})
exten => s,n,NoOp(--- From: ${CALLERID(all)} ---)
exten => s,n,Dial(SIP/${dialuri},120,tr)
exten => s,n,Congestion()

In macro-uridial, it sets the outgoing callerid using a database lookup to be the correct thing (you can always remove this if you are happy with the callerID, or if your SIP extensions are already correct.) Here I want to convert my numeric callerID (5XX) into the right outgoing SIP username. The entries in the asterisk database look like:

$ asterisk -r
boris*CLI> database put 501 user_sipname jeremy
Updated database successfully
boris*CLI> database put 502 user_sipname alice
Updated database successfully
boris*CLI> database show 501
/501/user_sipname : jeremy

You may of course hard code this, or have another way to get the outgoing callerID, or you might just not care about the outgoing caller ID.

Of course, reload asterisk after changing any .conf files: asterisk -rx reload
(database updates do not require a reload)

The previous sample dialplan does not work correctly with FreePBX. Specially, it does not take into account The FreePBX Caller ID scheme, and is conflicting with the Meetme application.

Here is another solution, tested with asterisk 1.2.18 and FreePBX 2.3.1.

Put this code inside extensions_custom.conf, and place the desired phones inside the dial-uri context so that they can dial URI.


; version 1.1 november 2007

; Set here the 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=

; 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(
exten => _.,n,Set(

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

exten => _.,n,Set(TRUNKOUTCID="Appel URI"<URICall>)

; 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.

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


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)})

Have fun with URI dialing !

(Work from Olivier ADLER from FRANCE IP, based on different ideas found on the web).

See also

Created by: robl, Last modification: Sun 02 of Dec, 2007 (15:36 UTC) by olivier1010
Please update this page with new information, just login and click on the "Edit" or "Discussion" tab. Get a free login here: Register Thanks! - Find us on Google+