Cisco IP Phone Directories using C#


Question?  How many languages does it take to provide a custom phone directory on a Cisco 79xx series IP phone?
Answer…  one…    The XDocument features available in the .NET runtime make creation of complex XML structures (Such as those needed to provision these devices) child’s play.

Technically the answer to the above is more than one, beacuse .NET has several languages, for this post though where going to use C#

So, I hear you ask, what exactly is an IP phone custom directory.  Most models of Cisco IP phone (and for that matter other manufacturers too) have a large display screen on them, typically this screen can be customised to read services and phone directorys from a web server that’s reachable on the same network as the device is connected to.

Unfortunately, to get the XML programmers documentation, you generally have to have a cisco account, and access to the on-line document catalogue.  Once you know the object types however, generating them is not really too hard.

For the purposes of this post, I’m testing all this using a grey-scale Cisco 7940G Series IP phone, and it’s already configured to talk to my IIS web server, so I’m not going to go into the details of provisioning the phone at this level, as that will be in your user guide.

We’ll start with a custom directory entry, press the directory button on your phone, then 5 for your external directory, that should call your web server to get the content.  (Depending on how you have it set already it may or may not return anything)

Now we’ll create a new standard website project in visual studio, and put it on the web server.  Once VS has finished it’s thing, remove everything from default.aspx except the first line:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="genxml.aspx.cs" Inherits="genxml" ContentType="text/xml" %>

by default the ContentType="text/xml" part won’t be there so make sure you add it.  Save default.aspx and that’s that we don’t need to touch this file any more.

next open up default.cs and add the following to the form_load function.

      XDocument directory = new XDocument(
        new XElement("CiscoIPPhoneDirectory",
          new XElement("Title","Cisco Phone Directory"),
          new XElement("Prompt","up/down/select or nums to dial"),
          new XElement("DirectoryEntry",
            new XElement("Name","Shawty 1"),
            new XElement("Telephone","01234567890")
          ),
          new XElement("DirectoryEntry",
            new XElement("Name","Shawty 2"),
            new XElement("Telephone","01234567891")
          )
        )
      );
      Response.Write(directory.ToString());

You’ll likely also need to add

using System.Xml.Linq;

to the top of the file also.  Place this file on your web server where the phone can find it, for me i put it in a folder called ciscodir and then ensure your IP phone is configured to get it’s directory from that URL.

All being well, when you press 5 this time you’ll see your 2 directory entries.

So what just happened?

In reality all you did was generate the following XML snippet:

<CiscoIPPhoneDirectory>
  <Title>Cisco Phone Directory</Title>
  <Prompt>up/down/select or nums to dial</Prompt>
  <DirectoryEntry>
    <Name>Shawty 1</Name>
    <Telephone>01234567890</Telephone>
  </DirectoryEntry>
  <DirectoryEntry>
    <Name>Shawty 2</Name>
    <Telephone>01234567891</Telephone>
  </DirectoryEntry>
</CiscoIPPhoneDirectory>

but the trick is you did it using an ASPX file, which now means you can generate these from a standard ADO and/or Linq data-source dynamicly.

A word of warning though, you can only return 32 entries at a time (The phone will ignore any more) so you will have to find a way of paging the directory entries, which is not difficult beacuse the XML pull model for these devices also provides structures to produce custom menus, display images, receive user input and much more.

For example:

      XDocument directory = new XDocument(
        new XElement("CiscoIPPhoneMenu",
          new XElement("Title","Cisco Phone Directory"),
          new XElement("Prompt","up/down/select to choose"),
          new XElement("MenuItem",
            new XElement("Name","A Entries"),
            new XElement("URL","http://1.2.3.4/directory.aspx?filter=A&quot;)
          ),
          new XElement("MenuItem",
            new XElement("Name","B Entries"),
            new XElement("
URL","http://1.2.3.4/directory.aspx?filter=B&quot;)

          )


        )


      );


      Response.Write(directory.ToString());


Will produce a custom menu that has 2 pages in marked "A entries" & "B entries", each of which will call the appropriate directory.aspx page to generate the directory entries as shown above.

      XDocument directory = new XDocument(
        new XElement("CiscoIPPhoneText",
          new XElement("Title","Cisco Phone Directory"),
          new XElement("Prompt","up/down/select to choose"),
          new XElement("Text","Some informative text returned by the service…")
        )

      );


      Response.Write(directory.ToString());



Will return a scrollable page of plain text to the phone, and last but not least

      XDocument directory = new XDocument(
        new XElement("CiscoIPPhoneInput",
          new XElement("Title","Cisco Phone Directory"),
          new XElement("Prompt","Please enter name to search for"),
          new XElement("URL","http://1.2.3.4/search.aspx&quot;),
          new XElement("InputItem",
            new XElement("DisplayName","Name:"),
            new XElement("QueryStringParam","searchname")
            new XElement("DefaultValue",""),
            new XElement("InputFlags","A")
          )
        )

      );


      Response.Write(directory.ToString());

Will produce a page allowing the user to enter a search name.

The Input structure is a little more involved that your other XML structures, but again once you realise what it’s doing, it’s quite easy.  The root, title and prompt are all standard, URL is the web page to call to process the input, then the actual Input Item is defined (Note you can have more than one on a page)

In our case we want to display "Name:" on the page displayed on the phone, and we don’t want any default value entered, the "QueryStringParam" is the name of the parameter that will be added to the page specified in the URL that the data will be processed by, so here well actually end up calling

http://1.2.3.4/search.aspx?searchname=<whatever was entered>

The last tag "InputFlags" tells the phone what type of input to allow, and can be one of the following:

A – Plain ASCII Text, use all the keys on the keypad with multiple presses to get the correct letter/number/symbol
T – Telephone number only, so numbers 0 to 9 and * #
N – Numeric only, so only numbers permitted nothing else
E – Equation, only numbers and math symbols allowed
U – Only upper case letters allowed
L – Only lower case letters allowed
P – Modify any of the above to be a password field and * the value out on the display

There are a lot more things you can do, but that’s going into more detail than I have space for here.  I do intend to make a complete system for the phone’s for my own use, but it’s definitely one of these "Pet project" scenarios, so it’s going to be at the bottom of the priorities pile.

I will however make it available here once it’s done, In the meantime I hope I’ve showed you how easy it is to generate custom XML from a simple C# web form.  There are lots of different other ways of doing this, the key is experimentation.

C-Ya,  Shawty


Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s