agi-test.agi
[110]im Verzeichnis
/var/lib/asterisk/agi-bin/
abgespeichert. Anhand
dieses Perl-Programms werden wir die grundsätzliche Arbeit mit
AGI-Skripten beschreiben.extensions.conf
wie folgt aufgerufen:exten => 1234,1,Answer() exten => 1234,2,AGI(agi-test.agi) exten => 1234,3,Hangup()
#!/usr/bin/perl use strict;Die ersten zwei Zeilen sagen dem ausführenden Betriebssystem, dass es sich um ein Perl-Programm handelt, das mit dem Interpreter
/usr/bin/perl
ausgeführt werden soll.
use strict
bewirkt eine konsequentere Behandlung von
Fehlern innerhalb des Perl-Programms.$|=1;Diese kleine Zeile bringt Perl dazu, die Ausgabe von Text nicht zu puffern. So können wir sicher sein, dass alle Ausgaben auch unmittelbar an Asterisk übergeben und nicht erst in einem Buffer zwischengespeichert werden.
# Setup some variables my %AGI; my $tests = 0; my $fail = 0; my $pass = 0;Hier werden verschiedene Variablen definiert. Das Hash
%AGI
nimmt die initialen Eingaben von Asterisk auf. Die restlichen
Variablen zählen die Gesamtanzahl der Tests, die Anzahl der
fehlgeschlagenen Tests und die Anzahl der funktionierenden
Tests.while(<STDIN>) { chomp; last unless length($_); if (/^agi_(\w+)\:\s+(.*)$/) { $AGI{$1} = $2; } }Die eben eingelesenen Werte werden zum Debuggen auf STDERR, also im Endeffekt auf dem CLI ausgegeben:
print STDERR "AGI Environment Dump:\n"; foreach my $i (sort keys %AGI) { print STDERR " -- $i = $AGI{$i}\n"; }Danach geht es mit
checkresult
weiter:sub checkresult { my ($res) = @_; my $retval; $tests++; chomp $res; if ($res =~ /^200/) { $res =~ /result=(-?\d+)/; if (!length($1)) { print STDERR "FAIL ($res)\n"; $fail++; } else { print STDERR "PASS ($1)\n"; $pass++; } } else { print STDERR "FAIL (unexpected result '$res')\n"; $fail++; } }Die Subroutine
checkresult
liest das Ergebnis
eines Befehls an Asterisk aus und bestimmt, ob der Test erfolgreich
war oder nicht. Entsprechend werden die Variablen $fail
und $pass
hochgezählt. Nachdem die Grundlagen gelegt
sind, können die einzelnen Tests beginnen: Die Datei
beep.gsm
wird abgespielt.print STDERR "1. Testing 'sendfile'..."; print "STREAM FILE beep \"\"\n"; my $result = <STDIN>; &checkresult($result);Der Text "hello world" wird an den Anrufer geschickt. Das funktioniert natürlich nur, wenn das Protokoll und das Endgerät diese Funktion unterstützen.
print STDERR "2. Testing 'sendtext'..."; print "SEND TEXT \"hello world\"\n"; my $result = <STDIN>; &checkresult($result);Das Bild "asterisk-image" wird an den Anrufer geschickt. Auch diese Funktion ist vom Protokoll und dem Endgerät abhängig.
print STDERR "3. Testing 'sendimage'..."; print "SEND IMAGE asterisk-image\n"; my $result = <STDIN>; &checkresult($result);Die Zahl 192837465 wird dem Anrufer vorgelesen:
print STDERR "4. Testing 'saynumber'..."; print "SAY NUMBER 192837465 \"\"\n"; my $result = <STDIN>; &checkresult($result);Dieser Befehl wartet 1000 Millisekunden auf die Eingabe von DTMF-Tönen durch den Anrufer:
print STDERR "5. Testing 'waitdtmf'..."; print "WAIT FOR DIGIT 1000\n"; my $result = <STDIN>; &checkresult($result);Ein 3000 Millisekunden langes GSM-Soundfile mit dem Namen
testagi.gsm
wird
aufgenommen. Die Aufnahme kann durch die Eingabe der Zahlen 1, 2, 3
oder 4 unterbrochen werden.print STDERR "6. Testing 'record'..."; print "RECORD FILE testagi gsm 1234 3000\n"; my $result = <STDIN>; &checkresult($result);Das soeben aufgenommene Soundfile wird abgespielt:
print STDERR "6a. Testing 'record' playback..."; print "STREAM FILE testagi \"\"\n"; my $result = <STDIN>; &checkresult($result);Nun erfolgt die Ausgabe auf dem CLI, wie viele Tests funktioniert oder nicht funktioniert haben:
print STDERR "================== Complete ======================\n"; print STDERR "$tests tests completed, $pass passed, $fail failed\n"; print STDERR "==================================================\n";
fwrite(STDOUT,"BEFEHL $value \"\"\n"); # ^^^^^^^Der in dieser Zeile unterschlängelte Teil (zwischen
$value
und
);
) ist zwingend erforderlich, damit der Befehl
korrekt ausgeführt wird. Es handelt sich hierbei um ein Argument
ohne Inhalt, das durch zwei gequotete Anführungszeichen
dargestellt wird. Abgeschlossen wird der gesamte Befehl durch ein
„line feed“ (ein Zeilenende-Zeichen), in diesem Fall
ein \n
.lotto.php
), das 6 zufällige Zahlen
von 1 bis 49 auswählt und dem Anrufer vorspricht. Die Beschreibung der
einzelnen Schritte erfolgt im Quellcode.#!/usr/bin/php -q <?php # Sicherheitseinstellung. Das Skript läuft nicht # laenger als 8 Sekunden. ################################################# set_time_limit(8); # Output Buffer wird deaktiviert # Alternativ könnten wir nach jeder Ausgabe # fflush(STDOUT); aufrufen. ################################################# ob_implicit_flush(); # PHP Error Reporting wird deaktiviert ################################################# error_reporting(0); # Für die Kommunikation mit Asterisk benötigen # wir STDIN und STDOUT Filehandles ################################################# if (!defined('STDIN')) define('STDIN' , fopen('php://stdin' , 'r')); if (!defined('STDOUT')) define('STDOUT', fopen('php://stdout', 'w')); if (!defined('STDERR')) define('STDERR', fopen('php://stderr', 'w')); # Die von Asterisk übergebenen Variablen und # Werte werden ausgelesen und im Array $agi # gespeichert. ################################################# $agi = array(); while (!feof(STDIN)) { $tmp = trim(fgets(STDIN,4096)); if (($tmp == '') || ($tmp == "\n")) break; $var1 = split(':',$tmp); $name = str_replace('agi_','',$var1[0]); $agi[$name] = trim($var1[1]); } # Ein Array mit 6 zufälligen und nicht # doppelten Zahlen von 1 bis 49 wird generiert. ################################################# $Lottozahlen = array(); do { $Zahl = rand(1,49); if (array_search($Zahl, $Lottozahlen) == FALSE) { $Lottozahlen[] = $Zahl; } } while (count($Lottozahlen) < 6); # Vor der ersten Ansage wird eine Sekunde # gewartet. ################################################# fwrite(STDOUT,"EXEC Wait 1 \"\"\n"); fflush(STDOUT); # Die Zahlen werden nacheinander vorgelesen. # Zwischen den einzelnen Zahlen gibt es immer # eine Pause von einer Sekunde. ################################################# foreach ($Lottozahlen as $value) { fwrite(STDOUT,"SAY NUMBER $value \"\"\n"); fflush(STDOUT); fwrite(STDOUT,"EXEC Wait 1 \"\"\n"); fflush(STDOUT); } ?>Das Programm
lotto.php
muss im
Verzeichnis /var/lib/asterisk/agi-bin/
abgespeichert werden und wird in der
extensions.conf
wie folgt aufgerufen:exten => 1234,1,Answer() exten => 1234,2,AGI(lotto.php) exten => 1234,3,Hangup()
<?php /** * @package phpAGI_examples * @version 2.0 */ function my_ip(&$agi, $peer) { $ip = 'unknown'; $asm = $agi->new_AsteriskManager(); if($asm->connect()) { $peer = $asm->command("sip show peer $peer"); $asm->disconnect(); if(!strpos($peer['data'], ':')) echo $peer['data']; else { $data = array(); foreach(explode("\n", $peer['data']) as $line) { $a = strpos('z'.$line, ':') - 1; if($a >= 0) $data[trim(substr($line, 0, $a))] = trim(substr($line, $a + 1)); } } if(isset($data['Addr->IP'])) { $ip = explode(' ', trim($data['Addr->IP'])); $ip = $ip[0]; } } $agi->text2wav("Your IP address is $ip"); } ?>
gem install adhearsion
vollzogen
werden.exten => _.,1,AGI(agi://127.0.0.1)
ahn
, das mit
ahn create applikationsname
aufgerufen wird.
Beispiel:stefan@pbx:~$ahn create apfelmus_app
create create components/simon_game create components/disabled/stomp_gateway create components/ami_remote create components/restful_rpc/spec create config create .ahnrc create components/simon_game/simon_game.rb create components/ami_remote/ami_remote.rb create components/disabled/stomp_gateway/stomp_gateway.rb create components/disabled/stomp_gateway/config.yml create components/disabled/stomp_gateway/README.markdown create components/restful_rpc/restful_rpc.rb create components/restful_rpc/config.yml create components/restful_rpc/README.markdown create components/restful_rpc/example-client.rb create components/restful_rpc/spec/restful_rpc_spec.rb create config/startup.rb create dialplan.rb create events.rb create README create Rakefile stefan@pbx:~$cd apfelmus_app
stefan@pbx:~/apfelmus_app$
ahn start
.
stefan@pbx:~/apfelmus_app$ ahn start .
INFO ahn: Adhearsion initialized!
dialplan.rb
definiert. Hier ein
einfaches Beispiel:intern { case extension when 22 play "hello-world" hangup else dial "SIP/#{extension}" end }
intern
ist in diesem Beispiel der benutzte Context,
aus dem Adhearsion aufgerufen wurde.