Tuesday, January 4, 2011

Lync Enterprise Voice Best Practices - Normalization

In my last post, I talked about the importance of using E.164 in your internal Active Directory phone list. Assuming you've got that all straightened out, what's next?  Since users won't always be dialing the wonderfully consistent numbers you've provided them in Active Directory, how do you handle all the different methods used for making calls?  You have to normalize them using normalization rules in Lync.

The end-goal for normalization rules is to ensure you pass a properly formatted E.164 phone number to the appropriate gateway, no matter what the user tries to enter. Call routing and additional number manipulation is much easier when you know you're going to be getting a standard format.

You need to think about the ways users typically dial their numbers. Are they used to excluding the 1 for local calls?  Do they dial 7-digit local numbers without the area code for their specific location?  Do they dial internal extensions?  What do they have to dial to make an international call?

You also have to think about how any PBX you might have in your environment sends numbers to Lync?  Is it capable of sending full E.164 formatted phone numbers, or can it only send extensions?

When you have all the answers to those questions, you can start building normalization rules. Normalization rules are built using regular expressions. If you're not familiar with regular expressions, a good place to learn about them is from regular-expressions.info. Thankfully, the Lync Control Panel has a wizard that handles most typical scenarios. You'll only need to understand regular expressions for more advanced needs.


Dial Plans
Normalization rules are assigned to dial plans in Lync. A dial plan is a collection of normalization rules that are assigned to sites, pools or users. You can even assign a dial plan to an individual gateway, which can be handy for inbound number normalization (as described by VOIPNorm here).  You can re-use the same normalization rules in multiple dial plans, so its best to name the rules so they're descriptive, like NorthAmerica-International, CA-ON-Toronto-Local or Italy-National.

Normalization Basics
Let's start with a very basic normalization rule that normalizes a North American 10-digit number to a properly formatted E.164 number:
^(\d{10})$  --> +1$1
A regular expression should start with a ^ which signifies the beginning of the string, and end with a $ which signifies the end. The \d represents a single number, but since its followed by 10 in curly brackets, it means 10 numbers. A matched number within the round brackets is accessible as a variable: $1.  If you have more than one set of brackets, then each bracket set is represented by $1, $2$3 etc.  You don't have to do anything special to make sure things like dashes, brackets and periods are excluded from the regular expression.  Lync handles that internally.

The right side of the arrow shows the normalized form. Start with +1 and insert the digits represented by the variable $1.  The normalized form does not follow regular expression rules (for instance, to represent a + sign, you'd normally have to precede it with a backslash \).

So, if someone dials 4163334444, the rule ^(\d{10})$ is matched, since its a 10-digit number.  The normalization rule simply sticks a +1 in front, so we get the E.164 formatted number +14163334444.

Advanced Normalization
In my deployments, I've taken that rule and expanded it somewhat to catch a wide variety of scenarios. Have a look at this:
^1?([2-9]\d\d[2-9]\d{6})(\s*\S*)*$ --> +1$1
A bit more complicated, but I'll explain. Since some users will actually enter the 1 when typing a phone number, I want to make sure it falls under this rule, so the 1? is added to the front.  The ? means the preceding number can be either present or not for a match. The [2-9] means "match any single digit between 2-9".  Then there are two single digits, represented by \d\d. Together, this indicates the area code, which can be any number from 200-999. The [2-9]\d{6} represents the local number which is 7 digits long but has to start with 2-9.  The (\s*\S*)* simply means "anything".  This is handy for accepting phone numbers from users' Outlook contacts which could have some phone numbers with oddly formatted extensions at the end of the number, like "ext 443 or "x443". The expression will drop the extension from the number.

The end result is a nicely formatted E.164 phone number. If the user enters "14165551111" or "4165551111" or "4165551111 extension number 42" (from Outlook for instance), it will be normalized as +14165551111.

Incidentally, my post on Normalizing Outlook Contact Phone Numbers includes a very handy script that will clean up users' personal Outlook contacts and ensure that every number is formatted for E.164.

International Normalization
For international numbers, you want to ensure users have to dial their usual international routing code (like 00 or 011) to make sure they really want to dial an international number.  If you stick with pure E.164 dialling, you could dial internationally when you meant to dial locally.  If you were to try to dial a Vancouver number by dialing 6046901111, you wouldn't want it to be routed to Penang, Malaysia by accident (60 is Malaysia's country code, and 46 is the city code for Penang).  In this case, you want your users to dial 011 (or whatever) before they enter an international number.  This rule takes care of that:
^011(\d{7,})$ --> +$1
So, with the first rule described earlier, when a user dials 6046901111, the number is normalized to +16046901111.  If they meant to dial Penang, Malaysia, they'd have to dial 0116046901111, which would normalize to +6046901111.

