Telefonieren mit Asterisk (IV)

Asterisk LogoIn den beiden letzten Kapiteln wurde der Grundstein für eine einfache, private Telefonzentrale gelegt, die das Führen externer Gespräche ermöglicht und jedem angeschlossenen Telefon eine interne, private Nummer zuweist, so dass auch interne Gespräche und Weiterleitungen möglich sind. Dabei sind einige wenige Anweisungen in den Wählplan eingebaut worden. Der Wählplan ist das Herzstück des Asterisk Servers und enthält ein enormes Potential. Mit Hilfe einer leicht verständlichen Makrosprache können einfache Aufgaben, wie etwa die bisher vorgestellte realisiert werden. Damit wird aber nur ein Bruchteil der Möglichkeiten ausgeschöpft, die der Wählplan bietet. Beispielsweise kann mit dem Wählplan festgelegt werden, dass ein Anrufer eine Nachricht (Voicemail) hinterlassen kann, wenn nach 60 Sekunden niemand den Anruf entgegenimmt oder die Leitung besetzt ist. Anhand der Nummer eines Anrufenden oder der Tages- oder Nachtzeit (…) kann entschieden werden, ob und wie ein Anruf entgegengenommen wird. Immer häufiger verwenden Teilnehmer die Rufnummerunterdrückung, vielleicht soll auch dieser Fall speziell berücksichtigt werden.

Ich will im folgenden die Lösung für ein Problem vorstellen, das mir schon mehrfach begegnet ist: Anrufe zu später Stunde oder auch mitten in der Nacht! Meist geschieht dies nicht willentlich, jemand hat sich verwählt oder einfach vergessen, dass es auf unserem Planeten Zeitzonen gibt. Für das um seinen Schlaf gebrachte «Opfer» ist dies verständlicherweise ein schwacher Trost. Also habe ich meine Telefonzentrale so eingestellt, dass zwischen 22 Uhr Abends und acht Uhr am Morgen keine Anrufe entgegengenommen werden. Um diese Aufgabe zu lösen, müssen zwei Vorkehrungen getroffen werden:

  1. Aufteilen des bisher erstellten Wählplanes in zwei Kontexte. Ein Kontext übernimmt die bisherigen Anweisungen des Wählplanes und ist tagsüber aktiv. Der zweite Kontext legt fest, dass Anrufe in der Nacht mit einem Besetztzeichen beantwortet werden.
  2. Festlegen der Zeit, wann welche Kontexte aktiv sind

Kontexte sind nichts anderes als Teile eines Wählplanes, die unter einem gemeinsamen Namen zusammengefasst werden. Diese Aufteilung ist nicht nur bei grossen Wählplänen sinnvoll, sie ermöglicht es auch, festzulegen, welche Teilnehmer welche Kontexte nutzen dürfen oder – unser Beispiel – welche Kontexte zu welchen Tageszeiten, resp. Tagen aktiv sind. Beispielsweise kann bei einer Firma für das Wochenende ein Kontext weekend aktiviert werden, der nach einer Mitteilung («Sie rufen ausserhalb unserer Geschäftszeiten an…») den Voicemail Dienst aufruft. Die Möglichkeiten, die mit Kontexten geschaffen werden, sind vielfältig. Gerne werden sie auch für «virtuelle» Zentralen genutzt: Mehrere Firmen teilen sich dabei einen Server; mit Kontexten werden die verschiedenen Wählpläne den Teilnehmern zugewiesen.

Das Definieren eines Kontextes gestaltet sich denkbar einfach: vor die Anweisungen im Wählplan wird der Name des Kontextes in eckige Klammern gesetzt. Alle nun folgenden Extensions gehören zu diesem Kontext. Erst das Ende der Datei oder ein neuer Kontext beenden den Gültigkeitsbereich. In der extensions.conf, die unseren Wählplan enthält, sind bereits einige Kontexte definiert. Der wichtigste davon ist default. Wenn nicht anders bestimmt, nimmt er alle neuen Extensions auf, die am Ende der Datei angehängt werden. Wird bei einem Anruf nicht explizit ein Kontext bestimmt, durchsucht Asterisk stets den default Kontext nach einer passenden Extension. In meiner Version von extensions.conf steht der Kontext default fast am Ende der Datei:

[default]
;
; By default we include the demo. In a production system, you
; probably don't want to have the demo there.
;
include => demo
...

Wir erstellen nun einen neuen Kontext daily-calls und verschieben alle Extensions für eingehende Anrufe in diesen Kontext. Wichtig: Der Kontext muss am Ende der Datei, also hinter allen bisher erstellten Anweisungen in der Datei zu stehen kommen. Die Extensions für eingehende Anrufe müssen an ihrer bisherigen Stelle gelöscht werden.

