Thursday, March 10, 2011

Internal Extension Dialing in Lync

If you've created normalization rules in Lync, you've likely noticed a checkbox at the bottom of the page that says "Internal Extension".

If you clicked on the question mark icon, you'd see this helpful bit of text:
"Select this check box if the normalization rule results in a phone number that is internal to the organization."
If your normalization rule did in fact deal with internal extensions, you might have checked this box and moved on. Chances are, the normalization rule wouldn't behave any different than your other rules and you probably shrugged your shoulders and didn't give it a second thought.  Well, that's the way I typically rolled until I experienced an issue with a client that made me dig deeper into the whole internal extension thing.

I recently deployed Lync and a small number of Polycom phones for a Vancouver-based client. This client is currently testing the Polycom phones with various users to iron out any issues that arise before they deploy to the rest of the organization.  Most people seemed to like the phones, but there was one user who was having issues dialing certain numbers. She would press the speakerphone button to hear the dialtone or lift the receiver off the hook (called off-hook dialing), type in the local area code (604), pause as she looked up the other digits and then type them in.  More often than not, if she delayed long enough, the phone would dial an internal user before she had the chance to finish punching in the final digits.

The issue lay in the way the normalization rules were formatted.  One rule would normalize 10-digit numbers to +1<10DigitNumber>.  This is pretty typical for North America.  People are used to dialing 10-digits, especially for local numbers.  However, this client happened to have a legacy PBX that used 3-digit extensions that started with 6, so there was a rule that translated 6xx extensions to full E.164 phone numbers (like +160455526xx). When she started off-hook dialing an outside number and paused after 604, the phone matched the 6xx normalization rule, normalized the 604 to +16045552604 and dialed that particular internal user.  Of course, this was a frustrating experience.

This is only an issue for off-hook dialing because when dialing on-hook, which is the way that the Lync PC client always works, the user tells the system when they are finished entering digits by clicking the Dial button. When dialing off-hook, as you might with a desk phone (either Lync or PBX), calls are dialed as soon as there are enough digits to satisfy the local dialing rules.  In this case, it led to undesired behaviour.

To get around this behaviour, PBX vendors usually required users to press 9 (or some other number) to signify the call is meant for the external telephone network. That way, you avoid any conflict with off-hook dialing internal extensions.

Lync provides the same functionality at the dial plan level.

You'll notice the help text for the External access prefix box reads:
"You need to specify an external access prefix only if you need to dial a number to get an outside line in your organization. Type the number that you need to dial for an outside line in this field"
The help text is a bit misleading. If you enter an external access prefix, it doesn't suddenly mean that you'll have to tell all your Lync users to dial 9 for external numbers.  As you'll see, this is only necessary for Lync deskphone users who like to dial numbers in off-hook mode. Even then, it won't force the user to specify a 9 before dialing.

If you enable this feature, then when a Lync deskphone user makes a call in off-hook mode (either by picking up the handset or pressing the speakerphone button before dialing), they should dial a 9 for external numbers.  What really happens in the background is when 9 is pressed, Lync will ignore any normalization rule that is labeled as "Internal extension".  The actual digit 9 is ignored and not used when applying your other normalization rules.

So, by using the earlier example, when a deskphone user goes off-hook, dials 9604 and pauses before they enter the rest of the number, the 6xx normalization rule is ignored because I applied the Internal extension flag to that rule.  The phone won't normalize the 604 to +16045552604. When the user finishes entering the rest of the digits (say 96047771111), the 10-digit normalization rule will apply (its not flagged as an internal extension), and it will normalize the number to +16047771111 and send it on its way.

If the user means to dial the 604 internal extension in off-hook mode, they dial 604, wait a beat and Lync will normalize the number to +16045552604 and send it off to the internal user. Since the external prefix 9 wasn't entered, the number gets dialed as soon as that 6xx normalization rule matches.

Keep in mind that this only applies to off-hook dialing from Lync deskphones. None of this is required for standard Lync dialing, nor is it explicitly required for Lync deskphones when dialing on-hook (ie. dial the number and THEN pick up the phone or press the speakerphone button).  In fact, if the Lync deskphone user doesn't dial a 9 in off-hook mode, it will allow external dialing, as long as they don't pause too long between digits. They won't be forced to use the 9, but they run the risk of accidental dials if they don't.

