Hack 94. Monitor Asterisk from Your Perl Scripts
If you've used Linux (or FreeBSD or Mac OS X or Solaris) for longer than an hour, chances are good you've used Perl. Now, use Perl to monitor and control your Asterisk PBX.
The Perl module of choice for Asterisk is appropriately called asterisk-perl. It provides connections between the Asterisk Gateway Interface (AGI) and the venerable scripting language named after a misspelled maritime phenomenon. It also links Perl with Asterisk's Manager interface, a socket application programming interface (API) that lets you control and monitor Asterisk by sending messages to it on a TCP port5038 to be exact.
For ad hoc interaction with the Asterisk Manager, you can telnet to that port on your Asterisk serverif the manager is enabled, that is. To ensure Asterisk Manager is indeed running and able to respond to your requests so that your Perl programs will actually do something once asterisk-perl is installed, you need to pay a visit to /etc/asterisk/manager.conf. Make it look roughly like this, being sure to include enabled=yes and to add a section like the [hansolo] one to define a username and password with which to access the Asterisk Manager later on:
; ; Asterisk Call Management support ; [general] enabled = yes port = 5038 bindaddr = 0.0.0.0 [hansolo] secret = falcon deny=0.0.0.0/0.0.0.0 permit=127.0.0.1/255.255.255.0 read = system,call,log,verbose,command,agent,user write = system,call,log,verbose,command,agent,user
You'll need to restart Asterisk (run asterisk rx as root at the shell prompt) to commit these config changes. Next, you'll need to install the Asterisk Perl module. Download, compile, and install it as follows:
# wget http://www.netdomination.org/mirror/asterisk.gnuinter.net/ \ files/asterisk-perl-0.08.tar.gz # tar xvzf asterisk-perl-0.08.tar.gz # cd asterisk-perl-0.08 # perl Makefile.PL # make all # make install
Now, pop into your asterisk-perl source directory and check out the Asterisk Manager example in the examples directory. It's called manager-test.pl, and it demonstrates how to poke Asterisk with Perl. For it to work, though, it will need to be authenticated as a legitimate Asterisk Manager API user, and that means adjusting the beginning of the script to match the username and password you put in /etc/asterisk/manager.conf. Open manager-test.pl and make the username and password match:
$astman->user('hansolo'); $astman->secret('falcon'); $astman->host('localhost');
localhost is used to specify the host that the Perl script will connect to in order to send messages to the Asterisk server; in this case, it'll connect to the same machine as the one where the script is running. Run the script like this:
If you place a call to any of the channels on the Asterisk server, the script will give you output like this, via its connection to Asterisk Manager:
Event: Newchannel Uniqueid: 1121992811.1 Callerid: <unknown> Channel: Zap/3-1 State: Ring Event: Newexten Channel: Zap/3-1 Context: default 1121992811.1: Extension: s Application: Answer appdata: Uniqueid Priority: 1 Event: Newstate Callerid: "Cleveland OH" <4403281441> Channel: Zap/3-1 State: Up Uniqueid: 1121992811.1
This output says that the Asterisk server has received a call from 440-328-1441 on channel Zap/3, assigned it a unique ID (for tracing it among the other Asterisk Manager output), and indicated that it is being handled by extension s (the default extension) in the default context. The State: Ring bit indicates that the channel is merely ringing and hasn't yet been answered. The Application: Answer line indicates that, in accordance with the dial plan in /etc/extensions.conf, this call is being handled by the Answer( ) command. Quite a lot of useful information for a short, simple Perl program.
Besides viewing status output (using the eventloop method of the Asterisk:: Manager class), you can also use the asterisk-perl Perl extensions to issue commands to Asterisk. Consider this simple Perl script:
#!/usr/bin/perl use lib './lib' '/..lib'; use Asterisk::Manager; my $astman = new Asterisk::Manager; $astman->user('hansolo'); $astman->secret('falcon'); $astman->host('localhost'); $astman->connect || die $astman->error . "\n"; print STDERR $astman->command('iax show peers');
The output of this script, at least on my Asterisk server, which has a single permanent IAX peer set up, looks like this:
Name/Username Host Mask Port Status mtech/199 220.127.116.11 (S) 255.255.255.255 4569 Unmonitored
Of course, with the command method of the Asterisk::Manager class, you can send any Asterisk console command and get its output. So, you can grab the whole dial plan using show dialplan or zaptel show channels to show all the current Zaptel activity on the system. Once you get that output, you've got to parse it. Otherwise, your Perl program won't be able to do much more than print it out. So I recommend that you brush up on those great Perl text-parsing functions.
If you're familiar with the Asterisk Manager API command structure, you can also send API commands, allowing you to originate phone calls, hang up and transfer calls in progress, and do other fun things. There's a nice Asterisk Manager API reference at the end of my book Switching to VoIP (O'Reilly). There nowyou have the tools to build an Asterisk empire using Perl and Perl alone. Go now, and conquer.