The AGI Hello-World program



The AGI Hello-World program

Just as with any other programming language, we shall begin our journey with a simple “Hello-World” AGI script.

In order to make our life easier, we shall use an astRead function and an astWrite function that will help us read and write information, to and from Asterisk in a more efficient manner.

function astRead() 
{ 
   global $stdin, $debug, $stdlog; 
   $input = str_replace("\n", "", fgets($stdin, 4096)); 
   if ($debug) fputs($stdlog, "read: $input\n"); 
   return $input; 
} 

function astWrite($agiCommand) 
{ 
   global $debug, $stdlog; 
   if ($debug) fputs($stdlog, "write: $agiCommand\n"); 
   echo $agiCommand."\n"; 
}

The astRead function reads information from a global variable, indicated by the $in variable. The $in variable will simply indicate our STDIN stream. The astWrite function writes its $agiCommand directly to STDOUT, simply passing the AGI command directly to Asterisk.

Let’s combine everything together:

#!/usr/bin/php -q 
<?
   ob_implicit_flush(false); 
   set_time_limit(6);

   $stdin = fopen(‘php://stdin’, ‘r’);
   $stdlog = fopen(‘my_agi.log’, ‘w’);

   $debug = false;

   /* Read input from Asterisk and output via $astOutput */
   function astRead() 
   { 
	  global $stdin, $debug, $stdlog; 
      $astOutput = str_replace("\n", "", fgets($stdin, 4096)); 
      if ($debug) fputs($stdlog, "read: $input\n"); 
      return $astOutput ; 
   } 

 
   /* Write AGI command to Asterisk */
   function astWrite($agiCommand) 
   { 
      global $debug, $stdlog; 
      if ($debug) fputs($stdlog, "write: $agiCommand\n"); 
      echo $agiCommand."\n"; 
   }

   /* Handling execution input from Asterisk */

   while (!feof($stdin)) 
   { 
  	 $temp = fgets($stdin); 
  	 $temp = str_replace("\n","",$temp); 
  	 $s = explode(":",$temp); 
  	 $agivar[$s[0]] = trim($s[1]); 
  	 if ($temp == "")  
      { 
    	break; 
  	} 
   }

   /* Operational Code starts here */

   ..
   ..
   ..


   /* Finalization of AGI script and clean-ups */

   fclose ($stdin);
   fclose ($stdlog);
   exit(0);

?>

The above code snippet will form our basic AGI script construct. We’ve now defined our stream handling functions and our Asterisk input execution handling, as we get ready to start our first AGI script.

Our first script will make use of the AGI command STREAM FILE. Another command that we shall use will be SAY NUMBER.

/* Operational Code starts here */

/* Playback the demo-congrats.gsm file from the
 * directory /var/lib/asterisk/sounds/ 
 */

astWrite("STREAM FILE demo-congrats #");
astRead();

/* Say the number 123456 */
astWrite("SAY NUMBER 123456 #");
astRead();

This AGI code performs a fairly simplistic function—upon execution, it plays back the demo-congrats.gsm file, followed by the number 123456. Ok, that’s simple enough; so let’s put everything together:

File: helloworld.php

#!/usr/bin/php -q 
<?
   ob_implicit_flush(false); 
   set_time_limit(6);

   $stdin = fopen(‘php://stdin’, ‘r’);
   $stdlog = fopen(‘my_agi.log’, ‘w’);

   $debug = false;

   /* Read input from Asterisk and output via $astOutput */
   function astRead() 
   { 
	 global $stdin, $debug, $stdlog; 
      $astOutput = str_replace("\n", "", fgets($stdin, 4096)); 
      if ($debug) fputs($stdlog, "read: $input\n"); 
      return $astOutput ; 
   } 

 
   /* Write AGI command to Asterisk */
   function astWrite($agiCommand) 
   { 
      global $debug, $stdlog; 
      if ($debug) fputs($stdlog, "write: $agiCommand\n"); 
      echo $agiCommand."\n"; 
   }

   /* Handling execution input from Asterisk */
   $agivar = array();
   while (!feof($stdin)) 
   { 
  	 $temp = fgets($stdin); 
  	 $temp = str_replace("\n","",$temp); 
  	 $s = explode(":",$temp); 
  	 $agivar[$s[0]] = trim($s[1]); 
  	 if ($temp == "")  
     { 
    	break; 
  	} 
   }

   /* Operational Code starts here */

   /* Playback the demo-congrats.gsm file from the
    * directory /var/lib/asterisk/sounds/ 
    */

   astWrite("STREAM FILE demo-congrats #");
   astRead();

   /* Say the number 123456 */
   astWrite("SAY NUMBER 123456 #");
   astRead();

   /* Finalization of AGI script and clean-ups */

   fclose ($stdin);
   fclose ($stdlog);
   exit(0);

?>

In order to execute our AGI script, we are required to define an extension in our extensions.conf configuration file, and indicate the execution of our script from there. The following is an extract from the”default” context of my Asterisk server. You may insert these into any other context or extension, depending on your Asterisk server configuration:

exten => 999,1,Answer
exten => 999,n,Wait(0.5)
exten => 999,n,AGI(helloworld.php)
exten => 999,n,Hangup()

This code snippet will add a new extension named 999 to your dialplan. When this extension is dialed, your AGI script will be invoked. As your script is executed, the following can be observed on the Asterisk CLI console:

Note that as your AGI script is being executed, the only thing you will see on the CLI is the result of the AGI command, and not the actual execution of the AGI script. Also note that CLI output may vary, depending on your configuration.

AGI debugging

Asterisk provides a means of debugging AGI Scripts as these are executed. In order to use the AGI debugger, you need to have access to Asterisk’s CLI interface, and issue the following command:

agi debug

As your script is executed with debug mode enabled, your CLI output would look like this:

As you can see, the example in the preceding screenshot shows the full execution of the AGI script, including the initial information sent from Asterisk to the AGI script. Information traversing from Asterisk to our AGI script is prefixed with the AGI Tx >> marking, while information from our AGI script to Asterisk is prefixed with the AGI Rx >> marking. Although this may look weird, it is perfectly logical when examined from Asterisk’s point-of-view.

Advertisements
%d bloggers like this: