AGI
Sommaire |
Introduction
Les AGIs peuvent être écris en php, perl, python, java, C, ou tout autre language.
Les AGIs peuvent être de deux types :
- AGI : le type par défaut.
- FastAGI : utilisé pour faire tourner un AGI sur une autre machine du même réseau.
Les AGIs sont appelés depuis le dialplan.
La communication avec Asterisk s'effectue via les fichiers stdin et stdout.
Les Fonctions
Pour connaitre la liste des fonctions utilisables dans les AGIs, vous devez vous connecter à la console d'Asterisk et faire : agi show
Execution de l'AGI
L'AGI est envoyé par Asterisk depuis le dialplan.
L'appel à un AGI se fait par :
exten => s,n,AGI([<interpreteur>,]"<script_agi>"[,var1[,var2[,..]]])
Exemple :
exten => s,n,AGI(/usr/bin/php,"/var/lib/asterisk/agi-bin/test_php.agi")
Exemple avec paramètres :
exten => s,n,AGI(/usr/bin/php,"/var/lib/asterisk/agi-bin/test_php.agi",${Myvar1},${Myvar2})
il est possible de ne pas préciser l'interpréteur (suivant la version d'Asterisk) ni le chemin de l'agi si celui-ci se trouve dans le repertoire paramètré dans /etc/asterisk/asterisk.conf entrée astagidir (par defaut : /var/lib/asterisk/agi-bin).
PHP
AGI simple
Voici un exemple utilisant le langage PHP, l'AGI est appelé depuis le dialplan. le script php doit être dans le repertoire /var/lib/asterisk/agi-bin et doit avoir les droits d'exécution pour Asterisk.
Script (test_php.agi) :
#!/usr/bin/php -q
<?php
// limite le temps d'execution du script a 60 secondes
set_time_limit(60);
// supprime le "buffering" sur les sorties
ob_implicit_flush(false);
// supprime l'affichage des erreurs pour éviter que celles-ci interferent avec Asterisk
error_reporting(0);
// creation des fichiers STDIN, STDOUT et STDERR si besoin
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'));
// # retrieve all AGI variables from Asterisk
// récupération des variables envoyés par Asterisk au lancement de l'AGI.
while(!feof(STDIN))
{
$temp = trim(fgets(STDIN,4096));
if (($temp == "") || ($temp == "\n")) break;
$s = split(":",$temp);
$name = str_replace("agi_","",$s[0]);
$agi[$name] = trim($s[1]);
}
// l'ordre que l'on envoi à Asterisk, dans cette exemple, on met "bonjour" dans "Myvar"
fwrite(STDOUT,"SET VARIABLE Myvar Bonjour\n");
// force l'envoi de l'ordre. Pas réellement nécessaire puisse que la bufferisation
// est désactivée, mais conseillé.
fflush(STDOUT);
exit();
?>
Dialplan :
[AGI_PHP]
exten => s,1,Set(Myvar=Test)
exten => s,n,NoOp(Myvar=${Myvar})
exten => s,n,AGI(/usr/bin/php,"/var/lib/asterisk/agi-bin/test_php.agi")
exten => s,n,NoOp(Myvar=${Myvar})
Affichage CLI :
-- Executing [s@AGI_PHP:1] Set("SIP/201-08fe4158", "Myvar=Test") in new stack
-- Executing [s@AGI_PHP:2] NoOp("SIP/201-08fe4158", "Myvar=Test") in new stack
-- Executing [s@AGI_PHP:3] AGI("SIP/201-08fe4158",
"/usr/bin/php,"/var/lib/asterisk/agi-bin/test_php.agi"") in new stack
-- Launched AGI Script /usr/bin/php
-- <SIP/201-08fe4158>AGI Script /usr/bin/php completed, returning 0
-- Executing [s@AGI_PHP:4] NoOp("SIP/201-08fe4158", "Myvar=Bonjour") in new stack
-- Executing [s@AGI_PHP:5] Hangup("SIP/201-08fe4158", "") in new stack
AGI avec paramètres
Voici un autre exemple avec passage de paramètres Script (test_php_var.agi) :
#!/usr/bin/php -q
<?php
// limite le temps d'execution du script a 60 secondes
set_time_limit(60);
// supprime le "buffering" sur les sorties
ob_implicit_flush(false);
// supprime l'affichage des erreurs pour éviter que celles-ci interferent avec Asterisk
error_reporting(0);
// creation des fichiers STDIN, STDOUT et STDERR si besoin
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'));
// # retrieve all AGI variables from Asterisk
// récupération des variables envoyés par Asterisk au lancement de l'AGI.
while(!feof(STDIN))
{
$temp = trim(fgets(STDIN,4096));
if (($temp == "") || ($temp == "\n")) break;
$s = split(":",$temp);
$name = str_replace("agi_","",$s[0]);
$agi[$name] = trim($s[1]);
}
// l'ordre que l'on envoi à Asterisk, dans cette exemple, on met le resultat
// de la multiplication de "arg1" par "arg2" dans "Myvar"
fwrite(STDOUT,"SET VARIABLE Myvar ".($agi[arg_2]*$agi[arg_3])."\n");
// force l'envoi de l'ordre. Pas réellement nécessaire puisse que la bufferisation
// est désactivée, mais conseillé.
fflush(STDOUT);
exit();
?>
Dialplan :
[AGI_PHP_VAR]
exten => s,1,Set(Myvar=Test)
exten => s,n,Set(Myvar1=2)
exten => s,n,Set(Myvar2=3)
exten => s,n,NoOp(Myvar=${Myvar})
exten => s,n,AGI(/usr/bin/php,"/var/lib/asterisk/agi-bin/test_php_var.agi",${Myvar1},${Myvar2})
exten => s,n,NoOp(Myvar=${Myvar})
Affichage CLI :
-- Executing [s@AGI_PHP_VAR:1] Set("SIP/201-08fdd448", "Myvar=Test") in new stack
-- Executing [s@AGI_PHP_VAR:2] Set("SIP/201-08fdd448", "Myvar1=2") in new stack
-- Executing [s@AGI_PHP_VAR:3] Set("SIP/201-08fdd448", "Myvar2=3") in new stack
-- Executing [s@AGI_PHP_VAR:4] NoOp("SIP/201-08fdd448", "Myvar=Test") in new stack
-- Executing [s@AGI_PHP_VAR:5] AGI("SIP/201-08fdd448",
"/usr/bin/php,"/var/lib/asterisk/agi-bin/test_php_var.agi",2,3") in new stack
-- Launched AGI Script /usr/bin/php
-- <SIP/201-08fdd448>AGI Script /usr/bin/php completed, returning 0
-- Executing [s@AGI_PHP_VAR:6] NoOp("SIP/201-08fdd448", "Myvar=6") in new stack
-- Executing [s@AGI_PHP_VAR:7] Hangup("SIP/201-08fdd448", "") in new stack
AGI et base de données
Voici un exemple avec récupération de valeur depuis une base de données Mysql.
Dans cet exemple, la base s'appelle asterisk et la table s'appelle testagi.
Table testagi :
CREATE DATABASE IF NOT EXISTS asterisk; USE asterisk; DROP TABLE IF EXISTS `testagi`; CREATE TABLE `testagi` ( `ID` int(11) NOT NULL auto_increment, `Nom` varchar(16) NOT NULL default , `Code` varchar(10) NOT NULL default , PRIMARY KEY (`ID`) );
Contenu table testagi :
INSERT INTO `testagi` (`Nom`,`Code`) VALUES ('usertest','1234');
Script (test_php_sql.agi) :
#!/usr/bin/php -q
<?php
// limite le temps d'execution du script a 60 secondes
set_time_limit(60);
// supprime le "buffering" sur les sorties
ob_implicit_flush(false);
// supprime l'affichage des erreurs pour éviter que celles-ci interferent avec Asterisk
error_reporting(0);
// creation des fichiers STDIN, STDOUT et STDERR si besoin
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'));
// # retrieve all AGI variables from Asterisk
// récupération des variables envoyés par Asterisk au lancement de l'AGI.
while(!feof(STDIN))
{
$temp = trim(fgets(STDIN,4096));
if (($temp == "") || ($temp == "\n")) break;
$s = split(":",$temp);
$name = str_replace("agi_","",$s[0]);
$agi[$name] = trim($s[1]);
}
// ouverture de la base
$DataBase = 'asterisk';
$HostBase = '127.0.0.1';
$UserBase = 'Asterisk';
$PwdBase = 'password';
$Table = 'testagi';
$db = mysql_connect($HostBase, $UserBase, $PwdBase);
if(!$db) exit(1);
mysql_select_db($DataBase, $db);
// recuperation du code
$SQLstr="Select Code from $Table where Nom='".$agi[arg_2]."'";
$Res = mysql_query($SQLstr, $db);
$tresult = mysql_fetch_array($Res);
@mysql_free_result($Res, $db);
@mysql_close($db);
// l'ordre que l'on envoi à Asterisk, dans cette exemple, on met le code de l'utilisateur
fwrite(STDOUT,"SET VARIABLE usercode ".$tresult['Code']."\n");
// force l'envoi de l'ordre. Pas réellement nécessaire puisse que la bufferisation
// est désactivée, mais conseillé.
fflush(STDOUT);
exit();
?>
Dialplan :
[AGI_PHP_SQL]
exten => s,1,Set(UserName=usertest)
exten => s,n,NoOp(UserName=${UserName})
exten => s,n,Set(usercode="")
exten => s,n,AGI(/usr/bin/php,"/var/lib/asterisk/agi-bin/test_php_sql.agi",${UserName})
exten => s,n,NoOp(usercode=${usercode})
exten => s,n,Hangup()
Affichage CLI :
-- Executing [s@AGI_PHP_SQL:1] Set("SIP/201-08fe1928", "UserName=usertest") in new stack
-- Executing [s@AGI_PHP_SQL:2] NoOp("SIP/201-08fe1928", "UserName=usertest") in new stack
-- Executing [s@AGI_PHP_SQL:3] Set("SIP/201-08fe1928", "usercode=""") in new stack
-- Executing [s@AGI_PHP_SQL:4] AGI("SIP/201-08fe1928",
"/usr/bin/php,"/var/lib/asterisk/agi-bin/test_php_sql.agi",usertest") in new stack
-- Launched AGI Script /usr/bin/php
-- <SIP/201-08fe1928>AGI Script /usr/bin/php completed, returning 0
-- Executing [s@AGI_PHP_SQL:5] NoOp("SIP/201-08fe1928", "usercode=1234") in new stack
-- Executing [s@AGI_PHP_SQL:6] Hangup("SIP/201-08fe1928", "") in new stack
Annexe
Pour simplifier la programmation d'AGI en php, il existe un module nommé : PHPAGI, téléchargeable sur : http://phpagi.sourceforge.net/
Exemple :
<?
require 'phpagi.php';
$agi = new AGI();
$agi->set_variable("Myvar", "Bonjour");
?>