Source for file phpagi_1.php

Documentation is available at phpagi_1.php

  1. <?php
  2. /**
  3.   * phpagi-asmanager.php : PHP Asterisk Manager functions
  4.   * Website: http://phpagi.sourceforge.net
  5.   *
  6.   * $Id: phpagi_1.php,v 1.1 2005/05/27 00:03:18 masham Exp $
  7.   *
  8.   * Copyright (c) 2004, 2005 Matthew Asham <matthewa@bcwireless.net>, David Eder <david@eder.us>
  9.   * All Rights Reserved.
  10.   *
  11.   * This software is released under the terms of the GNU Lesser General Public License v2.1
  12.   *  A copy of which is available from http://www.gnu.org/copyleft/lesser.html
  13.   *
  14.   * We would be happy to list your phpagi based application on the phpagi
  15.   * website.  Drop me an Email if you'd like us to list your program.
  16.   *
  17.   * @package phpAGI
  18.   * @version 2.0
  19.   */
  20.  
  21.  
  22.  /**
  23.   * Written for PHP 4.3.4, should work with older PHP 4.x versions.
  24.   * Please submit bug reports, patches, etc to http://sourceforge.net/projects/phpagi/
  25.   * Gracias. :)
  26.   *
  27.   */
  28.  
  29.   if(!class_exists('AGI'))
  30.   {
  31.     require_once(dirname(__FILE__DIRECTORY_SEPARATOR 'phpagi.php');
  32.   }
  33.  
  34.  /**
  35.   * Asterisk Manager class
  36.   *
  37.   * @link http://www.voip-info.org/wiki-Asterisk+config+manager.conf
  38.   * @link http://www.voip-info.org/wiki-Asterisk+manager+API
  39.   * @example examples/sip_show_peer.php Get information about a sip peer
  40.   * @package phpAGI
  41.   */
  42.   class AGI_1 extends AGI
  43.   {
  44.    /**
  45.     * Response structure
  46.     *
  47.     * array('code'=>$code, 'result'=>$result, 'data'=>$data)
  48.     *
  49.     * @var array 
  50.     * @access public
  51.     */
  52.     var $response;
  53.  
  54.    /**
  55.     * Constructor
  56.     *
  57.     * @param string $config is the name of the config file to parse
  58.     * @param array $optconfig is an array of configuration vars and vals, stuffed into $this->config['phpagi']
  59.     */
  60.     function AGI_1($config=false$optconfig=false)
  61.     {
  62.       if(!$config$config NULL;
  63.       if(!$optconfig$optconfig array();
  64.       parent::AGI($config$optconfig);
  65.     }
  66.  
  67.    /**
  68.     * Evaluate an AGI command
  69.     *
  70.     * @access private
  71.     * @param string $command 
  72.     * @return array ('code'=>$code, 'result'=>$result, 'data'=>$data)
  73.     */
  74.     function evalutate($command)
  75.     {
  76.       $this->response = parent::evalute($command);
  77.       return $this->response;
  78.     }
  79.  
  80.    /**
  81.     * Execute an AGI command
  82.     *
  83.     * @access private
  84.     * @param string $str 
  85.     * @return array ('code'=>$code, 'result'=>$result, 'data'=>$data)
  86.     */
  87.     function agi_exec($str)
  88.     {
  89.       return $this->evaluate($str);
  90.     }
  91.  
  92.    /**
  93.     * Check for error in result structure
  94.     *
  95.     * @param array $retarr 
  96.     * @return boolean true on error
  97.     */
  98.     function agi_is_error($retarr)
  99.     {
  100.       // Returns TRUE if the command returned an error.
  101.  
  102.       if($retarr['code'!= AGIRES_OK)
  103.       {
  104.         $this->conlog("DEBUG:  Bad command?  Returned code is {$retarr['code']} result={$retarr['result']}");
  105.         return true;
  106.       }
  107.  
  108.       if(!isset($retarr['result']))
  109.       {
  110.         $this->conlog("DEBUG:  No 'result' value returned from asterisk!  Eww!");
  111.         return true;
  112.       }
  113.  
  114.       if($retarr['result'== -1)
  115.         return true;
  116.  
  117.       return false;
  118.     }
  119.  
  120.    /**
  121.     * Read the result from Asterisk
  122.     *
  123.     * @return array 
  124.     */
  125.     function agi_readresult()
  126.     {
  127.       return $this->response;
  128.     }
  129.  
  130.    /**
  131.     * Sends $message to the Asterisk console via the 'verbose' message system.
  132.     *
  133.     * If the Asterisk verbosity level is $vbl or greater, send $str to the console.
  134.     *
  135.     * The Asterisk verbosity system works as follows. The Asterisk user gets to set the desired verbosity at startup time or later
  136.     * using the console 'set verbose' command. Messages are displayed on the console if their verbose level is less than or equal
  137.     * to desired verbosity set by the user. More important messages should have a low verbose level; less important messages
  138.     * should have a high verbose level.
  139.     *
  140.     * @link http://www.voip-info.org/wiki-verbose
  141.     * @param string $str 
  142.     * @param integer $vbl from 1 to 4
  143.     */
  144.     function agi_verbose($str$vbl=1)
  145.     {
  146.       $this->verbose($str$vbl);
  147.     }
  148.  
  149.    /**
  150.     * Get the response code from the last command
  151.     *
  152.     * @return integer 
  153.     */
  154.     function agi_response_code()
  155.     {
  156.       return $this->response['code'];
  157.     }
  158.  
  159.    /**
  160.     * Get the result code from the last command
  161.     *
  162.     * @return integer 
  163.     */
  164.     function agi_response_result()
  165.     {
  166.       $this->conlog("result is {$this->response['result']}");
  167.       return $this->response['result'];
  168.     }
  169.  
  170.    /**
  171.     * Get the response data from the last command
  172.     *
  173.     * @return string 
  174.     */
  175.     function agi_response_data()
  176.     {
  177.       return $this->response['data'];
  178.     }
  179.  
  180.    /**
  181.     * Get the response variable from the last command
  182.     *
  183.     * @param string $var 
  184.     * @return mixed 
  185.     */
  186.     function agi_response_var($var)
  187.     {
  188.       if(!isset($this->response[$var]))
  189.         return false;
  190.       return $this->response[$var];
  191.     }
  192.  
  193.    /**
  194.     * Check for error in response
  195.     *
  196.     * @return boolean true on error
  197.     */
  198.     function agi_response_is_error()
  199.     {
  200.       return $this->agi_is_error($this->response);
  201.     }
  202.  
  203.    /**
  204.     * Log to console if debug mode
  205.     *
  206.     * @param array $arr to print
  207.     * @param string $label 
  208.     * @param integer $vbl verbose level
  209.     */
  210.     function con_print_r($arr$label=''$lvl=0)
  211.     {
  212.       if($lvl == && $label != '')
  213.         $this->conlog("debug: $label");
  214.  
  215.       $this->conlog(print_r($arrtrue)$lvl);
  216.     }
  217.  
  218.  
  219.    /**
  220.     * Plays the given file and receives DTMF data.
  221.     *
  222.     * This is similar to STREAM FILE, but this command can accept and return many DTMF digits,
  223.     * while STREAM FILE returns immediately after the first DTMF digit is detected.
  224.     *
  225.     * Asterisk looks for the file to play in /var/lib/asterisk/sounds by default.
  226.     *
  227.     * If the user doesn't press any keys when the message plays, there is $timeout milliseconds
  228.     * of silence then the command ends.
  229.     *
  230.     * The user has the opportunity to press a key at any time during the message or the
  231.     * post-message silence. If the user presses a key while the message is playing, the
  232.     * message stops playing. When the first key is pressed a timer starts counting for
  233.     * $timeout milliseconds. Every time the user presses another key the timer is restarted.
  234.     * The command ends when the counter goes to zero or the maximum number of digits is entered,
  235.     * whichever happens first.
  236.     *
  237.     * Pressing the # key has the same effect as the timer running out: the command ends and
  238.     * any previously keyed digits are returned. A side effect of this is that there is no
  239.     * way to read a # key using this command.
  240.     *
  241.     * @link http://www.voip-info.org/wiki-get+data
  242.     * @param integer $len number of digits to read
  243.     * @param integer $timeout milliseconds
  244.     * @param string $terminator character on which to quit
  245.     * @param string $prompt file to play. Do not include file extension.
  246.     * @return array of characters
  247.     */
  248.     function agi_getdtmf($len$timeout$terminator=false$prompt=false)
  249.     {
  250.       if($prompt)
  251.       {
  252.         if(!is_array($prompt)) $prompt array($prompt);
  253.  
  254.         foreach($prompt as $p)
  255.         {
  256.           if($p[0== '$')
  257.           {
  258.             $this->text2wav(substr($p1));
  259.           }
  260.           else
  261.           {
  262.             $this->stream_file($p'#');
  263.           }                
  264.         }
  265.       }
  266.  
  267.       $ret array();
  268.       for($i 0$i $len$i++)
  269.       {
  270.         $res $this->wait_for_digit($timeout);
  271.         $this->con_print_r($res);
  272.         if($this->agi_response_is_error())
  273.         {
  274.           $this->conlog('error?');
  275.       return false;
  276.         }
  277.         $ch chr($res['result']);
  278.         $this->conlog("got $ch");
  279.         if($terminator && $ch == $terminator)
  280.       return $ret;
  281.  
  282.         $ret[$i$ch;
  283.       }
  284.       return($ret);
  285.     }
  286.  
  287.    /**
  288.     * Read $len characters as DTMF codes
  289.     *
  290.     * @param integer $len 
  291.     * @return string 
  292.     */
  293.     function agi_dtmf2text($len)
  294.     {
  295.       $numbers=array('1'=>'1''2'=>'2abc''3'=>'3def''4'=>'4ghi''5'=>'5jkl''6'=>'6mno',
  296.                      '7'=>'7pqrs''8'=>'8tuv''9'=>'9wxyz''0'=>'0');
  297.  
  298.       $last false;
  299.       $i $times 0;
  300.       $abort 0;
  301.  
  302.       $char '';
  303.       do
  304.       {
  305.         $res $this->agi_getdtmf(14000);
  306.         $res $res[0];
  307.  
  308.         if($res == falsebreak;
  309.  
  310.         if($last == false)
  311.           $last $res;
  312.         elseif($last != $res || $res == false)
  313.         {
  314.           $ret[$i$char;
  315.           $this->conlog("Character $i is $char");
  316. //          $this->text2wav($char);                    
  317.           $times 0;
  318.           $i++;
  319.         }
  320.  
  321.         $char $numbers[$res][$times++];
  322.         $this->conlog("Number $res is '$char'");
  323.  
  324.         if(strlen($numbers[$res]== $times$times 0;
  325.  
  326.         $last $res;
  327.       while($i $len && !$abort);
  328.  
  329.       $str '';
  330.       foreach($ret as $k$str .= $k ' ';
  331.  
  332.       $this->text2wav($str);
  333.       return($str);
  334.     }    
  335.  
  336.    /**
  337.     * Alias of PHP join function
  338.     *
  339.     * @param array $arr 
  340.     * @return string 
  341.     */
  342.     function arr2str($arr)
  343.     {
  344.       return trim(join(' '$arr));
  345.     }
  346.  
  347.    /**
  348.     * Retrieves an entry in the Asterisk database for a given family and key.
  349.     *
  350.     * @link http://www.voip-info.org/wiki-database+get
  351.     * @param string $family 
  352.     * @param string $key 
  353.     * @return string 
  354.     */
  355.     function db_get($family$key)
  356.     {
  357.       $res $this->database_get($family$key);
  358.       if($res['code'!= AGIRES_OK || $res['result'== 0return false;
  359.       return $res['data'];
  360.     }
  361.  
  362.    /**
  363.     * Adds or updates an entry in the Asterisk database for a given family, key, and value.
  364.     *
  365.     * @param string $family 
  366.     * @param string $key 
  367.     * @param string $val 
  368.     * @return integer result code
  369.     */
  370.     function db_put($family$key$val)
  371.     {
  372.       $res $this->database_put($family$key$val);
  373.       return $res['code'];
  374.     }
  375.  
  376.    /**
  377.     * Deletes an entry in the Asterisk database for a given family and key.
  378.     *
  379.     * @link http://www.voip-info.org/wiki-database+del
  380.     * @param string $family 
  381.     * @param string $key 
  382.     * @return integer result code
  383.     */
  384.     function db_del($family$key)
  385.     {
  386.       $res $this->database_del($family$key);
  387.       return $res['code'];
  388.     }
  389.  
  390.    /**
  391.     * Fetch the value of a variable.
  392.     *
  393.     * Does not work with global variables. Does not work with some variables that are generated by modules.
  394.     *
  395.     * @link http://www.voip-info.org/wiki-get+variable
  396.     * @link http://www.voip-info.org/wiki-Asterisk+variables
  397.     * @param string $var variable name
  398.     * @return string 
  399.     */
  400.     function get_var($var)
  401.     {
  402.       $res $this->get_variable($var);
  403.       if($res['code'!= AGIRES_OK || $res['result'== 0return false;
  404.       return $res['data'];
  405.     }
  406.  
  407.    /**
  408.     * Sets a variable to the specified value. The variables so created can later be used by later using ${<variablename>}
  409.     * in the dialplan.
  410.     *
  411.     * These variables live in the channel Asterisk creates when you pickup a phone and as such they are both local and temporary.
  412.     * Variables created in one channel can not be accessed by another channel. When you hang up the phone, the channel is deleted
  413.     * and any variables in that channel are deleted as well.
  414.     *
  415.     * @link http://www.voip-info.org/wiki-set+variable
  416.     * @param string $var is case sensitive
  417.     * @param string $val 
  418.     * @return integer result code
  419.     */
  420.     function set_var($var$val)
  421.     {
  422.       $res $this->set_variable($var$val);
  423.       return $res['code'];
  424.     }
  425.  
  426.    /**
  427.     * Hangup the current channel.
  428.     *
  429.     * @link http://www.voip-info.org/wiki-hangup
  430.     * @param string $channel 
  431.     */
  432.     function agi_hangup()
  433.     {
  434.       $this->hangup();
  435.     }
  436.  
  437.    /**
  438.     * Get the status of the specified channel.
  439.     *
  440.     * @link http://www.voip-info.org/wiki-channel+status
  441.     * @param string $channel 
  442.     * @return array, ('status'=>$res['result'], 'description'=>$res['data'])
  443.     */
  444.     function agi_channel_status($channel)
  445.     {
  446.       $res $this->channel_status($channel);
  447.       return array('status'=>$res['result']'description'=>$res['data']);
  448.     }
  449.  
  450.    /**
  451.     * Record sound to a file until an acceptable DTMF digit is received or a specified amount of
  452.     * time has passed. Optionally the file BEEP is played before recording begins.
  453.     *
  454.     * @link http://www.voip-info.org/wiki-record+file
  455.     * @param string $file to record, without extension, often created in /var/lib/asterisk/sounds
  456.     * @param string $format of the file. GSM and WAV are commonly used formats. MP3 is read-only and thus cannot be used.
  457.     * @param integer $timeout is the maximum record time in milliseconds, or -1 for no timeout.
  458.     * @param string $prompt to play
  459.     */
  460.     function agi_recordfile($file$format$timeout=5000$prompt=FALSE)
  461.     {
  462.       if($prompt$this->stream_file($prompt);
  463.       $this->record_file($file$format'#'$timeouttrue);
  464.     }
  465.  
  466.    /**
  467.     * Play the given audio file, allowing playback to be interrupted by a #. This command is similar to the GET DATA
  468.     * command but this command returns after the first DTMF digit has been pressed while GET DATA can accumulated any number of
  469.     * digits before returning.
  470.     *
  471.     * @link http://www.voip-info.org/wiki-stream+file
  472.     * @param string $file filename without extension, often in /var/lib/asterisk/sounds
  473.     */
  474.     function agi_play($file)
  475.     {
  476.       $this->stream_file($file'#');
  477.     }
  478.  
  479.    /**
  480.     * Goto - Set context, extension and priority
  481.     *
  482.     * @param string $con context
  483.     * @param string $ext extension
  484.     * @param string $pri priority
  485.     */
  486.     function agi_goto($con,$ext='s',$pri=1)
  487.     {
  488.       $this->goto($con$ext$pri);
  489.     }
  490.  
  491.    /**
  492.     * Say the given digit string, returning early if # is received on the channel.
  493.     *
  494.     * @link http://www.voip-info.org/wiki-say+digits
  495.     * @param integer $digits 
  496.     */
  497.     function agi_saydigits($digits)
  498.     {
  499.       $this->say_digits($digits'#');
  500.     }
  501.  
  502.    /**
  503.     * Say the given number, returning early if # is received on the channel.
  504.     *
  505.     * @link http://www.voip-info.org/wiki-say+number
  506.     * @param integer $number 
  507.     */
  508.     function agi_saynumber($number)
  509.     {
  510.       $this->say_number($number'#');
  511.     }
  512.  
  513.    /**
  514.     * Say a given time, returning early if # is received on the channel.
  515.     *
  516.     * @link http://www.voip-info.org/wiki-say+time
  517.     * @param integer $time number of seconds elapsed since 00:00:00 on January 1, 1970, Coordinated Universal Time (UTC).
  518.     */
  519.     function agi_saytime($time='')
  520.     {
  521.       if($time == ''$time time();
  522.       $this->say_time($time'#');
  523.     }
  524.  
  525.    /**
  526.     * Set Language
  527.     *
  528.     * @param string $language code
  529.     */
  530.     function agi_setlanguage($language='en')
  531.     {
  532.       $this->exec_setlanguage($language);
  533.     }
  534.  
  535.    /**
  536.     * Perform enum lookup
  537.     *
  538.     * @param string $telnumber 
  539.     * @param string $rDNS 
  540.     * @return array 
  541.     */
  542.     function enum_lookup($telnumber$rDNS='e164.org')
  543.     {
  544.       // returns a sorted array of enum records 
  545.  
  546.       if($telnumber[0== '+')
  547.         $telnumber substr($telnumber1);
  548.  
  549.       for($i 0$i strlen($telnumber)$i++)
  550.         $rDNS $telnumber[$i'.' $rDNS;
  551.  
  552.       if(!isset($this->config['phpagi']['dig'])) $this->config['phpagi']['dig'$this->which('dig');
  553.       $dig=trim($this->config['phpagi']['dig']);
  554.  
  555.       $execstr$dig " +short " escapeshellarg($rDNS" NAPTR";
  556.       $lines trim(`$execstr`);
  557.  
  558.       $lines explode("\n"$lines);
  559.       $arr array();
  560.       foreach($lines as $line)
  561.       {
  562.         $line trim($line);
  563.         $line str_replace("\t"' '$line);
  564.         while(strstr($line'  '))
  565.           $line str_replace('  '' '$line);
  566.         $line str_replace("\""''$line);
  567.         $line str_replace("\'"''$line);
  568.         $line str_replace(' ''|'$line);
  569.         $bits explode('|'$line);
  570.         $bit explode('!'stripslashes($bits[4]));
  571.         $URI @ereg_replace($bit[1]$bit[2]'+' $telnumber);
  572.         if($URI[3== ':'$URI[3'/';
  573.         if($URI[4== ':'$URI[4'/';
  574.         $arr[array('order'=>$bits[0]'prio'=>$bits[1]'tech'=>$bits[3]'URI'=>$URI);
  575.       }
  576.  
  577.       foreach($arr as $key=>$row)
  578.       {
  579.         $order[$key$row['order'];
  580.         $prio[$key$row['prio'];
  581.       }
  582.  
  583.       array_multisort($orderSORT_ASC$prioSORT_ASC$arr);
  584.       return($arr);
  585.     }
  586.  
  587.    /**
  588.     * Perform enum txt lookup
  589.     *
  590.     * @param string $telnumber 
  591.     * @param string $rDNS 
  592.     * @return string 
  593.     */
  594.     function enum_txtlookup($telnumber$rDNS='e164.org')
  595.     {
  596.       // returns the contents of a TXT record associated with an ENUM dns record.
  597.       // ala reverse caller ID lookup.
  598.       if($telnumber[0== '+')
  599.         $telnumber substr($telnumber1);
  600.  
  601.       for($i 0$i strlen($telnumber)$i++)
  602.         $rDNS $telnumber[$i'.' $rDNS;
  603.  
  604.       if(!isset($this->config['phpagi']['dig'])) $this->config['phpagi']['dig'$this->which('dig');
  605.       $dig=trim($this->config['phpagi']['dig']);
  606.  
  607.       $execstr $dig ' +short ' escapeshellarg($rDNS' TXT';
  608.       $lines trim(`$execstr`);
  609.  
  610.       $lines explode("\n"$lines);
  611.       foreach($lines as $line)
  612.       {
  613.         $line str_replace("\t"' 'trim($line));
  614.         while(strstr($line'  ')) $line str_replace('  '' '$line);
  615.         $line str_replace("\""''$line);
  616.         $line str_replace("\'"''$line);
  617.         $ret .= $line;
  618.       }
  619.       $ret trim($ret);
  620.       if($ret == ''return false;
  621.       return $ret;
  622.     }
  623.  
  624.    /**
  625.     * Send the given text to the connected channel.
  626.     *
  627.     * Most channels do not support transmission of text.
  628.     *
  629.     * @link http://www.voip-info.org/wiki-send+text
  630.     * @param $text 
  631.     * @return boolean true on success
  632.     */
  633.     function send_text($txt)
  634.     {
  635.       $res parent::send_text($txt);
  636.       if($res['code'!= AGIRES_OK || $res['result'== -1return false;
  637.       return true;
  638.     }
  639.  
  640.    /**
  641.     * Send the specified image on a channel.
  642.     *
  643.     * Most channels do not support the transmission of images.
  644.     *
  645.     * @link http://www.voip-info.org/wiki-send+image
  646.     * @param string $image without extension, often in /var/lib/asterisk/images
  647.     * @return boolean true on success
  648.     */
  649.     function send_image($image)
  650.     {
  651.       $res parent::send_image($image);
  652.       if($res['code'!= AGIRES_OK || $res['result'== -1return false;
  653.       return true;
  654.     }    
  655.   }
  656. ?>

Documentation generated on Thu, 30 Sep 2010 02:22:07 -0700 by phpDocumentor 1.4.2