Thursday, January 29, 2015

Out of the Gutter: The Ken Lasko Story, Part 2

Part 2 - Higher Learning

Through most of high school, I was a solid C student. I did the minimum effort required to get by without raising the ire of my parents or teachers. I was more focused on having fun without giving much thought to the future.

It was on a cool, cloudy spring day in 1989 when I made the decision to go along with a bunch of friends on a road trip to check out some universities in Southwestern Ontario. I was in Grade 12 and probably should have been thinking about what university to apply to, but I really wasn't. Our school system was on the verge of eliminating Grade 13, so there were some who would head off to college/university after Grade 12, and others who would wait another year and go through Grade 13.

So, we all piled into a few cars and made the 3 hour road trip down the 401 past Toronto to check out
Me and my car. KITT never liked being second-billed. I'm not
sure what I'm holding in my hand, but it looks large!
3 universities in one day. The first one was an arts focused university, which I knew I would never go to. The second was a university well-known for its math and computer departments. We did the campus tour, but I never got a good vibe from it. It felt cold and sterile. The third university was well-known for its veterinary and agricultural colleges. More importantly, it had a very warm and cozy feeling that made me instantly feel like I had found my match. We took a trip into the downtown core, where I felt even more at home. I had found where I wanted to go to university.

Now, you might be thinking that since I'm in IT now, and based on my familiarity with computers growing up, that I would have felt the math and computer science focused university was my place. Strangely enough, I never felt like I was a "computer guy" growing up. Sure I knew my way around a PC, but it was always with a goal of getting something else...games to play. The computer was just a tool to do that. I hadn't really come to any conclusion on "what I wanted to be when I grew up". All I knew that it would be related to a science major, which my chosen university was a solid performer.

There was just one problem...my marks. Being a C student wasn't going to get me into a university of the calibre that I fell in love with. So, since I had a year to get my act together, I did just that. I was determined to get into my chosen university, so I hunkered down, applied myself, did the work, and turned myself from a C student to very close to an A+ student. Heh, my parents and teachers were right after all: "If you only applied yourself..."

I applied to 3 top sciences related universities in the province and got accepted to all of them. Which
one to choose? My criteria was simple: I had to be far enough away from home to keep my parents from dropping in all the time, but close enough to get home without too much difficulty should the need arise (ie. home-cooked meals, free laundry). My selection process was a bit dodgy though. I eliminated the one math/computer university solely on the campus atmosphere. I was left with two, both equally good. One was the university I fell in love with during a campus tour, and the other was one that I hadn't gotten the chance to see, but looked very promising. Decisions, decisions. My final choice came down to a simple thing not at all related to academics or career potential: I could get a pizza with my meal card at 2 in the morning at the university I toured and loved, but not at the other. Yeah, that was the clincher.

So, in the fall of 1990 I showed up at university and started off on a life sciences major with vague aspirations to be either a marine biologist or a kinesiologist. I partied a lot, and slipped back into solid C student territory. I was introduced to the concept of "email", where I was absolutely floored that I could send a message via computer to someone on the other side of the world, even though I didn't know anybody on the other side of the world. There were chat rooms, newsgroups and text-based games people would play. Since most people didn't have a computer, you would have to sign up to use one of a bank of computers in the library.

