Friday, October 15, 2010

Least Cost Routing in Lync

NOTE (June 2011):  While the general idea around least cost routing hasn't changed, the process required to use the Dialing Rule Optimizer has been greatly simplified and enhanced since I originally created this post.  See this post for the most up-to-date information on how to best use the Dialing Rule Optimizer.  I do encourage you to read on for general background information on how least-cost routing works.

Companies that have a number of offices spread across a wide geographical area often wish to leverage something called Least Cost Routing to reduce their telephony costs.  Least Cost Routing is the process of selecting the cheapest telephony route for a given call.  If you're a company with offices spread over a wide area, it makes sense to route your calls so that you avoid long-distance changes whenever possible.

Say you are in a company with offices in Toronto, Vancouver, Dallas and Miami. If you're in the Toronto office and you need to call someone in the Miami area, it can be much cheaper to route your call over the WAN to your Miami office and then out to the PSTN. What would have been a long-distance call is now a local one.

Traditionally, it's been extremely tedious to implement Least Cost Routing effectively. You need to obtain lists of all the local calling areas for all your offices, massage the data into something your telephony system understands, and then import that data.  Keeping track of changes can be challenging at best, and near impossible at worst. Publicly available lists such as those from make obtaining the raw data relatively easy, but manually working that data into something manageable is extremely difficult.

For instance, look at the local calling area for Dallas, TX.  The results include 1737 individual lines of data!  Sure, the data is setup for easy import into a spreadsheet, but turning this into something usable will take a very long time. What happens when there are changes? How do you keep track of new additions or corrections?  What if you have to do this for a company with offices across the continent?  How many rules will your device accept before it reaches its limit?

Some people might take a simpler approach and route all calls for a given area code through that office. For Dallas, they might look at the 1737 rules and decide to route all calls to the 214, 469 and 972 area codes through the Dallas office. Sure this works in some cases (like New York City), but most telephone numbers cannot make local calls to every number in that area code.  So, you would be routing some calls over your WAN (which incurs data costs) to your Dallas office and have to pay long-distance anyways.

How can someone easily setup Least Cost Routing without giving themselves an administrative aneurysm when faced with a challenge like this? Well, guess what?  I've got a solution.

Using the data from and the ease-of-administration inherent in Lync's Powershell command structure, I've created a web-based tool called the Dialing Rule Optimizer that does almost everything you need to implement Least Cost Routing in your Lync deployment.

First, you need to make sure your Lync deployment is complete. Specifically, make sure you've defined and published the PSTN gateways for all your offices using Topology Builder.  Make sure the PSTN gateways are associated with the appropriate mediation server.  Also, make sure that all your normalization rules normalize numbers to the E.164 standard ie. +15195551111.

Once published, you need to add the PSTN gateways as Pool Trunks in Lync Control Panel.  Go to Voice Routing - Trunk Configuration.  Click New - Pool Trunk for each PSTN gateway.  Make sure the name of the pool trunk is the same as the PSTN Gateway.  Once complete, you should have something similar to this:

Now, go to the Dialing Rule Optimizer at  I originally created this tool to help create optimized local dialing rules for AudioCodes and Dialogic gateways.  I've recently added Lync functionality.  You will be presented with the following screen:

Enter the area code (NPA) and exchange (NXX) for each of your sites. Leave the gateway type as Lync 2010.  If your PSTN gateway requires a 9 or other number to be dialed before the actual phone number, enter it at External Access #.  Enter the PSTN gateway name in the same format as you created in Topology Builder. In our example, we'll use miami.root.loc. Enter your email address so you will be notified when dialing rule changes are detected.

If your local dialling area allows 7-digit dialling and the 7-digit dialing area spans more than one area code, select the 7-Digit Normalization option.  The program will create 7-digit normalization rules that correspond to your local dialing area.  For example, Kansas City, MO allows 7-digit dialling across the 816 and 913 area codes. With 7-digit normalization selected, the Dialing Rule Optimizer will ensure that user-dialled 7-digit numbers are normalized to E.164 format for the correct area code.  For example: if a user dials 2915555, Lync will normalize the number to +18162915555.  If they dial 2195555, Lync will normalize it to +19132195555.

