Wer statt einer Fritzcard eine andere passive ISDN-Karte sein Eigen nennt, kann in der Regel unter Linux weder Faxe senden noch empfangen. Doch die Bibliothek Libfritzhook hintergeht als kommunikative Notstandslösung die Fritz-Software.
Der Linux-Kernel unterstützt von Haus aus die gängigen ISDN-Chipsätze und digitalen B-Kanal-Protokolle zur Datenübertragung, etwa zum Aufbau von Dialup-Verbindungen ins Internet. Doch fehlen dem Linux-Kernel ganz essenzielle Funktionen zum Betreiben von G3-Faxprogrammen wie Capifax und Capifaxrcvd. Gründe sind das nicht triviale Modulationsverfahren – besonders in Empfangsrichtung – und durch Patente bedingte Nutzungseinschränkungen.
Besitzer einer Fritzcard von AVM kennen das Problem nicht. Für ihre Karte bietet der Hersteller einen eigenen Linux-Treiber an, der im Funktionsumfang den Windows-Varianten in nichts nachsteht. Der Quellcode des Treibers liegt aber nicht komplett vor, sodass ihn die Community nicht für ISDN-Karten anderer Hersteller modifizieren kann.
Die eigentliche Funktionalität samt Hardware-Abhängigkeit kapselt AVM in der unfreien Objektdatei »fcclassic-lib.o«. Der unter der LGPL-Lizenz veröffentlichte und Kernel-abhängige Teil des Treibers legt aber wenigstens die Schnittstelle zwischen dem Kernel-CAPI und der Objektdatei offen. Die ISDN-Chips auf der Fritzcard Classic sind ebenfalls bekannt (ISAC/HSCX). Mit dieser Information und seinen Kenntnissen im Umgang mit dem CAPI 2.0 [1] war der Autor dieses Artikels in der Lage, eine Userspace-Bibliothek zu programmieren, die sich der Faxfunktionalität des Fritzcard-Treibers bedient.
Transplantationszentrum
Die Fritzhook-Bibliothek benötigt lediglich ein funktionsfähiges CAPI; Distribution und Typ der passiven Karte spielen dabei kaum eine Rolle. Der Artikel beschreibt die Transplantation des Fritzcard-Treiber-Herzens – der Objektdatei »fcclassic-lib.o« – in den Userspace. Abbildung 1 zeigt die originale und die neue Struktur. Gegen Ende des Artikels wird praktisch beschrieben, wie man an die Fritzhook-Bibliothek rankommt und sie installiert und testet.
Von hinten durch die Brust
Normalerweise führt der Linux-Kernel mit Hilfe des CAPI-Subsystems das Fritzcard-Treibermodul aus. Das Subsystem besitzt eine allgemeine Schnittstelle zur Kommunikation mit ISDN-Geräten und bildet die Brücke zum Userspace. Über die Schnittstelle erfolgen das An- und Abmelden, der Datenaustausch und die Statusüberwachung der Geräte.
Um die Objektdatei »fcclassic-lib.o« in den Userspace umzusiedeln, klinkt sich die Bibliothek »libfritzhook.so« des Autors zwischen die »libcapi20.so«-Bibliothek und die Faxapplikation ein. Sie lädt die Objektdatei, überlädt deren IO-Funktionen und simuliert eine Fritzcard Classic, die mit der Vermittlungsstelle verbunden ist. Der integrierte CAPI-Automat baut den virtuellen D-Kanal selbstständig auf und ab.
Statt des von der Applikation gewählten B-Kanal-Protokolls T.30 for Group 3 fax baut »libfritzhook.so« einen transparenten B-Kanal auf, der den virtuellen B-Kanal-Controller (HSCX) der Fritzcard-Simulation mit Daten versorgt. Damit jede CAPI-Message zum richtigen Empfänger findet, enthält die Bibliothek eine Filterkomponente. Sie manipuliert die Inhalte der Messages und stellt die richtigen Weichen (Abbildung 2).
Bewegt wird das Ganze mit den periodischen Aufrufen von »capi20_get_message()« durch die Applikation. Die Grundlage hierfür bildet das Fritzcard-Treiberarchiv »fcclassic-suse8.2-03.11.02.tar.gz«, es steht auf [2] zur Verfügung.