I had saved up some money during the summer and bought myself a computer, which was a 286 with probably 1 or 2 MB of RAM and a small hard drive (likely 20MB). Again, it was used for word-processing and as always...games. At some point, I managed to get it hooked up to the school network, probably via modem, but the details are fuzzy (it was nearly a quarter century ago.....damn, I'm getting old).

My 1st year roommate studying hard.
Early in second year, I took a introductory computer course geared towards science students. It offered BASIC programming, WordPerfect, Lotus 1-2-3 and basic DOS command line stuff.  I already knew WordPerfect, Lotus and DOS, so I figured it would be an easy A. Sadly, the course itself was terrible. The teacher was disorganized and the course materials (developed by the teacher) were hard to understand or flat out incorrect.

We had numerous labs where we had to create BASIC programs, make spreadsheets and that sort of thing. It turned out that I had a knack for programming, and I was always among the first to complete the labs. I would then go around and help others with their labs too. I had a lot of fun doing that and it definitely helped me meet the ladies, which wasn't hard since this particular university was known for its abnormally high percentage of women (as high as 75% by some estimates). I came out of that course with the highest mark of my university career.

Unfortunately, my marks in courses like Biochemistry did nothing to keep up a good average. I wasn't enjoying myself, and was struggling. I recalled how well I did in Intro to Computers, and thought that maybe I should switch to Computer Science instead. So I did.
My on-campus residence room in 2nd year, circa fall 1991. I had a thing for Marilyn Monroe...and Cindy Crawford.
Working at a photo lab allowed me to print out lots of the many party pictures I took, which I used as wallpaper.

If I chose this particular university because of the female to male ratio, then I completely undid that by going into Computer Science. The classes were 95% male, and I didn't have much in common with any of them, so didn't make many new friends. On any given evening, most of them were in the UNIX lab programming, while I focused on my alcohol consumption. I did alright, but nothing really set me on fire (figuratively or literally). There were many courses that bored me to tears, but in order to not lose any ground with the courses I already took, I kept Biology as a minor, so there was some variety.

It was during this time that someone introduced me to something called the World-Wide-Web. You could use a "mouse" (a new thing at the time) to click on text in a "browser", which would go to a server somewhere else in the world and show you a picture or something, all without using a keyboard. I recall the first thing I saw was a picture of the Earth from space. The picture took several seconds to draw, even over the dedicated Internet line. I was amazed. The possibilities seemed truly endless.

During a class in COBOL (why????), my teacher (not-so-interesting trivia: that teacher is now the
I excelled at Falconry 101
Minister of Education for my province) posted a notice about becoming a teaching assistant for the Introduction to Computers course I aced a few years back. I jumped at the chance. Not only would it give me some much needed extra cash, but I actually truly enjoyed it when I was helping others with their computer problems.

I applied for, and got, a teaching assistant position for that course. For the rest of my university career, I taught labs and helped people through the still awful course material. I hung out with some of the other TAs, who were a year ahead of me and weren't your typical 90's era computer-types at all.  Every night that I would go to the bar (which was usually every night), people would come up to me and say "Hey, you're my TA!!"  I felt like a minor celebrity.

I went through most of university like this. I took 4 or 5 courses a semester (usually 4, dropping whatever course had night classes or a too-early Friday morning class). I held down 3 jobs at the same time: I was a TA, worked at a 1-hour photo lab, and DJ'd at a local bar/restaurant every other Saturday night. With all these jobs, I had enough money to continue going out almost every night. I have no idea how I managed to do this, plus pass all my courses...maybe that's one of the best things I learned at university: work hard, play hard.

Join me next time as the TA job leads to something that starts me down the path that ultimately put me where I am today, in Part 3 - Tech Support Hijinks.

Monday, January 26, 2015

Out of the Gutter: The Ken Lasko Story, Part 1

I've really gotten a kick out of reading people's IT backstories on their blogs, so I thought I'd add mine in.  This will be much like the Twilight and Hunger Games film series.  There will be 3 parts, but the third part will be broken up into Part I and Part II to drag things out and to maximize profits.

April 1941, London, UK. The Germans had been bombing London for more than 6 months, in what had been called "the Blitz".  I was a teenager then.....no wait. That wasn't me.

Part I - Boyhood, but not as good as the movie

I grew up in a farmhouse in the middle of nowhere in central Ontario, Canada during the 1970's and
You can almost see the sweat in this true-to-life simulation.
80's. Our nearest neighbour was nearly a kilometer away, and we had lots of land to entertain me and my younger brother. We rode our bikes, explored the forest, played in barns; very wholesome stuff. My very first exposure to anything computer-related would have been the seminal Atari Pong video game, which we had in our Grade 1 classroom when I was 6 years old. Even with the simple graphics of the time, it was something that we loved to play when allowed. A few years later, I started to waste as much time as my parents would let me playing the growing number of arcade games located at our local mall. I can still remember playing Space Invaders, Asteroids and all those early classics with the precious few quarters I got for an allowance. I was never the video game master that I imagined I was in my mind.

The possibilities were endless!
My first experience with a real computer was the Commodore PET computer that resided in our classroom. I think it was Grade 5, which would have been 1982. I remember inserting a cassette tape and waiting for sometimes up to 30 minutes for the program to load. The longer it took, the better we thought the game would be. The only game I remember was some variation of Lunar Lander, which I thought was awesome. This was also my very first exposure to programming, which usually consisted of the following extremely complex BASIC program:
10  PRINT "<InsertSwearWordHere>";
20  GOTO 10

This would endlessly scroll the chosen swear word, but with the added feature of filling the entire screen, instead of just a single column, thanks to the addition of the semi-colon. This alone differentiated me from the other students, and pegged me as a "computer genius" (or maybe nerd). From that moment forward, I knew computers were going to be an important part of my life....actually no. It was just a way to waste time with games and to irritate teachers.

Look familiar?
My parents brought home the Magnavox Odyssey2 gaming system sometime during the same period. This thing was a true piece of crap, with bad graphics even by the very low standards of the day. My parents thought the built-in touch keyboard would encourage us to take up programming, but we had very little interest in this. We only played the various terrible knock-off games that were available, like KC Munchkin (think Pac-Man). Despite the general awfulness of the Odyssey2 games, we played the hell out of that thing.

A few years later (probably 1984), my parents brought home an odd-looking beige box with a small, heavy 16-colour CGA monitor attached.  This was yet another attempt to get my brother and I to "learn about these new-fangled computer things".  This was the very first PC, an IBM clone.  It had no hard drive. It had 640K of memory. Its only storage media was a pair of 5 1/4" floppy disk drives. I remember inserting the DOS disk, listening to the floppy drive buzz and churn away until finally a single A:\ prompt flashed at me. Without any manual to read, I thrashed my way around until I figured out how to get things done. And by "get things done", I meant "play video games".

It's Sexytime! Imagine that "CENSORED" box moving up and down,
and you get the idea. Mass parental hysteria ensued.
I have no idea how I did it, but I managed to get illicit copies of all sorts of games. This was long before the Internet, and BBS's were still years away. My favourites were the adventure games of the era, starting with King's Quest, then Police Quest, Space Quest, and the infamous Leisure Suit Larry series, which was the first to have "are you an adult?" verification, which was extremely simple for a young, determined kid to get around.

I didn't realize this at the time of course, but this was my very first interaction with Microsoft via an early version of MS-DOS. Little did I know just how much of an effect this would have on my life, just not in exactly the way my parents intended.  I became familiar with computers, even though I didn't use them much more than a medium for playing games.

Later on, as I became older, I used the PC for more than just games. I used it in high school to write
My high school picture
papers with WordPerfect when others were still either writing them by hand or typing them on a typewriter (yes, a typewriter). I printed out my assignments on a dot-matrix printer, and my teachers were impressed by the neatness and lack of liquid paper normally required on most typical type-written papers to hide the mistakes.

We eventually got a 1200 or 2400 baud modem (can't recall which), which allowed us to dial-up to local Bulletin Board Systems (BBS), and download games at blistering speeds. (a 1 MB game would take about an hour at 2400 bps). If my mother picked up the phone while we were downloading (and that happened a lot), she would hear a nice screech, and our download would get interrupted, forcing us to start over. More screeching would happen from both me for the wasted DL time, and my mother who couldn't use the phone any more.

Other than dabbling with computer games and word processing, I lived life like a normal teenager. Rode bicycles all over the place (got into racing and did pretty well), chased girls (not so well), watched TV (yes, Knight Rider was on my 'Must-See' list), and got into typical teenage mischief (all too well).

This continued until one fateful day in 1988, when I encountered something that would change my life....forever. (Best read like a movie trailer voiceover).

Coming soon, the mid-point of this thrilling saga: Part 2 - Higher Learning

Thursday, January 22, 2015

Service Number Formatting in Lync


I recently had the distinct pleasure of engaging the Lync community via Twitter to ask how many people normalized their service and emergency numbers to include a plus sign (+). I asked this question because I had come across a couple of SIP providers in both the US and internationally that expected E.164 (global numbers starting with a plus sign) phone numbers for all except for emergency and service numbers. To put it another way, they wanted a plus in front of all phone numbers except for emergency/service numbers.

My very informal poll results were as follows:
Use + for everything: 6 votes
No + for emergency/service numbers: 4 votes
It depends: 1 vote
A "lively" discussion ensued between @ucomsgeek and @CAnthonyCaragol (the C stands for "Corky", in case you were wondering) on the validity of using a + sign in front of numbers that are not dialable from outside the originating country. The discussion got a little crazy and we very nearly came to blows on several occasions. @ucomsgeek had to be admitted to the hospital with what can only be described as an "RFC induced heart palpitation".

I had traditionally used a + in front of everything, adhering to my mantra of "E.164, E.164, E.164".  This included service numbers like 911 in North America, or 112 in Europe, so they would get normalized to +911 and +112.  My experiences with SIP providers not wanting a + in front of those numbers made me think, which is a rare occurrence, and is usually followed by being distracted by shiny things. If SIP providers don't want a + in front of those types of numbers, there must be a good reason for it.

So, whenever I'm faced with the great unknown, I turned to the trusty Interweb to find answers. I didn't have to look far. Phone number formatting is governed by the E.164 standard published by the Telecommunication Standardization Sector of the International Telecommunication Union or ITU-T for short (which is a good thing, because having to say "the Telecommunication Standardization Sector of the International Telecommunication Union" gets tiresome).  E.164 number representation within the Tel URI format used in SIP is governed by RFC3966 published by the Internet Engineering Task Force (IETF).

Reading these documents is an enlightening and mind-expanding experience. The E.164 standard takes a lot of pages to say that an E.164 number consists of the country code, followed by area code (national destination code or NDC) and the subscriber number.

Other than that, it doesn't say anything about plus signs or anything else other than just boring numbers, so we turn our attention to the much more interesting and relevant RFC3966.

RFC3966 has a lot to say about how to format numbers for use in computer/telecom equipment. The first thing that struck me was that the plus sign is reserved ONLY for global numbers, meaning numbers that are globally unique and adhere to the E.164 standard described above.

Section 5.1 says:
   The 'telephone-subscriber' part of the URI indicates the number.  The
   phone number can be represented in either global (E.164) or local
   notation.  All phone numbers MUST use the global form unless they
   cannot be represented as such.  Numbers from private numbering plans,
   emergency ("911", "112"), and some directory-assistance numbers
   (e.g., "411") and other "service codes" (numbers of the form N11 in
   the United States) cannot be represented in global (E.164) form and
   need to be represented as a local number with a context.  Local
   numbers MUST be tagged with a 'phone-context'

Section 5.1.4 describes how to format a global number:
   Globally unique numbers are identified by the leading "+" character.
   Global numbers MUST be composed with the country (CC) and national
   (NSN) numbers as specified in E.123 [E.123] and E.164 [E.164].
   Globally unique numbers are unambiguous everywhere in the world and
   SHOULD be used.

So, since numbers like 911 are not global numbers, they can't be referenced with a plus sign, but have to be formatted with a context, which is described a little bit later.

Section 5.1.5 describes how to format a local number (which includes service/emergency numbers by definition of not being global numbers):
   Local numbers are unique only within a certain geographical area or a
   certain part of the telephone network, e.g., a private branch
   exchange (PBX), a state or province, a particular local exchange
   carrier, or a particular country.  URIs with local phone numbers
   should only appear in environments where all local entities can
   successfully set up the call by passing the number to the dialling
   software.  Digits needed for accessing an outside line, for example,
   are not included in local numbers.  Local numbers SHOULD NOT be used
   unless there is no way to represent the number as a global number.

Section 5.1.5 goes on to say more about how to format local numbers:
   Local numbers MUST have a 'phone-context' parameter that identifies
   the scope of their validity.  The parameter MUST be chosen to
   identify the local context within which the number is unique
   unambiguously.  Thus, the combination of the descriptor in the
   'phone-context' parameter and local number is again globally unique.
   The parameter value is defined by the assignee of the local number.
   It does NOT indicate a prefix that turns the local number into a
   global (E.164) number.

What the above says is that local numbers must use a specific parameter called "phone-context" to ensure there is no ambiguity with global numbers. A little further reading brings up 911 number formatting as an example:
   A context consisting of the initial digits of a global number does
   not imply that adding these to the local number will generate a valid
   E.164 number.  It might do so by coincidence, but this cannot be
   relied upon.  (For example, "911" should be labeled with the context
   "+1", but "+1-911" is not a valid E.164 number.)

So, for example, 911 should be formatted as tel:911;phone-context=+1 for North America, but clearly says that +1911 is not acceptable.  However, Lync doesn't support phone-context in normalization rules or routing logic (trust me, I tried), so we're kinda stuck if we want to be fully RFC3966 compliant with regards to emergency and service numbers.

We're left with two options for service/emergency numbers really, either use the plus sign or don't. Since the plus sign is supposed to be reserved for global numbers, we probably shouldn't use it for emergency/service numbers. But on the other hand, people are generally used to seeing all their dialed numbers in Lync magically get formatted with a plus sign when it matches up with a normalization rule, which gets taken as a sign that you're good to go (at least that's the way I take it).

But consider this weird little thought experiment. If you normalize 911 to +911, you could think that this represents a really short number within India (country code 91). Yes, I know that a country of more than a billion people is likely going to have more than 9 phones, but you get the idea. What if India decided you could dial the Prime Minister of India by dialing "1"? Then anybody in North America trying to have an engaging conversation with Narendra Modi would end up talking to North American emergency services instead, which would be baffling for both sides.

Another possibility is that you could inadvertently route emergency calls to a global destination. Imagine you have a Lync server in India, and you decide to use least-cost routing to save on toll costs by routing any India-bound call to that Lync server. You configure a route and PSTN usage that sends any call starting with +91 to the India Lync gateway. You inadvertently put that PSTN usage above a PSTN usage meant for local service numbers. Now any call to 911 gets routed to India, and will most likely fail.

You could say the solution to the above scenario is just to make sure that service PSTN usages are above any international PSTN usage, but I'm a fan of engineering solutions that don't rely on someone setting things in exactly the proper order to get the desired results. I'm thinking of administrator/human fault tolerance here.

Rather than say the odds of any given service number conflicting with a real global number is vanishingly small (probably true, but you can't know for certain.....at least until the Lync Optimizer has dial rules for every country in the world), I'd rather ensure with 100% certainty it won't happen, by not putting a plus in front of emergency/service numbers.

Lync will happily route numbers with or without a plus, as long as your routing logic allows for it. You could build your entire Lync Enterprise Voice deployment around not using plus signs at all if you wanted to, but I wouldn't advise it, mostly because of Lync federation. Published phone numbers from federated contacts with a plus sign would not route in a deployment built around not using the plus sign.

So, there you have it. This blog post has convinced me that not using a plus sign for non-global numbers is the way to go.  I've updated the Lync Optimizer code to follow this tweak in best practices. What are your thoughts?  Does this change your view?  Does this very long blog post on the topic of a plus sign make you fear for my sanity? Let me know in the comments.

Wednesday, January 21, 2015

Adventures in Normalization

One of the things that differentiate Lync from its competitors is its reliance on 3rd party peripherals like deskphones. This is often touted as a Good Thing, since you're not locked into a single vendor for phones. Phones from single-vendor solutions are often more expensive than an equivalent Lync phone simply because you can't get them from anywhere else, so competition is low and prices are higher.

Since Lync phones are provided by different vendors, there is naturally a lot of variation in the specific details on how things work. Microsoft has alleviated this somewhat by instituting a Lync-qualified devices program.  This is a fairly thorough program that puts devices through their paces to ensure they function properly within Lync. 

However rigorous the program, little details slip through the cracks. One of the details that I've noticed is how different phones (and even the Lync client) handle regular expressions in different ways. For anyone familiar with the minutiae (thanks Word of the Day Calendar) of Lync Enterprise Voice, regular expressions are used for phone number normalization and routing. 

All Lync-qualified devices handle basic regex in the same manner. For most people, this is not an issue, but sometimes you need to use lesser-known regex patterns to accomplish certain goals. When you try to get fancy with regex, things sometimes break down with disparate results between clients and phones. 

Over the years, I've heard about and personally experienced situations where Lync Optimizer-generated regex doesn't work on specific phones. The affected vendors have eventually fixed these issues, but I figured that I should do some hardcore 60 Minutes style investigation into just how well different devices handle some of the more esoteric regex patterns out there. 

To do this, I used my wide variety of Lync deskphones I have available for testing in my home lab.  (You should hear what it sounds like when someone phones me.  Everything is ringing and flashing, and I usually go "AAAAhhhhh" and run out of the room.)  I used a Polycom VVX 600, a Polycom CX600, a Snom 760, and an old LG-Nortel "Tanjay" series phone.  My AudioCodes 440HD wasn't connecting to our Lync server at the time, so it was left out of testing. Every phone was updated with the latest firmware available at testing time. 

For the first round of the Lync Normalization Olympics, I decided to keep it simple, using some of the rule formats commonly used by the Lync Optimizer.  I input the normalization rules into Lync via the Control Panel, and I used the "Create voice routing test case information" to see how Lync Control Panel would interpret the regex, and included that in the results too. For all the rulesets, I used a unique "identifier" for each rule to allow me to setup a series that I could test all at once.  

Commas

First off, I used a regex rule that included a comma, which I had heard caused normalization issues with one particular vendor. In the below example, I'm looking for a pattern of numbers that starts with 999 followed by 10 or 11 digits. The 999 gets stripped and puts a + in its place.

Pattern: ^999(\d{10,11})$
Translation: +$1
Input number: 99915552223333 then 9995552223333
Expected output: +15552223333 then +5552223333

Control Panel
Lync Client
Tanjay Phone
Polycom CX
Polycom VVX
Snom
+15552223333
+15552223333
+15552223333
+15552223333
+15552223333
+15552223333
+5552223333
+5552223333
+5552223333
+5552223333
+5552223333
+5552223333
Everything passed that one with flying colours, so rumours of a phone type not handling commas seem to no longer apply.

Dealing with Extensions, Part I

Another common rule used in the Optimizer is a rule to accept any dialed number, but strip out any extensions and leave it as an externally routable E.164 number. This rule was meant mostly for click-to-dial from the Lync client, but I did hear about a particular vendor's phone not being able to parse that particular rule. In the next example, I'm looking for a pattern of numbers that starts with 998 followed by 11 digits, followed by some regex that would strip anything else beyond the 11 digits. The 998 gets stripped and puts a + in its place.

Pattern: ^998(\d{11})\d*(\D+\d+)?$
Translation: +$1
Input number: 99815552223333
Expected output: +15552223333

Control Panel
Lync Client
Tanjay Phone
Polycom CX
Polycom VVX
Snom
+15552223333
+15552223333
+15552223333
+15552223333
+15552223333
+15552223333
Everything passed that one with flying colours, so rumours of a phone type not parsing those rules seem to no longer apply.

Dealing with Extensions, Part II

The next rule test is a variation on the first example above, using a slightly different regex pattern to strip any extension. This format was used a long time ago in the Lync Optimizer, but was replaced with the "cleaner" looking version above.  One person told me he used this format to get around an issue with a particular phone vendor's issue parsing the previous example's format.

Pattern: ^997(\d{11})(\s*\S*)*?$
Translation: +$1
Input number: 99715552223333
Expected output: +15552223333

Control Panel
Lync Client
Tanjay Phone
Polycom CX
Polycom VVX
Snom
+15552223333
+15552223333
+15552223333
+15552223333
+15552223333
+15552223333
Again, no issues on any platform.

Extensions with Optional Site Code

In companies with multiple sites that provide its users with extension dialing, its often necessary to use site codes to properly differentiate one site from another. This is especially true if there are overlapping extension ranges originating from legacy PBXs. So, for a company using 4-digit extensions, they may prepend a site code to ensure uniqueness. So, Site #101 could use 1015xxx for their extension range, and Site #102 could use 1025xxx for their extension range.

One particular company wanted to ensure that users within any given site could dial their own users by extension without the prepended site code, but still allow them to enter the site code if they wanted to. I did this in one rule by using a bit of fancy regex. In the below example, a user should be able to enter the extension with or without the 996 "site code".

Pattern: ^(?:996)?(5\d{3})$$
Translation: +1555222$1
Input number: 9965000 then 5000
Expected output: +15552225000

Control Panel
Lync Client
Tanjay Phone
Polycom CX
Polycom VVX
Snom
+15552225000
+15552225000
+15552225000
+15552225000
+15552225000
+15552225000
+15552225000
+15552225000
+15552225000
+15552225000
+15552225000
+15552225000
Sigh, once again, no issues on any platform.

OK, boooooring. All the phones passed the basic regex tests without issue. Not at all "exciting". I use "exciting" in quotes, because how exciting can the topic of normalization be?

Multiple Replacement Strings

Sometimes you need to use multiple replacement strings in a rule (ie $1, $2 etc). Rumour has it some phones have issues with this.

Pattern: ^996(\d{3})000(\d{7})$
Translation: +1$1$2
Input number: 9965550002223333
Expected output: +15552223333

Control Panel
Lync Client
Tanjay Phone
Polycom CX
Polycom VVX
Snom
+15552223333
+15552223333
+15552223333
+15552223333
+15552223333
+15552223333
Running out of ways to say "No issues".


Advanced Normalization Tests 

To really gauge how well a phones' regex engine functions, we have to throw at it some regex that would only be used in very specific circumstances. 

For example, let's say I have a need to translate a set of digits into a pattern where those digits are buried within other numbers.  For example, I want to take 92xx and translate it to +155592xx999.  So, 9201 translates to +15559201999.  If you try to create a pattern like ^(92\d{2})$ and translate it to +1555$1999, there is ambiguity on whether you mean +1555 $1 999 or +1555 $19 99. 

Normally, I would follow the .NET regex reference which has different ways of dealing with this, but none of them work in the Lync client.  I did stumble upon one that did work, even though it isn’t a valid .NET expression.  Not only that, but testing with other phones gave different results most of the time.

I tried various patterns, and plugged in 9100, 9200, 9300 etc to see the results in both Control Panel and Lync softclient and desk phones. The results proved interesting.

Pattern: ^(91\d{2})$
Translation: +1555$1999
Input number: 9100
Expected output: Expect failure, but want to see how various devices handle this situation.

Control Panel
Lync Client
Tanjay Phone
Polycom CX
Polycom VVX
Snom
+1555$1999
+155599
+15559100999
+15559100999
No match
+1555
Seems as though the old Tanjay and CX-series phone work in this situation, but nothing else. No big deal, because I wouldn't expect any consistent behaviour here.


Pattern: ^(92\d{2})$
Translation: +1555${1}999
Input number: 9200
Expected output: +15559200999

Control Panel
Lync Client
Tanjay Phone
Polycom CX
Polycom VVX
Snom
+15559200999
No match
+15559200999
+15559200999
+15559200999
No match
Using ${1} is a valid way to prevent any ambiguity between $1 or $19 in this example. Sadly only the Lync client and the Snom don't respect this valid regex.


Pattern: ^(93\d{2})$
Translation: +1555$_999
Input number: 9300
Expected output: +15559300999

Control Panel
Lync Client
Tanjay Phone
Polycom CX
Polycom VVX
Snom
+15559300999
No match
No match
No match
+15559300999
No match
Using $_ is a way to substitute the entire string. Not ideal code-wise, but wanted to see if it would work.  Only the Control Panel and Polycom VVX phones properly parsed it.


Pattern: ^(?<1>94\d{2})$
Translation: +1555${1}999
Input number: 9400
Expected output: +15559400999

Control Panel
Lync Client
Tanjay Phone
Polycom CX
Polycom VVX
Snom
+15559400999
No match
No match
No match
+15559400999
No match
This is a valid .NET regex method to use named replacement strings instead of numeric. So, I could have easily used ^(?<DigItDude>94\d{2})$ -->  +1555${DigItDude}999.  Again, only the Control Panel and Polycom VVX phones properly parsed it.


Pattern: ^(95\d{2})$
Translation: +1555($1)999
Input number: 9500
Expected output: +15559500999

Control Panel
Lync Client
Tanjay Phone
Polycom CX
Polycom VVX
Snom
+1555(9500)999
+15559500999
+15559500999
+15559500999
+15559400999
+1555(9500)999
This is actually not a valid .NET regex method. Surprisingly, all the devices except for the Snom managed to parse it correctly.

Conclusions

As long as your phone number normalization requirements don't require any digit replacement buried within other digits, you can safely use just about any Lync-qualified device.  However, if you know in advance that you have such a requirement (and its very unlikely that you would), I would avoid Snom phones at this time, simply because they couldn't handle any of the advanced regex I threw at them in my attempts to solve that specific issue.

The way I see it, if I build a regex pattern in Lync Control Panel, I should be able to trust that every single device will parse that regex pattern the same way.  I find it rather annoying that there isn't any rigorous checking to see if vendors adhere to .NET regex standards. On that front, I feel Microsoft needs to be more diligent with their phone qualification process.  Its these little details that can lead to frustration for anybody deploying Lync Enterprise Voice.

If you got to the end of this post and are still not asleep.....congratulations!  This post has been entered in the "Most Boring Tech Post of the Year" for 2015. Yes, I know its early, but I think this is an early front-runner for the win.

Wednesday, November 19, 2014

The Importance of Lync Location Policies

Lync Location Policies are used to specify how to deal with emergency calls originating from Lync clients.  Quite a bit has been written about location policies and how they are used in E911 emergency dialing scenarios (for a few examples, see Technet or Mark King's UnplugthePBX blog).


Unfortunately, E911 only exists in the US, so anybody reading the documentation outside the US might conclude that location policies aren't required, and that emergency calls can be routed as other normal calls. While this is technically true, location policies still provide some critically important functions in specific scenarios that may not be apparent until you have to deal with them firsthand.

The Problem

Imagine the following two common scenarios:
  1. Your company has a single site spread across several floors of a building and everyone is assigned an extension, instead of a full directly-dialable phone number (DID). Your company has a single main office external phone number which rings to reception.
  2. Your company uses a centralized SIP trunk for normal calls, but all remote sites are configured with small PSTN gateways used to provide Lync-based local emergency dialing via a few analog lines.  Each user have their own dedicated directly-dialable phone number.  Users are assigned to a voice policy that ensures that emergency calls will route out the local PSTN gateway. 
For scenario #1, if someone within the office calls the emergency service applicable for their country (lets use 112, a common emergency number in Europe and many parts of the world), the number that will be presented to emergency services will be your main office number. 

For scenario #2, if someone from a remote office calls 112, the phone number that will be presented to emergency services will be that of the analog line assigned to the PSTN gateway. 

For both scenarios, you might be thinking "OK, so emergency calls go out the proper gateway, and emergency services will know where the office is. What's your point?"  You're correct in that emergency services will know the office location and will be able to dispatch personnel as required, but now think about these two factors:
  1. The user who called 112 accidentally hangs up because that zombie finally caught up to him.  What happens next (other than you now have two zombies)?  We'll call it the "Hang-up of Death".
  2. What happens when someone travels from their usual office to another and has to call emergency services because of....yeah, zombies?  It's the "Travelling Salesman of Doom".

The Hang-Up of Death

For #1, the typical response from emergency services is to re-dial the number that will show up on their console. In the single office/extension scenario, they will reach reception who may have no idea about who called 112, which can waste valuable time, depending on how fast the zombie horde grows.

In the remote site scenario with a dedicated analog phone line, emergency services would redial the analog number, and the call would ring endlessly, since its not likely that anybody considered someone calling inbound to an emergency number.  Or if someone was bright enough to forward incoming calls to reception, they still might not have any idea on who called 112 in the first place, again wasting valuable zombie killing time.

Travelling Salesman of Doom

For the unfortunate travelling user in #2, remember that unless you've implemented location-based routing, the user's calling behaviour won't change based on their current location.  If they call 112, then the call will route out the user's normal PSTN gateway which means emergency services will show up in their normal office, while our poor guy gets chased down by zombies.  If location-based routing has been implemented, then we still have to deal with the fact that reception at the local site still has no idea where the zombie attack is taking place.

The Solution

As you hopefully have discerned, location policies can help with both of these situations very well.

Firstly, location polices can be configured to notify one or more users by IM that someone's called emergency services. This way, when emergency services shows up, or if they have to call back, reception or security or whoever will have a bit more information about the situation than they would otherwise.

Secondly, location policies can be assigned to Lync network sites, which means that emergency calls will go out the proper gateway no matter where the user is typically situated.  This works very similarly to location-based routing, except that it's only for emergency calls.

Takeaways

If you are outside the US, you should still configure location policies for every site that has a PSTN gateway.  Consider doing the following:
  • Configure Lync network sites and subnets for everywhere that Lync users could go.
  • Configure location policies and assign them to each Lync network site, and set it to use the local PSTN gateway for emergency calls. Check the box marked "Enable Enhanced 9-1-1 (E9-1-1)" even if you don't use E911. This seems to be a prerequisite for emergency dialing via Location Policies to work at all, despite what Technet says.

  • Assign the appropriate default location policy to every user, to act as a fallback in case they are outside a Lync-defined subnet. 
  • Configure the notification URI field* in the location policy so that the appropriate people are aware whenever the configured emergency number is dialed.
  • If using analog gateways for emergency dialing only, make sure that inbound calls route to the appropriate person, should emergency services need to call back (ideally the same person who's been assigned to the notification URI field).
  • Consider populating the location information services (LIS) database even if outside the US, because this can help reception figure out where the person who called emergency services is located.
* A special note about the the Conferencing URI fields: You probably noticed these fields, which implies you can conference someone in when they dial the emergency number. Unfortunately, this doesn't work unless you're actually using an E911 provider in the US. If you're outside the US, you can enter values here to your heart's content, but it won't do anything. Boo-urns! Thanks to C. Anthony Caragol (check out his LyncFix blog) for bringing this annoying little tidbit to my attention.

For detailed instructions on how to configure Lync network sites and location policies for non-US locations, I strongly recommend Elan Shudnow's blog post on the subject.

Tuesday, October 7, 2014

Lync Enterprise Voice Misconceptions #3 - Inter-trunk Routing

During my travels across the Lync Enterprise Voice landscape, I come across numerous Lync deployments that make some fundamental mistakes in how to manage phone numbers, call routing and other details.  I've covered a lot of these details in parts of my OTHER Enterprise Voice Best Practices, but its obviously a lot to take in, and I've seen enough of the same sort of errors in the wild that prompted me to do this series.

Last week's episode talked about how to properly use the external access prefix in Lync. This week, we're talking about...

#3 - Inter-Trunk Routing

If you've ever manually created trunk translation rules for a PSTN gateway in Lync, you've probably noticed the "Associated PSTN Usages" section.


The wording is vague, and even Technet's description of the setting doesn't tell you much.


From what I've seen in multiple deployments, people tend to add the PSTN Usages that were created specifically for the particular trunk, which sort of makes sense if you use Technet's description as your only guide.

Some other places on the Internet take this idea even further, and imply that this section is used to define the PSTN usages that are allowed to use the specified trunk. If you think about it, you already accomplish this by defining the PSTN Usage/route combination without having to do anything else, so that can't be right either.

Now, you might be aware that Microsoft mentions in their Technet planning documentation that Lync can do "inter-trunk routing".  From their own documentation:
This new capability enables Lync Server to provide call control functionalities to downstream telephony systems. Intertrunk routing can interconnect an IP-PBX to a public switched telephone network (PSTN) gateway so that calls from a private branch exchange (PBX) phone can be routed to the PSTN, and incoming PSTN calls can be routed to a PBX phone. Similarly, Lync Server can interconnect two or more IP-PBX systems so that calls can be placed and received between PBX phones from the different IP-PBX systems.

In more general terms, Lync can pass inbound phone calls on to a different destination, which could be another PBX system or even back out to the PSTN.  So, now you're thinking "That's a great feature, but what does this have to do with Associated PSTN Usages?"  Since the title of this article says "Inter-Trunk Routing", it should dawn on you that "Associated PSTN Usages" has something to do with inter-trunk routing.  If it doesn't, then lie down a while and come back after a good nap.

As you hopefully have surmised by now, inter-trunk routing is done using "Associated PSTN Usages" from within a trunk.  The details behind how to do this are helpfully discussed in some of my own blog posts, Technet and also those by fellow Lync MVP Richard Brynteson:
http://ucken.blogspot.com/2013/06/inter-trunk-routing-in-lync-2013.html
http://masteringlync.com/2013/06/07/inter-trunk-routing-deep-dive/
http://technet.microsoft.com/en-us/library/gg425831.aspx

To summarize those blog posts, if an incoming call from a trunk can't be routed to an internal user, it will attempt to route the call to an alternate trunk, if there is a matching PSTN Usage/route combination assigned to the incoming trunk.

When people add the PSTN usages to a trunk that are already assigned to that very same trunk, incoming calls could potentially be sent back out the same way they came in, if there isn't a matching user in Lync. This could result in odd behaviour, including calls bouncing back and forth between a PBX and Lync, in what I call the "Telecom Routing Donut of Doom".  Fortunately, in most cases, adding PSTN usages to the trunk has no effect, since there is almost always a Lync user assigned to the incoming phone numbers.

I've seen numerous deployments where they've added PSTN usages willy-nilly (my Word-of-the-Day calendar entry for today).  If I see those, my next question is "Oh, so you're using inter-trunk routing."  If the reply I get back is some variation of  "What's inter-trunk routing?", then I remove those PSTN usages from the trunk configuration.

There you have it.  Tune in next time (not necessarily next week, since I'm bad at reading calendars) where we talk about something else that I haven't quite figured out yet.