Cisco 7942 API/XML Application Hacking
I came across a few Cisco 7942 IP Phones a while back. Typically, these aren’t that much use as they usually come with the Cisco SCCP (Skinny) firmware flashed, meaning they’ll only work with the proprietary Cisco CallManager software (or with Asterisk using the skinny channel driver, but that’s something else…).
As it happened, it was quite easy to flash the SIP firmware with a TFTP server (I used the standard inetd
server) and a DHCP server (I used isc-dhcp-server
) to point the phones to the right place (with DHCP option 66). Once they were flashed, they’d happily talk to Asterisk after a little more configuration, most of which you can find out about in the Asterisk Book.
After all the initial setup and playing around with Asterisk is done, there’s a few other nice things you can do with these phones in particular.
They have a rather neat set of APIs for performing various actions on the phone remotely using simple HTTP requests with XML_ish_ payloads. Some of these involve requesting content from remote servers and displaying it on the phone for the user to interact with, and some of them involve POST
ing instructions to the phone to invoke certain actions. I’ll detail some of them here but you can of course also (at your peril) refer to the colossal PDF manual Cisco offer on the subject.
Authentication
Authentication works in a fairly bizarre but ultimately straightforward way.
Essentially, the configuration file for each phone (SEPXXXXXXXXXXXX.cnf.xml
, where the X
s are replaced with an uppercase hexadecimal representation of the phone’s Ethernet MAC address) which resides on the TFTP server contains an XML node called <authenticationURL>
under the top-level <device>
node. This node contains a URL, to which the phone is to query using a HTTP GET
request whenever an authenticated service is required. The phone passes a few query string parameters (UserID
, Password
and devicename
containing the MAC address of the phone, including the SEP
prefix).
The expectation is that the body of the response to this request will contain only the 10 bytes - AUTHORIZED
- if the user is accepted by the server, or any other content if not.
Display Screenshot
Perhaps one of the coolest (but least useful, aside from maybe debugging phones on the other side of a building/the world) that the 7942 offers is the ability to request an image of the display. This one is a good one to test your authentication setup described earlier as it’s a simple GET
request that you can make in the browser. When you make the request, you’ll be prompted for a username and password (the phone uses HTTP Basic authentication for API requests sent to the phone).
The request URI will be something like http://<IP>/CGI/Screenshot
, obviously replacing <IP>
with the IP address of your 7942 IP Phone.
Fortune Teller
The phone’s XML applications are a little dated in concept but still fun to play with. Simply put, you can write sort of primitive hypermedia applications that work by serving up XML using a special proprietary Cisco schema to the phone when requested.
As an example, I wrote a Fortune Teller one using fortune
.
The application has two parts. Firstly, there’s a Services Menu XML document that describes the services menu items that will be shown to the user when they press the Services button on their phone:
You can add more <MenuItem>
nodes for additional items. I think there’s some arbitrary limit like 32 menu items per <CiscoIPPhoneMenu>
but this might vary on different models of IP Phone.
The second part of the application is the resource at http://[Server-IP]/fortune.php
that will be the pithy quip displayed by the service. A PHP script renders this for us:
Note that we escaped the output of /usr/games/fortune
just in case the characters it contains aren’t so fortunate.
There’s a handy Update softkey to re-send the GET
request and display another quip too.
Dial-on-Click with Protocol Handlers
One of the Free Desktop standards, the Desktop Entry standard details a file format for describing how programs should be launched from within the desktop environment.
One of the ways programs using this standard can be launched is via protocol handlers like tel:
.
I wanted to set up a script such that when a tel:
link was clicked in any application on my desktop, my desk phone would automatically dial the corresponding number. As it turns out, using the 7942’s XML API and the Desktop Entry file standard, it was quite easy to accomplish.
The first step was defining the desktop entry - this took the form of a file in /usr/share/applications/
with content as follows:
After an invocation of /usr/bin/update-desktop-database
to refresh the database of Desktop Entries, clicking a tel:
link automatically executes /usr/local/bin/dial
and passes the link string to it as the first argument string.
My implementation of /usr/local/bin/dial
was pretty simple too, just a Python script using the Requests library to send of a HTTP POST
request to the phone. This request uses the CiscoIPPhoneExecute
XML node to trigger an action on the phone itself.
Worth noting the odd XML=
syntax around the start of the request body - not sure why this is required but it took some digging to find out that it was. It’s also worth noting the HTTP Basic auth that’s taking place here - this is the same authentication as described previously - the credentials are just passed on to your <authenticationUrl>
URL - as long as the response is AUTHORIZED
, it’ll work.
And as if by magic, when I click tel:
link in Chrome or Firefox, my desk phone instantly dials it and I can pick up the receiver and talk.