Abbildung 1: Mit Hilfe des im Artikel beschriebenen Kunstgriffs arbeitet die Fritzcard-Objektdatei »fcclassic-lib.o« nicht mehr im Kernelspace (links), sondern im Userspace (rechts).
Vom Kernel in den Userspace
Das Objekt direkt zum Rest des Projekts zu linken scheidet aus, da ausführbare Speicherbereiche als read-only markiert sind, der Speicherschutz verhindert das Überladen der IO-Funktionen. Darum lädt die Bibliothek das Objekt wie ein Kernelmodul mit »insmod« in einen allokierten Speicherbereich. Diese Technik erlaubt es sogar, die Bibliothek für andere I-386-Betriebssysteme zu erzeugen.
Als Basis dient die Quelldatei »insmod.c« aus dem Busybox-Projekt [3]. Ihre Funktionen »check_module_name_match()« und »insmod_main()« sowie die Strukturdefinition »old_symbol_table« führen beim Übersetzen aber zu Fehlern. Die Fritzhook-Bibliothek braucht diese aber nicht, es reicht, die entsprechenden Zeilen auszukommentieren. Neu ist die Funktion »loadmod()« aus Listing 1. Sie lädt das Objekt »fcclassic-lib.o« und macht das einzige externe Symbol des Objekts, »printl«, bekannt.
Zusätzlich ermittelt die Funktion die Startadressen der Funktionen »avm_lib_attach()«, »avm_lib_detach()«, »OutpByte()«, »InpByte()«, »OutpByteBlock()« und »InpByteBlock()«. Die Namen der IO-Funktionen gehen aus der Datei »io.c« hervor, die Bestandteil des Fritzcard-Treiberarchivs ist.
Schnittstelle des Fritzcard-Treibers
Die Funktion »avm_lib_attach()« bietet den Einsprungspunkt in das Fritzcard-Objekt. Sie erwartet als Übergabeparameter einen Zeiger auf eine Struktur des Typs »lib_interface_t«. Sie ist in der Quelldatei »libdefs.h« des Fritz-Treiberarchivs definiert und enthält eine Liste von Zeigern auf die externen Funktionen des Fritzcard-Objekts. Die meisten Funktionen sind systemabhängig, zum Beispiel »malloc()« und »free()«.
Die Aufrufe »get_message()« und »put_message()« gehören zur Schnittstelle des Objekts und spielen später eine wichtige Rolle. Hierbei zeigt das Strukturelement »get_message()« auf die Funktion »msg2stack()«, das Element »put_message« auf die Funktion »msg2capi«.
|
Listing 1: »loadmod« |
|---|
01 void *loadmod( void )
02 {
03 FILE *fp;
04 struct obj_file *f;
05 void *pRet = NULL;
06 void *pSym = NULL;
07 int size;
08 static START Ret;
09
10 if((fp = fopen( "/lib/fcclassic-lib.o", "rb")) != NULL)
11 {
12 if( f = obj_load( fp, 1 ))
13 {
14 obj_allocate_commons(f);
15 arch_create_got(f);
16 size = obj_load_size (f);
17 pRet = malloc( size );
18 memset( pRet, 0xAB, size );
19 obj_add_symbol(f, "printl", -1,
20 ELFW(ST_INFO) (STB_GLOBAL, STT_NOTYPE),
21 SHN_HIRESERVE + 1, printl, 0);
22 obj_check_undefineds(f);
23 obj_relocate(f, (unsigned long)pRet);
24 obj_create_image(f, pRet);
25 Ret.pFunc[0] = (void *)obj_symbol_final_value(f, obj_find_symbol(f, "avm_lib_attach" ));
26 Ret.pFunc[1] = (void *)obj_symbol_final_value(f, obj_find_symbol(f, "avm_lib_detach" ));
27 Ret.pFunc[2] = (void *)obj_symbol_final_value(f, obj_find_symbol(f, "OutpByte" ));
28 Ret.pFunc[3] = (void *)obj_symbol_final_value(f, obj_find_symbol(f, "InpByte" ));
29 Ret.pFunc[4] = (void *)obj_symbol_final_value(f, obj_find_symbol(f, "OutpByteBlock" ));
30 Ret.pFunc[5] = (void *)obj_symbol_final_value(f, obj_find_symbol(f, "InpByteBlock" ));
31 }
32 else
33 printf("obj_load failedn");
34 fclose( fp );
35 }
36 else
37 {
38 printf("fopen failedn" );
39 return NULL;
40 }
41 return &Ret;
42 }
43 /* fax.c */
|
Der Rückgabewert von »avm_lib_attach()« ist ebenfalls ein Zeiger auf eine Struktur, deren Definition in »libdefs.h« steht und im Wesentlichen aus Zeigern auf interne Schnittstellenfunktionen besteht. Außer Konkurrenz laufen die Funktionen »lib_heap_init()«, »lib_heap_exit()«, »lib_heap_alloc()« und »lib_heap_free()« – zusammen eine eigenständige Speicherverwaltung, die Fritzhook aber nicht braucht.
Die zentrale Schnittstelle des Fritzcard-Objekts besteht aus vier Funktionen: Der Aufruf »cm_schedule()« triggert den Zeitplaner des Fritzcard-Treibers und ist damit der Antrieb des Systems. Er stößt alle externen Operationen wie »msg2capi()« und »msg2stack()« an. Ein Aufruf von »cm_handle_events()« verarbeitet Unterbrechungsanforderungen der Hardware. Die Funktionen »msg2capi()« und »msg2stack()« kommunizieren mit dem CAPI-Automaten. Um eine CAPI-Message an den Automaten zu schicken, ruft der Fritzcard-Treiber »msg2capi()« auf. Für die Gegenrichtung, also das Abholen von Messages, verwendet er »msg2stack()«.
Funktionstausch
Zur Simulation der Fritzcard und der Vermittlungsstelle implementiert die vorgestellte Lösung die IO-Funktionen »OutpByte()«, »InpByte()«, »OutpByteBlock()« und »InpByteBlock()« neu. Sie führen keine Hardwarezugriffe mehr aus, sondern simulieren die Registerdynamik der ISDN-Chips im Arbeitsspeicher.
|
Listing 2: |
|---|
01 void Hook( void *pOld, void *pNew, unsigned char *pData )
02 {
03 unsigned char *pbOld = ( unsigned char *)pOld;
04 unsigned short reg = 0;
05
06 __asm__ ( "mov %%cs, %0;"
07 :"=r"(reg)
08 );
09 if( pData )
10 memcpy( pData, pbOld, 7 );
11 *pbOld++ = 0xEA;
12 *(( unsigned long *)pbOld ) = (unsigned long)pNew;
13 pbOld += 4;
14 *(( unsigned short *)pbOld ) = reg;
15 }
|
Damit der Fritzcard-Treiber diese Funktionen anspringt, schreibt »Hook()« aus Listing 2 ab Zeile 11 an die Startadressen der ursprünglichen Funktionen einen Sprungbefehl (Far Jump, 0xEA), der als Parameter die absolute Adresse des Sprungziels sowie einen Codesegment-Selektor erwartet. Der Selektor (hier »reg«) entspricht dem aktuellen Wert des CS-Registers (Zeilen 5 bis 8). Das Jump-Ziel »pNew« ist die Startadresse der neu erstellten IO-Funktion.
|
Tabelle 1: |
||
|---|---|---|
|
Offset |
Bereich |
Funktion |
|
0x0000 |
HSCX0_FIFO |
B-Kanal 1 |
|
0x0400 |
HSXC0_REGS |
B-Kanal 1 |
|
0x0800 |
HSCX1_FIFO |
B-Kanal 2 |
|
0x0C00 |
HSCX1_REGS |
B-Kanal 2 |
|
0x1000 |
ISAC_FIFO |
D-Kanal |
|
0x1400 |
ISAC_REGS |
D-Kanal |
|
0x1800 |
AVM-ASIC |
Interrupt-Status |
Virtuelle Fritzcard
Auf einer Fritzcard Classic befinden sich drei integrierte Schaltkreise: Ein D-Kanal-Controller (ISAC; Infinenon PSB 2186, [4]), ein B-Kanal-Controller (HSCX; Infineon PSB 21525 oder SAB 82525, [5]) und ein ASIC (kundenspezifischer Schaltkreis) des Kartenherstellers. Tabelle 1 zeigt das Fritzcard-Portmapping mit den drei verantwortlichen Chips relativ zur gewählten Basisadresse. Auf Grundlage dieser Zuordnung entscheiden die neu implementierten IO-Funktionen bei einem Zugriffsversuch, für welchen Baustein der Portzugriff bestimmt war.
Für die D-Kanal-Pakete reicht es, nur die Fifo-Datenpuffer der ISDN-Chips zu betrachten. Die 32 Byte Größe pro Richtung sind ausreichend. Der Fritzcard-Treiber kann damit jedes D-Kanal-Paket in einem Zyklus schreiben beziehungsweise lesen. B-Kanal-Daten transferiert er dagegen in mehreren Zyklen.
Um den Empfang von D-Kanal-Daten anzuzeigen, kopiert »libfritzhook.so« die Daten in den virtuellen Empfangs-Fifo des ISAC und manipuliert einige Registerinhalte. Mit dem Aufruf von »cm_handle_events()« übernimmt der Treiber die Daten. Ein Schreibzugriff des Treibers auf den ISAC-Versand-Fifo signalisiert der Fritzhook-Bibliothek den Versand eines D-Kanal-Pakets und stößt dessen Verarbeitung an.