Lync PC users can also dial a 9 before dialing external numbers if they want. It will strip the 9 before dialing.  Interestingly enough, if you're like me, you've got a 10-digit normalization rule that normalizes to +1<10digitnumber>.  I was curious as to what would happen if I tried dialing something like 9054441111 (905 is a valid Ontario area code).  I thought it would strip the 9 and leave me with an undialable number.  Fortunately, Lync is smart enough to know this, and it will normalize the number to +19054441111.

Here are some examples, given the following dialing rules:
  • Normalize <10DigitNumber> to +1<10DigitNumber>
  • Normalize 1<10DigitNumber> to +1<10DigitNumber>
  • Normalize 6xx to +160455526xx. Select Internal Extension checkbox
  • 9 assigned as external dialing prefix
  • Off-hook dial 604                      -->  +16045552604 (Matches 6xx rule)
  • Off-hook dial 9604                    --> Nothing happens.
  • Off-hook dial 6045551111        --> +16045551111 (Matches 10-digit rule)
  • Off-hook dial 96045551111      --> +16045551111 (Matches 10-digit rule)
  • Off-hook dial 916045551111    --> +16045551111 (Matches 11-digit rule)
  • Lync dial 9054441111               --> +19054441111 (Matches 10-digit rule)
  • Lync dial 99054441111             --> +19054441111 (Matches 10-digit rule)

Even if all your phone numbers are normalized to E.164, your PBX is still expecting a 9 for outbound calls. To make sure Lync puts a 9 in front of all outbound phone calls, you  use Trunk Translation rules in Lync to strip the + and add the 9.  Here's an example:
^\+(\d{6,}) --> 9$1

This rule will strip the + from any phone number with 6 or more digits and put a 9 in front.

As a final note, if you don't want to confuse things for your users (although, I'm sure most are familiar with having to dial 9 from the olden PBX days), there IS something you can possibly do with normalization rules to avoid some of the most common issues.

If you want to allow people to off-hook dial a commonly used area code without it being matched to an existing internal extension normalization rule, you can exclude the area code from your internal extension normalization rule.  This assumes nobody is assigned the extension that matches the area code in question.

Using the previous example, assume we have a normalization rule for 3-digit extensions starting with 6, and we want to allow users to off-hook dial the 604 (Vancouver), 613 (Eastern Ontario) and 647 (Greater Toronto Area) area codes without being matched to the 6xx normalization rule (assuming nobody is assigned those extensions). The original rule might look like this:
^(6\d{2})$   -->  +16045552$1
Change the normalization rule to this:
(?=^6\d{2}$)^((?!604|613|647).*)$  -->  +16045552$1
This rule will match any 3-digit number starting with a 6, EXCEPT for 604, 613 and 647.  Don't ask me to explain exactly how this works (I found examples via Google), but it does.  In most cases, this would make your users happy.

So, in summary, if you're planning on deploying Lync deskphones, you'll have to pay particular attention to how you manage internal extensions.  There is some scattered guidance on how to do this out there on the Intertubes, but nothing that was all-encompassing.  Hope this was helpful!  Comments are always welcomed.


  1. For the life of me, I could not get this to work no matter what I did or how long I waited. But, I found that with some clever RegEx I can achieve the same effect. Basically, in my dialing plan I have several rules with and without the preceding "9" as a requirement. If you dial 9, then seven digits, it will dial local with the area code and "+1" automatically prepended. If you dial "91" then it expects ten more digits. The way you keep the local plan from dialing is simply to use the "not" character in a custom regex. So it looks like this: ^(9[^1]\d(6))$

    That means, if there is a 9, then any number except 1, and it is exactly seven digits long (six digits plus the not-1 digit), translate this rule and dial the number.


  2. We have a much simpler rule for internal extension dialing.
    Fortuently our Lync deployment is enhancing our PBX so all Lync needs to do is forward the calls in a E.164 format or a 4 digit extension and then the PBX handels the rest.

    Under our Global Dial Plan i have a Normalization Rule called "4 digits - call PBX ext"
    Pattern to match: ^(\d{4})$
    Translation Rule: $1
    Ineternal Extension is enabled.

    Under Route i have a Voice Route called "4 digit extensions to the PBX"
    Match this Pattern: ^(\d{4})$

    I then have the apporpiate Associated gateways and PSTN Usages setup.


  4. when happens when the external prefix is set to 9, and some one dials 911.

    how this will normalize. 911 or +11

    Pattern : ^011?([2-9]\d{6,14})$
    Translation : +$1

    Pattern : 1?([2-9]\d{9})$
    Translation : +1$1

    Pattern : ^([2-9]11)$
    Translation : +$1