Nachrichtenaustausch zwischen CAPI und Anwendung

Funktionen wie die im letzten Kapitel angesprochene Operation CAPI_GET_PROFILE sind reine Informationsfunktionen. Die Funktion wird von der Anwendung aufgerufen und die CAPI liefert irgendwas zurück. Das wars dann auch. Darin liegt aber noch nicht der Kern der Kommunikation mit der CAPI, nämlich dem, worum es in 95% der CAPI Doku. geht. Die CAPI ist vor allem dazu da, den Datenaustausch zwischen ISDN-Anwendungen auf verschiedenen Rechnern über das ISDN-Netz zu ermöglichen. Das zu unterstützen beschreibt die CAPI Doku. einen ausgefeilten Kommunikationsmechanismus zwischen der CAPI und der ISDN-Anwendung.


Ablauf der Kommunikation im Überblick

Ein solcher Kommunikationsmechanismus besteht immer aus folgenden Aktionen:

Mindestens eine Frage bleibt noch: Mit CAPI_GET_MESSAGE holt die Anwendung eine Nachricht von der CAPI ab. Wie aber weiß die Anwendung, wann eine neue Nachricht zum Abholen bereitsteht?

Es ist zwar möglich, in einer Schleife CAPI_GET_MESSAGE solange aufzurufen, bis die Funktion keinen Fehler mehr liefert (sog. Polling-Verfahren), besonders ressourcensparend ist das aber nicht. Speziell für diesen Zweck gibt es nämlich die beiden Funktionen CAPI_SET_SIGNAL und CAPI_WAIT_FOR_SIGNAL. Welche dieser beiden Funktionen zu verwenden sind, hängt vom Betriebssystem ab. Über CAPI_SET_SIGNAL wird der CAPI die Adresse einer Callback-Funktion mitgegeben, die die CAPI aufruft, sobald eine neue Nachricht verfügbar ist. Diese Message ist für Betriebssysteme und Programme gedacht, die kein Multithreading unterstützten.

Für Windows 95 oder Windows NT gibt es bei Verwendung der CAPI2032.DLL die Funktion CAPI_WAIT_FOR_SIGNAL. Diese Funktion wird von der Anwendung in einem parallelen Thread aufgerufen (siehe CPHAND.PAS TCapiCallback). Die Programmausführung bleibt innerhalb des Threads solange in der Funktion CAPI_WAIT_FOR_SIGNAL stehen, bis eine neue Nachricht von der CAPI verfügbar ist oder die Anwendung sich von der CAPI abmeldet (siehe TCapiCallback.Execute).


Was ist eigentlich eine Nachricht ?

Einfach gesagt ist eine Nachricht ein Bereich im Arbeitsspeicher, der je nach dem Sinn der Nachricht bestimmte Inhalte enthalten muss. Will die Anwendung eine solche Nachricht an die CAPI geben, übergibt sie der Funktion CAPI_PUT_MESSAGE einen Zeiger auf den vorher aufbereiteten Speicherbereich. Bei CAPI_GET_MESSAGE erhält die Anwendung einen Zeiger auf einen von der CAPI aufbereiteten Speicherbereich.

Der allgemeine Aufbau einer solchen Nachricht ist immer gleich (CAPI Doku.Kapitel 3.3 Message Structure) . Der Speicherbereich beginnt mit einem Message-Header fester Länge, auf den ein Datenbereich variabler Länge folgt.


Message Header

Wie der Message-Header definiert ist, finden Sie in der Unit CPMSG.PAS als Typ TCapiMessageHeader. Die im public-Bereich definierten Variablen sind die Inhalte des Message-Headers.

