gordon.dewis.ca - Random musings from Gordon


Replacement for my Unlimitel dialplan

April 11, 2008 @ 22:44 By: gordon Category: VoIP

When I started using Voice over IP technology, I acquired a wholesale DID from Unlimitel for an extremely reasonable monthly cost. Shortly thereafter I created an Asterisk-friendly version of the dialplan information they provided and made it available for download. It was a very simplistic set of Dial() statements, one per areacode-exchange combination. This resulted in a large number of statements and as Unlimitel’s on-net service area grew, so did it. It also meant that it was easy for my dialplan to be out of date as new exchanges were added. If you wanted to do anything before the Dial() statement you had to either create another context with a pattern that caught what you wanted to do and then went to your outbound Unlimitel context or you had to take my dialplan and insert new statements.

Way too much work and also way too many statements.

I had thought about writing a small Perl program to parse the dialplan information and collapse it to match with broader patterns, but never found the time. And when I had the time, I really didn’t feel like it because, frankly, things were working for me so I didn’t feel like changing it.

When I upgraded my blog a few months ago, I dropped the dialplan from my website during the migration. I hadn’t updated it in months and I knew that Unlimitel had made whole sale changes. A reader looking for my dialplan asked me if I would put it back up.

Recently, I overhauled my dialplans and made things more efficient with macros rather than explicit Dial() statements for every combination of areacode and exchange. For various reasons, I use a couple of different providers to provide outbound paths. Since most of my calls are local, I first try to send the call out via Unlimitel. If Unlimitel doesn’t handle the destination, I then try to send it out via Link2Voip.

The result is that I have eliminated most of the lines being loaded while eliminating the need to maintain an unwieldy dialplan.

Here’s how I did it…

First, I created a macro called “dialout” in extensions.conf thusly:

   1: [macro-dialout]
   2: exten => s,1,Set(CALLERID(all)="Gordon Dewis" <16135555555>)
   3: exten => s,n,Dial(SIP/${ARG1}@unlimitel,60)
   4: exten => s,n,Goto(s-${DIALSTATUS},1)
   6: exten => s-ANSWER,1,Hangup
   8: exten => s-CONGESTION,1,AGI(festival-agi.pl|Status: Congestion for ${ARG1}.)
   9: exten => s-CONGESTION,2,Hangup
  11: exten => s-BUSY,1,NoOp
  12: exten => s-BUSY,n,Macro(diallink2voip,${ARG1})
  14: exten => s-CHANUNAVAIL,1,AGI(festival-agi.pl|Status: Channel unavailable.)
  15: exten => s-CHANUNAVAIL,2,Hangup
  17: exten => s-DONTCALL,1,AGI(festival-agi.pl|Status: Don't call.)
  18: exten => s-DONTCALL,2,Hangup
  20: exten => s-TORTURE,1,AGI(festival-agi.pl|Status: Torture.)
  21: exten => s-TORTURE,2,Hangup
  23: exten => s-INVALIDARGS,1,AGI(festival-agi.pl|Status: Invalid arguments.)
  24: exten => s-INVALIDARGS,2,Hangup

Elsewhere, I call it like this:

exten => _NXXXXXXXXX,1,Macro(dialout,${EXTEN})

So, what happens is this: The _NXXXXXXXXX catches a ten-digit phone number (I can’t be bothered to dial 1 and Unlimitel doesn’t require it) and calls the “dialout” macro passing in the number being dialed.

The macro enters at line 2 in the [macro-dialout] context where I set some callerID info and then try to place the call via Unlimitel. Depending on the result of the Dial() in line 3, various other things kick in.

If Unlimitel returns a busy status (which I’ve only ever seen for a call Unlimitel can’t handle), the call is passed to a similar macro for Link2Voip in lines 11 and 12.

Dial() can return other status codes, so I’ve put things in place to catch the rest (as supported in Asterisk 1.4). Basically, I use Festival to provide some indication of why the call didn’t go through before hanging up. I don’t think I’ve had any of them trip.

By chaining macros like this together, you can set things up so that your call goes out through the most preferred provider that can handle the call.

It could be improved by implementing true least-cost routing (LCR) because I have another outbound provider that has a slightly cheaper per-minute cost for called to US48, but frankly I don’t make enough calls to notice the $0.003/minute difference. That’s a project for the future.

I hope you find this useful. šŸ™‚

Leave a Reply