Wichtiger Hinweis: Leider verfälschen die Google-Übersetzungen die Quellcodes. Bitte öffnet den Quellcode in einem anderen Fenster, wie es das nachstehende Bild zeigt. Von dort lassen sich die Quellcodes auch leichter herauskopieren:
1.11.2022 (zuletzt am 8.02.2023 aktualisiert)
Schwedische Wählscheiben besitzen gegenüber den meisten Wählscheiben auf der Welt eine abweichende Anordnung der Ziffern. Diese sind um eine Stelle entgegen des Uhrzeigersinns verrutscht dargestellt. Wer sich an den aufgedruckten Ziffern eines schwedischen Wählscheibentelefons orientiert, wählt falsch, wenn das Telefon z.B. an einer üblichen Telefonanlage, an einem Asterisk-Server oder an einer FritzBox angeschlossen ist.
Dieser Artikel ist so gestaltet, dass man keine Kenntnisse über PHP und AGI mitbringen muss. Lediglich Grundkenntnisse über Linux und Asterisk sind Voraussetzung. Dieser Artikel dient auch dazu, die ersten Schritte mit AGI-Skripten zu erleichtern und Fallstricke zu erkennen, damit es ohne Erfahrung gelingt, vorgefertigte Skripte in Asterisk erfolgreich einzubinden. Deshalb ist hier einiges weitschweifend mehrfach erklärt und mit Beispielen untermauert.
Das Problem: Die Mechanik der schwedischen und übrigen Wählscheiben ist im Prinzip gleich. Nur der Aufdruck der Ziffern ist abweichend von den üblichen Zifferblättern, wie sie mit wenigen Ausnahmen in den allermeisten Ländern der Welt vorkommen.
Schwedisches Ziffernblatt: 9876543210
Übliches Ziffernblatt: 0987654321
Orientiert sich jemand an einem schwedischen Ziffernblatt, wird eine falsche Nummer gewählt. Diese falsche Nummer muss wieder Ziffer für Ziffer umgewandelt werden, damit die Telefonanlage die korrekte Nummer wählt. Beispiel: Jemand orientiert sich an dem schwedischen Ziffernblatt und wählt die Nummer 089 123. Tatsächlich wählt er dann die Nummer 190 234. Diese Nummer muss das Programm wieder korrigieren. Die Ziffer 0 wird zur 9. Bei den restlichen Ziffern von 1 bis 9 ist immer eine 1 abzuziehen.
Das Problem mit der schwedischen Wählscheibe ist ebenfalls hier beschrieben worden:
Wie bedient man ein schwedisches Wählscheibentelefon? – 23.10.2022: Schwedische Wählscheibentelefone besitzen ein unübliches Ziffernblatt. Die aufgedruckten Ziffern sind um eine Stelle entgegen des Uhrzeigersinns verschoben. Das macht das Wählen an einer normalen Nebenstellenanlage oder im Rest der Welt außerhalb Schwedens zum Problem. Wie wählt man unter diesen erschwerten Bedingungen die richtigen Nummern? – weiter – |
Softwarelösung für Asterisk-Telefonanlagen: Nun gibt es eine Softwarelösung für die Asterisk-Telefonanlagen in Form eines kleinen PHP-Programms, das mit Hilfe von AGI (Asterisk Gateway Interface) mit Asterisk Daten austauschen kann. Das nachfolgend hier vorgestellte Programm se2eu.php wurde von Rainer Dohmen, DL5PD, verfasst und er stellt es mit freundlicher Genehmigung zur Verfügung.
Es wandelt alle Nummern, die entsprechend einer schwedischen Wählscheibe „falsch“ gewählt wurden in die richtigen Nummern um.
Auf welcher Umgebung läuft das Skript? Getestet wurde es unter anderem auf PHP 7.3, Asterisk 16.2.1 und auf einem Raspberry Pi 3B+ mit Raspbian Buster (Debian) als Betriebssystem.
PHP nachinstallieren: Bei Raspbian Buster musste ich vorher noch PHP installieren, damit PHP-Skripte ausgeführt werden können.
sudo apt-get update sudo apt-get install php
Dies führte zur Installation von PHP 7.2 Die installierte Version kann mit
php -v
in Erfahrung gebracht werden.
Wohin das Skript kopieren? Jetzt müssen wir noch wissen, in welchen Pfad wir die kleine PHP-Datei zu kopieren haben. Dies erfahren wir in der asterisk.conf. Sie befindet sich in dem Pfad, in dem sich die anderen Asterisk-Konfigurationsdateien befinden. Nachfolgend ein Ausschnitt aus der asterisk.conf:
[directories](!) astcachedir => /var/cache/asterisk astetcdir => /etc/asterisk astmoddir => /usr/lib/asterisk/modules astvarlibdir => /var/lib/asterisk astdbdir => /var/lib/asterisk astkeydir => /var/lib/asterisk astdatadir => /var/lib/asterisk astagidir => /var/lib/asterisk/agi-bin ; Hier steht der Pfad für die AGI-Skripte astspooldir => /var/spool/asterisk astrundir => /var/run/asterisk astlogdir => /var/log/asterisk astsbindir => /usr/sbin [options]
Unter astagidir ist der Pfad eingetragen, in dem Asterisk die Skripte findet. Im obigen Beispiel also /var/lib/asterisk/agi-bin. Bei meiner Version Asterisk 16.2.1 sind die AGI-Skripte unter /usr/share/asterisk/agi-bin untergebracht.
Kodierung der Skripte: Auf jeden Fall müssen die Skripte wie in Linux üblich auch unter Windows mit UTF-8 kodiert sein, weshalb ich die Skripte unter Windows mit Notepad++ bearbeite.
Windows- und DOS-Textdateien für Linux umwandeln: Wer seine Skripte auf Windows bearbeitet oder erhält und dann auf den Raspberry kopiert, wird die Programme nicht zum Laufen bekommen. Der Grund sind die unterschiedlichen Steuerzeichen für den Wagenrücklauf (CR) und den Zeilenumbruch (LF). Die Bezeichnungen stammen noch aus der Zeit, als mit UNIX-Rechnern auf Fernschreibern ausgedruckt wurde. Zum Glück gibt es eine Lösung, die auf https://phoenixnap.com/kb/convert-dos-to-unix beschrieben ist. Demnach müssen wir auf unserem Linux bzw. Raspbian mit dem Befehl
sudo apt install dos2unix
ein kleines Programm installieren, mit dem wir mit dem Befehl dos2unix die Windows- oder DOS-Dateien konvertieren können. Wie das genau geht, steht auf der vorhergehend genannten Seite. Zum Beispiel geht das für unser Beispiel wie folgt:
sudo dos2unix /usr/share/asterisk/agi-bin/se2eu.php
Dem Skript-Dateien Zugriffsrechte vergeben: Damit die Skripte auch laufen, müssen sie noch einige Zugriffsrechte erhalten und die Rechte für die Ausführbarkeit erhalten. Dies können wir radikal mit dem Befehl
sudo chmod 777 /usr/share/asterisk/agi-bin/se2eu.php
erreichen.
Das PHP-Skript „se2eu.php“ für die schwedische Wählscheibe: Die nachfolgenden Zeilen in eine Text-Datei kopieren und als se2eu.php umbenennen. Keine Schreibprogramme wie Word oder ähnliches verwenden. Die letzte Zeile darf keine Leerzeile sein.
#!/usr/bin/php -q <?php # Script to convert swedish dialpulses to european numbers # 2022-10-31 by DL5PD, Rainer, dl5pd ätt darc punkt de # tested with Asterisk 16 and PHP 7.4.30 # from Dialplan, call: same => n,AGI(se2eu.php,${EXTEN}) # with ${EXTEN} to be the number to be converted # after Script execution, the converted number is found in ${EXTNEW} # don't let this script run for more than 10 seconds set_time_limit(10); # turn off output buffering ob_implicit_flush(false); # retrieve all AGI variables from Asterisk # and put them in array $agi while (!feof(STDIN)) { $temp = trim(fgets(STDIN,4096)); if (($temp === "") || ($temp == "\n")) { break; } $s = explode(":",$temp); $name = str_replace("agi_","",$s[0]); $agi[$name] = trim($s[1]); } # first argument (number to be converted) is found in $agi[arg_1] $testinput = $agi[arg_1]; #local debug #$testinput = "015394"; # expected output: "904283" # here is the conversion: 0 gets 9, anything else is -1 for ($i=0; $i < strlen($testinput); $i++) { if (is_numeric($testinput[$i]) and $testinput[$i] == 0) { $testinput[$i] = 9; } elseif (is_numeric($testinput[$i]) and $testinput[$i] > 0) { $helper = $testinput[$i]; $helper -= 1; $testinput[$i] = $helper; } } #local debug #echo $testinput; # sending variable ${EXTNEW} to Asterisk with converted number fwrite(STDOUT, "SET VARIABLE EXTNEW $testinput"); fflush(STDOUT); ?>
Die Wählregeln in der extensions.conf: Nun muss noch in der extension.conf von Asterisk das PHP-Skript „se2ueu.php“ angesprochen werden. Es gibt verschiedene Lösungen:
[telefone] ; Test für schwedische Wählscheibentelefone ; Vorwahl 65 auf der schwedischen Wählscheibe exten => _76.,1,Answer() same => n,AGI(se2eu.php,${EXTEN:2}) same => n,NoOP(Aus Script: ${EXTNEW}) same => n,Goto(telefone,${EXTNEW},1) same => n,Hangup()
Das obige Beispiel eignet sich für die ersten Tests und ist im Context „telefone“ der extensions.conf untergebracht, in der sich die extensions (Wahlregeln) für die meisten Telefone befinden. Wählt man auf der schwedischen Wählscheibe die 65 vor, dann wird die „falsch“ gewählte Nummer umgewandelt und die Vorwahl wird abgeschnitten.
Ohne Vorwahl geht das Wählen auch: Es geht auch ohne Vorwahl. Dafür schaffen wir einen neuen Context, den ich im Beispiel sm_telefone genannt habe.
[sm_telefone] include => telefone exten => _X.,1,Answer() same => n,AGI(se2eu.php,${EXTEN}) same => n,NoOP(Aus Script: ${EXTNEW}) same => n,Goto(telefone,${EXTNEW},1) same => n,Hangup()
Das ist der gesamte Inhalt des Contextes sm_telefone.
Telefonanschlüsse für schwedische Wählscheibentelefon erhalten in der sip.conf ebenfalls den Context sm_telefone. Nachfolgend ein Ausschnitt aus der sip.conf für den Telefonanschluss 1483:
[1483] ; Dagobert Duck type=friend context=sm_telefone ; Hier ist der Context einzutragen. secret=money_makes_the_world_go_round host=dynamic username=1483 canreinvite=no port=5064 dtmfmode=rfc2833 callerid = "Dagobert Duck" <1483>
Alle schwedischen Wählscheibentelefone erhalten also in der sip.conf den Context sm_telefone. Dadurch werden sämtliche mit ihnen gewählten Nummern umgewandelt. Eine Vorwahl ist nicht mehr nötig. Nun hat man beim Wählen fast das Gefühl in Schweden des letzten Jahrhunderts zu sein.
Was passiert bei der Ausführung des AGI-Skripts: Damit wir in der Asterisk-Konsole sehen können, was beim Ausführen des AGI-Skripts passiert, müssen wir das Debugging für AGI aktivieren:
agi set debug on
Wählen wir vom schwedischen Wählscheibentelefon 1002 das „normale“ Telefon 1012 an, dann ist in der Asterisk-Konsole folgendes zu beobachten:
An der Leitung für das schwedische Telefon hängt noch ein normales Telefon: Damit man vom normalen Telefon, das parallel zum schwedischen Telefon angeschlossen ist, beim Wählen nicht umrechnen muss, kann man wieder mit Vorwahlen arbeiten:
[sm_telefone] include => telefone exten => _X.,1,Answer() same => n,AGI(se2eu.php,${EXTEN}) same => n,NoOP(Aus Script: ${EXTNEW}) same => n,Goto(telefone,${EXTNEW},1) same => n,Hangup() exten => _65.,1,Answer() same => n,NoOP(Ziel-Nummer: ${EXTEN:2}) same => n,Goto(telefone,${EXTEN:2},1) same => n,Hangup()
Im obigen Beispiel (Context sm_telefone der extensions.conf) bewirkt die Vorwahl 65, dass das AGI-Skript nicht zum Einsatz kommt. Alle Nummern, die mit 65 beginnen, werden normal gewählt und die ersten zwei Ziffern werden entfernt.
Und hier das PHP-Skript mit ChatGPT nach Python 2.7 umgewandelt: Der Vorteil ist, das in Raspbian Python schon installiert ist.
Es ist ein mit der Hilfe von ChatGPT geschriebenes AGI-Script auf der Basis von Python 2.7. Es wurde erfolgreich auf Asterisk 1.6.2 getestet. Es wandelt die mit einer schwedischen Wählscheibe gewählten Ziffern in die richtigen Ziffern um, wie sie in den meisten Ländern der Welt (z.B. Deutschland, USA) verwendet werden.
#!/usr/bin/python import sys agi = {} while True: temp = raw_input().strip() if temp == '': break s = temp.split(':') name = s[0].replace("agi_", "") agi[name] = s[1].strip() testinput = agi['arg_1'] result = "" for i in range(len(testinput)): if testinput[i].isdigit(): if int(testinput[i]) == 0: result += '9' else: result += str((int(testinput[i]) - 1) % 9) print("SET VARIABLE EXTNEW " + result) sys.stdout.flush()
Wie habe ich das gemacht? Ich habe die Kommentarzeilen das PHP-Programms von DL5PD entfernt und ChatGPT um folgendes gebeten: „Bitte wandle dieses AGI-Script in Python 2 um.“ Darunter habe ich das PHP-Skript mit den entfernten Kommentarzeilen einkopiert.
Das Ergebnis war, dass es funktionierte, aber sich bei der 9 verrechnete. Ich musste dann ChatGPT nochmals bitten: „Kannst du mir dieses agi-skript so abändern, dass die eingegebenen ziffern wie folg konvertiert: aus 1 wird 0, aus 2 wird 1, aus 3 wird 2, aus 4 wird 3, aus 5 wird 4, aus 6 wird 5, aus 7 wird 6, aus 8 wird 7, aus 9 wird 8, aus 0 wird 9“.
Nachfolgend in den Screenshots die von ChatGPT verfassten Kommentaren zu den einzelnen Programmschritten:
Das dann von ChatGPT erstellte Programm war sofort fehlerfrei. Ich habe dann den Code in eine Text-Datei mit dem Namen swedial.py kopiert und musste die extensions.conf für den Aufruf des AGI-Scripts anpassen:
exten => _X.,1,Answer() ; same => n,AGI(se2eu.php,${EXTEN}) same => n,AGI(swedial.py,${EXTEN}) same => n,NoOP(Aus Script: ${EXTNEW}) same => n,Goto(janson,${EXTNEW},1) same => n,Hangup()
Das war es im Prinzip.
Hier das AGI-Skript in Python 2.7 für neuseeländische Wählscheiben: ChatGPT war so freundlich und hat das Script für neuseeländische Wählscheiben angepasst. Es klappte nach dem zweiten Anlauf. Das Schema ist so simpel, dass man es selbst ohne Programmierkenntnisse für alle möglichen und unmöglichen Wählscheiben anpassen kann.
#!/usr/bin/python import sys agi = {} while True: temp = raw_input().strip() if temp == '': break s = temp.split(':') name = s[0].replace("agi_", "") agi[name] = s[1].strip() testinput = agi['arg_1'] result = "" for i in range(len(testinput)): if testinput[i].isdigit(): if int(testinput[i]) == 0: result += '0' elif int(testinput[i]) == 1: result += '9' elif int(testinput[i]) == 2: result += '8' elif int(testinput[i]) == 3: result += '7' elif int(testinput[i]) == 4: result += '6' elif int(testinput[i]) == 5: result += '5' elif int(testinput[i]) == 6: result += '4' elif int(testinput[i]) == 7: result += '3' elif int(testinput[i]) == 8: result += '2' elif int(testinput[i]) == 9: result += '1' print("SET VARIABLE EXTNEW " + result) sys.stdout.flush()
Auf https://www.telmuseum.de/telnz.htm ist ein neuseeländisches Wählscheibentelefon abgebildet.
Mit AGI für Asterisk ist fast alles möglich: Mit AGI lassen sich übrigens nicht nur PHP-Skripte in Asterisk einbinden. Es funktionieren auch Skripte, die mit Python, Perl und viele weitere Programmiersprachen verfasst sind. Für viele Programmiersprachen stehen AGI-Bibliotheken zur Verfügung, die den Programmieraufwand reduzieren. Auf jeden Fall befindet man sich auf einem sehr spezialisierten Umfeld.
AGI-Skripte für Asterisk unter Windows editieren – Was ist zu beachten? – 9. März 2023: Windows ist weit verbreitet. Deshalb schreiben nicht wenige ihre AGI-Skripte auf Windows, um sie dann in ihren Raspberry Pi zu kopieren. Wer einige Dinge nicht beachtet, wird die Skripte nicht zum Laufen bekommen. Hier sind die Fallstricke beschrieben, die mich viel Zeit gekostet haben. Die Beispiele beziehen sich auf Python. Sie haben für andere Programmiersprachen die entsprechende Gültigkeit. – weiter – |
Asterisk-Telefonserver auf einem Raspberry Pi – Installation, Konfiguration, Programmierung, SIP, IAX2, AGI-Skripte, Sicherheit und Tipps zum praktischen Betrieb – 2.11.2022: Diese Seite richtet sich an jene, welche einen Asterisk-Telefon-Server auf einem Raspberry Pi betreiben möchten und später ein kleines Netzwerk aus Asterisk-Servern planen, um ein eigenständiges Telefonnetz aufzubauen. Los geht es mit der Installation von Raspbian und Asterisk auf einem Raspberry Pi und dann nach Lust und Laune immer tiefer in die Programmierung von Asterisk. Die Themen werden laufend erweitert.
Selbstverständlich muss es nicht unbedingt ein Raspberry Pi sein. Andere Linux-Rechner gehen auch. – weiter – |