Asterisk FastAGI with PHP

Lately I’ve been involved in some work projects related to Asterisk.
I had the opportunity to play with the Asterisk Gateway Interface (AGI) to see what can be done with it.

In a few words, it allows you to execute scripts on an action (eg: a user calling an extension), that will interact with other systems (eg: retrieve information from a database and store other input data) and trigger other actions.

First of all, given that I’m more familiar with PHP than Perl, I looked around for libraries that can interact with my loved PHP.
You can get a lot of useful information at http://voip-info.org, being more specific at: http://www.voip-info.org/wiki/view/Asterisk+AGI
This will help you understand what can and cannot be done…

I used one of our company (Fonality Australia) trixbox Pro test systems for playing around with this.
What I was interested on, was specifically the FastAGI. Basically call remote agi scripts that communicate with your Asterisk system via tcp sockets (more info here).

This is interesting because it allows you to install software in your remote machine, without exposing your trixbox appliance to new software (even unsupported one).

First of all I’ve installed the phpagi library (that can be found on sourceforge at http://phpagi.sourceforge.net/) and had a look at the code.
The server side part (so the one that the trixbox system will call in the next steps) will execute as a deamon with the aid of xinetd on your linux box.
In my case xinetd wasn’t installed, and in a Debian flavoured linux distribution you can easily install it with “sudo apt-get install xinetd”, and of course you can get more info about xinetd at http://xinetd.org.

You can get more info on how all the the super server system is structured in the wikipedia inetd page here

Of course you have to make sure you have a working command line php server on your linux box (for Debian flavour: sudo apt-get install php5-cli) and test it running a command line script (php -f file.php).

As a first step of the installation of the library you need to unzip it somewhere in your linux box and that path will be from now on _PHP_LIBRARY_PATH
You need to list the server port inside the services list (/etc/services). So at the bottom add the line “fastagi 4573/tcp”.
And then to add a config entry inside /etc/xinetd.d/fastagi.
For testing I’ve entered as follows:

service fastagi
{
socket_type = stream
user = test
group = test
server = _PHP_LIBRARY_PATH/phpagi-fastagi.php
wait = no
protocol = tcp
disable = no
}

After restarting xinetd, our server side is ready to go and will accept requests from external IPs.
Just for being safe, I would ssh on a remote machine and see if we can telnet into the port of our FastAGI server and see if the server is listening (telnet IP_ADDRESS 4573).
All good? Let’s go.

Now we create a sample agi script. I will write the php file at _PHP_LIBRARY_PATH/sample.php
with just this as a content:

<?php
$fastagi->verbose('cool, the FastAGI server has been called!');
?>

Now we go inside our nice little trixbox menu interface and we add an agi script entry on the trixbox call menu with this syntax: agi://agi_server_ip_address/sample.php and save.

We can now ssh inside our trixbox box (or whatever asterisk based system you have) and access the asterisk cli interface with “asterisk -r” and enable the agi debugging with “agi debug”.

Now you can try to call your trixbox, and when you will reach the right menu steps you are calling the AGI script with… you will see the command sent from the php library to your Asterisk system!

Now you can have a play with the library and easily extend your phone system with new fancy features!
Using the instance of the AGI object $fastagi you can call any method of the phpagi library, listed and explained in here

You can do a lot of other fancy stuff with AGI, like communicating via soap with other systems, accessing data, saving data, recording messages, playing messages, read and play DTMF tones, even read new messages with text to speech libraries and the other way around!

I guess there is no limit to the possibility it can give to your phone system!

See you next!

17 thoughts on “Asterisk FastAGI with PHP

  1. You can read the fastagi library’s manual.
    You should use fastpass_get_data() or get_data().
    Let me know how that goes…

  2. Great Post!!! However, i was setting up the server and apparently it is up and running. Then i called the test script you mentioned but for some reason it’s not running. I used lsof -n-i-P to check my xinet service. which is running fine. I telnet from another machine it says

    connected to —–
    Escape character is ‘^]’.
    connection closed by foreign host.

    Also i ran the phpagi-fastagi.php script manually and it gave an error:
    PHP Fatal error: require_once(): Failed opening required ‘/var/lib/asterisk/agi-bin/phpagi/’ (include_path=’.:/usr/share/pear:/usr/share/php’) in /var/lib/asterisk/agi-bin/phpagi/phpagi-fastagi.php on line 78

    Now i am a bit confused that if there is an error in my php script then why is it running fine as a service. Can you please help me troubleshoot it ?? Many thanks in advance !!!

  3. Mustafa, it is actually pretty hard for me to debug your issue.

    I do not understand why your phpagi-fastagi.php would require /var/lib/asterisk/agi-bin/phpagi/…
    Is that something you configured somewhere?

    Did you try to create the sample.php as described?
    And did you try calling the sample.php from your call script menu inside your asterisk instance?

    I would suggest you to try again the whole setup, following my post step by step.

    Cheers

  4. Mustafa, did you ever get this resolved? I’m having the same issue and can’t find an answer anywhere.

    Jazak!

    Travis

  5. Hi Travis – Unfortunately i didn’t get to further explore the realm of PHP :s instead i had been working on C# to implement IVR. But hopefully i do plan to explore it later. Sorry mate i couldn’t help you :s

    Mustafa

  6. Hi Travis – I was able to resolve the issue of running phpagi-fastagi.php manually by copying following files in the same folder as phpagi-fastagi.php
    – phpagi.php
    – phpagi-asmanager.php

    Enrico i have created the sample.php file as you suggested and tried calling it through asterisk dialplan but it’s not working. Can you please help me trouble shoot it?

    Mustafa

  7. Hi Mustafa,

    As I said, there are so many combinations that can go wrong with this configuration, maybe it is even because I used another version of the software (both php and fastagi php library) when the article was written 3 years ago.

    Did you try posting a question on the phpagi website, stating your configuration options? I would probably start from there, given that probably the versions I used at the time are different from the current ones.

    Also, as mentioned on the blog post, did you try connecting on the fastagi port from the remote asterisk server via telnet to see if the port is open and the initd server responding? Does it work?
    If it does not, try following the packets with tcpdump and try to guess where the problem is.
    If it works, did you run “agi debug” on the asterisk command line and see if you receive the message on asterisks when calling the phpagi script from the dialplan?
    If you get the message on the debug window, everything is working and you are good to go and ready to start coding your AGI script.

  8. Hi,

    Followed everything… but when i try to call and AGI call is made, i get

    xinetd[15712] : execv( /home/phpagi/phpagi-fastagi.php ) failed: No such file or directory (errno = 2)

    on remote server where AGI script is placed. have also rechecked PATH millions of time.
    i have changed server = /home/phpagi/phpagi-fastagi.php in /etc/xinetd.d/fastagi

    Any help on it?

  9. Hi Mehroz – Its seems like you have gone a step further than i did. And i was hoping if you can help. I have successfully able:
    – Define port in \etc\services
    – create fastagi php file from sample fastagi.xinetd inside \etc\xinetd.d\fastagi
    – Re started the xinetd service
    i used chkconfig –list command to confirm fast agi service is running. but when i do nmap -p t:4573, i don’t get anything. As if the service isn’t running. Can you please suggest what am i doing wrong?

    Thanks
    Mustafa

  10. i am using ngrep to monitor packets , like
    ngrep -W byline port 4573
    ___

    I can see AGIs requets passed on to remote server, but not in progress above that,
    Try this , and check in your dial plan how the script is being called, like
    exten => _X,1,AGI(agi://IP_ADDRESS:4573)

    Try mentioning port explicitly

  11. Mehroz it looks like you are really close!
    Did you change on the fastagi configuration the user and the group settings? Above they are using the user and group “test”.
    Also, if you check the permissions on the file “ls -la /home/phpagi/phpagi-fastagi.php” does the “test” user and group have permissions to read the file? Does the file exist?

  12. Hi, Thanks for the great post.
    There is a question, How do you setup a service to call multiple AGI scripts?
    i,e. only defining
    server = /home/phpagi/

    this directory(/home/phpagi/) should have other AGI scripts too, and You shoud be able to invoke them like
    exten => 100,1,AGI(agi://IP_ADDRESS/first.php)
    exten => 200,1,AGI(agi://IP_ADDRESS/second.php)
    ….

    I have tried this this scenario but xinetd cannot understand that and gives:
    xinetd[24520]: execv( /home/phpagi/) failed: Permission denied (errno = 13)
    _______

    It works fine when i explicitly mentioned script like
    server = /home/phpagi/sample.php

  13. Hi Mehroz,
    To be fair I’ve never tried, but if I had to try I would test two approaches at first:
    1 – Try to see if you can pass a variable somehow to the xinetd server (php files) from the phone system server (Asterisk), to define which action to execute
    2 – If you have a limited set of files (eg: only two or three actions) you could try as well to launch multiple servers listening to different ports, each of them pointing to a different file

    Maybe there are other possibilities as well…
    I’m not sure any of the above hints are actually doable, but give it a go and let me know, so that other people that read this post, will be able to solve the same isses!

    As a third option, I came across an open source socket server based on php that you could use instead of xinetd? Maybe it is worth while to have a look at it if you plan to develop a full on project… The url of the Google code project is: https://code.google.com/p/phpsocketdaemon/

    Also, if you are open at alternative solutions you could have a look at http://code.google.com/p/agispeedy/ as well… I’ve never used it, but it seems interesting.

    Cheers

  14. I don’t know you need solution now, but i will write the solution to error “execv( /home/phpagi/) failed: Permission denied (errno = 13)” here.

    If you edit your file phpagi-fastagi.php, you can see command interpreter php like:

    #!/usr/local/bin/php -q

    You can search your php commando with: “which php”

    In my case was in /usr/bin/php

    I changed path in phpagi-fastagi.php and all was fine.

Leave a Comment