Nach 10 Jahren habe ich meine ISDN-Telefonanlage Auerswald COMpact 3000 ISDN in den Ruhestand geschickt und durch eine FritzBox 7390 ersetzt (gebraucht für 15€). Zwei der drei Telefone habe ich direkt an die FritzBox-eigene DECT-Basisstation angehangen, und das dritte über den ISDN-Anschluss. Die Türklingel hängt noch am analogen Telefonanschluss.
Damit die Telefone wieder Namen von im zentralen LDAP-Adressbuch gespeicherten Rufnummern anzeigen, musste ich die Daten irgendwie auf die FritzBox bekommen. Obwohl die Liste der Telefonbuchprojekte lang ist, konnte keins davon die Daten aus LDAP extrahieren.
Ich habe mir also in 30 Minuten selbst eins gebastelt: ldap2fbxml. Das Script fragt den LDAP-Server ab und generiert eine XML-Datei, die dann manuell im Telefonbuch-Webinterface der Fritzbox hochgeladen werden kann ("Telefonbuch wiederherstellen)".
Ein regelmäßiger automatischer Sync ist nicht notwendig, da ich zu Hause sowieso bald von LDAP auf CardDAV umsteigen will.
After making PEAR compatible with PHP 7, I saw that my ISDN call montior did not start up anymore because of constructor visibility issues in the Net_LDAP2 package.
The original author did not have time to do the fixes anymore, so I stepped up to make the package compatible with PHP 7 and PEAR 1.10.1.
When fixing bugs in a package, I made it a rule to always set up automatic unit test runs when a commit or a git pull request come in; travis-ci makes that particularly easy and has nice integration into github. You see the build status directly in the pull requests and get images to embed into your README to show the current build status.
Net_LDAP2 is a library to interface with LDAP servers, and has a number of tests that require such a server. So getting slapd running on travis-ci was my task, for better test coverage.
travis-ci is switching to a docker-based environment, which means that tests start very fast (because no full VMs need to be started up), but also do not allow root access via sudo.
Fortunately for us, the Debian packages slapd (LDAP server) and ldap-utils (Programs to interact with slapd) are on travis' white list, which means that you can install them via a command in your .travis.yml file:
language: php
sudo: false
addons:
apt:
packages:
- ldap-utils
- slapd
...
The LDAP server needs some configuration: The root DN, admin username and password (use slappasswd) as well as some standard schemas like inetorgperson:
# See slapd.conf(5) for details on configuration options.
include /etc/ldap/schema/core.schema
include /etc/ldap/schema/cosine.schema
include /etc/ldap/schema/inetorgperson.schema
include /etc/ldap/schema/nis.schema
pidfile /tmp/slapd/slapd.pid
argsfile /tmp/slapd/slapd.args
modulepath /usr/lib/openldap
database ldif
directory /tmp/slapd
suffix "dc=example,dc=com"
rootdn "cn=admin,dc=example,dc=com"
rootpw {SSHA}AIzygLSXlArhAMzddUriXQxf7UlkqopP
And because we're not runing as root, the server has to run on a port > 1024 . The server has to run in the background, otherwise it would block the following script commands completely.
Apart from the basic configuration, the unit tests require some test data to exist, so we have to import them before. PHP on travis-ci does not have the LDAP module loaded, so we have to take care of this, too.
The resulting travis-ci configuration is the following:
I chose to sleep 3 seconds after starting slapd since one time I had the issue that ldapadd failed because the LDAP server wasn't up.
After all that works now, you can see Net_LDAP2 unit test results on travis-ci, and inspect the full .travis.yml file.
In 2007 I opted for evolutionPerson.schema as address book schema on my LDAP server. Time has passed, and I export the LDAP entries onto my kitchen radio, query it when someone calls and display that information on my television. It's also used by all the email clients in the house of course.
In all the years, I've been using JXplorer to edit the data. It worked, but was not comfortable and definitely not wife-compatible.
Some days ago I stumbled across ConTagged, a web-based LDAP address book editor written in PHP. Finally!
Apart from being written in PHP does it support the evolutionPerson schema out of the box, has a nice interface, supports public and private addresses, map display, CSV and vcard export, and displays QR codes for easy mobile phone import. And tags/categories. Wow.
It wasn't all gold, but easy to fix:
After those fixes, I have a nice LDAP address book editor that I enjoy to use. See my git repository for the code.
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.
Some years ago I bought a Auerswald COMpact 3000 telephony switchboard and am happy with it, if it wasn't for the awful web interface and almost no way to interact with it via scripts or tools.
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.
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!
The sources are GPLv3 licensed and are available on my own git server and are mirrored on github.
I am using a central LDAP server to manage my address book. After some investigations, I settled with evolutionPerson as schema for addressbook entries and edit the persons in the address book with Evolution, sometimes with JXplorer.
Many applications in my home network consume the entries: Claws Mail, Thunderbird, some custom scripts and even the radios.
Mozilla Thunderbird's address book invented its own LDAP schema, mozillaAbPersonAlpha .
Fortunately, Thunderbird lets you change how LDAP fields are mapped to the addressbook fields !
I had some fun (non-working address book) while configuring it (Preferences / Advanced / Editor). This are the settings I had to change to get nearly all information into the Thunderbird address book.
ldap_2.servers.default.attrmap.NickName mozillaNickname,xmozillanickname,fileAs ldap_2.servers.default.attrmap.PagerNumber pager,pagerphone,otherPhone ldap_2.servers.default.attrmap.FaxNumber facsimiletelephonenumber,fax,homeFacsimileTelephoneNumber ldap_2.servers.default.attrmap.HomeAddress mozillaHomeStreet,homePostalAddress ldap_2.servers.default.attrmap.WorkAddress street,streetaddress,postOfficeBox,postalAddress ldap_2.servers.default.attrmap.WorkAddress2 mozillaWorkStreet2,roomNumber ldap_2.servers.default.attrmap.JobTitle title,businessRole ldap_2.servers.default.attrmap.Notes description,notes,note ldap_2.servers.default.attrmap.Custom1 mozillaCustom1,custom1,birthDate ldap_2.servers.default.attrmap.Custom2 mozillaCustom2,custom2,anniversary ldap_2.servers.default.attrmap.Custom3 mozillaCustom3,custom3,spouseName
Note that address fields (separated with $) are not exploded - but they are at least visible. Multi-value fields like mail are not supported. Thunderbird will display only the first value.
Since moving into our house, I've constantly been trying to make our lives more pleasing in the technical way. Here is a depiction of what has been achieved yet.
Despite the non-standardness of UPnP (based on a µ$-draft for HTTP-over-UDP that expired back in 2001), it's the only common protocol that most devices in our network understand. UPnP has been rebranded to DLNA some time ago, but it's still the same old crap. There are quite some devices that understand UPnP, but all in their own interpretation. The most unfamous UPnP player amongst the MediaTomb developers is the Sony Playstation 3 which seems to support their own UPnP dialect only, thus needing dozens of hacks on UPnP A/V servers just to see the list of audio and video files. Not to speak of "oh, I play only that format at this bitrate"-wtf features. I don't have one, but that had to be mentioned here.
As I said, many devices in my network understand UPnP: The kitchen radio (a noxon iRadio), our bedroom alarm clock (Freecom MusicPal) and the satellite receiver (Dream Multimedia's Dreambox) using djmount.
The main goal of our central MediaTomb UPnP A/V server is to serve the music collection for the above mentioned devices. Due to its transcoding capabilities, it is able to convert the ogg/vorbis music files transparently to audio/wav streams - which is necessary because the MusicPal does not play ogg. Using it, we are also able to listen to satellite radio in the kitchen, transcoding the Dreambox'es mpeg2/ts streams to wav.
During the time I needed a way to manipulate the MediaTomb server from my PHP scripts. The development of Services_MediaTomb, a library to remotely administer the - surprise - MediaTomb server is one of the public results of my home automation efforts. I use it to sync radio stations from the Dreambox and to make the LDAP addressbook available on the radios. In the house we have access to telephone numbers and addresses from everywhere.
Another use case for Services_MediaTomb is GravDigger, the MediaTomb playlist editor. It's a two-pane file manager like application you can use to create playlists on the server, a functionality that MediaTomb keeps missing.
Also in use is CorpseShovel - also based on Services_MediaTomb - which shuffles all playlists on the server every night (Yes, MediaTomb can't shuffle playlists by itself).
Years ago, I wrote a software to remind me of upcoming birthdays and other anniversaries - due to my elaborate wording skills named "birthday reminder". In the meantime, it works on every operating system and reminds many people every day. The only problem I had was that you need to use your computer to see the coming dates.
Then I discovered that Freecom's MusicPal supports RSS feeds (and only RSS, no Atom!). Within some hours I had a script which takes a birthday file and creates an Atom and RSS feed from it. Now every morning I wake up, the Radio clock shows the latest events. It has one drawback: You have to move your head and stare at the display - something that will change once I find a reasonably sexy female voice for the festival speech synthesizing engine. The DreamBox is also able to display them via its SimpleRssFeed plugin (that shows Atom!).
Beside audio files streaming to various radio devices the server also holds our video collection. I made a nice HTML frontend to browse the files (FileLister) that automatically creates thumbnails for videos and photos. It links the files to download to the ftp server, so we get higher transfer rates.
The DreamBox is very limited in the choice of video codecs it can play. Luckily we have a VLC plugin which plays videos streamed from remote vlc instances. Just fire up VLC on your desktop or laptop, enable the HTTP interface and you can play any videos on that machine - very comfortable for watching DVDs.
Due to my limited internet connectivity, I am forced to keep things as local as they can be. The server hosts its own CDDB service, acts as Gentoo portage mirror (and synces itself from the laptop), is the backup device (using rsync and nfs) and provides a nice HTML and REST interface to the ISDN dialup connection. Not to forget the time service (ntp and timed), Dreambox mirror and NNTP server :)
There are more things to come: The next steps on the plan are local Wikipedia and OpenStreetmap servers, a complete Asterisk based telephony solution that integrates with the LDAP address book and the gate intercom. It shall also be possible to open the gate from everywhere and see the telephone callee on every device (Radio, Dreambox, PC, network printer). And the mobile phones shall sync themselves with the address book :) Much to do, but all ideas are possible to realize.
After getting my kitchen radio to stream radio from satellite, I played further around with MediaTomb. During playtime I - on purpose - deleted the whole database to get my songs reindexed. What I did not remember was that all my hand-crafted radio station entries would also be gone. And they were.
So I had two choices: Adding them again, piece for piece by hand, into the MediaTomb database via the web interface. Or creating a script that reads stations from dreambox and adds them into MediaTomb. Being a hacker, the choice was clear and the first result of my attempt to sync satellite receiver and kitchen radio was Services_MediaTomb.
Services_MediaTomb is a PEAR-installable PHP library which allows you to list, add, edit and delete containers (folders) and items on MediaTomb. It utilized the AJAX API which is used by MediaTomb's web UI (which could mean it breaks when a new MediaTomb version is released, but I added plenty of unit tests).
My first tool using Services_MediaTomb is enigtomb, which synchronizes dreambox radio bouqets onto MediaTomb. It has a delete-and-copy mode which cleans out the radio directory on the UPnP server and plainly copies over all radio stations (in their bouqets, of course). The other one synchronizes the items - which means it really updates them. This means your radios continue to play - and EPG information are updated! For now, you can find the code at enigtomb's git repository.
The second tools I hacked yesterday is ldaptomb which exports addresses from your LDAP server onto MediaTomb. What does this help? Your kitchen radio is always there, and if you quickly need a number or an address, you can use it to look it up. Code is at ldaptomb's git repository, too.
Some screenshots from my Noxon:
Sharing the addressbook of two computers means usually one of two things: Having trouble, or using LDAP. I opted for the second variant since my ISDN call monitor also uses LDAP to look up names for telephone numbers.
The OpenLDAP server ships with some standard schemas that can be used to store address data: person, organizationalPerson and inetOrgPerson. A person has a name, description, telephone number and a password. Far from enough for an address book since it doesn't even has an address field. organizationalPerson goes a bit further and has a telephone number, fax number, postal address and some more. Still no email field... So we're going to the next standard one: inetOrgPerson which has a mobile number field, carLicense, mail and a place for a jpegPhoto.
Now we could live happy forever if a) all programs would support the standard fields and b) we wouldn't have any other things to store in the address book. For example: Birthday and anniversary date, IM (instant messaging) account address, second/third email and a second address (to distinguish between home and work address).
I found JXplorer to be the best general LDAP editor, also suitable to create and maintain address book entries.
I spent quite a time searching for the golden standard schema that has all the things I need and is supported by most of the programs (Evolution, KAddressbook and Thunderbird/Mozilla Seamonkey). The conclusion: There is none.
Mozilla has its own schema called mozillaAbPersonAlpha since it is in very early alpha stages. I don't really like the schema since it doesn't fully use the existing ones (inetOrgPerson) and prefixes most own values with "mozilla". Great, isn't it? I don't care if it's mozilla's invention to add that field, I want it to work. While Thunderbird supports exporting its address book to a .ldif file, the generated one cannot be imported into you ldap directory without modifications, since the ldif is broken and has some non-existing fields. I almost forgot to add that Thunderbird cannot add/modify LDAP entries which makes it an LDAP-Viewer only.
Evolution on the other side has also its own schema called evolutionPerson. At least the schema file that installed into /usr/share/evolution-data-server-1.8/evolutionperson.schema when installing gnome-extra/evolution-data-server also contains a class called evolutionPersonList to e.g. group persons into a mailing list. The irony is that even this schema does not support all the settings allowed by the evolution address book itself. Great? The good things is the field names are at least half reasonable, and it has birthday field support.
So, where is the golden standard schema? Asking on the LDAP mailing list I got the definitive answer: There is none.
There were, however, some ideas to think about:
Someone also suggested creating your own hybridPerson schema that
combines all schemas (altough you can assign multiple classes to an entry,
which I do currently):
# Objectclass: mHybridPerson # Description: Seals the break in objectclass inheritence created # by officePerson and evolutionPerson descending from inetOrgPerson objectclass ( 1.3.6.1.4.1.6921.1.12 NAME 'mHybridPerson' DESC 'Combine several objectclasses to support multiple MUAs' SUP ( inetOrgPerson $ officePerson $ evolutionPerson ) STRUCTURAL )
So, where leaves us this? You are on your own, period. Despite many applications support LDAP, they developers did not even try to standardize the schemas. If only all the programs would allow LDAP entry <-> address book text field associations (which Thunderbird does now), it would be a bit better. Setting up an LDAP addressbook is worth the problems, since you really don't have to sync them anymore.
Quanah Gibson-Mount wrote an article called Creating a well defined LDAP directory query interface for email clients (local backup) with a list of things to consider when setting up your own directory.