There are a few variants of AGI that differ primarily in the method used to communicate with Asterisk. It is good to be aware of all of the options so you can make the best choice based on the needs of your application.
Process-based AGI is the simplest variant of AGI. The
“quick-start” example at the beginning of this chapter was an example of
a process-based AGI script. The AGI script is invoked by using the
AGI()
application from the Asterisk dialplan. The application to run
is specified as the first argument to AGI()
. Unless a full path is specified, the
application is expected to exist in the /var/lib/asterisk/agi-bin/
directory.
Arguments to be passed to your AGI application can be specified as
additional arguments to the AGI()
application in the Asterisk
dialplan. The syntax is:
AGI(command
[,arg1
[,arg2
[,...]]])
Ensure that your application has the proper
permissions set such that the user the Asterisk process is running as has
permissions to execute it. Otherwise, AGI()
will fail.
Once Asterisk executes your AGI application,
communication between Asterisk and your application will take place over
stdin and stdout. More details about this communication
will be covered in the section called “AGI Communication Overview”. For more
details about invoking AGI()
from the
dialplan, check the documentation built into Asterisk:
*CLI>
core show application AGI
It is the simplest form of AGI to implement.
It is the least efficient form of AGI with regard to resource consumption. Systems with high load should consider FastAGI, discussed in the section called “FastAGI—AGI over TCP”, instead.
EAGI (Enhanced AGI) is a slight variant on AGI()
. It is invoked in the Asterisk dialplan as EAGI()
. The difference is that in addition
to the communication on stdin and
stdout, Asterisk also provides a unidirectional
stream of audio coming from the channel on file descriptor 3. For more
details on how to invoke EAGI()
from the Asterisk dialplan,
check the documentation built into Asterisk:
*CLI>
core show application EAGI
It has the simplicity of process-based AGI, with the addition of a simple read-only stream of the channel’s audio. This is the only variant that offers this feature.
Since a new process must be spawned to run your application for every call, it has the same efficiency concerns as regular process-based AGI.
For an alternative way of getting
access to the audio outside of Asterisk, consider using JACK. Asterisk has a
module for JACK integration, called app_jack
. It provides the JACK()
dialplan application and the
JACK_HOOK()
dialplan
function.
In versions of Asterisk prior to 1.8, there was a dialplan
application called DeadAGI()
. Its
purpose was similar to that of AGI()
,
except you used it on a channel that had already been hung up. This
would usually be done in the special h
extension, when you wanted to use an AGI
application to aid in some type of post-call processing. Invoking
DeadAGI()
from the dialplan will
still work, but you will get a WARNING
message in the Asterisk log. It has been deprecated in
favor of using AGI()
in all cases.
The code for AGI()
has been updated
so it knows how to correctly adjust its operation after a channel has
been hung up.
None. It’s dead.
It’s dead. Really, don’t use it. If you do, your
configuration may break if DeadAGI()
is completely removed from
Asterisk in a future
version.
FastAGI is the term used for AGI call control over a TCP connection. With process-based AGI, an instance of an AGI application is executed on the system for every call and communication with that application is done over stdin and stdout. With FastAGI, a TCP connection is made to a FastAGI server. Call control is done using the same AGI protocol, but the communication is over the TCP connection and does not require a new process to be started for every call. The AGI protocol is discussed in more detail in the section called “AGI Communication Overview”. Using FastAGI is much more scalable than process-based AGI, though it is also more complex to implement.
FastAGI is used by invoking the AGI()
application in the Asterisk dialplan, but instead of
providing the name of the application to execute, you provide an
agi://
URL. For example:
exten => 1234,1,AGI(agi://127.0.0.1)
The default port number for a FastAGI connection
is 4573
. A different port number can
be appended to the URL after a colon. For example:
exten => 1234,1,AGI(agi://127.0.0.1:4574)
Just as with process-based AGI, arguments can be
passed to a FastAGI application. To do so, add them as additional
arguments to the AGI()
application,
delimited by commas:
exten => 1234,1,AGI(agi://192.168.1.199,arg1
,arg2
,arg3
)
FastAGI also supports the usage of SRV records
if you provide a URL in the form of hagi://
. By using SRV records, you can list
multiple hosts that Asterisk can attempt to connect to for purposes of
high availability and load balancing. In the following example, to find
a FastAGI server to connect to, Asterisk will do a DNS lookup for
_agi._tcp.shifteight.org
:
exten => 1234,1,AGI(hagi://shifteight.org)
It’s more efficient than process-based AGI. Instead of spawning a process per call, a FastAGI server can handle many calls.
DNS can be used to achieve high availability and load balancing among FastAGI servers to further enhance scalability.
It is more complex to implement a FastAGI server than to implement a process-based AGI application. However, implementing a TCP server is something that has been done countless times before, so there are many examples available for virtually any programming language.
Async AGI is a newer method of using AGI that was first introduced in Asterisk 1.6.0. The purpose of async AGI is to allow an application that uses the Asterisk Manager Interface (AMI) to asynchronously queue up AGI commands to be executed on a channel. This can be especially useful if you are already making extensive use of the AMI and would like to take advantage of the same application to handle call control, as opposed to writing a detailed Asterisk dialplan or developing a separate FastAGI server.
More information on the Asterisk Manager Interface can be found in Chapter 20, Asterisk Manager Interface (AMI).
Async AGI is invoked by the AGI()
application in the Asterisk dialplan. The argument to
AGI()
should be agi:async
, as shown in the following
example:
exten => 1234,1,AGI(agi:async)
Additional information on how to use async AGI over the AMI can be found in the next section.
An existing AMI application can be used to control calls using AGI commands.
It is the most complex method of using AGI to implement.