The Asterisk Gateway Protocol: A practical introduction and tutorial to agi applications
TweetAGI: the workhorse for your VoIP and General Telephony Applications for the Asterisk PBX
The Asterisk Gateway Protocol (AGI from now on) is the protocol used by the Asterisk server as its interface for telephony applications.
AGI is just a way that allows you (as a software developer) to easily make telephony applications that asterisk will run someway along
the dialplan. Through AGI, you can read input from the user, play sound files, control the call and its flow, and pretty much everything
needed to make a successfull IVR (Interactive Voice Response) in virtually any programming language.
You might also be interested in PAGI. An AGI client/framework that allows you to quickly develop agi applications in an oop fashion.
Asterisk PBX configuration for your AGI telephony applications
To start your agi application you will use the AGI() dialplan application from you own dialplan. For example, in extensions.conf:
exten => 1,1,AGI(myApplication.php)
This will tell asterisk to start an agi application when a call is made to the '1' extension. That's it ;)
Overview of the AGI (Asterisk Gateway Interface) Protocol
AGI is a very simple protocol. Asterisk communicate with the applications through their standard input (stdin) and standard output (stdout). So you can send commands to asterisk via your stdout and receive asterisk responses through your stdin. This makes AGI very easy to deal with from any programming language.
When a call is received by asterisk, it will start to execute the dial plan in the configured
context. This context will depend on various reasons that escape the scope of this article, so I wont
get into any details.
When the AGI() application is called from the dialplan, asterisk will fork() a new process
and execute that application, communicating (as stated above) with it through its standard
input and standard output (normally file descriptors 0 -zero- and 1 respectively).
Before forking and executing the new agi process, asterisk will set the following
environment variables:
- AST_CONFIG_DIR: astetcdir key from asterisk.conf.
- AST_CONFIG_FILE: absolute path to the asterisk.conf file used.
- AST_MODULE_DIR: astmoddir key from asterisk.conf.
- AST_SPOOL_DIR: astspooldir key from asterisk.conf.
- AST_MONITOR_DIR: usually AST_SPOOL_DIR/monitor
- AST_VAR_DIR: astvarlibdir key from asterisk.conf.
- AST_DATA_DIR: astdbdir key from asterisk.conf.
- AST_LOG_DIR: astlogdir key from asterisk.conf.
- AST_AGI_DIR: astagidir key from asterisk.conf.
- AST_KEY_DIR: astkeydir key from asterisk.conf.
- AST_RUN_DIR: astrundir key from asterisk.conf.
As soon as your application is fork()ed from asterisk, it starts to receive the channel variables via its standard input, which are:
- agi_request: The filename of your script.
- agi_channel: The originating channel.
- agi_language: The language code.
- agi_type: The originating channel type.
- agi_uniqueid: A unique ID for the call.
- agi_version: The version of Asterisk (since Asterisk 1.6).
- agi_calleridv: The caller ID number (or "unknown").
- agi_calleridname: The caller ID name (or "unknown").
- agi_callingpres: The presentation for the callerid.
- agi_callingani2: PRI Channels ani2 variable.
- agi_callington: The type of number used in PRI Channels.
- agi_callingtns: An optional 4 digit number (Transit Network Selector).
- agi_dnid: The dialed number id (or "unknown").
- agi_rdnis: The referring DNIS number (or "unknown").
- agi_context: Origin context in extensions.conf.
- agi_extension: The called number (dnis).
- agi_priority: The priority it was executed as in the dial plan.
- agi_enhanced: The flag value is 1.0 if started as an EAGI script, 0.0 otherwise.
- agi_accountcode: Account code of the origin channel.
- agi_threadid: Thread ID of the AGI script.
The variables come in the following format:
<variable_name>:<space><variable_value>
Example:
agi_context: default
Quick IVR (Interactive Voice Response) example in a shell script
Let's try a very basic example to see in action what we've covered so far:
Configure asterisk to run an example
Let's configure a demo application, adding 3 (optional, of course) arguments to it:
exten => 1,1,AGI(/tmp/agi.sh,arg1,arg2,arg3)
Create the agi application
Run the IVR application
Make a call to the '1' extension. Your agi application should run and create the file /tmp/dump.txt with the output from the channel variables. This application does nothing at all. It will end when asterisk sends an empty line, which marks the end of the channel variables block.
Example of the file /tmp/dump.txt generated:
Notice how asterisk passes the variables from the dialplan to your application (i.e: the "special" channel variables agi_arg_x where x is the argument index).
Sending AGI commands and receiving responses to create a basic IVR
An example agi command that logs to the console is:
VERBOSE "message" 3
In this case, the command is "verbose", which accepts 2 arguments: the message to log, and the log level
needed in order to log the message. Asterisk can respond with something like:
200 result=1
So asterisk responses have a format. The format is:
<error_code><space>result=<result_data><space>[additional_data]
Meaning:
- error_code: An integer number that indicates the result of the operation (see below).
- result_data: The result value for the command executed.
- additional_data: Optional additional data returned along with the result_data.
The error code can be one of:
- 200: Operation was completed successfully.
- 510: Invalid or unknown command.
- 511: The command cant be executed on a dead (closed, terminated, hung up) channel.
- 520: End of proper usage, when the command returns its syntax.
As an AGI script, you should always set the AGI variable AGISTATUS to one of:
- SUCCESS
- FAILURE
- HANGUP
That's about it, you can find the complete list of commands here.
Quick IVR example: Part 2
Now let's modify the example, like this:
Example of the file /tmp/dump.txt generated:
Rapidly implement VoIP telephony applications (like IVRs) for the Asterisk PBX
As you can see, its fairly easy to implement almost *any* ivr application very quickly and easy
via agi. One of the most important keys to the success of asterisk as a telephony software and
product. I hope this tutorial helps you out in making agi applications in your language of choice.
Marcelo Gornstein <marcelog@gmail.com>