Asterisk

Dialing URL-based SIP targets

[index] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] [16]

URL-based SIP Dialing

I also posted this to the digium asterisk-users mailing list. This page is updated as of 17-Nov with a clean and working solution. See below for details:

One of the more puzzling frustrations I've faced in working with Asterisk is that the dialplan seems to have been built without the accomodation for SIP dialing to be done through the Asterisk box acting as a sip proxy. I was startled to discover that dialing an URI-based SIP address such as sip:nugget@macnugget.org from my cisco phone or from a soft phone like x-lite resulted in a connection to a local "nugget" extension to the phone's Asterisk server. I was surprised that Asterisk was stripping off the SIP domain before working through the dialplan, although I've grown familiar with working with the dialplan this way it still feels odd to me.

Early on in my configuring I discovered a functional (albeit crufty and akward) approach devised by Wayne Harrison. It's not what I'd prefer because it requires a strange transformation of the URI and involves dialing prefixes. He has documented his approach at his web site.

While that does work, it wasn't what I was hoping to accomplish. I later found this little tease which leads the reader to the conclusion that SIP dialing through Asterisk is just a Simple Matter of ProgrammingTM but seems to handwave past the hurdles that would face a person designing a dialplan as described.

I think I've got a workable solution, though. It involves creating a stub "preamble" context for those devices which need the ability to proxy URL-target SIP calls through asterisk. For me, this is my [house] context devices and [remote] context devices. What I did was move my current [house] context dialplan to a new [house-noturi] context so that non-URL target calls would be unaffected. Then I put a single "match everything" extension in the now-empty [house] context which checks ${SIPDOMAIN} for locality. I defined some variables to simplify this test. Elided sample:

; Script constants
MYDOMAIN => macnugget.org
MYFQDN => suburbia.notslacker.com

[macro-uridial]
exten => s,1,NoOp(Outbound SIP URI call ${ARG1})
exten => s,2,SetCIDNum(5125380508)
exten => s,3,Dial(SIP/${ARG1})
exten => s,4,Congestion()

[house]
exten => _.,1,NoOp(Incoming Call from house extension ${CALLERID} for ${EXTEN}@${SIPDOMAIN})
exten => _.,2,GotoIf($[${LEN(${SIPDOMAIN})} = 0]?10)
exten => _.,3,GotoIf($[${SIPDOMAIN} = ${MYDOMAIN}]?10)
exten => _.,4,GotoIf($[${SIPDOMAIN} = ${MYFQDN}]?10)
exten => _.,5,GotoIf($[${SIPDOMAIN} = ${MYFQDN}:5060]?10)
exten => _.,6,NoOp(@${SIPDOMAIN} is remote, forwarding...)
exten => _.,7,Macro(uridial,${EXTEN}@${SIPDOMAIN})
exten => _.,8,HangUp()
exten => _.,10,Goto(house-noturi,${EXTEN},1)
exten => h,1,HangUp()

[house-noturi]
include => local
include => trunkld
include => trunkint
include => emergency

If a SIP client in the [house] context places a call now, it will always match the _. extension. This gives me a nice, detailed log line via NoOp and then tests to see if the SIPDOMAIN variable is local. If so, it shunts straight to the "old" house context which now lives in [house-noturi]. If SIPDOMAIN is remote it calls my uridial macro. (This could just be handled directly, but I like macros :)

In practice I'm finding that it works really well. Here's a sample dialplan log:

 -- Executing NoOp("SIP/nugget-4f46", "Incoming Call from house extension David McNett
    <201> for tomn@sneaky.net") in new stack
  -- Executing GotoIf("SIP/nugget-4f46", "0?10") in new stack
  -- Executing GotoIf("SIP/nugget-4f46", "0?10") in new stack
  -- Executing NoOp("SIP/nugget-4f46", "@sneaky.net is remote| forwarding...") in new stack
  -- Executing Macro("SIP/nugget-4f46", "uridial|tomn@sneaky.net") in new stack
  -- Executing NoOp("SIP/nugget-4f46", "Outbound SIP URI call tomn@sneaky.net") in new stack
  -- Executing SetCIDNum("SIP/nugget-4f46", "5125380508") in new stack
  -- Executing Dial("SIP/nugget-4f46", "SIP/tomn@sneaky.net") in new stack
  -- parse_srv: SRV mapped to host sun.sneaky.net, port 5060
  -- Called tomn@sneaky.net
  -- SIP/sneaky.net-391c is ringing
  -- SIP/sneaky.net-391c is making progress passing it to SIP/nugget-4f46
  -- SIP/sneaky.net-391c answered SIP/nugget-4f46
  -- Attempting native bridge of SIP/nugget-4f46 and SIP/sneaky.net-391c
== Spawn extension (macro-uridial, s, 3) exited non-zero on 'SIP/nugget-4f46' in macro 'uridial'
== Spawn extension (house, tomn, 5) exited non-zero on 'SIP/nugget-4f46'
  -- Executing Hangup("SIP/nugget-4f46", "") in new stack
== Spawn extension (house, h, 1) exited non-zero on 'SIP/nugget-4f46'

Yay. I've published my most recent extensions.conf if you want to see the whole thing in context. Feedback and suggestions would be welcomed.

Next: I can never remember phone numbers!

contacts comments