Variablen

Variablen sind Platzhalter für konkrete Werte. Diese konkreten Werte sind abhängig von der Definition der Variablen, also dem Typ, und können bei Asterisk Zahlen, Buchstaben und Buchstabenfolgen sein. Variablen dienen dazu, das kompilierte Programm flexibler zu gestalten und für unterschiedliche oder wechselnde Einsatzzwecke anzupassen. Die Verwendung von Variablen ermöglicht erst den individuellen Einsatz eines Programms, ohne die erneute Übersetzung des Programmcodes in ein ausführbares Programm.

[Tipp]

Wer noch nie programmiert hat oder mit Variablen in Berührung gekommen ist, sollte sich an dieser Stelle kurz bei http://de.wikipedia.org/wiki/Variable_%28Programmierung%29 in die Materie einlesen.

Variablen haben bei Asterisk unterschiedliche Reichweiten. Es gibt lokale (im Asterisk-Jargon Channel-Variablen genannt) Variablen, die Werte nur für den jeweiligen und aktiven Channel (also das aktuelle Gespräch) setzen, und globale Variablen, die Werte für alle Channels setzen. Die bereits von Asterisk vorgesehenen Variablen haben wir ja in Form der Parameter in den Konfigurationsdateien schon ausführlich kennen gelernt. Neben diesen gibt es auch die Möglichkeit, eigene Variablen zu definieren und diese in den Konfigurationsdateien zu verwenden.

Variablen in einer Extension auslesen

Der Wert einer Variable kann immer in der Syntax ${VARIABLENNAME} ausgelesen werden. Es gibt Variablen, die vom Asterisk-System automatisch gesetzt werden. So wird z.B. die angerufene Nummer immer in der Variable EXTEN abgespeichert. Durch Regular Expressions und den Einsatz von Variablen kann man somit einen langen Dialplan häufig stark komprimieren.

Beispiel vorher:

exten => 100,1,Dial(SIP/100)
exten => 101,1,Dial(SIP/101)
exten => 102,1,Dial(SIP/102)
exten => 103,1,Dial(SIP/103)
exten => 104,1,Dial(SIP/104)
exten => 105,1,Dial(SIP/105)
exten => 106,1,Dial(SIP/106)
exten => 107,1,Dial(SIP/107)
exten => 108,1,Dial(SIP/108)
exten => 109,1,Dial(SIP/109)

Beispiel nachher:

exten => _10X,1,Dial(SIP/${EXTEN})

Allgemeines

Variablennamen müssen nicht wie in unseren Beispielen großgeschrieben werden und sind auch nicht an Groß- und Kleinschreibung gebunden. Die Großschreibung von Variablen führt aber meistens zu besser lesbarem Code, da Sie bereits an der Schreibweise erkennen können, dass es sich um eine Variable handelt. Umgekehrt bedeutet das aber auch, dass Groß- und Kleinschreibung nicht für die Unterscheidung von Variablen verwendet werden kann.

[Wichtig]

Die von Asterisk selbst generierten Variablen wie ${EXTEN} müssen immer in Großbuchstaben geschrieben werden.

Strings

Strings (als Variablen, die keine Zahlen, sondern Text enthalten) sollten immer in Anführungszeichen gesetzt werden. Asterisk akzeptiert sie aber auch ohne diese Markierung. So sind die folgenden zwei Zeilen im Ergebnis gleich:

exten => 1234,1,Set(OBST=Apfel)
exten => 1234,2,Set(OBST="Apfel")

Sollte der String ein Komma oder ein Leerzeichen enthalten, dann müssen Sie Anführungszeichen verwenden, da diese sonst als Kommandos und nicht als Strings interpretiert werden:

exten => 1234,1,Set(OBSTSORTEN="Apfel, Birne, usw.")

Quoting

Bei einer Variablen, die Zeichen oder Zeichenfolgen (Wörter, Text) als Werte enthält, kann es vorkommen, dass man bestimmte Zeichen verwenden möchte, die bereits für andere Funktionen reserviert sind. Wollen Sie zum Beispiel ein Underscore-Zeichen als Bestandteil des Variablenwertes verwenden, müssen Sie es besonders kennzeichnen, bzw. maskieren. Diese Kennzeichnung nennt man beim Programmieren escapen. Folgende Zeichen müssen auf jeden Fall maskiert („escaped“) werden:

[ ] $ " \

Das Quoting in der extensions.conf erfolgt mit einem vorangestellten \ (Backslash).

Beispiel:

exten => 1234,1,Set(BETRAG="10,00 US \$")

Integer

Bestehen Variablen aus einer Ganzzahl (Integer), so kann diese maximal 18 Stellen betragen. Bei Zahlen, die größer sind, tritt ein Fehler auf, der im Logfile protokolliert wird.

[Tipp]

Wer mit größeren oder Kommazahlen (Real) arbeiten will, kann dies mit einem AGI-Skript realisieren (siehe ???).

Globale Variablen in der extensions.conf definieren

Eine globale Variable kann am Anfang der extensions.conf gesetzt werden. Dies muss im besonderen Context [globals] erfolgen (er folgt dem Context [general]).

Beispiel:

[general]

[globals]
KLINGELZEIT=90

[from-intern]
exten => _XXX,1,Dial(SIP/${EXTEN},${KLINGELZEIT})
exten => _XXX,n,VoiceMail(${EXTEN})

Variablen mit Set() definieren

Die Applikation Set() wird benutzt, um eine Variable in einer Extension zu setzen.[25]

Syntax

Set(Variablenname=Wert[,Variablenname2=Wert2][,Option])

Als Option kann ein g angegeben werden. Mit diesem g kann mit Set() eine globale Variable gesetzt werden. Ohne diese Option geht Asterisk immer von lokalen Channel-Variablen aus.

Beispiel:

; Eine globale Variable setzen:
exten => 10,1,Set(KLINGELZEIT=90,g)

; Eine Channel-Variable setzen:
exten => 10,2,Set(LIEBLINGSOBSTSORTE="Apfel")

; Zwei Channel-Variablen auf einmal setzen:
exten => 10,3,Set(VAR1=10,VAR2=23)

; Die Variablen auf dem CLI ausgeben
exten => 10,4,NoOp(KLINGELZEIT = ${KLINGELZEIT})
exten => 10,5,NoOp(LIEBLINGSOBSTSORTE = ${LIEBLINGSOBSTSORTE})
exten => 10,6,NoOp(VAR1 = ${VAR1})
exten => 10,7,NoOp(VAR2 = ${VAR2})

Vererbung von Channel-Variablen

Wird im Lauf eines Gespräches ein weiterer Channel aufgebaut, so hat dieser natürlich wieder eigene Channel-Variablen.

Einstufige Vererbung

Will man eine Channel-Variable übergeben, aber keine globale Variable dafür benutzen, so kann man der Channel-Variable ein _ (Underscore) voransetzen. Diese Channel-Variable wird dann an den nächsten Channel vererbt. Dabei wird der Underscore entfernt. Die Vererbung kann also nur einmal erfolgen.

Beispiel:

exten => 1234,1,Set(_KUCHENSORTE="Marmorkuchen")

Mehrstufige Vererbung

Will man eine Channel-Variable beliebig oft vererben, so muss man zwei __ (Underscore)-Zeichen vor die Variable setzen. Die zwei Underscore-Zeichen werden dann immer mitvererbt.

[Warnung]

Asterisk unterscheidet die Namen von Variablen, die mit einem Underscore anfangen, nicht von Variablen, die keinen Underscore haben. So wird im folgenden Beispiel aus der vererbbaren Channel-Variable KUCHENSORTE eine normale (nicht vererbbare) Channel-Variable:

exten => 1234,1,Set(__KUCHENSORTE="Marmorkuchen")
exten => 1234,n,Set(KUCHENSORTE="Marmorkuchen")

Beispiel:

exten => 1234,1,Set(__KUCHENSORTE="Nusskuchen")

Bei einem Abruf einer vererbten Channel-Variable ist es egal, ob man die Unterstriche voranstellt oder nicht. Die beiden folgenden Zeilen geben zweimal den gleichen Wert im CLI aus:

exten => 1234,1,NoOp(${__KUCHENSORTE})
exten => 1234,n,NoOp(${KUCHENSORTE})

Feste Channel-Variablen

Die folgende Liste enthält die wichtigsten fest einprogrammierten Channel-Variablen, die nicht in der extensions.conf überschrieben, aber ausgelesen werden können.

[Warnung]

Eine komplette Liste aller vordefinierten Variablen finden Sie in der Datei doc/README.variables (Asterisk 1.2) und doc/channelvariables.txt (Asterisk 1.4). In dieser Liste werden nur nicht DEPRECATED Variablen aufgelistet. So finden Sie z.B. ein ${CALLERIDNUM} nicht in dieser Liste, weil dies deprecated ist (man soll anstatt die Funktion ${CALLERID(num)} benutzen).

Die für das jeweilige Thema relevanten Variablen werden aber im Buch immer in jedem Kapitel extra aufgeführt.[26]

[Anmerkung]

Bei einigen der hier aufgeführten Variablen handelt es sich gar nicht um Variablen, sondern um eingebaute Funktionen. Da dies in der Praxis aber oft verschwimmt, werden sie hier trotzdem aufgelistet.

${ANSWEREDTIME}

Die Gesamtzeit (in Sekunden) seitdem das Gespräch zustande gekommen ist.

${BLINDTRANSFER}

Der Name des Channels auf der anderen Seite eines Blind-Transfers.

${CHANNEL}

Name des aktuellen Channels

${CONTEXT}

Name des aktuellen Contextes

${EPOCH}

Aktueller Unix Style Epoch.

${EXTEN}

Aktuell gewählte Extension

${ENV(VARIABLENNAME)}

Umgebungsvariable VARIABLENNAME