TotalLength ist die Gesamtlänge der Nachricht (einschließlich Header). Diese Information ganz am Anfang der Nachricht ist notwendig, da bei CAPI_PUT_MESSAGE und CAPI_GET_MESSAGE ja jeweils nur ein Zeiger auf einen Speicherbereich übergeben wird und aus dem Zeiger allein die Länge der Nachricht nicht erkannt werden kann. Von einer maximalen Länge einer Nachricht, die es noch in der CAPI 1.1 mit 180 Bytes gab, ist in der CAPI 2.0 nicht mehr die Rede.
ApplId ist die Kennung, die bei CAPI_REGISTER von der CAPI zugeteilt wurde.
Command, SubCommand Die Felder Command und SubCommand enthalten den Typ der Message. SubCommand gibt an, ob es eine REQ, CONF, IND oder RESP-Message ist. Command identifiziert die Nachricht genauer. Bei der Beschreibung der Messages (siehe CAPI Doku. Kapitel 5) steht zu jeder Message als erstes, welches Command/Subcommand-Pärchen die Nachricht identifziert. Sie finden die in der CAPI Doku. definierten Werte in der Unit CPCONST.PAS als Konstantendefinitionen wieder. (z.B. LISTEN_REQ = $0580).
Messagnumber Jede Nachricht bekommt eine Nummer zugeteilt, die z.B. der Kontrolle der Lückenlosigkeit der Nachricht dienen kann. Sendet die Anwendung einen REQ an die CAPI, setzt die CAPI beim folgenden CONF die selbe MessageNumber, die die Anwendung im REQ verwendet hat. Umgekehrt muss die Anwendung beim RESP dieselbe Nummer verwenden, die die CAPI beim zugehörigen IND verwendet hat.


Message Parameter

Welche Daten auf den Message-Header folgen (dürfen), ist für die einzelnen Messages in der CAPI Doku. festgelegt. Eine sehr einfache Message INFO_RESP, die die Anwendung auf eine INFO_IND-Message der CAPI sendet, ist z.B. so definiert (siehe CAPI DOku. Kap. 5.36):

INFO_RESP Command 0x08
  Subcommand 0x83
Parameter Type Comment
Controller/PLCI dword Controller / Physical Link Connection Identifier (as in INFO_IND)

Im Speicher würde das dann etwa so aussehen:

Wichtig sind hier die fett markierten Werte in der Struktur. Totallength (12) beschreibt die Länge in Bytes (ein Kästchen sind 2 Bytes oder 1 word). Command/SubCommand ist der Eintrag für den Messagetyp: Command $08 für eine INFO-Message und Subcommand $83 für eine Message vom Typ RESP. ApplID, Messagenumber und PLCI wurden von der CAPI vergeben.


Parameter Typen

In der CAPI Doku. werden für Message-Parameter lediglich 4 Typen zugelassen, die sich, bis auf einen recht gut mit Hilfe von Object Pascal darstellen lassen:

CAPI-Typ Pascal-Typ
byte byte
word word
dword dword (unit SysUtils)
struct -

Eine Struct ist sehr ähnlich einer CAPI-Message aufgebaut. Das erste Byte enthält die Länge des folgenden Datenbereichs. Ist der folgende Datenbereich länger als 255 Bytes, enthält das erste Byte 255 und das folgende word gibt die Länge des danach folgenden Datenbereichs an. Der Unterschied des Längenbytes zum Eintrag TotalLength in der CAPI-Message ist der, dass TotalLength einer CAPI-Message die Gesamtlänge einschließlich des Feldes TotalLength ist, das Längenbyte einer Struct aber die Länge der dem Längenbyte folgenden Daten angibt.

Sucht man nach einem passenden Typ, um eine Struct darzustellen, drängt sich der alternde Pascal-String auf, dessen ersten Byte das Längenbyte ist, dem die Daten folgen. Eine CAPI-Struct hat aber die unangenehme Eigenschaft, dass sie auch länger als 255 Zeichen sein kann. In diesem Fall wird das erste Byte der Struct mit 255 belegt und erst das folgende word gibt die Länge der Struktur an. Eine genaue Entsprechnung des CAPI-Typs Struct gibt es also in Pascal nicht. Auch anderen Programmiersprachen geht es ähnlich, so dass beim Typ Struct immer Handarbeit angesagt ist.

Um eine Verwendung ähnlich eines Typs zu ermöglichen, wurde im Programmbeispiel die Definition als Objekt gewählt (TStruct in CPSTRUCT.PAS). Das nächste Kapitel erklärt ein wenig genauer, wie das Beispielprojekt funktioniert.


Home Infos Download Links Feedback