ONLY USE THE 7-DIGIT NORMALIZATION OPTION IF 7-DIGIT DIALLING IS ALLOWED IN YOUR AREA. If you generate 7-digit normalization rules for an area that does not allow 7-digit dialling, you will likely see inconsistent results.

Once done, press Generate Rules.  After a short while, you will see a link to a text file that contains all the Powershell commands required to setup Least Cost Routing for that particular site.  Copy the contents of the text file into the Lync Powershell dialog box.  The rest should be taken care of! 

Here's a sample of what the Powershell commands look like for 305-836 (Miami) with a PSTN gateway name of miami.root.loc:
Set-CsPSTNUsage –Identity global –Usage @{Add='NA-FL-Miami-Local'}

New-CSVoiceRoute -Name 'NA-FL-Miami-1' -Description 'Least cost routing for Miami, FL' -PSTNUsages 'NA-FL-Miami-Local' -PSTNGatewayList 'miami.root.loc' -NumberPattern '(\+1561((21[0238])|(2(06|08|37|39|41|45|87|88|89))|(36[1278])|(39[12345])|(3(00|02|05|72|78))|(44[2357])|(45[1678])|(4(16|17|70|77|79))|(5(04|05|44|49))|(67[24])|(75[06])|(86[2469])|(8(83|86|92|93))|(98[1289])|(99[145789])|(9(10|12|22|23|29|53|55|61|62))|((226|297|314|322|338|347|353|400|435|520|558|613|620|636|705|773|807|826|852|939|948))|(48)))|(\+1754(([234578])))|(\+1954(([23456789])))|(\+1786(([23456789])))|(\+1305(([23456789])))'

New-CSOutboundTranslationRule -Parent 'PstnGateway:miami.root.loc' -Name 'NA-FL-Miami-1-Local' -Description 'Removes +1 for local calls to Miami, FL' -Pattern '\+1((561((21[0238])|(2(06|08|37|39|41|45|87|88|89))|(36[1278])|(39[12345])|(3(00|02|05|72|78))|(44[2357])|(45[1678])|(4(16|17|70|77|79))|(5(04|05|44|49))|(67[24])|(75[06])|(86[2469])|(8(83|86|92|93))|(98[1289])|(99[145789])|(9(10|12|22|23|29|53|55|61|62))|((226|297|314|322|338|347|353|400|435|520|558|613|620|636|705|773|807|826|852|939|948))|(48)))|(754(([234578])))|(954(([23456789])))|(786(([23456789])))|(305(([23456789]))))' -Translation '$1'

Repeat for each gateway in your environment.  To check the results, use Lync Control Panel. Under Voice Routing - Route, you should see something like the following:

Auto-created routes are formatted like this NA-state-city-#.  For example, NA-TX-Dallas-1. If the route length is longer than 1024 characters (like Dallas), it has to be split into multiple routes, hence NA-TX-Dallas-2.

PSTN Usages should contain a PSTN Usage for each site, named like NA-state-city-Local
.  For example, NA-TX-Dallas-Local.  The PSTN Usage will contain all the routes for that particular city.

Finally, each PSTN gateway defined in Trunk Configuration should have at least one trunk normalization rule.  This rule will strip the +1 from the phone number before sending it to the PSTN gateway.

Drilling down into one of the trunks shows the translation rules for that particular trunk.

If you've selected the option to create 7-digit normalization rules, these rules will be placed in the Global dial plan in the format NA-state-city- Local Calls.  You should copy the rules to the appropriate dial plan.

One final step that's required to pull it all together is to assign the auto-created PSTN Usages to the appropriate Voice Policy.  Edit the voice policy/policies you want the Least Cost Routing to apply to, and add the PSTN Usages to those policies.  Commit the changes and you're done!

Now, when your users dial any number that is local to a defined city, the call will be routed out the appropriate PSTN gateway.  As long as you entered your email address, incorporating changes is as simple as re-applying the updated rules that are emailed to you to your Lync deployment. 

This post shows you how easy it is to configure Lync Server 2010 for Least Cost Routing.  Comments are always appreciated!

For more background on the Dialing Rule Optimizer, see this post.