${HANGUPCAUSE}

Grund für das Beenden (hangup) eines Gespräches

${INVALID_EXTEN}

Wird in der i-Extension benutzt und enthält die gewählte Extension.

${PRIORITY}

Aktuelle Priorität innerhalb der Extension

${TRANSFER_CONTEXT}

Context eines weiterverbundenen Gespräches

${UNIQUEID}

Im System einzigartige (unique) ID für das aktuelle Gespräch

${SYSTEMNAME}

In der /etc/asterisk/asterisk.conf Datei eingetragener systemname Parameter.

Variablenmanipulation

Variablen an sich eröffnen ihren Nutzen erst dann, wenn man sie zur Laufzeit verändern kann. Mit Hilfe dieser Variabilität lassen sich komplexe Verhaltensweisen steuern und vorsehen.

Substring

In der Regel bezeichnen Strings eine Aneinanderreihung einzelner Zeichen (character). Die Größe eines Strings bestimmt sich durch die Anzahl der identifizierbaren einzelnen Zeichen. Zum Beispiel besteht der String „Apfelbaum“ aus 9 Zeichen. Ein String kann grundsätzlich in so genannte Teilstrings zerlegt werden, also Strings, die, wenn man sie wieder aneinanderreiht, den ursprünglichen String ergeben. Im genannten Beispiel könnten wir den String „Apfelbaum“ in die Teilstrings „Apfel“ und „baum“ zerlegen, aber auch „Apf“ und „elbaum“ sind echte Teilstrings. Ein String hat theoretisch keine begrenzte Größe, er kann beliebig viele Zeichen enthalten, der gesamte Text dieses Buches könnte so als ein String aufgefasst werden. Natürlich wäre das dann nicht mehr sehr handlich, dennoch ist der Vorgang des Zerlegens eines Strings in Teilstrings eine Standardprozedur beim Programmieren von Anwendungen. In vielen Programmiersprachen heißt die hier beschriebene Funktionalität Substring. Mit einer Substring-Funktion kann man Teile eines Strings ausschneiden und das Ergebnis in einer anderen Variablen abspeichern. In Asterisk gibt es keine eigenständige Routine für diese Substring-Funktion, sondern hierfür wird ein : (Doppelpunkt) nach dem Variablennamen eingesetzt. Vom Inhalt der Variablen, also dem String, wird dann eine vorgegebene Anzahl von Zeichen (Länge) als Teilstring abgetrennt.

Syntax

${VARIABLENNAME[:Anfang[:Laenge]]}

Beispiele

Bei einer Telefonanlage wird traditionell eine führende 0 (Null) gewählt, um eine Amtsleitung zu bekommen. Die zu wählende Telefonnummer darf diese 0 aber nicht enthalten. Wird die Nummer 0030 227 32320 gewählt, so kann man mit folgender Zeile die eigentliche Rufnummer in die Variable ${RUFNUMMER} abspeichern.[27]

exten => _0X.,1,Set(RUFNUMMER=${EXTEN:1})

Wenn die Angabe der Länge fehlt, wird automatisch der Rest des Strings genommen.

Wenn wir die letzten 5 Ziffern der gewählten Nummer benötigen, dann erreichen wir das mit einer negativen Zahl. Bei der oben gewählten Nummer würde die folgende Zeile den Wert 32320 in der Variablen ${DURCHWAHL} abspeichern.

exten => _0X.,1,Set(DURCHWAHL=${EXTEN:-5})

Möchten wir die Vorwahl in einer separaten Variable abspeichern, so erreichen wir dies durch:

exten => _0X.,1,Set(VORWAHL=${EXTEN:1:3})

Diese Zeile geht davon aus, dass die Vorwahl 3-stellig ist und speichert sie in der Variable ${VORWAHL}.[28]

Nehmen wir an, wir möchten bei Telefonaten zur Nummer 00012024562121 nach Amerika die einzelnen Bestandteile herausfiltern:[29]

exten => _0001X.,1,Set(INTERNATIONALEVORWAHL=${EXTEN:3:1})
exten => _0001X.,n,Set(ORTSVORWAHL=${EXTEN:4:3})
exten => _0001X.,n,Set(RUFNUMMER=${EXTEN:7})
exten => _0001X.,n,Set(DURCHWAHL=${EXTEN:-4}


[25] siehe auch Set()

[26] Ein klassisches Henne-Ei-Problem

[27] Für alle neugierigen Leser: Das ist die Telefonnummer des Parlamentsarchives des Deutschen Bundestages in Berlin.

[28] Leider macht diese Variante in Deutschland wenig Sinn, da es unterschiedlich lange Vorwahlen gibt. Mehr Informationen zur deutschen Vorwahl finden Sie unter http://de.wikipedia.org/wiki/Telefonvorwahl_%28Deutschland%29.

[29] Um Ihnen das Gespräch nach Amerika zu sparen: Dies ist die Nummer der Besucherzentrale des Weißen Hauses in Washington DC. ;-)