Geändert: 1. 12. 2007, 19:34
ISDN-Versteckspiel
1-2-3: ich komme! Los, raus aus euren Löchern! Ich darf Geld ausgeben, also nicht verstecken!
Was wir vorhaben ist eigentlich ganz simpel: wir bauen uns eine Asterisk-Telefonanlage. Nach außen geht es über mehrere ISDN-Leitungen, die natürlich irgendwie in den Rechner kommen müssen. Da ich keine Lust habe eine ganze Batterie von Karten in den Rechner zu stecken brauche ich also Karten, die mehr als einen S0-Bus verkraften. PCIe wäre toll, aber normales PCI ist auch ok. Dann wollen wir doch mal gucken:
AVM
Wenn der Begriff "ISDN-Karte" fällt ist mein erster Gedanke immer "AVM". Das nenne ich mal gutes Marketing. Mag vielleicht auch daran liegen, dass ich jahrelang selbst über eine AVM-Karte ins Netz gegangen bin. AVM hat jedenfalls aus mir völlig unerfindlichen Gründen nur noch Karten im Angebot, die lediglich einen einzigen S0-Bus verkraften (namentlich A1 und B1). Die ganzen "großen" Karten (C2, C4 und T1) sind aus dem Programm geflogen. Ok Leute, das war ja nichts.
Eicon
Wirklich zu tun hatte ich mit dem Laden nie, allerdings ist mir der Name in den entsprechenden Menüs im Kernel schon mal über den Weg gelaufen. Anscheinend ist der Laden mittlerweile aufgekauft oder sonstwie umbenannt worden. Und die ISDN-Karten scheinen auch dort Auslaufmodelle zu sein.
HST
Von dem Laden hatte ich noch nie was gehört, aber unser Händler schlug mir eine der Karten vor. Dank eines Links von ihm fand ich auch schnell den Linux-Treiber für deren Karten. Ich entwickle ja nicht umsonst hauptberuflich Gerätetreiber als das mich das nicht reizen würde. Also flugs runtergeladen und gestöhnt:
- schon auf den ersten Blick fällt auf das der Treiber offensichtlich sowohl Linux 2.4 als auch Linux 2.6 mit dem selben Code unterstützen will. Die Art und Weise wie Geräte erkannt, verwaltet und angesprochen werden hat sich ja auch nur grundlegend geändert :| Dieser Versuch erscheint mir so sinnvoll wie ein Versuch von VW für alle Golf-Modelle vom Golf I (1974) bis Golf V (2003) das selbe Getriebe zu benutzen. Kann man machen, muss man aber nicht.
- Auf den zweiten Blick wird klar das es sich bei dem Treiber um einen gemischten Treiber handelt, dessen eine Hälfte als Binärmodul, die andere im Quellcode vorliegt. Dies ist ein lizenzrechtlicher Kniff der Hersteller um interne Schnittstelleninformationen nicht offenlegen zu müssen. Häufig gehen damit aber Einschränkungen bei den unterstützten Kernelversionen einher.
- Der Coding-Style sieht überhaupt nicht Kernel-artig aus. Das allein wäre ja nicht so schlimm, der Treiber ist ja nicht Bestandteil des Kernels. Was mich aber wirklich nervt sind die Bezeichnungen für die Datentypen. Statt der üblichen C-Typen wie unsigned int verwendet man eigene Definitionen wie WORD, DWORD usw. . Das ganze sieht auf den ersten Blick ziemlich nach einem umgestrickten Windoze-Treiber aus. So etwas habe ich schon mal gesehen und ich weiß spätestens seitdem: das ist überhaupt keine gute Idee.
- Ich bin mir noch nicht sicher, aber ich will die Maschine möglicherweise im 64 Bit-Modus betreiben. Die Kombination der beiden vorherigen Punkte lässt da nichts gutes erahnen.
- Ach wie nett: das Interface für den Interrupt-Handler passt nicht mehr zu dem, der in aktuellen Kernels verwendet wird.
- Ich sehe da spezielle Definitionen für den Fall das der Kernel auf einer Multiprozessor-Maschine läuft oder nicht. Die typische Interpretation von soetwas ist: ihr habt das Locking verpfuscht.
- Das hier ist einfach zu hässlich um nicht zitiert zu werden: öffnet mal im Archiv die Datei sa_fio.c. Dort gleich in der ersten Funktion wird der Rückgabewert der Funktion filp_open() geprüft. filp_open() liefert (zumindest in aktuellen Kernels) einen Pointer zurück. Das Makro IS_ERR stammt aus dem Kernel und erlaubt herauszufinden ob der Rückgabewert einen Fehlercode enthält oder einen gültigen Pointer. Wenn jedoch ein Fehlercode zurückgegeben wird (IS_ERR() liefert wahr zurück) prüft man die zurückgegebene Adresse und lässt das ganze möglicherweise doch durch. Wenn man sich dann mal anguckt wie IS_ERR eigentlich definiert ist stellt man fest, dass es eigentlich genau das macht. Allerdings nur auf einer 32 Bit-Maschine. Warum wird hier ein Makro verwendet und anschließend mit ein wenig Voodoo das ganze nochmal so ähnlich (aber unportabel) implementiert? Die Funktion gibt dann im Fehlerfall einfach 1 zurück anstatt den codierten Fehlercode auszuwerten. Wer braucht denn auch schon Fehlercodes.
- Pointer werden einfach mal auf DWORDs gecastet und munter wieder zurück. Zum Glück ist der Typ auf unsigned long definiert, so dass da tatsächlich immer ein Pointer reinpasst. Warum man nicht einfach den Pointer herumreicht erschließt sich mir aber nicht. Die Variablen heißen ganz nebenbei auch noch handle und man hat sich einen eigenen Typ HANDLE definiert, der einem void-Pointer entspricht. Warum nicht den benutzen?
Insgesamt sieht das Zeug jedenfalls überhaupt nicht vertrauenserweckend aus, ganz abgesehen davon das es in unserem Rechner mit einem neuen Kernel nicht funktionieren wird. Gut, ihr bekommt also auch kein Geld von uns.
Digium
Diese Firma hat Asterisk entwickelt, wir können also davon ausgehen das die Karten mit Asterisk auch zusammenarbeiten. Mein Freund Jani sagte er hätte den Treiber auch im Quellcode, allerdings muss ich die Details da noch untersuchen. Wäre natürlich schön, denn das scheint im Moment so ziemlich unsere letzte Chance zu sein.
Kleines Detail am Rande: die entsprechenden ISDN-Karten kostet fast so viel wie der Rest des Rechners.