3.2. Extension
Die einzelnen Dialplan-Programme werden Asterisk-intern Extensions
genannt. Eine Extension wird nicht kompiliert, sondern bei jedem Durchlauf
von Asterisk interpretiert. Das Einlesen erfolgt einmalig automatisch
während des Startens des Asterisk-Daemons.[7] Das erneute Einlesen des Dialplans kann aber auch im
laufenden Betrieb im CLI (Command Line Interface) durch den Befehl
reload now
bzw. dialplan reload
forciert werden.3.2.1. Syntax
Eine Extension besteht immer aus folgenden Teilen:
- Extension (Nummer oder Name)
- Priorität (also der Programmzeilenzähler)
- Applikation – das ist die Anweisung, die Asterisk ausführen soll.
exten =>z. B.:Extension
,Priorität
,Applikation
()
exten => 123,1,Answer()
Wichtig
Die erste Priorität in einer Extension muss immer eine 1
(eins) sein. Ansonsten wird Asterisk diese Extension nicht aufrufen.
Die nächsten Prioritäten müssen danach immer um +1 erhöht werden.
Größere Sprünge werden von Asterisk nicht erkannt.
3.2.2. Grundlegende Applikationen
Um die Programmierbeispiele in diesem Kapitel halbwegs sinnvoll zu
gestalten[8], benötigen wir folgende Applikationen (alle diese
Applikationen werden später noch in Anhang C, Applikationen im Dialplan
genau erklärt):
Answer()
DieAnswer()
-Applikation dient dazu, einen Verbindungsversuch zu akzeptieren. Wenn ein Channel klingelt, dann kannAnswer()
den virtuellen Hörer abnehmen (siehe auch Abschnitt C.10, „Answer()
“).Hangup()
Hangup()
ist das Gegenstück zuAnswer()
. Die Verbindung wird getrennt, und der virtuelle Hörer wird aufgelegt (siehe auch Abschnitt C.68, „Hangup()
“).Playback(Soundfile)
MitPlayback()
kann man Sounddateien abspielen. Diese finden sich, wenn kein anderes Verzeichnis angegeben worden ist, im Verzeichnis/var/lib/asterisk/sounds/
. Die Dateiendung wird dabei nicht angegeben (Asterisk sucht sich den optimalen Codec selbstständig heraus; siehe auch Abschnitt C.117, „Playback()
“).Wait(Zahl)
MitWait()
kann man eine Pause abrufen. Die Zahl in der Klammer gibt die Anzahl der zu wartenden Sekunden an (siehe auch Abschnitt C.188, „Wait()
“).NoOp(String)
Die ApplikationNoOp()
macht nichts. „NoOp“ steht für No Operation. Sie ist aber ein praktisches Tool, um Dialpläne zu debuggen. Der Inhalt des übergebenen Strings wird auf dem CLI ausgegeben. Im CLI muss dafür aber der Verbose-Level auf mindestens 3 eingestellt sein. (Geben Sie einfach im CLIcore set verbose 3
ein; siehe auch Abschnitt C.107, „NoOp()
“.)VoiceMail(Voicemailbox,u)
Die ApplikationVoiceMail()
gibt dem Anrufer die Möglichkeit, eine Sprachnachricht auf der Voicemailbox zu hinterlassen, die als erster Parameter bestimmt wird (siehe auch Abschnitt C.186, „VoiceMail()
“).VoiceMailMain()
Die ApplikationVoiceMailMain()
gibt dem Anrufer Zugang zum Voicemail-System. Wer über eine Voicemailbox verfügt, kann diese dort abhören (siehe auch Abschnitt C.187, „VoiceMailMain()
“).
3.2.3. Priorität
Eine typische Extension besteht aus mehreren Schritten. Damit
Asterisk diese Schritte in der richtigen Reihenfolge ausführen kann, ist
eine Art Zähler nötig. Das erinnert ein wenig an frühe BASIC-Programme,
die auch am Anfang einer jeden Zeile einen solchen Zähler hatten. Dieser
Zähler heißt bei Asterisk Priorität. Prioritäten
werden der Reihenfolge nach abgearbeitet (es wird immer +1 gezählt).
Wenn die nächste logische Priorität (Lücken sind nicht zulässig!) nicht
definiert ist, bricht Asterisk ab – gibt aber leider keine
Fehlermeldung auf dem CLI aus.
Ein hello-world-Beispiel
Die folgende Extension wird immer ausgelöst, wenn ein Telefon
mit dem Context
apfelmus
die Nummer 8888 anruft. Asterisk
nimmt dann ab, spielt den Sprachbaustein
hello-world
ab und legt auf.[apfelmus] exten => 8888,1,Answer() exten => 8888,2,Playback(hello-world) exten => 8888,3,Hangup()
n-Priorität
Seit der Asterisk-Version 1.2 ist es möglich, Prioritäten nicht
nur streng mit Zahlen, sondern auch mit dem Platzhalter
n
zu belegen. Der n-Zähler fungiert hierbei als ein automatischer
Programmzeilenzähler. Jedes Mal, wenn die Programmsteuerung auf die
n-Priorität stößt, addiert sie 1 zum letzten Wert der Priorität. Dies
ist dann hilfreich, falls Sie viele aufeinanderfolgende Regeln
definiert haben und eine weitere Regel einfügen möchten, denn dann
müssen Sie nicht mehr die Zähler der nachfolgenden Regeln neu
nummerieren. Wenn eine normale Extension wie folgt aussieht:exten => 1234,1,Answer() exten => 1234,2,Wait(2) exten => 1234,3,Playback(hello-world) exten => 1234,4,Wait(2) exten => 1234,5,Hangup()
kann man die gleiche Extension auch mit der n-Priorität
definieren:
exten => 1234,1,Answer() exten => 1234,n,Wait(2) exten => 1234,n,Play(hello-world) exten => 1234,n,Wait(2) exten => 1234,n,Hangup()
Dies kann nicht nur an der zweiten Priorität, sondern an einer
beliebigen Stelle passieren:
exten => 1234,1,Answer() exten => 1234,2,Wait(2) exten => 1234,3,Play(hello-world) exten => 1234,n,Wait(2) exten => 1234,n,Hangup()
[7] Eine Ausnahme stellt hier die Asterisk RealTime Architecture (ARA) dar. In einem ARA-System wird der Dialplan in einer Datenbank (z. B. MySQL) abgespeichert und dort von Asterisk bei jedem Anruf neu eingelesen (also nicht nur einmal beim Starten von Asterisk). So können Dialpläne auch im laufenden Betrieb ständig geändert werden. Allerdings hat diese Variante viele Nachteile. Nährere Informationen zu ARA finden Sie unter http://www.voip-info.org/wiki/view/Asterisk+RealTime.
[8] Ein typisches Henne-Ei-Problem. Man kann eine Applikation nur verstehen, wenn man die Programmierung eines Dialplans versteht, und umgekehrt.