Mar
31

For many of you geeks and nerds out there like me (I’ll take a poll as to which one is better at another time), you’ve worked with some *NIX flavor for many years now. For others of you, you have most likely dabbled with various Linux distro’s and have come to know commands as needed. One extremely powerful tool that you may or may not have come across during your years is SED or the Stream Editor (sometimes referred to as the String Editor as well). This tool can take input from stdin and manipulate it as it leaves via stdout.

For those of you that have used SED in the past, you will certainly notice some similarities to the Cisco set of commands known fondly to many voice folks as Voice Translation Rules, and given your ability to pick out the differences, may help you in your quick adaptation to Cisco’s iteration of this tool.

For those of you that have not ever used this tool, take no worry. For in these next series of blog posts I will attempt to break down not only the components of Voice Translation Rules, but of the overall science of Digit Manipulation in IOS, into bite-sized chunks that will help you to digest it much easier.

Here in this first installation of the blog series, I won’t so much go into practical application along with placement, debugging and the big picture, as I will seek to first help you out with the laws that must be conformed to, in a single rule within the overarching ruleset. Then in near future installations, I will provide not only the framework for wherein this ruleset applies, but also how it affects other forms of digit manipulation as well as detailed debugging to give you a full pragmatic understanding of the power of Digit Manipulation in IOS.

So to begin with, a quick understanding of what we are attempting to accomplish is probably in line. We desire to take a string of digits, in whatever form they are given to us, and change them to something different. We may wish to change a small part of the digits, or the entirety of them. We may not wish to change anything at all about the digits themselves, but instead possibly something about them, namely their Type and Plan attributes.

In order to begin using Voice Translation Rules, we must start out with an understanding of how they work, that is to say “What laws govern them? What laws must we follow in order to obtain our desired output?”.

The First Law of Voice Translation Rules we will very basically see is that our beginning matched number, and our output translated number, must both be surrounded in (or delineated by) a set of forward slashes. So the syntax goes:

voice translation-rule 1
   rule 1 /matched-digit-string/ /translated-digit-string/

So it would stand to reason that:

voice translation-rule 1
 rule 1 /6145551212/ /6148682121/

Would result in the number 6145551212 being translated to 6148682121 – and that would be correct. We also have a handy test tool to assist us in deciding if what we put in and desire to get out – works the way we intended it to. We run it from exec mode (not global config mode) – and it goes like this:

VORack52R1#test voice translation-rule 1 6145551212
Matched with rule 1
Original number: 6145551212     Translated number: 6148682121
Original number type: none      Translated number type: none
Original number plan: none      Translated number plan: none

VORack52R1#

So that’s the first bit. Not too overly complicated is it? Not really – but as we add flexibility in what we can match and what we can do with what we match, you will begin to see the amount of complexity go up. Really what you may see is the amount of readability go down – but again just remember – bite-sized-chunks – after all it’s the only way to eat an elephant (INE does not condone the harming of animals in any way – it’s just a colloquialism).

So next let’s take a look at things a step further. Notice in my above example I didn’t do anything to change the prefixed digits of 614, I seemingly desired for them to stay the same. That being the case, did I need to even include them? What if I simply omitted them altogether? Would everything still match and result in the same output? Let’s take that question/theory for a spin:

VORack52R1#sh run | s voice t
voice translation-rule 1
 rule 1 /5551212/ /8682121/
VORack52R1#
VORack52R1#
VORack52R1#test voice translation-rule 1 6145551212
Matched with rule 1
Original number: 6145551212     Translated number: 6148682121
Original number type: none      Translated number type: none
Original number plan: none      Translated number plan: none

VORack52R1#

It certainly looks like everything still worked just fine. But why did it? Voice Translation-Rules don’t manipulate data that they are not given to match on. In other words, if the data isn’t included the beginning matched number, then it is simply left alone (e.g. whatever came in – goes out – untouched). OK, you might say – but why did the matched number of /5551212/ allow a match on a string of 6145551212 – the string in the matched number didn’t include the prefix of 614 – so why did it allow the match? Simple answer: Because we never told it that it wasn’t allowed to. Well – can we tell it that it isn’t allowed to? Sure – this brings us to our Second Law of Voice Translation Rules – namely the ability to use Regular Expressions (or “regex”) in the matched number. NOTE: Regex can only be used in matching numbers, not in the translated number. This is the same in IOS as it is in CUCM. Most regular expressions apply. As a reminder, I will very, very briefly excerpt a few more commonly used elements here:

? Matches the preceding element zero or one time.

+ Matches the preceding element one or more times.

^ Matches the beginning of a literal string.

$ Matches the end of a literal string.

| Defines that what goes directly before and after this symbol is a Boolean OR.

\(  \) Defines a marked subexpression. The string matched within the parentheses can be recalled later.

So if we go back to our most recent example with only 7 digits beginning with 555 to match from, and give it a ^ before the matched number, we should see that our input of 10 digits beginning with 614, will simply not match:

VORack52R1#sh run | s voice t
voice translation-rule 1
 rule 1 /^5551212/ /8682121/
VORack52R1#
VORack52R1#
VORack52R1#test voice translation-rule 1 6145551212
6145551212 Didn't match with any of rules
VORack52R1#    

And that’s exactly what we see. However if we modify our input number to only 7 digits beginning with 555, we should still have a match and a subsequent translate:

VORack52R1#test voice translation-rule 1 5551212
Matched with rule 1
Original number: 5551212        Translated number: 8682121
Original number type: none      Translated number type: none
Original number plan: none      Translated number plan: none

VORack52R1#  

And of course indeed we do.

