• Aucun résultat trouvé

Setting Up a FastAGI Server with Asterisk::FastAGI

Dans le document 436_XSS_FM.qxd 4/20/07 1:18 PM Page ii (Page 152-157)

Asterisk has a module called Asterisk::FastAGI that automates much of the setup pro-cess of an AGI server.Throughout this example, we will be referring to two servers:

the AGI server, which is the server that will be hosting the AGI script; and the Asterisk server, which will be handling the calls.

Starting with the AGI server, we must install Asterisk::FastAGI.The module is also available through CPAN, so you can grab it by running the following command either as root or as the user that Asterisk runs under:

perl -MCPAN -e 'install Asterisk::FastAGI'

This will run the CPAN module and install Asterisk::FastAGI.

Next, you need to create two files because of the way Asterisk::FastAGI is set up:

a perl module that will contain the code to execute when the request AGI request comes in, and the server itself.The first file you should create is the module file.

We’ll use the “example script” we’ve used repeatedly in this chapter, but recoded to support FastAGI. Place this anywhere on the AGI server:

#!/usr/bin/perl

# fastcallerid.pm – Code portion of the simple Asterisk::FastAGI example

# that reads back Caller ID

package AGIExample;

use base 'Asterisk::FastAGI';

sub say_callerid { my $self = shift;

my %input = $self->agi->ReadParse(); #Get the variables from Asterisk

$self->agi->stream_file('auth-thankyou'); # "Thank You"

$self->agi->say_digits($input{'callerid'}); # Say the phone number

$self->agi->hangup(); # hang up

}

return 1;

Next, create the server script:

#!/usr/bin/perl

# fastcallerid.pl – Server portion of the simple Asterisk::FastAGI example

# that reads back Caller ID

use AGIExample;

AGIExample->run();

Next, run the server script:

perl ReallyFastAGI.pl

This should print out text similar to the following:

2007/03/18-21:07:45 AGIExample (type Asterisk::FastAGI) starting!

pid(1014)

Port Not Defined. Defaulting to '20203' Binding to TCP port 20203 on host *

Group Not Defined. Defaulting to EGID '0 0' User Not Defined. Defaulting to EUID '0'

Pay attention to the port number, we’ll need that in the next step.

Next, switch back to your Asterisk server and open up your extensions.conf and add the following to the context you wish to make this script available to:

exten => 3278,n,AGI(agi://<AGI Server Address>:20203/say_callerid));

Make sure you replace <AGI Server Address> with the AGI server’s address. As always, you may want to alter the cutesy extension, 3278 (“FAST”), with something you like. Finally, open up the Asterisk CLI and issue a reload command.

After Asterisk reloads, dial up the extension and watch your console. Hopefully, you should hear your Caller ID being read back to you. Congratulations! You’re run-ning FastAGI!

This was obviously a trivial example, but FastAGI makes sense for applications that use heavy I/O or consume a lot of processor time. Rather than have an AGI script compete with Asterisk for CPU cycles, FastAGI lets you have a separate server handle the heavy processing while Asterisk handles the call load.

DeadAGI

DeadAGIs are AGIs that continue to function after the channel has hung up. As stated previously, Asterisk terminates the AGI when the HANGUP command is given or if the caller hangs up on the script, no questions asked. DeadAGIs continue to execute after the channel is in the Hung Up state.This is useful if you want to call the caller back at a number given to confirm it’s their number, or if you just want the script to do some additional cleanup before executing.

Using DeadAGI is easy. Let’s say we wanted to use the IMAP by Phone script as a DeadAGI rather than an AGI. We would simply replace the existing AGI command:

exten => 4627,n,AGI(imap.pl);

with the DeadAGI command:

exten => 4627,n,DeadAGI(imap.pl);

It’s that easy.

A word of warning, with DeadAGI, it is vitally important to make sure the script exits after a hang up, or else you may end up with processes waiting for a response that will never come, tying up server resources in the process.This can be an issue if you have a script that is used a lot.

EAGI

EAGI is identical to AGI, with the exception of an audio path on file descriptor 3.

This can be useful if you want to record people interacting with your script for usability studies or to make sure the script is functioning properly.

For example, if we wanted to be nosey and listen to everyone using IMAP by Phone, we would replace the AGI command:

exten => 4627,n,AGI(imap.pl);

with the EAGI command:

exten => 4627,n,EAGI(imap.pl);

Then adjust the code to read the audio to file descriptor 3.

Checklist

Make sure that if you are using the System() dial plan command, you have taken steps to mitigate the possible use of un-escaped data.

Make sure that remote AGI scripts are coming from a trusted source.

Summary

One of Asterisk’s greatest features is its ability to interact with other programs on the computer.This can be done in two main ways: through Asterisk’s System() dial plan command and the Asterisk Gateway Interface.

Calling external applications from the dial plan is a quick and easy way to cute another application for Asterisk.The problem is that once this program is exe-cuted, Asterisk can no longer interact with the script.This severely limits both

Asterisk’s and the script’s functionality, but is handy if you don’t need to interact with either application once it is executed.

The Asterisk Gateway Interface is a powerful yet simple system that allows scripts to interact with callers through Asterisk. AGI is controlled via the standard Unix file descriptors STDIN and STDOUT, so almost any programming language can use AGI. AGIs can play audio files, get data from the caller via the telephone keypad, and do many other things.There are numerous ways to interact with the caller, both on the input side and the output side. Callers can interact with the AGI script via the telephone keypad or by speech recognition, and the AGI script can interact with the caller via recordings or text-to-speech programs.

AGI has become popular enough that numerous third-party libraries are available for use that automate most of the repetitive tasks of AGI programming.This is advan-tageous to the programmer since they can focus more on developing the application rather than having to interface with Asterisk. Libraries are available for almost every popular language.Two of the more popular libraries are Asterisk::AGI for Perl and phpAGI for PHP.

There are three “special” Asterisk AGI commands: FastAGI, DeadAGI, and EAGI.

FastAGI lets you offload the AGI script onto a separate server and have Asterisk con-nect to it via a network concon-nection. DeadAGI allows an AGI script to continue functioning after the channel is hung up. EAGI is identical to AGI, except that all audio is on a special file descriptor that the script can read from.

Solutions Fast Track

Calling Programs from within the Dial Plan

Calling external programs from within the dial plan is the simplest way to execute a program using Asterisk.

Once the program is forked, there is no way to control the execution of the program or interact with it in any other way.

At one time, Asterisk had numerous add-ons that let you embed various programming languages directly in the dial plan; however, they do not support the newer versions of Asterisk.

Using the Asterisk Gateway Interface

AGI lets Asterisk hand off the user to a script that will take control of playing prompts, listen for input, and do all the jobs the dial plan usually handles.

AGI is supported by any programming language that can handle STDIN and STDOUT.

In normal AGI operation, once a channel is hung up, the script will be terminated.

You can get input from your caller to your script in two ways: Interactive Voice Response menus and Speech recognition. IVR menus are much easier to implement, but often have usability issues. Speech recognition is harder and will cost extra; however, it is generally easier to use from the user’s standpoint.

You can get output from your script to your users in two ways as well:

recordings and text to speech. Recordings sound better, but are fairly limited as to what they can say.Text to speech can sound less life-like, but it can say text that is dynamic.

Dans le document 436_XSS_FM.qxd 4/20/07 1:18 PM Page ii (Page 152-157)