Article updated on

How to handle Asterisk Calls with Java (AGI)

Java is one of the best languages to handle calls in Asterisk, in terms of speed, memory usage and security. It performs better than PHP and it's much more developed for multi-threading, data base connection and concurrency, besides you don't have the risk to produce core dumps while managing calls. With java you can create complex IVRs with much less effort than with default Asterisk Syntax.

In this example The following features are covered.

  • How to Connect Asterisk with Java with an AGI.
  • How to Change channel variables from Java and print them in the asterisk console.
  • How to debug a phone call routing with Eclipse.
  • How to detect that the caller hanged up from java and the asterisk console.

Download the required Libraries.

Download the libraries. here or use maven:

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

* it is optional but it is also recommened to download the sources.

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)

 

Set up Asterisk

  • Change your sips.conf and extensions.conf as shown above.
  • Log a Sip phone to your asterisk you can use extensions 1001 or 1002 pasword 1234
  • Test that everything is working in the Asterisk part by calling 555, 666

Set up the java part

  • Create a new java project. If you are using eclipse, go to new-> new java project
  • Add libraries and reference the libraries downloaded
  • create a new file called fastagi-mapping.properties . This file references the AGIs to our java classes so that It can be called from the asterisk extensions.conf  888,1,Agi(agi://localhost/hello.agi)
  • make sure the fastagi-mapping.properties is in the class path or put it in the same folder as your compiled classes.

Once you have created a project and the asterisk libraries and the fastagi-mapping.properties is in the class path do the following changes and create 2 new java classes:

 

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, Hello world");
            verbose("Hello World", 2);            
            System.out.println("call count :" + counter + channel.getChannelStatus());
        } catch (org.asteriskjava.fastagi.AgiHangupException e) {
            System.out.println("the user hanged up!!");
            setVariable("myvar", "the user hanged up!!");
        }
        counter++;
    }
}

In eclipse it should look like something like this.

img/0/39/_002.jpeg

 

Running the Java Part

In eclipse Go to run configurations, the main class must be org.asteriskjava.Cli click on run and you should get a INFO: Listening on *:4573. This means that the java application is ready to receive AGI requests.

img/0/39/_005.jpeg

Testing the example

  • Call 888 from your Sip phone to call the first example, you should hear the tt-mokeys asterisk track.
  • Call 999 from your Sip phone to call the second example. go to the Asterisk console sudo rasterisk, change the verbosity level to at least 2 core set verbose 2 you should see the following traces

img/0/39/_006.jpeg

  • Call 999 from your Sip Phone and hang up as soon as you hear welcome. You should get a The user hanged up!! trace in your java console and a == Hang-> The channel name is The user hanged up! in the Asterisk Cli

 

Running the example outside Eclipse

  • copy the files asterisk-java-1.0.0-m2.jar  fastagi-mapping.properties  HelloAgiScript2.class  HelloAgiScript.class in the same folder
  • Run as java -cp .:asterisk-java-1.0.0-m2.jar org.asteriskjava.Cli

img/0/39/_007.jpeg

* To run in background in linux use nohup java -cp .:asterisk-java-1.0.0-m2.jar org.asteriskjava.Cli &

Notes

  • Set some breakpoints and click on Debug as to debug the application.
  • This example works with the asterisk-java-1.0.0-m2 and Asterisk 1.8 try a older version such us 0.2 o 0.3 to work with older Asterisk versions.