Asterisk Asterisk Gateway Interface AGI La AGI (o Asterisk Gateway Interface) provee una interfaz estándar para que programas externos puedan controlar el plan de marcación. Generalmente, los scripts AGI se utilizan para realizar lógica avanzada, comunicarse con base de datos relacionales, etc. Los lenguajes más comunes de programación de scripts AGI son: PHP, Python y Perl, aunque se puede utilizar cualquier otro lenguaje. Julián Dunayevich, Lázaro Baca, Andrés Brassara, Santiago Alberch, Antonio Lobo 2 AGI El intercambio de información del script con Asterisk se realiza vía los canales de comunicación: STDIN, STDOUT y STDERR. Lee desde STDIN para obtener información. Escribe en STDOUT para enviar información. Escribe en STDERR para enviar información de debugging. El script AGI envía comandos a Asterisk escribiendo en el STDOUT. Seguidamente Asterisk envía una respuesta por cada uno de ellos que es leída por el script. Julián Dunayevich, Lázaro Baca, Andrés Brassara, Santiago Alberch, Antonio Lobo 3 AGI La respuesta del servidor Asterisk ante un pedido es de la sig forma: <code> result=<result> [data] donde code es un código de respuesta similar a HTTP (200 en caso de éxito, 5XX en caso de error). result es el resultado del comando (los valores más convencionales son -1 para errores, 0 si fue exitosa la ejecución) data es un conjunto de datos adicionales que pueden ser enviados por comando específicos (por ej, “timeout” para un comando temporizado) Julián Dunayevich, Lázaro Baca, Andrés Brassara, Santiago Alberch, Antonio Lobo 4 AGI Cuando Asterisk comienza la llamada al script, envía un conjunto de variables relacionadas con el canal en el STDIN. Por ejemplo: agi_request: nombre del script agi_channel: nombre del canal agi_language: lenguaje del canal (en, es) agi_type: tipo de canal (sip, iax, etc.) etc. Julián Dunayevich, Lázaro Baca, Andrés Brassara, Santiago Alberch, Antonio Lobo 5 AGI Algunos ejemplos de comandos son: ANSWER: atiende. HANGUP: cuelga. SAY [NUMBER | DIGITS | ALPHA | PHONETICS]: dice un número, dígito, caracter o una cadena fonéticamente. SET [CONTEXT | EXTENSION | PRIORITY]: establece un nuevo contexto, extensión o prioridad luego de finalizada la ejecución de script. VERBOSE: imprime un mensaje en el log. WAIT FOR DIGIT: espera que se presione un dígito. [SET | GET] VARIABLE: asigna u obtiene el valor de una variable del plan de marcación. Julián Dunayevich, Lázaro Baca, Andrés Brassara, Santiago Alberch, Antonio Lobo 6 AGI El programa debe: Tener derechos de ejecución y presentar un intérprete válido Ej yum –y install php; chmod 755 mi_script.php Estar localizado por defecto en /var/lib/asterisk/agibin Cómo llamar al script desde el dialplan: exten => 123,1,Answer() exten => 123,2,AGI(mi_script.php,arg1,..,argn) Julián Dunayevich, Lázaro Baca, Andrés Brassara, Santiago Alberch, Antonio Lobo 7 AGI: ejemplo en PHP El siguiente script está escrito en PHP y dicta los números que se encuentran en el archivo que se le pasa como parámetro: #!/usr/bin/php -q <?php // Esta línea es para que que haga no mantenga en un buffer el output ob_implicit_flush(true); set_time_limit(60); error_reporting(0); // Se abren los diferentes archivos (STDIN, STDOUT y un archivo de log del AGI) $in = fopen("php://stdin","r"); $out = fopen("php://stdout","w"); $stdlog = fopen("/var/log/asterisk/my_agi.log", “a"); // Si debug es true, escribe en el archivo de log definido anteriormente $debug = true; Julián Dunayevich, Lázaro Baca, Andrés Brassara, Santiago Alberch, Antonio Lobo 8 AGI: ejemplo en PHP // Toma el nombre del archivo con los números a dictar del primer parámetro $archivo = $argv[1]; // Define la funcion read, que lee el input del STDIN function read() { global $in, $debug, $stdlog; $input = str_replace("\n", "", fgets($in, 4096)); if ($debug) fputs($stdlog, "read: $input\n"); return $input; } // Define la funcion write, que escribe el output en el STDOUT function write($line) { global $debug, $stdlog, $out; if ($debug) fputs($stdlog, "write: $line\n"); fputs($out,$line."\n"); fflush($out); } Julián Dunayevich, Lázaro Baca, Andrés Brassara, Santiago Alberch, Antonio Lobo 9 AGI: ejemplo en PHP // Parsea los headers del AGI (variables de entorno, etc) while ($env=read()) { $s = split(": ",$env); $agi[str_replace("agi_","",$s[0])] = trim($s[1]); if (($env == "") || ($env == "\n")) { break; } } // Lee el archivo que se paso como parametro $lines = file($archivo); Julián Dunayevich, Lázaro Baca, Andrés Brassara, Santiago Alberch, Antonio Lobo 10 AGI: ejemplo en PHP // Reproduce los digitos contenidos en cada linea del mismo // informando en el log del Asterisk la accion realizada foreach ($lines as $line) { $line=trim($line); for ($i=0;$i<strlen($line);$i++) { write("VERBOSE \"REPRODUCIENDO DIGITO $line[$i]\""); read(); write("SAY DIGITS $line[$i] \"\""); read(); sleep(1); } } // Se cierran todos los handlers de archivos fclose($in); fclose($out); fclose($stdlog); exit; Julián Dunayevich, Lázaro Baca, Andrés Brassara, Santiago Alberch, Antonio Lobo 11 AGI: ejemplo en PHP Por ejemplo, si se quiere asociar el script a la extensión 200, se debe agregar al dialplan: exten => 200,1,Answer(); exten => 200,2,AGI(dicta.php|/tmp/numeros.txt) exten => 200,3,Hangup() Julián Dunayevich, Lázaro Baca, Andrés Brassara, Santiago Alberch, Antonio Lobo 12 AGI: CLI Los siguientes comandos pueden ser ejecutados en la CLI para obtener información sobre la AGI: agi show command topic <command>: muestra información sobre el comando <command> del AGI agi show commands: lista todos los comandos del agi agi set debug on/off: activa/desactiva el debugging de la ejecución de scripts vía la AGI Julián Dunayevich, Lázaro Baca, Andrés Brassara, Santiago Alberch, Antonio Lobo 13 Ejercicio 10: AGI Implementar una funcionalidad en Asterisk utilizando AGI Julián Dunayevich, Lázaro Baca, Andrés Brassara, Santiago Alberch, Antonio Lobo 14 Curso elaborado por Julián Dunayevich, Lázaro Baca, Andrés Brassara, Santiago Alberch y Antonio Lobo [email protected] [email protected] [email protected] [email protected] [email protected] Detalles de la licencia: http://creativecommons.org/licenses/by-nc-sa/2.5/deed.es_AR Autores:: Julián Dunayevich, Lázaro Baca, Andrés Brassara Autores Brassara,, Santiago Alberch,, Antonio Lobo Alberch (cc) Creative Commons - Attribute Non Non--Commercial Share Share--Alike 2.5 Basándose en: Irontec: [email protected] (CC) Asterisk, The Future of Telephony, Jim Meggelen, Jared Smith, and Leif Madsen, O´REILLY, 2005 Julián Dunayevich, Lázaro Baca, Andrés Brassara, Santiago Alberch, Antonio Lobo 15