7-Digit Normalization
If your users are used to dialing 7-digit numbers for local calls AND your 7-digit dialing area includes only a single area code, you can create a normalization rule that goes something like this:
^([2-9]\d{6})$ --> +1613$1
So, if a user dials 2224444, the number will be normalized to +16132224444.

The preceding example works great for smaller sites that can only do 7-digit local dialing to a single area code. However, there are numerous sites that allow 7-digit dialling that encompass multiple area codes, such as Kansas City, MO (816 and 913). Using Kansas City as an example, you can’t simply do a blanket 7-digit to 11-digit normalization for the entire area code, because you won’t know if the 7-digit number is supposed to be expanded to 816 or 913. For instance, if a user dials 204-1111, it should be normalized to +18162041111, but if they dial 205-1111 it should be normalized to +19132051111.

Once again, the Dialing Rule Optimizer gallops in for the rescue! A new option will create the necessary normalization rules for special cases such as Kansas City, MO, so that you can dial 7-digit numbers with confidence.
A very special thanks to Henry Creagh who brought the multi-area code 7-digit dialing issue to my attention and helped test the solution.

Internal Extensions
For internal extensions, things get a bit more interesting. Your users may expect to be able to dial internal extensions directly.  If all your company's internal extensions map directly and consistently to external phone numbers (DIDs), then you'll be laughing.  For example, if your 4-digit extensions that start with 7 all map to DIDs that are in the +14162227xxx range, then your rule will look like this:
^(7\d{3}) --> +1416222$1
If your internal extensions don't have a corresponding DID, then you'll need to do something like this (pretend the main office number is 1 (416) 222-1111):
^(5\d{3}) --> +14162221111;ext=$1
If this is your situation, your users assigned Lync phone numbers will have to be in the same format, of course.  You shouldn't use the user's 4-digit extension as their Lync number.  You should use +14162221111;ext=5000 (for example).

If you're unlucky, your internal extensions and corresponding DIDs might not have anything in common for you to develop a simple set of normalization rules. In that case, you're going to have to either go through the tedious process of developing a large number of normalization rules, or you'll need to tell your users they simply can't use extension dialing anymore. There might be a temporary uprising until they realize they don't need to memorize extensions any more because their frequently called contacts appear in Lync.

If you are routing calls to a PBX that only accepts extensions, it's best to first normalize the extensions to E.164 format (with the ;ext=) and then use a trunk translation rule to revert back to the extension format before sending to the PBX. I will talk about trunk translation rules in a later post.

As a momentary aside, I've been thinking about developing a program that accepts a CSV file with DIDs and corresponding extensions and outputs the Powershell commands to create the appropriate normalization rules. I imagine it would be very helpful in the previous paragraph's scenario. If you think something like that would be useful, please leave a comment in the Comments section.

Putting it all Together
Lastly, you'll need some normalization rules to accept emergency and other non-standard numbers like 411, 611 or 911 (which incidentally is routed automatically if you've defined Location Services properly). If you're not in North America, your rule will be different.
^([2-9]11)$ --> +$1
Once you've got your normalization rules defined, you can assign them to a dial plan.  Since Lync starts at the top of the normalization rule list and works its way down till it finds a match, its best to place your most used rules up top. If a phone number can be matched by more than one rule, put the more restrictive rule first. Your final normalization rules for a simple dial plan might look like this:
NamePatternTranslation
NA-National^1?([2-9]\d\d[2-9]\d{6})(\D+\d+)?$+1$1
NA-International^011(\d{7,})$+$1
7xxx Extensions^(7\d{3})+1416222$1
5xxx Extensions^(5\d{3})+14162221111;ext=$1
NA-ServiceCodes^([2-9]11)$+$1
 
Since everything is normalized to a unique and standardized E.164 phone number, its much easier to modify at the gateway level to comply with local PSTN or PBX requirements. This is accomplished with trunk translation rules, which I will talk about in a later post. 

One last thing to remember is that any number that starts with a + sign is assumed to be already formatted for E.164, and no normalization rules will apply.  It will be dialled as is.  Keep this in mind when formatting phone numbers in Active Directory.

Now that you've got normalization sorted out, its time to handle routing.  My next post will discuss what I think is the best way to route your calls in Lync.

If you've got questions or issues about my methods, please drop me a line in the Comments section.