Abbildung 2: Die Filterkomponente der Fritzhook-Bibliothek manipuliert die Inhalte der CAPI-Messages.
»libfritzhook.so« versorgt den virtuellen B-Kanal-Controller (HSCX) mit Daten, indem er die CAPI-Message »DATA_B3_IND« empfängt. Beim Eintreffen dieser Botschaft ruft die Funktion »FaxProcessDataInd()« aus Listing 3 dank »FaxPoll()« (Zeile 18) so lange »cm_handle_events()« auf, bis der Fritzcard-Treiber das ganze Datenpaket gelesen hat (Zeile 13).
Während dieses Vorgangs erzeugt der Treiber gleichzeitig Versanddaten, welche die Funktion »FaxProcessDataInd()« zu einem CAPI-Versandpaket akkumuliert. Ist ein Paket vollständig, schickt der CAPI-Filter einen »DATA_B3_REQ« zur CAPI-Bibliothek. Bestätigt das CAPI das Paket durch eine »DATA_B3_CONF«-Message, gibt die Funktion »FaxProcessDataConf()« den verwendeten Sendepuffer wieder frei.
Virtuelle Vermittlungsstelle ist nie besetzt
Die Kommunikation zwischen virtueller Vermittlungsstelle und Fritzcard-Treiber erfolgt über das EDSS1-D-Kanal-Protokoll [5]. Näheres zum D-Kanal-Protokoll der Schicht 2 liefert die Webseite des European Telecommunication Standards Institute [6]. Für den aktiven Verbindungsaufbau sendet die Funktion »FaxStartConnection()« aus Listing 4 die CAPI-Message »CONNECT_REQ« (Zeilen 16 bis 19) an den Treiber, der daraufhin ein »SETUP« über den D-Kanal zur Vermittlungsstelle schickt.
Da die virtuelle Vermittlungsstelle niemals besetzt ist, quittiert sie den Verbindungsversuch sofort mit »CALL_PROCEEDING« und »CONNECT«. Daraufhin erzeugt der Treiber die CAPI-Message »CONNECT_ACTIVE_IND«, die dem CAPI-Automaten anzeigt, dass die D-Kanal-Verbindung besteht. Nun baut der Automat den B-Kanal auf. Passive Verbindungen initiiert »libfritzhook.so« ebenfalls durch Aufruf von »FaxStartConnection()«. Dazu schickt die Funktion eine »LISTEN_REQ«-Message zum Treiber, um ihn dazu zu animieren, auf eingehende Anrufe zu reagieren.
Gleich danach sendet »FaxStartConnection()« per »Ring« über den virtuellen D-Kanal ein »SETUP«. Der ankommende Ruf generiert ein »CONNECT_IND« beim CAPI-Automaten, der den Anruf durch Versand der CAPI-Message »CONNECT_RESP« sofort entgegennimmt. Die virtuelle Vermittlungsstelle beantwortet den Connect des Treibers mit »CONNECT_ACKNOWLEDGE«. Jetzt trifft ein »CONNECT_ACTIVE_IND« beim CAPI-Automaten ein – der D-Kanal steht.
Der CAPI-Automat verarbeitet CAPI-Messages für den D-Kanal intern. Die für den B-Kanal zuständigen führt er hingegen der Anwendung zu. Tabelle 2 gibt eine Übersicht darüber, welche Messages der Automat intern beantwortet und welche er zur Applikation schickt.
|
Tabelle 2: |
||
|---|---|---|
|
Message |
Aktion |
Ziel |
|
CONNECT_ACTIVE_IND |
CONNECT_ACTIVE_RESP+CONNECT_B3_REQ (nur ausgehender Ruf) |
keins |
|
CONNECT_B3_ACTIVE_IND |
CONNECT_B3_ACTIVE_RESP |
Applikation |
|
CONNECT_IND |
CONNECT_RESP |
keins |
|
CONNECT_B3_IND |
CONNECT_B3_RESP |
keins |
|
DATA_B3_IND |
keine |
Applikation |
|
DATA_B3_RESP |
keine |
Applikation |
|
DISCONNECT_IND |
DISCONNECT_RESP |
keins |
|
DISCONNECT_B3_IND |
DISCONNECT_B3_RESP |
Applikation |
|
DISCONNECT_B3_CONF |
keine |
Applikation |
CAPI-Filter
Damit die Fritzhook-Bibliothek in einer Applikation funktioniert, muss deren Benutzer beim B-Kanal-Protokoll »T.30 for Group 3 fax« wählen. Stellt er ein anderes B-Kanal-Protokoll ein, verhält sich der CAPI-Filter transparent: Er reicht die CAPI-Messages beider Richtungen durch, ohne ihren Weg oder Inhalt zu verändern (Abbildung 2).
Das Filtern der Messages erfolgt mit den Funktionen »capi20_put_message()« und »capi20_get_message()« der Fritzhook-Bibliothek. Ruft eine Applikation »capi20_ get_message()« auf, sieht die Funktion erst mit »Fax_Get_Message()« nach, ob das Treiber-CAPI eine Message für die Applikation in der Warteschlange hat.
Wenn ja, kehrt »capi20_get_message()« zur Applikation zurück und stellt ihr die Message zur Verfügung. Ist die Warteschlange leer, erfolgt ein Aufruf der realen »capi20_get_message()«-Funktion aus »libcapi20.so«. Ist eine Message vorhanden, übergibt sie der Filter durch den Rückgabewert 0 an die Anwendung. Der Rückgabewert 0x1104 (Queue is empty) verbirgt die Message vor der Applikation. Dann führt »capi20_get_message()« abhängig vom Typ der Message interne Aktionen aus. »capi20_put_message()«-Aufrufe der Anwendung laufen analog ab. Die Tabellen 3 und 4 zeigen eine Übersicht des Filterverhaltens.
|
Listing 3: |
|---|
01 unsigned FaxProcessDataInd( PFAX pFax,
02 unsigned char *pData, unsigned short length )
03 {
04 int len = 0;
05 int count = 0;
06 if( pFax )
07 {
08 int doWrite = 1, j;
09 unsigned short i = (length >> 3 );
10 pFax->pRxData = pData;
11 pFax->pRxDataEnd = pData + length;
12
13 while( pFax->pRxData < pFax->pRxDataEnd && i > 0 )
14 {
15 if( doWrite )
16 NextB3Write( pFax->bCh );
17 NextB3Read( pFax->bCh );
18 FaxPoll(3);
19 i--;
20 count++;
21 if( pFax->length % 2048 )
22 doWrite = 1;
23 else
24 doWrite = 0;
25 }
26
27 if( pFax->length > ( 2048 * ( B3_BLOCKS - 2 )))
28 pFax->fStartSend = 1;
29
30 if( pFax->fStartSend )
31 {
32 len = (int)pFax->pDataBufw - (int)pFax->pDataBufr;
33 if( len < 0 )
34 {
35 len += ( 2048 * B3_BLOCKS );
36 }
37
38 }
39 return len;
40 }
41 else
42 {
43 return 0xFFFFFFFF;
44 }
45 }
|
Ausprobieren
|
Tabelle 3: |
||
|---|---|---|
|
Message |
Aktion |
Ziel |
|
CONNECT_B3_ACTIVE_IND |
FaxStartConnection |
keins |
|
DATA_B3_CONF |
FaxProcessDataConf |
keins |
|
DATA_B3_IND |
FaxProcessDataInd und DATA_B3_REQ |
keins |
|
DISCONNECT_B3_IND |
FaxStopConnection |
keins |
|
DISCONNECT_B3_CONF |
keine |
keins |
|
Andere |
keine |
Applikation |
Sobald der experimentierfreudige Besitzer einer Nicht-AVM-Karte das Archiv »fritzhook.tar.gz« [7] entpackt hat, übersetzt er den Quelltext mit »make« und kopiert die erzeugte Bibliothek »libfritzhook.so« in das Verzeichnis »/lib«. An dieselbe Stelle gehört die Objektdatei »fcclassic-lib.o« aus dem Verzeichnis »fritz/lib« des Fritzcard-Archivs.
Zum Testen bieten sich die Programme Capifax und Capifaxrcvd an, deren Quellen zum Isdn4k-utils-Paket [8] gehören. Beide müssen gegen die Fritzhook-Bibliothek linken. Hierzu ist die Variable »LDADD« in der Datei »isdn4k-utils/capifax/Makefile.am« von »-lcapi20« in »-lfritzhook« zu ändern. Die Kommandos
make clean ./configure make
erzeugen die Faxanwendungen mit der gewünschten Abhängigkeit zur Fritzhook-Bibliothek. Startet der Anwender nun die frisch übersetzte Serverapplikation »capifaxrcvd« und ruft sie mit einem Telefon an, ertönt der Fax-Signalton.
|
Listing 4: |
|---|
01 unsigned long FaxStartConnection( PFAX pFax )
02 {
03 if( !pFax )
04 return 0xFFFFFFFF;
05 Register_Appl( pFax->wApplId, capi_card, 4, 2048 );
06
07 pFax->fStarted = 1;
08
09 pFax->bCh = GetBChannel( capi_card );
10
11 if( !pFax->fInbound )
12 {
13 unsigned char num[5];
14 num[0] = 0x04; num[1] = 0x80; num[2] = 0x32; num[4] = 0x00;
15 num[3] = 0x30 | pFax->bCh;
16 SF_CONNECT_REQ( pFax->wApplId, 1, 1,
17 1, num, "", "", "",
18 pFax->BProt, "", "", "",
19 "" );
20 FaxPoll( 4 );
21 }
22 else
23 {
24 unsigned long dwTmpPlci = pFax->bCh;
25 dwTmpPlci <<= 16;
26 dwTmpPlci |= ( pFax->dwPlci & 0xFFFF );
27 SF_LISTEN_REQ( pFax->wApplId,
28 1,
29 1,
30 0,
31 0xFF,
32 0,
33 "",
34 "" );
35 FaxPoll( 4 );
36 Ring( dwTmpPlci );
37 }
38 return 0;
39 }
|
|
Tabelle 4: |
||
|---|---|---|
|
Message |
Aktion |
Ziel |
|
CONNECT_REQ |
B-Kanal-Protokoll (transparent) |
»libcapi20.so« |
|
CONNECT_RESP |
B-Kanal-Protokoll (transparent) |
»libcapi20.so« |
|
DISCONNECT_REQ |
keine |
Treiber-CAPI |
|
DATA_B3_REQ |
keine |
Treiber-CAPI |
|
DATA_B3_RESP |
keine |
Treiber-CAPI |
|
DISCONNECT_B3_REQ |
keine |
Treiber-CAPI |
|
DISCONNECT_B3_RESP |
keine |
Treiber-CAPI |
|
Andere |
keine |
»libcapi20.so« |
Zum Schluss
Wer eine faxfähige ISDN-Karte für Linux braucht, fährt mit dem Kauf einer AVM-Karte zweifelslos am besten. Besitzer anderer passiver Hardware versetzt die vorgestellte Fritzhook-Technik aber auch in die Lage, unter Linux Faxe zu senden und empfangen. Das Ganze ist ein wenig experimentell und zudem auf die AVM-Treibersoftware angewiesen, funktioniert aber überaus zufrieden stellend. (jk)
|
Infos |
|---|
|
[1] Spezifikation von CAPI 2.0: [http://www.capi.org] [2] Fritzcard-Treiber für Linux: [http://www.avm.de] [3] Busybox-Projekt: [http://www.busybox.net] [4] ISAC User\’s Manual (»iste_11m.pdf«): [http://www.infineon.com] [5] HSCX User\’s Manual (»hscx_21m.pdf«): [http://www.infineon.com] [6] ETS 300 125 und ETS 300 102-1: [http://www.etsi.org], Suche mit [http://pda.etsi.org/pda/queryform.asp] [7] Fritzhook-Bibliothek: [ftp://www.linux-magazin/pub/Service/Listings/2005/11/CAPI-Treiber] [8] Isdn4k-utils: [http://www.isdn4linux.de] |
|
Der Autor |
|---|
|
Andreas Teiss [andreas.teiss@gmx.de] arbeitet seit 1996 als Soft- und Hardware-Entwickler in der Telekommunikationsbranche. Den ersten intensiven Kontakt zu Linux hatte er 2002 mit der Aufnahme seiner freiberuflichen Tätigkeit. |





