Schritt-für-Schritt-Analyse des agi-test.agi-Skripts

Wir besprechen das Beispiel-Skript zeilen- oder abschnittsweise.

#!/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";
[Warnung]

Bei vielen AGI-Befehlen sehen Sie den folgenden Aufbau:

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 Zeilenendzeichen), in diesem Fall ein \n.