| Funktionsweise
von TCapiMonitor |
  |
Überblick
Die folgende Abbildung gibt zunächst einen Überblick
über die angesprochenen Units:

- CPDLL.PAS definiert die Funktionen der CAPI für die
Verwendung im Programm. Die Unit enthält die Funktion zum Laden der CAPI2032.DLL
(CapiInitDLL) und kümmert sich selbst um das Entladen.
- Die in der CAPI Doku. definierten Messages sind als Objekte
in CPMSG.PAS definiert. Vorfahr aller Messages ist TCapiMessage. Die Aufgabe der
Message-Objekte ist es, bei Messages in Richtung CAPI (Put_Message) aus Message-Parametern
den Datenbereich zu füllen, auf den ein Zeiger an die CAPI übergeben wird. Der
constructor Create des Message-Objekts erfüllt diese Aufgabe. Bei Messages von der CAPI,
bestücken die Message-Objekte Ihre Variablen aus der Message, damit die Anwendung die
Message-Parameter bequem abfragen kann. Dazu werden Sie über den Constructor
CreateFromData mit einem Zeiger auf die CAPI-Message erzeugt.
- Die als Structs definierten Parameter der CAPI-Messages sind
in CPSTRUCT.PAS definiert. Alle Structs sind Nachfahren des Objekts TStruct, der die
Basismethoden einer Struct an seine Nachfahren weitergibt.
- CPHAND.PAS enthält den CAPI-Handler TCapi und den Thread
TCapiCallBack. TCapi ist das zentrale Objekt für höhere Anwendungen (wie TCapiMonitor),
das sich um die Erzeugung, Verteilung und Zerstörung der CAPI-Nachrichten kümmert. TCapi
bietet eine Defaultbehandlung für CAPI-Nachrichten an, so dass in vielen Fällen die
Anwendung selbst nicht eingreifen muss. TCapiCallBack ist der Thread, der eigentlich
nichts weiter zu tun hat, als zu warten, dass eine neue Nachricht von der CAPI ankommt und
diese dann an TCapi weiterzugeben.
- TCapiMonitor (CPMONI.PAS) zeigt, wie TCapi und die
Message-Objekte verwendet werden können, um eine sehr einfache CAPI-Anwendung zu
realisieren.
- CPCONST.PAS enthält einige Konstanten, z.B. für
Message-Parameter, die die Anwendung der Units vereinfachen sollen.
- Die Objekte zur Verwaltung von Verbindungen CPCONNEC.PAS
kommt erst dann ins Spiel, wenn tatsächlich eine Verbindung aufgebaut wird.
Erläuterungen zum Ablauf
Bevor mit der Programmierung anfangen werden kann, muss
bekannt sein, welche Messages in welcher Reihenfolge ankommen und wie sie beantwortet
werden müssen. Dabei hilft die CAPI Doku. weiter. Im Anhang der CAPI Doku. (ANNEX A) sind
einige Beipiel-Diagramme, die die Messageabfolge für verschiedene Situationen zeigen.
Für unser Beispielprojekt ist A.2 Incoming Call interessant. Die folgende Abbildung
zeigt, von A.2 abgeleitet, wie sich die Abfolge der Messages für TCapiMonitor darstellt:

