Article updated on

Como gestionar llamadas de Asterisk Con Java (AGI)

Java es uno de los mejores lenguajes para gestionar llamadas con Asterisk en cuanto a velocidad, uso de memoria  y seguridad se refiere. Tabaja mucho mejor que PHP y está mucho más desarrollado para múltiples hilos, conexión con base de datos, y concurrencia, además no tienes riesgo de producir un core-dump si tienes errores de código o goteos de memoria. Con java puedes crear IVRs complejas con mucho menos esfuerzo que con la sintaxis por defecto de Asterisk.

En este ejemplo se tratan los siguientes puntos.

  •  Conectar a Asterisk con Java via AGI.
  •  Cambiar variables de canal desde java y mostrarlas por la consola de Asterisk.
  •  Usar el modo debug de Eclipse sobre una llamada en curso.
  • Detectar que el usuario ha colgado mientras esta la llamada en curso.

Descarga las librerías

Descarga las librerías. here or usa maven:

<dependency>
    <groupId>org.asteriskjava</groupId>
    <artifactId>asterisk-java</artifactId>
    <version>1.0.0-m2</version>
</dependency>

* Es opcional pero recomendado usar los fuentes.

sips.conf

    [general]
    context=default
    bindport=5060
    disallow=all
    allow=ulaw
    allow=alaw

    [1000]
    type=friend
    host=dynamic
    secret=1234
    context=default

    [1001]
    type=friend
    host=dynamic
    secret=1234
    context=default

    [1002]
    type=friend
    host=dynamic
    secret=1234
    context=default

 

extensions.conf

[general]
static=yes
writeprotect=no

[default]
exten => 1001,1,Answer()
exten => 1001,n,Dial(SIP/1001,20,tr)
exten => 1001,n,Hangup

exten => 1002,1,Answer()
exten => 1002,n,Dial(SIP/1002,20,tr)
exten => 1002,n,Hangup

exten => 555,1,Answer()
exten => 555,n,Playback(tt-monkeys)
exten => 555,n,Hangup

exten => 666,1,Playback(thank-you-cooperation)
exten => 666,n,Hangup()

exten => 888,1,Agi(agi://localhost/hello.agi)

exten => 999,1,Agi(agi://localhost/hello2.agi)
exten => 999,n,Verbose(2,The channel name is ${MYVAR})
exten => 999,n,Playback(thank-you-cooperation)
exten => 999,n,Hangup()
exten => h,1,Verbose(2,Hang-> The channel name is ${MYVAR})
exten => t,1,Verbose(2,timeout t)
exten => T,1,Verbose(2,timeout T)
exten => i,1,Verbose(2,timeout T)

 

Prepara Asterisk

  • Cambia tu sips.conf y  extensions.conf por los ejemplos mostrados arriba.
  • Loga un teléfono sip o softphone a la extensión 1001 o 1002 con contraseña 1234
  • Comprueba que todo funciona llamando a la extensión 555 o 666.

 

Prepara la parte Java

  • Crea un nuevo proyecto java. Si usas eclipse, ve a  new-> new java project
  • Añade las librerías que te has bajado al class path.
  • Crea un nuevo fichero llamado fastagi-mapping.properties. Este archivo referencia las AGIs a nuestras clases de Java para que puedan ser llamadas desde el extensions.conf  ej. 888,1,Agi(agi://localhost/hello.agi)
  • Asegurate de que el fastagi-mapping.properties esta en el classpath o en la misma carpeta donde están las librerías.

* Crea 2 clases java y modifica el properties tal y como se muestra debajo.

 

fastagi-mapping.properties

hello.agi = HelloAgiScript
hello2.agi = HelloAgiScript2

 

HelloAgiScript.java

import org.asteriskjava.fastagi.*;
public class HelloAgiScript extends BaseAgiScript
{    
    public void service(AgiRequest request, AgiChannel channel)
            throws AgiException
    {
        // Answer the channel...
        answer();
        // ...say hello...
        streamFile("welcome");
        streamFile("tt-monkeys");
        // ...and hangup.
        hangup();               
    }        
}

 

HelloAgiScript2.java

import org.asteriskjava.fastagi.*;
public class HelloAgiScript2 extends BaseAgiScript {
    private static int counter = 0;
    public void service(AgiRequest request, AgiChannel channel)
            throws AgiException {
        try {        
            setVariable("myvar", "Hello World!");
            // Answer the channel...
            answer();
            // ...say hello...
            streamFile("welcome");
            //streamFile("tt-monkeys");                                
            channel.exec("Verbose", "2, Hola Mundo");
            verbose("hola mundo", 2);            
            System.out.println("call count :" + counter + channel.getChannelStatus());
        } catch (org.asteriskjava.fastagi.AgiHangupException e) {
            System.out.println("Ha colgado el cabrón!!");
            setVariable("myvar", "Ha colgado el cabrón!!");
        }
        counter++;
    }
}

En eclipse debería parecerse a esta imagen. Haz clic para agrandar.

img/0/39/_002.jpeg

 

Ejecuta la parte Java

En eclipse ve a Run Configurations, en la clase principal debe ser org.asteriskjava.Cli . Ejecutala debería aparecer una traza con el mensajeINFO: Listening on *:4573. Lo que nos dice que la aplicación esta preparada para recibir peticiones AGI.

img/0/39/_005.jpeg

Comprueba los ejemplos

  • Llama al 888 desde tu teléfono Sip para probar el primer ejemplo, deberías escuchar el sonido de asterisk tt-mokeys
  • Llama al 999 desde tu teléfono Sip para probar el segundo ejemplo, vete a la consola de asterisk sudo rasterisk, cambia el verbosity a nivel 2 core set verbose 2 y deberías ver las siguientes trazas.

img/0/39/_006.jpeg

  • Llama al 999 desde tu teléfono Sip y cuelga cuando escuches "welcome". Deberías ver un The user hanged up!!  en tu consola Java y  == Hang-> The channel name is The user hanged up! en el CLI de Asterisk.

 

Ejecutar fuera de eclipse

  • copia los archivos asterisk-java-1.0.0-m2.jar  fastagi-mapping.properties  HelloAgiScript2.class  HelloAgiScript.class en la misma carpeta.
  • Ejecuta como java -cp .:asterisk-java-1.0.0-m2.jar org.asteriskjava.Cli desde consola

img/0/39/_007.jpeg

* Para ejecutar en background usa nohup java -cp .:asterisk-java-1.0.0-m2.jar org.asteriskjava.Cli &

Notas

  • Establece algunos puntos de ruptura(breakpoints) y haz clic sobre Debug As para Debugear la aplicación.
  • Este ejemplo funciona con la librería asterisk-java-1.0.0-m2 y Asterisk 1.8 prueba con versiones más antiguas de la librería como la 0.2 o 0.3 si usas una versión más antigua de Asterisk.