Para permitir una forma más dinámica de programar el plan de marcado (dialplan) de Asterisk, se emplea lo que se conoce como AGI. Viene a ser como el CGI pero a través de la entrada y salida estándares, stdin y stdout.

Como hacer fork dentro de la misma máquina y lanzar los intérpretes de los lenguajes que se suelen usar para AGI (PHP, Perl, Python...) trae consigo una carga considerable a una máquina que puede ya, de por sí, tener bastante carga con Asterisk, la aplicación de dialplan AGI, trae consigo la posibilidad de cambiar el medio de comunicación de entrada y salida estándar, por un socket abierto hacia otro equipo.

Esto trae consigo la ventaja de que, al estar el código de AGI en otra máquina, ya no tiene que lanzarse cada vez una ejecución de intérprete y su consiguiente carga de memoria y tiempo.

Además, otra ventaja, es que el programa externo no tiene que ser lanzado cada vez, sino que puede permanecer en ejecución, con lo que se ahorra aún más.

Prácticamente, todos los lenguajes tienen ya desarrollado un interfaz abierto o libre que maneja lo que se conoce como FastAGI: Java, PHP, Perl, Python... e incluso Erlang.

El lenguaje Erlang me llamó hace poco la atención por ser un lenguaje, al igual que Scala, orientado a la concurrencia, al desarrollo distribuido y tolerante a fallos, por lo que pensé que podría ser un buen lenguaje para desarrollar soluciones que tuviesen que ver con Asterisk, ya que es lo que siempre se busca en las empresas de telecomunicaciones: redundancia, escalabilidad y alta disponibilidad.

El desarrollo de ErlAst está algo abandonado, pero la parte que se refiere a fast_agi es totalmente funcional, por lo que, siguiendo estas líneas, se puede instalar sin problemas en nuestro equipo. Doy por hecho que Erlang se tiene ya instalado y funcionando, al igual que Asterisk. En un sistema Debian o Ubuntu, instalar ambos se hace con apt-get ;-)

Configura ErlAst

Tal y como se dice en la página oficial del proyecto, lo que hay que hacer es bajar la última versión de erlast del repositorio con el siguiente comando:

svn co http://tools.assembla.com/svn/erlast/trunk erlast

NOTA: el código viene con un error que hace que la aplicación de ejemplo no funcione. Tendremos que agregar, antes de trace(true) en el fichero fast_agi.erl el siguiente código:

trace(on) -> trace(true);
trace(off) -> trace(false);

Una vez descargado, tendremos el directorio erlast creado. Como la versión de AMI es aún inestable, pasaremos a compilar y usar solo la parte de fast_agi:

cd erlast
make
cd lib/fast_agi/
make

NOTA: el primer make originará fallos, puesto que AMI no está aún terminado de implementar por el autor.

Escribimos un fichero de configuración dentro del directorio ebin, que se llame fast_agi_conf.config con el siguiente contenido:

[
    {fast_agi, [
        {port,4573},
        {opts, [
            {ip, {192,168,1,1}}
        ]}
    ]}
].

NOTA: configurar de forma correcta la IP que se ponga en este fichero, puesto que si la IP no corresponde con la de nuestro equipo, el sistema devolverá un error y no arrancará.

Por último, probamos que todo funcione, desde dentro del mismo directorio ebin ejecutamos:

$ erl -config fast_agi_conf
Erlang (BEAM) emulator version 5.5.5 [source] [async-threads:0] [kernel-poll:false]

Eshell V5.5.5  (abort with ^G)
1> application:start(fast_agi).
ok

Configura Asterisk

En este momento ya tendremos lanzada la aplicación y en escucha a través del puerto 4573, con lo que si configuramos un asterisk con el siguiente extensions.conf, debería de reproducirnos el audio de demo de asterisk (en caso de que esté) y colgar:

exten => 123,1,AGI(agi://192.168.1.1:4573/test_agi/test)
exten => 123,n,HangUp

Lanza una llamada contra asterisk al número 123 y debería de reproducirse el audio.

Conclusión

Visto esto, se puede combinar con el almacenamiento redundante y distribuido de mnesia para conseguir que la llamada a AGI sea tolerante a fallos y se tenga memoria del flujo de llamada, lo cual daría mucho juego y unas aplicaciones mucho más fiables.

Actualización 2013-10-16: hace no mucho probé para el desarrollo con Asterisk 1.8 otra implementación de FastAGI sobre Erlang. He ido agregando algunos patches, por lo que puedes verla aquí.