- In der Funktion TCapiMonitor.WaitForCall (vgl. CPMONI.PAS)
wird zunächst der Constructor des Objekts TCapi ausgeführt (vgl. CPHAND.PAS,
TCapi.Create). Dort wird, sofern noch nicht geschehen die CAPI20232.DLL geladen und dann
die Anmeldung bei der CAPI über die Funktion Capi_Register ausgeführt. Bei erfolgreicher
Anmeldung wird der Thread installiert, der auf Messages von der CAPI wartet
(TCapiCallBack.Create).
- Danach sendet TCapiMonitor über TCapi.PutMessage sofort
eine LISTEN_REQ Message an die CAPI, um CONNECT_IND Nachrichten erhalten zu können, also
von der CAPI benachrichtigt zu werden, wenn ein Ruf ankommt. TListenReq ist das Objekt,
das diese Message repräsentiert. Im Constructor von TListenReq (vgl. CPMSG.PAS,
TListenReq.Create) wird der Speicherbereich der Nachricht bestückt, damit über das
Property MessagePtr (vgl. CPMSG.PAS, TCapiMessage.GetMessagePtr) ein Zeiger auf die
Nachricht für CAPI_PUTMESSAGE zur Verfügung steht. Dieser Zeiger wird in
TCapi.PutMessage (vgl. CPHAND.PAS) an die CAPI-Funktion Put_Message als Parameter
übergeben.
- Als Bestätigung sendet die CAPI darauf eine LISTEN_CONF
Nachricht.
TCapiCallBack.Execute (siehe CPHAND.PAS) steht seit Aufruf des Constructors von TCapi auf
der Zeile "dwRet := Capi_WaitForSignal(FApplId);" Sobald die CAPI die Nachricht
bereitgestellt hat, entlässt sie TCapiCallBack aus der Funktion und die
Programmausführung geht damit weiter, dass TCapiCallBack Get_Message aufruft, um die
Nachricht abzuholen.
- FCapiGetMessageFunc wurde beim Erzeugen von TCapiCallBack in
TCapi.Create auf eine Funktion von TCapi, TCapi.CapiGetMessageFunc, geleitet.
TCapiCallBack ruft diese Funktion auf, um die Nachricht an TCapi weiterzugeben. Über den
Constructor CreateFromData von TListenConf (vgl. CPMSG.PAS) werden aus dem von der CAPI
übergebenen Speicherbereich die Variablen Controller und Info gefüllt, damit sie die
Anwendung bequem abfragen kann.
- TCapiMonitor ist die Anwendung von TCapi, und bekommt über
den Aufruf FOnCapiEvent in TCapi.HandleConfirmation die Nachricht zugesendet. Wie in
TCapiMonitor.WaitForCall (vgl. CPMONI.PAS) festgelegt, wird dabei die Funktion
TCapiMonitor.CapiEvent aufgerufen.
- In TCapiCallBack (vgl. CPHAND.PAS) steht das Programm
inzwischen wieder auf der Zeile Capi_WaitForSignal und harrt der Dinge die noch kommen
mögen.
- Mit einem ankommenden Ruf kommt plötzlich so ein Ding,
nämlich ein CONNECT_IND. Der Weg führt wieder auf dem gleichen Weg wie schon bei
LISTEN_CONF in die Funktion TCapiMonitor.CapiEvent (vgl. CPMONI.PAS)
- TConnectInd.CallingPartyNumber.Contents (vgl. CPMSG.PAS)
enthält die Rufnummer des Anrufers und wird an den Benutzer der Komponente TCapiMonitor
weitergegeben
- CONNECT_IND wird sofort durch ein CONNECT_RESP beantwortet.
Wichtig dabei ist der Parameter "Reject", der so gesetzt wird (rjeIgnoreCall,
vgl. CPCONST.PAS), dass andere Geräte oder Anwendungen den Ruf ungestört annehmen
können. In einer anderen Variante (Parameter RejectTimeOut der Funktion WaitforCall >
0) wird dem Benutzer erlaubt, den Rückgabewert selbst zu setzen. Das bringt aber nur dann
den gewünschten Effekt, wenn außer dem Anrufmontior kein anderes Gerät mit dem Anruf
etwas anfangen kann. Ein Anrufbeantworter würde z.B. ungeachtet dessen das Gespräch
annehmen.
- Darauf schickt die CAPI ein DISCONNECT_IND, das durch den
Default-Handler in TCapi.HandleIndication sofort mit einem DISCONNECT_RESP beantwortet
wird.
- Beim Beenden von TCapiMonitor (vgl. CPMONI.PAS,
TCapiMonitor.Destroy) wird TCapi freigegeben, wodurch TCapi.Destroy (vgl. CPHAND.PAS)
aufgerufen wird. Dort meldet sich TCapi über Capi_Release von der CAPI ab. Die
CAPI2032.DLL wird hier noch nicht, sondern erst bei Programmende freigegeben (vgl.
CPDLL.PAS - finalization-Teil).
Eine Beschreibung der Properties und Funktionen des
Anrufmonitors steht im Kopf von CPMONI.PAS.
Darauf, wie das Annehmen eines Anruf funktioniert, möchte
ich hier nicht weiter eingehen. Ich habe versucht, den Code so zu kommentieren, dass er
verständlich ist. Hilfereich für das Verständnis des Codes ist die Capi Doku. Das
Diagramm in ANNEX A, A.2 zeigt die Ablauf der Messages beim Verbindungsaufbau (einer
Schicht 3-Verbindung). A.5 zeigt den aktiven Verbindungsabbau.