; Eingehende Anrufe tagsueber
[daily-calls]
exten => 0325178180, 1, Dial(SIP/pc1&SIP/pc2,60)
exten => 0325178180, n, Hangup

Und nun folgt ein zweiter Kontext nightly-calls, der nächtliche Anrufer abfertigt:

; Eingehende Anrufe nachts
[nightly-calls]
exten => 0325178180,1,Answer
exten => 0325178180,2,Playtones(congestion)
exten => 0325178180,3,Congestion

Die drei Anweisungen bewirken dies: als erstes wird der Anruf mit Answer entgegengenommen (damit es den Anrufer auch etwas kostet…), dann senden wir mit Playtones(congestion) ein Besetztzeichen. Die dritte Anweisung Congestion signalisiert der Gegenstelle abschliessend, dass wir besetzt sind und wartet, bis der Anrufer auflegt. Dies ist sicher nicht die freundlichste Art, einen Anruf «entgegenzunehmen», ich werde deshalb in einem der folgenden Kapitel als Beispiel Voicemail verwenden, so dass der Anrufer eine Nachricht hinterlassen kann.

Nun müssen wir nur noch den Zeitplan definieren, der festlegt, wann welche Kontexte gültig sein sollen. Der Zeitplan kann an den Beginn des default Kontextes gestellt werden:

[default]
include => nightly-calls|22:00-23:59|*|*|*
include => nightly-calls|00:00-08:00|*|*|*
include => daily-calls

Der Zeitplan besteht aus include Anweisungen, vermöge derer Kontexte in den aktuellen Wählplan eingefügt werden können. Die include Anweisung kann auch genutzt werden, um externe Dateien einzubinden. Mit einem vierspaltigen Zeitschema kann jede include Anweisung an eine Zeit gebunden werden. Nur wenn alle der vier Platzhalter mit der aktuellen Zeit übereinstimmen, wird eingefügt. Die vier Platzhalter werden getrennt durch einen Balken (|) direkt an die include Anweisung angehängt. Ein Asterisk (*) als Platzhalter gilt immer als Übereinstimmung:

include => nightly-calls|Zeit|Wochentag|Tag|Monat

Die vier Spalten haben folgende Bedeutung, resp. folgende möglichen Werte:

Zeit: Die Tageszeit im 24-Stunden Format SS:MM, also zum Beispiel 18:00 für sechs Uhr Abends. Ein Zeitbereich wird in der Form SS:MM-SS:MM angegeben. Wichtig: Als Zeitmesser gilt die Uhr des Servers, auf dem Asterisk läuft. Ist dieser Server auf UTC (ehemals GMT) eingestellt, müssen die Zeitbereiche entsprechend angepasst werden.

Wochentag: Für Wochentage muss die englische Kurzform verwendet werden: mon, tue, wed, thu, fri, sat, sun. Auch hier sind Bereiche wie mon-fri möglich.

Tag: Der Tag im Monat, also Werte im Bereich 1..31. Praktisch, um in Verbindung mit dem Monat bestimmte Tage als Feiertage zu markieren (1. Mai, 24. Dezember, etc.). Wie bei den anderen Feldern sind Bereiche möglich.

Monat: Beim Monat muss wiederum die englische Kurzform verwendet werden. Mir ist zurzeit nicht bekannt, ob auch numerische Werte verwendet werden können.

Es müssen wie gesagt alle vier Zeitangaben mit der aktuellen Systemzeit übereinstimmen, nur dann wird der Kontext eingefügt. In unserem Beispiel verwenden wir nur die Tageszeit. Da ich nicht sicher bin, ob Zeitbereiche, die Mitternacht einschliessen, richtig interpretiert werden, verwende ich zwei Zeilen. Bei einem extern eingehenden Anruf geschieht nun folgendes:

Asterisk durchsucht den Wählplan und findet im default Kontext die include-Anweisungen. Asterisk durchsucht den Wählplan grundsätzlich sequentiell, also vom Beginn zum Ende der Datei, bis eine Extension gefunden wird, die mit der gewählten Nummer übereinstimmt!

Tagsüber wird der Kontext nightly-calls nicht eingefügt, wohl aber der daily-calls Kontext. Dieser ist nicht an eine bestimmte Zeit gebunden und wird somit immer eingefügt. Asterisk findet nun im daily-calls eine passende Extension und fürt diese aus: Die Telefone pc1 und pc2 beginnen zu klingeln.

Nach 22 Uhr Abends wird der Kontext nightly-calls eingefügt. Damit steht er nun vor dem Kontext daily-calls. Vermöge der Regel der sequentiellen Ausführung findet Asterisk jetzt in diesem Kontext eine passende Extension: Der Anrufer hört das Besetztzeichen und wir können weiterschlafen…

Ein Gedanke zu „Telefonieren mit Asterisk (IV)

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert