I've spent most of my free time in the last two months fixing something that was broken for too long: Incoming phone call notification.
For call notification it supports something called LAN-TAPI, which is Windows-only. Since my house has Linux machines only, I needed something different.
After digging around the docs and downloads a bit, I found the (Java) D-Kanal Dekoder software that connects to the switchboard's TCP debug port and displays the messages logged onto it. "D-Kanal" is german for "d-channel" and means the Euro ISDN d-channel, the channel where call data are transmitted.
A PHP script that connects to the port was quickly written, and I started to receive lines like this:
[DKANPROT-Debug 150949] N01: 02 FF FF 03 08 01 01 05 A1 04 03 80 90 A3 18 01 89 6C 0C 21 83 31 36 33 34 37 37 39 38 37 38 70 06 C1 34 30 38 36 32 7D 02 91 81 FF 0A
It turned out that this are actual ISDN d-channel data in hex notation.
ISDN protocol parser
What followed now was 1.5 months of implementing a ISDN (EDSS1) protocol parser up to the state that I could read all incoming messages with its information elements and determine when a call was setup, alerted to the phones, answered and terminated.
The message some lines above means the following, as my tool's debug mode shows:
Debug: N01: 02 FF FF 03 08 01 01 05 A1 04 03 80 90 A3 18 01 89 6C 0C 21 83 31 36 33 34 37 37 39 38 37 38 70 06 C1 34 30 38 36 32 7D 02 91 81 FF 0A bytes: ?????????????????l?!?1634779878p??40862}????? EDSS1_Message type 0x05 SETUP SAPI 0, CR 1, TEI 127, call 1-source, 5 parameters Parameter type 0xA1 SENDING_COMPLETE, 4 bytes: ???? Parameter type 0x18 CHANNEL_IDENTIFICATION, 1 bytes: ? Parameter type 0x6C Calling party number, 12 bytes: !?1634779878 1634779878 Number type: National number, plan: ISDN/Telephony Parameter type 0x70 Called party number, 6 bytes: ?40862 40862 Number type: Subscriber number, plan: ISDN/Telephony Parameter type 0x7D HIGH_LAYER_COMPAT, 2 bytes: ??
This was a lot of hard work; many thanks to Dr. Joachim Göller whose publication "Der ISDN-D-Kanal" was of great help. I also had the "pleasure" to read the "ITU-T Recommendation Q.931", which is one of the standards of ISDN. It was awful but gave me the details that were missing.
This is - as far as I know - the first ISDN protocol parser written in PHP!
After implementing the CallMonitor that keeps call state information and notifies loggers that a call is starting or finished, I wanted to enrich the call information: Apart from the number, the caller name and his location should be shown.
Caller name resolution was implemented by querying my LDAP addressbook using PEAR's nice Net_LDAP2 package.
For location detection I used OpenGeoDB, a free database that has information about probably all cities and towns of a number of european countries, including Germany. It knows the number of inhabitants, coordinates, zip codes and telephone number area codes. Matching the incoming telephone number against the database's area codes was no problem, and now I know the caller's location - at least if it's a call from a land line phone. For mobile phones, I display the network.
And if you don't have a LDAP addressbook, you can use a CSV file for name resolution.
Now that I had all call information I wanted, it was time to show the calls. The result were loggers for a SQL database, plain files, Linux desktop notifications and the Dreambox satellite receiver.
I am finally able to see incoming calls on my TV and my desktop!