In diesem Kapitel sollen anhand einiger Beispiel die Möglichkeiten von CPL gezeigt werden. Die Beispiele orientieren sich an der gegenwärtigen Implementierung, d.h. die Möglichkeiten, die sich durch den Einsatz eines Tcl-Interpreters ergeben sind hier nicht berücksichtigt.
state IncomingCall {
on enter {
log "$sysDate $sysTime: incoming call from $sysCallingParty\n"
accept
exec "iAuCat Welcome.au" # play outgoing message
exec "iAuTone 1300 100 50" # generate 1.3 kHz tone for 100 ms
timer recTimer local 00:01:00 # allow 1 minute recording time
audiorec "icm.au" # record incoming msg
}
on timer recTimer {
hangup
exit
}
}
Soll der Anrufbeantworter erst nach 10 Sekunden aktiviert werden, damit
der Anruf beispielsweise an einem anderen Telefon entgegengenommen
werden kann, so wäre das Beispiel wie folgt abzuändern:
state IncomingCall {
on enter {
timer pickupDelay local 00:00:10
}
on timer pickupDelay {
log "$sysDate $sysTime: incoming call from $sysCallingParty\n"
accept
exec "iAuCat Welcome.au" # play outgoing message
exec "iAuTone 300 100 50" # generate 1.3 kHz tone for 100 ms
timer recTimer local 00:01:00 # allow 1 minute recording time
audiorec "icm.au" # record incoming msg
}
on timer recTimer {
hangup
exit
}
}
Die -Anweisung, die den Anruf entgegennimmt, wird hier also
um 10 Sekunden verzögert. Wurde (an einem Mehrgeräteanschluß) der Anruf
an einem anderen Apparat angenommen, so wird ein Disconnect-Event
ausgelöst, durch das das Skript terminiert wird.
state Welcome {
on enter {
accept
exec "sun5/iAuCat ounds/GutenTag.au" # greeting message
if { $sysStatus != 0 } {
exec "sun5/iAuCat sounds/Fehler.au" # error message
hangup
exit
}
enter GetIPaddr
}
}
state GetIPaddr {
on enter {
exec "sun5/iAuCat sounds/ip.au"
timer t1 local 00:00:20 # allow 20 sec for IP addr.
}
on dtmf "D'*'D'*'D'*'D'#'" {
cvt ip $sysDtmf "DTMF2IP" # convert DTMF into IP addr.
if { $sysStatus != 0 } {
exec "sun5/iAuCat sounds/ipErr.au"
enter GetIPaddr }
else {
enter GetPortNo
}
}
on timer t1 {
exec "sun5/iAuCat sounds/Eingeschlafen.au"
enter GetIPaddr
}
}
state GetPortNo {
on enter {
exec "sun5/iAuCat sounds/PortNr.au"
timer t1 local 0:0:05 } # allow 5 sec. for input
on dtmf "ddddd" {
set port $sysDtmf
if {$port < 1024} {
exec "sun5/iAuCat sounds/IllPortNo.au"
enter GetPortNo
}
if {$port > 65535} {
exec "sun5/iAuCat sounds/IllPortNo.au"
enter GetPortNo
}
enter ListenToMbone }
on timer t1 {
exec "sun5/iAuCat sounds/Eingeschlafen.au"
enter GetPortNo
}
}
state ListenToMbone {
on enter {
exec "sun5/iAuCat sounds/BeendenMit.au"
redirect "rtp://$ip:$port"
if { $sysStatus != 0 } {
exec "sun5/iAuCat sounds/Fehler.au" # error message
hangup
exit
}
}
on dtmf "#" {
enter Welcome
}
}
Zur Veranschaulichung ist die State-Machine in Abbildung [pic-sm1]
grafisch dargestellt. Die in der folgenden
Beschreibung in Klammern gesetzten Zahlen entsprechen
den in der Abbildung schwarz hinterlegten Event-Nummern.
Nach dem Abspielen einer Begrüßungsnachricht im Startzustand Welcome
wird der Zustand GetIPaddr betreten (2), wo
der Benutzer zur Eingabe einer IP-Adresse in
Dotted-Decimal-Notation aufgefordert wird,
deren Eingabe er mit der \#-Taste abschließen muß. Für
die Eingabe bleiben ihm 20 s Zeit, danach (2a) wird eine Fehlermeldung
ausgegeben und der Zustand erneut betreten, d.h.
Eingabeaufforderung und Timerstart werden wiederholt.
Nach Erkennung der Eingabe wird diese mit
umgewandelt und der Zustand GetPortNo zur
Eingabe der Portnummer betreten (3). Diese wird als
fünfstellige Zahl erwartet ().
Nach Erkennung der Portnummer wird der Zustand ListenToMbone
betreten (4), in dem der Anrufer mittels
mit der gewünschten Audiokonferenz verbunden wird.
Die Konferenzteilnahme kann mit Hilfe der \#-Taste beendet werden (6), ohne gleichzeitig die Telefonverbindung zu beenden. Vielmehr gelangt der Anrufer wieder in den Ausgangszustand zurück.
# ans.cpl -- "Enhanced" answering machine
#
# (c) 1997 F. Oertel
#
state Welcome {
on enter {
set myPIN 4711
set sysTrace 1
accept
if { $sysTime < "17:00:00" } {
exec "sun5/iAuCat sounds/GutenTag.au" } # greeting message
else {
exec "sun5/iAuCat sounds/GutenAbend.au" } # greeting message
enter Selection
}
}
state Selection {
on enter {
exec "sun5/iAuCat sounds/Inhalt.au" # tell user the menu
timer t local 0:0:08 # allow 8 secs for input
}
on dtmf "1" { enter RecordMessage }
on dtmf "2" { enter PlayMessages }
on dtmf "3" { enter Redirect }
on dtmf "#" { exit }
on timer t {
exec "sun5/iAuCat sounds/Eingeschlafen.au"
enter Selection
}
}
state RecordMessage {
on enter {
exec "sun5/iAuCat sounds/Sprechen.au"
exec "sun5/iTone 1350 200 60" # beep
timer icm local 00:01:00 # allow 1 min for icm
audiorec "icm/i$sysCalls.au"
}
on dtmf "#" { # terminate recording
enter Selection }
on timer icm {
exec "sun5/iAuCat sounds/Genug.au" # "thank you for ..."
exit
}
}
state PlayMessages {
on enter {
AskForPIN
}
on dtmf "4711" { # we've got a PIN!
exec "sun5/iAuCat icm/*.au" # play all recorded messages
enter Selection
}
on timer pin {
exec "sun5/iAuCat sounds/Eingeschlafen.au"
enter Selection
}
}
state Redirect {
on enter {
AskForPIN
}
on dtmf 4711 {
timer pin stop
redirect "phone://35" # redirect to my handy
enter Selection
}
on dtmf "#" {
enter Selection
}
on timer pin {
exec "sun5/iAuCat sounds/Eingeschlafen.au"
enter Selection
}
}
proc AskForPIN {
exec "sun5/iAuCat sounds/PIN.au"
timer pin local 0:0:6 # wait 6 secs for PIN
}
Dieses Beispiel zeigt u.a. den Einsatz von Prozeduren. In AskForPIN
werden ein Audiofile abgespielt sowie ein Timer gestartet. Da die
Prozedur aus den Zuständen Redirect und PlayMessages aufgerufen
wird, gilt der Timer jeweils lokal in diesen Zuständen.
state Welcome {
on enter {
accept
exec "sun5/iAuCat sounds/GutenTag.au"
timer DialTimeout local 0:00:20
}
on dtmf "D'#'" {
timer DialTimeout stop
timer ConnectTimeout local 00:30:00
redirect "phone://$sysDtmf"
}
on timer DialTimeout {
exec "sun5/iAuCat sounds/att.au"
exit
}
}
Nach der Ansage hat der Benutzer 20 s lang Zeit eine
beliebige Nummer einzugeben. Nachdem er die Eingabe
mit der \#-Taste beendet hat, wird er sofort mit
der gewünschten Nummer verbunden. Die Verbindungsdauer wird
durch den Timer ConnectTimeout auf 30 Minuten
begrenzt.
Zu beachten ist, daß während des
Gespräches eine weitere Nummer eingegeben und mit
\# quittiert werden kann.
Das hierbei erneut ausgelöste DTMF-Event beendet
die aktuelle Umleitung automatisch, so daß der zweite
B-Kanal für das erneute sofort wieder
zur Verfügung steht.
Wichtig ist hier außerdem den Timer für die Nummerneingabe
zu beenden, da sonst nach Ablauf der 20 s die
Verbindung beendet wird.