Monday, May 21, 2012

Identifying Cisco IP Phone Models for Custom Directory

Earlier this year I decided to develop a web application (NetCraftsmen Enterprise Directory - NED) that could provide a multi-tenant and multi-source corporate directory feature for the Cisco Unified Communication Manager (CUCM) telephony environment. I have written custom corporate directory apps before using the Cisco IP Phone SDK. 

This time around, I decided to start from scratch. I also decided to use C# and the ASP.NET framework. So, I am immersed in a learning curve - which is really where I like to be. I thought that periodically I could throw a tidbit of information in this blog. Whether that information is about C#, ASP.NET, or just Cisco-isms.

In the current installment, I am going to provide a very simple example for determining what model of phone is connecting to a web application. Turns out, this is pretty important to create a robust corporate directory application for Cisco IP Phones.


So, what is the problem I am trying to solve? During the testing phase of the first prototype I came across an issue that seems to plague a lot of readers of my NetCraftsmen blog. When adding a custom directory application to an environment with a wide variety of Cisco IP phones, you learn pretty quickly that not every phone is treated equal in the eyes of the "Corporate Directory". 

The prime example is observed when you disable the Enterprise subscription for the built-in Corporate Directory. When you point phones to your custom web application you will find that on phone models like the 7961, 7962, and 7965 that everything looks the way you expect it to look. However, if you have a 7906, 7940, 7960, and the like you will find that the Personal Directory is no longer available. 

I attribute this problem to the fact the older phone models are not using the Enterprise Subscriptions/Internal Provisioning in the same way as newer models. That is probably oversimplification, but that is fine by m. The point is: it doesn't work.

The Fix

Right away I knew I needed the application to reliably identify the phone model. Fortunately for me, Cisco has a rich developer network ( What i found is that with every GET request, a Cisco IP phone will send some customer HTTP headers. For instance:
  • x_ciscoipphonemodelname: The actual phone model name
  • x_ciscoipphonesdkversion: The SDK version supported by the phone

These custom headers can give your application a pretty good idea of the capabilities of the requesting station. So, we know the "what", now we need the how.

I decided I needed to identify the client as soon as they sent a GET request for the URL associated to the Directories button on the phone. This is pretty obvious. I added the following code to the Page_Load routine in the appropriate aspx.cs code file:

public partial class test : sample
    protected string m_clienttype = "unknown";
    protected void Page_Load(object sender, EventArgs e)
        NameValueCollection headers = base.Request.Headers;
        for (int i = 0; i < headers.Count; i++)
            if (headers.GetKey(i).ToLower() == "x-ciscoipphonemodelname")
            { //we found the request header we want
                m_clienttype = headers.Get(i);
     ((some code ommitted))

Once we have identified the phone model (m_clienttype) then we can evaluate whether the requesting station needs some special treatment. For the 7940/60 (and similar models) we can add a simple if...then logic to build the appropriate XML menu structure to support the Personal Address Book (PAB) URL. 

Thanks for reading. If you have time, post a comment!

No comments:

Post a Comment