So now let’s move on and take a look at that last powerful expression I posted above – the one with open and close parenthesis, and those backslashes preceding each parenthesis. The backslashes are typical in most scripting languages to escape something that could otherwise be interpreted by the parser as part of the string. We need to inform the parser that it is not part of the string – but in fact an operator designed to do something. In this case it is designed to set apart a section or “set” of our string, that we wish to later recall. So let’s go back to the example of 10 digits that begin (and only begin) with 614, and then set about to change only the 555 to 868, while preserving whatever 4 trailing “Subscriber” digits come in following the 555 prefix. To do that we will include the 614 along with a ^ to denote that the string must begin with a 614. Then we will ”set apart” the part of the number beginning with 555 and ending in any 4 digits. Finally we will change the 555 to 868, and reuse whatever 4 Subscriber digits came into the original string. This brings us to a very important Third Law of Voice Translation Rules, which is that in the translated number portion of the rule – a backslash has a very different role: The Backslash is always followed by a Numeral – and that numeral defines which “section” or “set” from the original matched number is now being “recalled” to this current position. You may have multiple backslash\numerals – and each one independently of the others recalls whatever section is represented by a numeral. It is best to keep things simple and have as few as needed – but complexity can easily be undertaken if the desired outcome requires it. Here we will demonstrate this with a simple single “set” in the matched number, followed by a recall of that set to the translated number, and then of course the “test” to prove the theory.

 VORack52R1#sh run | s voice t
voice translation-rule 1
 rule 1 /^614555\(....\)/ /614868\1/
VORack52R1#
VORack52R1#
VORack52R1#test voice translation-rule 1 6145551212
Matched with rule 1
Original number: 6145551212     Translated number: 6148681212
Original number type: none      Translated number type: none
Original number plan: none      Translated number plan: none

VORack52R1# 

Again we could get a bit more complex with multiple “sets” and “recalls” in the matched and translated number respectively, and yet yield the same resultset:


VORack52R1#sh run | s voice t
voice translation-rule 1
 rule 1 /^\(614\)555\(....\)/ /\1868\2/
VORack52R1#
VORack52R1#
VORack52R1#test voice translation-rule 1 6145551212
Matched with rule 1
Original number: 6145551212     Translated number: 6148681212
Original number type: none      Translated number type: none
Original number plan: none      Translated number plan: none

VORack52R1#

Again – we simply created 2 sets, and then when the placeholder came time in the translated number to recall the contents of that first or second set, we did so with a \1 or \2, along with the other normal string digits (868) we wished to replace.

Another thing we can do is to, as I mentioned above, not change the matched number into anything, but rather to leave it be use the Voice Translation Rules to change the Numbering Type and Plan. The format is a bit odd – it is:

/matched-number/ /translated-number/ type matching-type translated-type plan matching-plan translated-plan

So here in this example we have a common US rural carrier issue, namely that the carrier will refuse the call if both the carrier international prefix string of “011″ and also the numbering type and plan of “international” and “isdn” are all included in the called party IE. To resolve this we simply need to allow any digits that come in, to go out, while at the same time changing the type and plan from ”international” and “isdn” to  ”unknown” and “unknown”. This will do the trick for some carriers.

VORack52R1#sh run | s voice t
voice translation-rule 1
 rule 1 // // type international unknown plan isdn unknown
VORack52R1#
VORack52R1#
VORack52R1#test voice translation-rule 1 011442055551212 type international plan isdn
Matched with rule 1
Original number: 011442055551212        Translated number: 011442055551212
Original number type: international     Translated number type: unknown
Original number plan: isdn      Translated number plan: unknown

VORack52R1#

So that will end our first dive into Voice Translation Rules – and beginning into the much bigger picture of Digit Manipulation in IOS. Stay tuned in the very near future as I will paint (with pretty visuals) a much deeper understanding of both as we take both a more detailed look into many of the components, as well as broader overall view as to where it’s best to use each component, and how they all fit and play nicely together.

About Mark Snow, CCIE #14073:

Mark Snow has been actively working with data and traditional telephony as a Network Consulting Engineer since 1995, and has been working with Cisco Call Manager and voice-over technology since 1998. Mark has been actively teaching and developing content for the CCIE Voice track since 2005, and the Security track since 2007. Mark's story with both data and voice technology started out quite young, as he began learning around the age of five from his father who was a patented inventor and a research scientist at AT&T Bell Laboratories. Mark started out on Unix System V and basic analog telephony, and went on from there to large data networking projects with technologies such as Banyan Vines, IPX and of course IP, and large phone systems such as Nortel 61c, Tadiran Coral, Avaya Definity and of course Cisco Unified Communications Manager in both enterprise and 911 PSAP environments across the US and internationally. Mark is also an accomplished pilot and punched his ticket in 2001. When Mark isn't learning, labing, consulting or teaching, he can be found either piloting or possibly jumping out of a perfectly good airplane, hanging off a rock somewhere or else skiing out west. He also might just be enjoying a quiet day at the beach with his wife and two wonderful young kids, Ryleigh and Judah.

Find all posts by Mark Snow, CCIE #14073 | Visit Website


You can leave a response, or trackback from your own site.

4 Responses to “Lost in (Voice) Translation – I didn’t quite hear what you SED”

 
  1. Hassan B. says:

    Awesome topic :D , keep going

  2. Angel says:

    You are the master!

  3. Samuel says:

    Thanks a lot Mark! Excellent Post! Can’t wait to read the remaining on the series.

  4. [...] Profiles allow for pattern matching and replacement in a similar (but not exact) method to that of Voice Translation Rules, and like them, are based (loosely) on the GNU SED stream editor. We will use this to match and [...]

 

Leave a Reply

Categories

CCIE Bloggers