/A2Billing_AGI/phpagi/phpagi.php
PHP | 1954 lines | 1744 code | 41 blank | 169 comment | 21 complexity | 8637fdd8e43ce6de231ee4f98707b272 MD5 | raw file
Possible License(s): AGPL-1.0
Large files files are truncated, but you can click here to view the full file
- <?php
- /**
- * phpagi.php : PHP AGI Functions for Asterisk
- * Website: http://phpagi.sourceforge.net/
- *
- * $Id: phpagi.php,v 2.14 2005/05/25 20:30:46 pinhole Exp $
- *
- * Copyright (c) 2003, 2004, 2005 Matthew Asham <matthewa@bcwireless.net>, David Eder <david@eder.us>
- * All Rights Reserved.
- *
- * This software is released under the terms of the GNU Lesser General Public License v2.1
- * A copy of which is available from http://www.gnu.org/copyleft/lesser.html
- *
- * We would be happy to list your phpagi based application on the phpagi
- * website. Drop me an Email if you'd like us to list your program.
- *
- *
- * Written for PHP 4.3.4, should work with older PHP 4.x versions.
- *
- * Please submit bug reports, patches, etc to http://sourceforge.net/projects/phpagi/
- * Gracias. :)
- *
- *
- * @package phpAGI
- * @version 2.0
- */
- /**
- */
- /*if(!class_exists('AGI_AsteriskManager'))
- {
- require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'phpagi-asmanager.php');
- }*/
- define('AST_CONFIG_DIR', '/etc/asterisk/');
- define('AST_SPOOL_DIR', '/var/spool/asterisk/');
- define('AST_TMP_DIR', AST_SPOOL_DIR . '/tmp/');
- define('DEFAULT_PHPAGI_CONFIG', AST_CONFIG_DIR . '/phpagi.conf');
- define('AST_DIGIT_ANY', '0123456789#*');
- define('AGIRES_OK', 200);
- define('AST_STATE_DOWN', 0);
- define('AST_STATE_RESERVED', 1);
- define('AST_STATE_OFFHOOK', 2);
- define('AST_STATE_DIALING', 3);
- define('AST_STATE_RING', 4);
- define('AST_STATE_RINGING', 5);
- define('AST_STATE_UP', 6);
- define('AST_STATE_BUSY', 7);
- define('AST_STATE_DIALING_OFFHOOK', 8);
- define('AST_STATE_PRERING', 9);
- define('AUDIO_FILENO', 3); // STDERR_FILENO + 1
- /**
- * AGI class
- *
- * @package phpAGI
- * @link http://www.voip-info.org/wiki-Asterisk+agi
- * @example examples/dtmf.php Get DTMF tones from the user and say the digits
- * @example examples/input.php Get text input from the user and say it back
- * @example examples/ping.php Ping an IP address
- */
- class AGI
- {
- /**
- * Request variables read in on initialization.
- *
- * Often contains any/all of the following:
- * agi_request - name of agi script
- * agi_channel - current channel
- * agi_language - current language
- * agi_type - channel type (SIP, ZAP, IAX, ...)
- * agi_uniqueid - unique id based on unix time
- * agi_callerid - callerID string
- * agi_dnid - dialed number id
- * agi_rdnis - referring DNIS number
- * agi_context - current context
- * agi_extension - extension dialed
- * agi_priority - current priority
- * agi_enhanced - value is 1.0 if started as an EAGI script
- * agi_accountcode - set by SetAccount in the dialplan
- * agi_network - value is yes if this is a fastagi
- * agi_network_script - name of the script to execute
- *
- * NOTE: program arguments are still in $_SERVER['argv'].
- *
- * @var array
- * @access public
- */
- var $request;
- /**
- * Config variables
- *
- * @var integer
- * @access public
- */
- var $nlinetoread=5;
-
- /**
- * Config variables
- *
- * @var array
- * @access public
- */
- var $_config;
- public $config_main = 'phpagi';
- /**
- * Asterisk Manager
- *
- * @var AGI_AsteriskManager
- * @access public
- */
- var $asmanager;
- /**
- * Input Stream
- *
- * @access private
- */
- var $in = NULL;
- /**
- * Output Stream
- *
- * @access private
- */
- var $out = NULL;
- /**
- * Audio Stream
- *
- * @access public
- */
- var $audio = NULL;
-
- /**
- * Whether the channel is answered
- */
- var $is_answered = false;
-
- public $is_alive = false; ///< If input stream is still running.
- /** asterisk version */
- public $astversion = "1.4";
-
- /** asterisk major version */
- public $astmajor = "1.4";
-
- /** Asterisk parameter separator.
- In 1.6, "," should be used instead */
- public $ast_sep ="|";
-
- /**
- * Constructor
- *
- * @param $config if string, the filename of a config file (ini format), if object,
- * an object to dynamically fetch conf from.
- *
- */
- function AGI(&$config=NULL,$defconf = 'phpagi')
- {
- // load config
- if(is_string($config) && file_exists($config))
- $this->_config = new IniConfig($config);
- else if( is_object($config))
- $this->_config = &$config;
- else $this->_config = new IniConfig();
- $this->config_main = $defconf;
- // add default values to config for uninitialized values
- $this->_config->SetDefVar($this->config_main,'debug',false);
- $this->_config->SetDefVar($this->config_main,'admin', NULL);
- $this->_config->SetDefVar($this->config_main,'tempdir', AST_TMP_DIR);
- // festival TTS config
- $this->_config->SetDefVar('festival','text2wave', $this->which('text2wave'));
- // swift TTS config
- $this->_config->SetDefVar('cepstral','swift', $this->which('swift'));
- ob_implicit_flush(true);
- // open stdin & stdout
- $this->in = defined('STDIN') ? STDIN : fopen('php://stdin', 'r');
- $this->out = defined('STDOUT') ? STDOUT : fopen('php://stdout', 'w');
- $this->is_alive = true;
- // initialize error handler
- if($this->GetCfgVar(NULL,'error_handler', true) == true)
- {
- set_error_handler('phpagi_error_handler');
- global $phpagi_error_handler_email;
- $phpagi_error_handler_email = $this->GetCfgVar(NULL,'admin',NULL);
- error_reporting(E_ALL);
- }
- // make sure temp folder exists
- $this->make_folder($this->GetCfgVar(NULL,'tempdir',AST_TMP_DIR));
- try{
- // read the request
- $str = fgets($this->in);
- while($str && $str != "\n")
- {
- $this->request[substr($str, 0, strpos($str, ':'))] = trim(substr($str, strpos($str, ':') + 1));
- $str = fgets($this->in);
- }
- }catch (Exception $ex){
- $this->is_alive = false;
- $this->conlog('AGI Request read failed:');
- $this->conlog($ex->getMessage());
- }
- // open audio if eagi detected
- if($this->request['agi_enhanced'] == '1.0')
- {
- if(file_exists('/proc/' . getmypid() . '/fd/3'))
- $this->audio = fopen('/proc/' . getmypid() . '/fd/3', 'r');
- elseif(file_exists('/dev/fd/3'))
- {
- // may need to mount fdescfs
- $this->audio = fopen('/dev/fd/3', 'r');
- }
- else
- $this->conlog('Unable to open audio stream');
- if($this->audio) stream_set_blocking($this->audio, 0);
- }
- $this->conlog('AGI Request:',3);
- $this->conlog(print_r($this->request, true),3);
-
- if (!empty($this->request['agi_version']))
- $this->astversion = $this->request['agi_version'];
- $this->astversion=$this->GetCfgVar(NULL,'ast_version',$this->astversion);
- $this->astmajor=$this->GetCfgVar(NULL,'ast_major', $this->astversion);
- {
- $elems = explode('.', $this->astmajor, 3);
- $this->astmajor = $elems[0]. '.' . $elems[1];
- if ($elems[0] > '1' || ($elems[0] == '1' && $elems[1] >= '6'))
- $this->ast_sep = ',';
- }
- // DONT WANT TO READ THE INTERNAL CONFIG
- /* $this->conlog('PHPAGI internal configuration:');
- $this->conlog(print_r($this->config, true));*/
- }
- function GetCfgVar($grp, $var, $default = null){
- if (is_null($grp))
- $grp = $this->config_main;
- return $this->_config->GetCfgVar($grp,$var,$default);
- }
- // *********************************************************************************************************
- // ** COMMANDS **
- // *********************************************************************************************************
- /**
- * Answer channel if not already in answer state.
- *
- * @link http://www.voip-info.org/wiki-answer
- * @example examples/dtmf.php Get DTMF tones from the user and say the digits
- * @example examples/input.php Get text input from the user and say it back
- * @example examples/ping.php Ping an IP address
- *
- * @return array, see evaluate for return information. ['result'] is 0 on success, -1 on failure.
- */
- function answer()
- {
- $this->is_answered=true;
- return $this->evaluate('ANSWER');
- }
- /**
- * Get the status of the specified channel. If no channel name is specified, return the status of the current channel.
- *
- * @link http://www.voip-info.org/wiki-channel+status
- * @param string $channel
- * @return array, see evaluate for return information. ['data'] contains description.
- */
- function channel_status($channel='')
- {
- $ret = $this->evaluate("CHANNEL STATUS $channel");
- switch($ret['result'])
- {
- case -1: $ret['data'] = trim("There is no channel that matches $channel"); break;
- case AST_STATE_DOWN: $ret['data'] = 'Channel is down and available'; break;
- case AST_STATE_RESERVED: $ret['data'] = 'Channel is down, but reserved'; break;
- case AST_STATE_OFFHOOK: $ret['data'] = 'Channel is off hook'; break;
- case AST_STATE_DIALING: $ret['data'] = 'Digits (or equivalent) have been dialed'; break;
- case AST_STATE_RING: $ret['data'] = 'Line is ringing'; break;
- case AST_STATE_RINGING: $ret['data'] = 'Remote end is ringing'; break;
- case AST_STATE_UP: $ret['data'] = 'Line is up'; break;
- case AST_STATE_BUSY: $ret['data'] = 'Line is busy'; break;
- case AST_STATE_DIALING_OFFHOOK: $ret['data'] = 'Digits (or equivalent) have been dialed while offhook'; break;
- case AST_STATE_PRERING: $ret['data'] = 'Channel has detected an incoming call and is waiting for ring'; break;
- default: $ret['data'] = "Unknown ({$ret['result']})"; break;
- }
- return $ret;
- }
- /**
- * Deletes an entry in the Asterisk database for a given family and key.
- *
- * @link http://www.voip-info.org/wiki-database+del
- * @param string $family
- * @param string $key
- * @return array, see evaluate for return information. ['result'] is 1 on sucess, 0 otherwise.
- */
- function database_del($family, $key)
- {
- return $this->evaluate("DATABASE DEL \"$family\" \"$key\"");
- }
- /**
- * Deletes a family or specific keytree within a family in the Asterisk database.
- *
- * @link http://www.voip-info.org/wiki-database+deltree
- * @param string $family
- * @param string $keytree
- * @return array, see evaluate for return information. ['result'] is 1 on sucess, 0 otherwise.
- */
- function database_deltree($family, $keytree='')
- {
- $cmd = "DATABASE DELTREE \"$family\"";
- if($keytree != '') $cmd .= " \"$keytree\"";
- return $this->evaluate($cmd);
- }
- /**
- * Retrieves an entry in the Asterisk database for a given family and key.
- *
- * @link http://www.voip-info.org/wiki-database+get
- * @param string $family
- * @param string $key
- * @return array, see evaluate for return information. ['result'] is 1 on sucess, 0 failure. ['data'] holds the value
- */
- function database_get($family, $key)
- {
- return $this->evaluate("DATABASE GET \"$family\ \"$key\"");
- }
- /**
- * Adds or updates an entry in the Asterisk database for a given family, key, and value.
- *
- * @param string $family
- * @param string $key
- * @param string $value
- * @return array, see evaluate for return information. ['result'] is 1 on sucess, 0 otherwise
- */
- function database_put($family, $key, $value)
- {
- $value = str_replace("\n", '\n', addslashes($value));
- return $this->evaluate("DATABASE PUT \"$family\" \"$key\" \"$value\"");
- }
- /**
- * Executes the specified Asterisk application with given options.
- *
- * @link http://www.voip-info.org/wiki-exec
- * @link http://www.voip-info.org/wiki-Asterisk+-+documentation+of+application+commands
- * @param string $application
- * @param mixed $options
- * @return array, see evaluate for return information. ['result'] is whatever the application returns, or -2 on failure to find application
- */
- function exec($application, $options='')
- {
- if(is_array($options)) $options = join($this->ast_sep, $options);
- return $this->evaluate("EXEC $application $options");
- }
-
- /**
- * Plays the given file and receives DTMF data.
- *
- * This is similar to STREAM FILE, but this command can accept and return many DTMF digits,
- * while STREAM FILE returns immediately after the first DTMF digit is detected.
- *
- * Asterisk looks for the file to play in /var/lib/asterisk/sounds by default.
- *
- * If the user doesn't press any keys when the message plays, there is $timeout milliseconds
- * of silence then the command ends.
- *
- * The user has the opportunity to press a key at any time during the message or the
- * post-message silence. If the user presses a key while the message is playing, the
- * message stops playing. When the first key is pressed a timer starts counting for
- * $timeout milliseconds. Every time the user presses another key the timer is restarted.
- * The command ends when the counter goes to zero or the maximum number of digits is entered,
- * whichever happens first.
- *
- * If you don't specify a time out then a default timeout of 2000 is used following a pressed
- * digit. If no digits are pressed then 6 seconds of silence follow the message.
- *
- * If you don't specify $max_digits then the user can enter as many digits as they want.
- *
- * Pressing the # key has the same effect as the timer running out: the command ends and
- * any previously keyed digits are returned. A side effect of this is that there is no
- * way to read a # key using this command.
- *
- * @example examples/ping.php Ping an IP address
- *
- * @link http://www.voip-info.org/wiki-get+data
- * @param string $filename file to play. Do not include file extension.
- * @param integer $timeout milliseconds
- * @param integer $max_digits
- * @param char $escape_character
- * @return array, see evaluate for return information. ['result'] holds the digits and ['data'] holds the timeout if present.
- *
- * This differs from other commands with return DTMF as numbers representing ASCII characters.
- */
- function get_data($filename, $timeout=NULL, $max_digits=NULL, $escape_character=NULL)
- {
- return $this->evaluate(rtrim("GET DATA $filename $timeout $max_digits $escape_character"));
- }
- /**
- * Fetch the value of a variable.
- *
- * Does not work with global variables. Does not work with some variables that are generated by modules.
- *
- * @link http://www.voip-info.org/wiki-get+variable
- * @link http://www.voip-info.org/wiki-Asterisk+variables
- * @param string $variable name
- * @param boolean $get_value
- * @return array if $get_value is not set or set to false.
- * If $get_value is set to true, the value of the variable is returned.
- * See evaluate for return information. ['result'] is 0 if variable hasn't been set, 1 if it has. ['data'] holds the value.
- */
- function get_variable($variable, $get_value = false)
- {
- $var = $this->evaluate("GET VARIABLE $variable");
- if(isset($get_value) && $get_value){
- return $var['data'];
- } else {
- return $var;
- }
- }
- /**
- * Hangup the specified channel. If no channel name is given, hang up the current channel.
- *
- * With power comes responsibility. Hanging up channels other than your own isn't something
- * that is done routinely. If you are not sure why you are doing so, then don't.
- *
- * @link http://www.voip-info.org/wiki-hangup
- * @example examples/dtmf.php Get DTMF tones from the user and say the digits
- * @example examples/input.php Get text input from the user and say it back
- * @example examples/ping.php Ping an IP address
- *
- * @param string $channel
- * @return array, see evaluate for return information. ['result'] is 1 on success, -1 on failure.
- */
- function hangup($channel='')
- {
- return $this->evaluate("HANGUP $channel");
- }
- /**
- * Does nothing.
- *
- * @link http://www.voip-info.org/wiki-noop
- * @return array, see evaluate for return information.
- */
- function noop()
- {
- return $this->evaluate('NOOP');
- }
- /**
- * Receive a character of text from a connected channel. Waits up to $timeout milliseconds for
- * a character to arrive, or infinitely if $timeout is zero.
- *
- * @link http://www.voip-info.org/wiki-receive+char
- * @param integer $timeout milliseconds
- * @return array, see evaluate for return information. ['result'] is 0 on timeout or not supported, -1 on failure. Otherwise
- * it is the decimal value of the DTMF tone. Use chr() to convert to ASCII.
- */
- function receive_char($timeout=-1)
- {
- return $this->evaluate("RECEIVE CHAR $timeout");
- }
- /**
- * Record sound to a file until an acceptable DTMF digit is received or a specified amount of
- * time has passed. Optionally the file BEEP is played before recording begins.
- *
- * @link http://www.voip-info.org/wiki-record+file
- * @param string $file to record, without extension, often created in /var/lib/asterisk/sounds
- * @param string $format of the file. GSM and WAV are commonly used formats. MP3 is read-only and thus cannot be used.
- * @param string $escape_digits
- * @param integer $timeout is the maximum record time in milliseconds, or -1 for no timeout.
- * @param integer $offset to seek to without exceeding the end of the file.
- * @param boolean $beep
- * @param integer $silence number of seconds of silence allowed before the function returns despite the
- * lack of dtmf digits or reaching timeout.
- * @return array, see evaluate for return information. ['result'] is -1 on error, 0 on hangup, otherwise a decimal value of the
- * DTMF tone. Use chr() to convert to ASCII.
- */
- function record_file($file, $format, $escape_digits='', $timeout=-1, $offset=NULL, $beep=false, $silence=NULL)
- {
- $cmd = trim("RECORD FILE $file $format \"$escape_digits\" $timeout $offset");
- if($beep) $cmd .= ' BEEP';
- if(!is_null($silence)) $cmd .= " s=$silence";
- return $this->evaluate($cmd);
- }
- /**
- * Say the given digit string, returning early if any of the given DTMF escape digits are received on the channel.
- *
- * @link http://www.voip-info.org/wiki-say+digits
- * @param integer $digits
- * @param string $escape_digits
- * @return array, see evaluate for return information. ['result'] is -1 on hangup or error, 0 if playback completes with no
- * digit received, otherwise a decimal value of the DTMF tone. Use chr() to convert to ASCII.
- */
- function say_digits($digits, $escape_digits='')
- {
- if ($this->GetCfgVar(NULL,'play_audio', true)){
- return $this->evaluate("SAY DIGITS $digits \"$escape_digits\"");
- }
- }
- /**
- * Say the given number, returning early if any of the given DTMF escape digits are received on the channel.
- *
- * @link http://www.voip-info.org/wiki-say+number
- * @param integer $number
- * @param string $escape_digits
- * @return array, see evaluate for return information. ['result'] is -1 on hangup or error, 0 if playback completes with no
- * digit received, otherwise a decimal value of the DTMF tone. Use chr() to convert to ASCII.
- */
- function say_number($number, $escape_digits='')
- {
- if ($this->GetCfgVar(NULL,'play_audio', true)){
- return $this->evaluate("SAY NUMBER $number \"$escape_digits\"");
- }
- }
- /**
- * Say the given character string, returning early if any of the given DTMF escape digits are received on the channel.
- *
- * @link http://www.voip-info.org/wiki-say+phonetic
- * @param string $text
- * @param string $escape_digits
- * @return array, see evaluate for return information. ['result'] is -1 on hangup or error, 0 if playback completes with no
- * digit received, otherwise a decimal value of the DTMF tone. Use chr() to convert to ASCII.
- */
- function say_phonetic($text, $escape_digits='')
- {
- if ($this->GetCfgVar(NULL,'play_audio', true)){
- return $this->evaluate("SAY PHONETIC $text \"$escape_digits\"");
- }
- }
- /**
- * Say a given time, returning early if any of the given DTMF escape digits are received on the channel.
- *
- * @link http://www.voip-info.org/wiki-say+time
- * @param integer $time number of seconds elapsed since 00:00:00 on January 1, 1970, Coordinated Universal Time (UTC).
- * @param string $escape_digits
- * @return array, see evaluate for return information. ['result'] is -1 on hangup or error, 0 if playback completes with no
- * digit received, otherwise a decimal value of the DTMF tone. Use chr() to convert to ASCII.
- */
- function say_time($time=NULL, $escape_digits='')
- {
- if ($this->GetCfgVar(NULL,'play_audio', true)){
- if(is_null($time)) $time = time();
- return $this->evaluate("SAY TIME $time \"$escape_digits\"");
- }
- }
- /**
- * Send the specified image on a channel.
- *
- * Most channels do not support the transmission of images.
- *
- * @link http://www.voip-info.org/wiki-send+image
- * @param string $image without extension, often in /var/lib/asterisk/images
- * @return array, see evaluate for return information. ['result'] is -1 on hangup or error, 0 if the image is sent or
- * channel does not support image transmission.
- */
- function send_image($image)
- {
- return $this->evaluate("SEND IMAGE $image");
- }
- /**
- * Send the given text to the connected channel.
- *
- * Most channels do not support transmission of text.
- *
- * @link http://www.voip-info.org/wiki-send+text
- * @param $text
- * @return array, see evaluate for return information. ['result'] is -1 on hangup or error, 0 if the text is sent or
- * channel does not support text transmission.
- */
- function send_text($text)
- {
- return $this->evaluate("SEND TEXT \"$text\"");
- }
- /**
- * Cause the channel to automatically hangup at $time seconds in the future.
- * If $time is 0 then the autohangup feature is disabled on this channel.
- *
- * If the channel is hungup prior to $time seconds, this setting has no effect.
- *
- * @link http://www.voip-info.org/wiki-set+autohangup
- * @param integer $time until automatic hangup
- * @return array, see evaluate for return information.
- */
- function set_autohangup($time=0)
- {
- return $this->evaluate("SET AUTOHANGUP $time");
- }
-
-
- /**
- * Changes the caller ID of the current channel.
- *
- * @link http://www.voip-info.org/wiki-set+callerid
- * @param string $cid example: "John Smith"<1234567>
- * This command will let you take liberties with the <caller ID specification> but the format shown in the example above works
- * well: the name enclosed in double quotes followed immediately by the number inside angle brackets. If there is no name then
- * you can omit it. If the name contains no spaces you can omit the double quotes around it. The number must follow the name
- * immediately; don't put a space between them. The angle brackets around the number are necessary; if you omit them the
- * number will be considered to be part of the name.
- * @return array, see evaluate for return information.
- */
- function set_callerid($cid)
- {
- return $this->evaluate("SET CALLERID $cid");
- }
- /**
- * Sets the context for continuation upon exiting the application.
- *
- * Setting the context does NOT automatically reset the extension and the priority; if you want to start at the top of the new
- * context you should set extension and priority yourself.
- *
- * If you specify a non-existent context you receive no error indication (['result'] is still 0) but you do get a
- * warning message on the Asterisk console.
- *
- * @link http://www.voip-info.org/wiki-set+context
- * @param string $context
- * @return array, see evaluate for return information.
- */
- function set_context($context)
- {
- return $this->evaluate("SET CONTEXT $context");
- }
- /**
- * Set the extension to be used for continuation upon exiting the application.
- *
- * Setting the extension does NOT automatically reset the priority. If you want to start with the first priority of the
- * extension you should set the priority yourself.
- *
- * If you specify a non-existent extension you receive no error indication (['result'] is still 0) but you do
- * get a warning message on the Asterisk console.
- *
- * @link http://www.voip-info.org/wiki-set+extension
- * @param string $extension
- * @return array, see evaluate for return information.
- */
- function set_extension($extension)
- {
- return $this->evaluate("SET EXTENSION $extension");
- }
- /**
- * Enable/Disable Music on hold generator.
- *
- * @link http://www.voip-info.org/wiki-set+music
- * @param boolean $enabled
- * @param string $class
- * @return array, see evaluate for return information.
- */
- function set_music($enabled=true, $class='')
- {
- $enabled = ($enabled) ? 'ON' : 'OFF';
- return $this->evaluate("SET MUSIC $enabled $class");
- }
- /**
- * Set the priority to be used for continuation upon exiting the application.
- *
- * If you specify a non-existent priority you receive no error indication (['result'] is still 0)
- * and no warning is issued on the Asterisk console.
- *
- * @link http://www.voip-info.org/wiki-set+priority
- * @param integer $priority
- * @return array, see evaluate for return information.
- */
- function set_priority($priority)
- {
- return $this->evaluate("SET PRIORITY $priority");
- }
- /**
- * Sets a variable to the specified value. The variables so created can later be used by later using ${<variablename>}
- * in the dialplan.
- *
- * These variables live in the channel Asterisk creates when you pickup a phone and as such they are both local and temporary.
- * Variables created in one channel can not be accessed by another channel. When you hang up the phone, the channel is deleted
- * and any variables in that channel are deleted as well.
- *
- * @link http://www.voip-info.org/wiki-set+variable
- * @param string $variable is case sensitive
- * @param string $value
- * @return array, see evaluate for return information.
- */
- function set_variable($variable, $value)
- {
- $value = str_replace("\n", '\n', addslashes($value));
- return $this->evaluate("SET VARIABLE $variable \"$value\"");
- }
- /**
- * Play the given audio file, allowing playback to be interrupted by a DTMF digit. This command is similar to the GET DATA
- * command but this command returns after the first DTMF digit has been pressed while GET DATA can accumulated any number of
- * digits before returning.
- *
- * @note Addition: if the channel is not answered yet, respect that!
- * Note: If the channel is answered, it makes sense to allow skip
- * of the message with '#'. If not, the audio path is one-way, so
- * we cannot hear any sound. This fn behaves accordingly.
- *
- * @example examples/ping.php Ping an IP address
- *
- * @link http://www.voip-info.org/wiki-stream+file
- * @param string $filename without extension, often in /var/lib/asterisk/sounds
- * @param string $escape_digits
- * @param integer $offset
- * @return array, see evaluate for return information. ['result'] is -1 on hangup or error, 0 if playback completes with no
- * digit received, otherwise a decimal value of the DTMF tone. Use chr() to convert to ASCII.
- */
- function stream_file($filename, $escape_digits='', $offset=0)
- {
- if (!$this->GetCfgVar(NULL,'play_audio', true))
- return;
-
- if ($this->is_answered)
- return $this->evaluate("STREAM FILE $filename \"$escape_digits\" $offset");
- else {
- return $this->evaluate("EXEC Playback $filename".$this->ast_sep."noanswer");
- }
- }
- /**
- * Enable or disable TDD transmission/reception on the current channel.
- *
- * @link http://www.voip-info.org/wiki-tdd+mode
- * @param string $setting can be on, off or mate
- * @return array, see evaluate for return information. ['result'] is 1 on sucess, 0 if the channel is not TDD capable.
- */
- function tdd_mode($setting)
- {
- return $this->evaluate("TDD MODE $setting");
- }
- /**
- * Sends $message to the Asterisk console via the 'verbose' message system.
- *
- * If the Asterisk verbosity level is $level or greater, send $message to the console.
- *
- * The Asterisk verbosity system works as follows. The Asterisk user gets to set the desired verbosity at startup time or later
- * using the console 'set verbose' command. Messages are displayed on the console if their verbose level is less than or equal
- * to desired verbosity set by the user. More important messages should have a low verbose level; less important messages
- * should have a high verbose level.
- *
- * @link http://www.voip-info.org/wiki-verbose
- * @param string $message
- * @param integer $level from 1 to 4
- * @return array, see evaluate for return information.
- */
- function verbose($message, $level=1)
- {
- switch ($level){
- case 0:
- $syslvl = LOG_ERR;
- break;
- case 1:
- $syslvl = LOG_WARNING;
- break;
- case 2:
- $syslvl = LOG_NOTICE;
- break;
- case 3:
- $syslvl = LOG_INFO;
- break;
- case 4:
- $syslvl = LOG_DEBUG;
- break;
- default:
- //$msg .= "\n what is level $level?";
- $syslvl = LOG_NOTICE;
- break;
- }
- foreach(explode("\n", str_replace("\r\n", "\n", print_r($message, true))) as $msg)
- {
- @syslog($syslvl, $msg);
- $msg = str_replace('"',"'",$msg);
- $ret = $this->evaluate("VERBOSE \"$msg\" $level");
- }
- return $ret;
- }
- static function verbose_s($message, $level=1)
- {
- foreach(explode("\n", str_replace("\r\n", "\n", print_r($message, true))) as $msg)
- {
- @syslog(LOG_WARNING, $msg);
- echo "VERBOSE \"$msg\" $level\n";
- }
- }
- /**
- * Waits up to $timeout milliseconds for channel to receive a DTMF digit.
- *
- * @link http://www.voip-info.org/wiki-wait+for+digit
- * @param integer $timeout in millisecons. Use -1 for the timeout value if you want the call to wait indefinitely.
- * @return array, see evaluate for return information. ['result'] is 0 if wait completes with no
- * digit received, otherwise a decimal value of the DTMF tone. Use chr() to convert to ASCII.
- */
- function wait_for_digit($timeout=-1)
- {
- return $this->evaluate("WAIT FOR DIGIT $timeout");
- }
- // *********************************************************************************************************
- // ** APPLICATIONS **
- // *********************************************************************************************************
- /**
- * Set absolute maximum time of call.
- *
- * Note that the timeout is set from the current time forward, not counting the number of seconds the call has already been up.
- * Each time you call AbsoluteTimeout(), all previous absolute timeouts are cancelled.
- * Will return the call to the T extension so that you can playback an explanatory note to the calling party (the called party
- * will not hear that)
- *
- * @link http://www.voip-info.org/wiki-Asterisk+-+documentation+of+application+commands
- * @link http://www.dynx.net/ASTERISK/AGI/ccard/agi-ccard.agi
- * @param $seconds allowed, 0 disables timeout
- * @return array, see evaluate for return information.
- */
- function exec_absolutetimeout($seconds=0)
- {
- return $this->exec('AbsoluteTimeout', $seconds);
- }
- /**
- * Executes an AGI compliant application.
- *
- * @param string $command
- * @return array, see evaluate for return information. ['result'] is -1 on hangup or if application requested hangup, or 0 on non-hangup exit.
- * @param string $args
- */
- function exec_agi($command, $args)
- {
- return $this->exec("AGI $command", $args);
- }
- /**
- * Set Language.
- *
- * @param string $language code
- * @return array, see evaluate for return information.
- * !! Depreciate on asterisk 1.2 & 1.4
- */
- function exec_setlanguage($language='en')
- {
- return $this->exec('SetLanguage', $language);
- }
-
- /**
- * Set Account Code
- * Set the channel account code for billing purposes.
- *
- * @param string $accountcode
- * @return array, see evaluate for return information.
- */
- function exec_setaccountcode($accountcode)
- {
- return $this->exec('SetAccount', $accountcode);
- }
- /**
- * Do ENUM Lookup.
- *
- * Note: to retrieve the result, use
- * get_variable('ENUM');
- *
- * @param $exten
- * @return array, see evaluate for return information.
- */
- function exec_enumlookup($exten)
- {
- return $this->exec('EnumLookup', $exten);
- }
- /**
- * Dial.
- *
- * Dial takes input from ${VXML_URL} to send XML Url to Cisco 7960
- * Dial takes input from ${ALERT_INFO} to set ring cadence for Cisco phones
- * Dial returns ${CAUSECODE}: If the dial failed, this is the errormessage.
- * Dial returns ${DIALSTATUS}: Text code returning status of last dial attempt.
- *
- * @link http://www.voip-info.org/wiki-Asterisk+cmd+Dial
- * @param string $type
- * @param string $identifier
- * @param integer $timeout
- * @param string $options
- * @param string $url
- * @return array, see evaluate for return information.
- */
- function exec_dial($type, $identifier, $timeout=NULL, $options=NULL, $url=NULL)
- {
- $parms = array("$type/$identifier");
- if ($timeout) array_push($parms,$timeout);
- if ($options) array_push($parms,$options);
- if ($url) array_push($parms,$url);
- return $this->exec('Dial', $parms);
- }
- /**
- * Goto.
- *
- * This function takes three arguments: context,extension, and priority, but the leading arguments
- * are optional, not the trailing arguments. Thuse goto($z) sets the priority to $z.
- *
- * @param string $a
- * @param string $b;
- * @param string $c;
- * @return array, see evaluate for return information.
- */
- function exec_goto($a, $b=NULL, $c=NULL)
- {
- $parms = array("$a");
- if ($b) array_push($parms,$b);
- if ($c) array_push($parms,$c);
-
- return $this->exec('Goto', $parms);
- }
- // *********************************************************************************************************
- // ** FAST PASSING **
- // *********************************************************************************************************
- /**
- * Say the given digit string, returning early if any of the given DTMF escape digits are received on the channel.
- * Return early if $buffer is adequate for request.
- *
- * @link http://www.voip-info.org/wiki-say+digits
- * @param string $buffer
- * @param integer $digits
- * @param string $escape_digits
- * @return array, see evaluate for return information. ['result'] is -1 on hangup or error, 0 if playback completes with no
- * digit received, otherwise a decimal value of the DTMF tone. Use chr() to convert to ASCII.
- */
- function fastpass_say_digits(&$buffer, $digits, $escape_digits='')
- {
- $proceed = false;
- if($escape_digits != '' && $buffer != '')
- {
- if(!strpos(chr(255) . $escape_digits, $buffer{strlen($buffer)-1}))
- $proceed = true;
- }
- if($buffer == '' || $proceed)
- {
- $res = $this->say_digits($digits, $escape_digits);
- if($res['code'] == AGIRES_OK && $res['result'] > 0)
- $buffer .= chr($res['result']);
- return $res;
- }
- return array('code'=>AGIRES_OK, 'result'=>ord($buffer{strlen($buffer)-1}));
- }
- /**
- * Say the given number, returning early if any of the given DTMF escape digits are received on the channel.
- * Return early if $buffer is adequate for request.
- *
- * @link http://www.voip-info.org/wiki-say+number
- * @param string $buffer
- * @param integer $number
- * @param string $escape_digits
- * @return array, see evaluate for return information. ['result'] is -1 on hangup or error, 0 if playback completes with no
- * digit received, otherwise a decimal value of the DTMF tone. Use chr() to convert to ASCII.
- */
- function fastpass_say_number(&$buffer, $number, $escape_digits='')
- {
- $proceed = false;
- if($escape_digits != '' && $buffer != '')
- {
- if(!strpos(chr(255) . $escape_digits, $buffer{strlen($buffer)-1}))
- $proceed = true;
- }
- if($buffer == '' || $proceed)
- {
- $res = $this->say_number($number, $escape_digits);
- if($res['code'] == AGIRES_OK && $res['result'] > 0)
- $buffer .= chr($res['result']);
- return $res;
- }
- return array('code'=>AGIRES_OK, 'result'=>ord($buffer{strlen($buffer)-1}));
- }
- /**
- * Say the given character string, returning early if any of the given DTMF escape digits are received on the channel.
- * Return early if $buffer is adequate for request.
- *
- * @link http://www.voip-info.org/wiki-say+phonetic
- * @param string $buffer
- * @param string $text
- * @param string $escape_digits
- * @return array, see evaluate for return information. ['result'] is -1 on hangup or error, 0 if playback completes with no
- * digit received, otherwise a decimal value of the DTMF tone. Use chr() to convert to ASCII.
- */
- function fastpass_say_phonetic(&$buffer, $text, $escape_digits='')
- {
- $proceed = false;
- if($escape_digits != '' && $buffer != '')
- {
- if(!strpos(chr(255) . $escape_digits, $buffer{strlen($buffer)-1}))
- $proceed = true;
- }
- if($buffer == '' || $proceed)
- {
- $res = $this->say_phonetic($text, $escape_digits);
- if($res['code'] == AGIRES_OK && $res['result'] > 0)
- $buffer .= chr($res['result']);
- return $res;
- }
- return array('code'=>AGIRES_OK, 'result'=>ord($buffer{strlen($buffer)-1}));
- }
- /**
- * Say a given time, returning early if any of the given DTMF escape digits are received on the channel.
- * Return early if $buffer is adequate for request.
- *
- * @link http://www.voip-info.org/wiki-say+time
- * @param string $buffer
- * @param integer $time number of seconds elapsed since 00:00:00 on January 1, 1970, Coordinated Universal Time (UTC).
- * @param string $escape_digits
- * @return array, see evaluate for return information. ['result'] is -1 on hangup or error, 0 if playback completes with no
- * digit received, otherwise a decimal value of the DTMF tone. Use chr() to convert to ASCII.
- */
- function fastpass_say_time(&$buffer, $time=NULL, $escape_digits='')
- {
- $proceed = false;
- if($escape_digits != '' && $buffer != '')
- {
- if(!strpos(chr(255) . $escape_digits, $buffer{strlen($buffer)-1}))
- $proceed = true;
- }
- if($buffer == '' || $proceed)
- {
- $res = $this->say_time($time, $escape_digits);
- if($res['code'] == AGIRES_OK && $res['result'] > 0)
- $buffer .= chr($res['result']);
- return $res;
- }
- return array('code'=>AGIRES_OK, 'result'=>ord($buffer{strlen($buffer)-1}));
- }
- /**
- * Play the given audio file, allowing playback to be interrupted by a DTMF digit. This command is similar to the GET DATA
- * command but this command returns after the first DTMF digit has been pressed while GET DATA can accumulated any number of
- * digits before returning.
- * Return early if $buffer is adequate for request.
- *
- * @link http://www.voip-info.org/wiki-stream+file
- * @param string $buffer
- * @param string $filename without extension, often in /var/lib/asterisk/sounds
- * @param string $escape_digits
- * @param integer $offset
- * @return array, see evaluate for return information. ['result'] is -1 on hangup or error, 0 if playback completes with no
- * digit received, otherwise a decimal value of the DTMF tone. Use chr() to convert to ASCII.
- */
- function fastpass_stream_file(&$buffer, $filename, $escape_digits='', $offset=0)
- {
- $proceed = false;
- if($escape_digits != '' && $buffer != '')
- {
- if(!strpos(chr(255) . $escape_digits, $buffer{strlen($buffer)-1}))
- $proceed = true;
- }
- if($buffer == '' || $proceed)
- {
- $res = $this->stream_file($filename, $escape_digits, $offset);
- if($res['code'] == AGIRES_OK && $res['result'] > 0)
- $buffer .= chr($res['result']);
- return $res;
- }
- return array('code'=>AGIRES_OK, 'result'=>ord($buffer{strlen($buffer)-1}), 'endpos'=>0);
- }
- /**
- * Use festival to read text.
- * Return early if $buffer is adequate for request.
- *
- * @link http://www.cstr.ed.ac.uk/projects/festival/
- * @param string $buffer
- * @param string $text
- * @param string $escape_digits
- * @param integer $frequency
- * @return array, see evaluate for return information.
- */
- function fastpass_text2wav(&$buffer, $text, $escape_digits='', $frequency=8000)
- {
- $proceed = false;
- if($escape_digits != '' && $buffer != '')
- {
- if(!strpos(chr(255) . $escape_digits, $buffer{strlen($buffer)-1}))
- $proceed = true;
- }
- if($buffer == '' || $proceed)
- {
- $res = $this->text2wav($text, $escape_digits, $frequency);
- if($res['code'] == AGIRES_OK && $res['result'] > 0)
- $buffer .= chr($res['result']);
- return $res;
- }
- return array('code'=>AGIRES_OK, 'result'=>ord($buffer{strlen($buffer)-1}), 'endpos'=>0);
- }
- /**
- * Use Cepstral Swift to read text.
- * Return early if $buffer is adequate for request.
- *
- * @link http://www.cepstral.com/
- * @param string $buffer
- * @param string $text
- * @param string $escape_digits
- * @param integer $frequency
- * @return array, see evaluate for return information.
- */
- function fastpass_swift(&$buffer, $text, $escape_digits='', $frequency=8000, $voice=NULL)
- {
- $proceed = false;
- if($escape_digits != '' && $buffer != '')
- {
- if(!strpos(chr(255) . $escape_digits, $buffer{strlen($buffer)-1}))
- $proceed = true;
- }
- if($buffer == '' || $proceed)
- {
- $res = $this->swift($text, $escape_digits, $frequency, $voice);
- if($res['code'] == AGIRES_OK && $res['result'] > 0)
- $buffer .= chr($res['result']);
- return $res;
- }
- return array('code'=>AGIRES_OK, 'result'=>ord($buffer{strlen($buffer)-1}), 'endpos'=>0);
- }
- /**
- * Say Puncutation in a string.
- * Return early if $buffer is adequate for request.
- *
- * @param string $buffer
- * @param string $text
- * @param string $escape_digits
- * @param integer $frequency
- * @return array, see evaluate for return information.
- */
- function fastpass_say_punctuation(&$buffer, $text, $escape_digits='', $frequency=8000)
- {
- $proceed = false;
- if($escape_digits != '' && $buffer != '')
- {
- if(!strpos(chr(255) . $escape_digits, $buffer{strlen($buffer)-1}))
- $proceed = true;
- }
- if($buffer == '' || $proceed)
- {
- $res = $this->say_punctuation($text, $escape_digits, $frequency);
- if($res['code'] == AGIRES_OK && $res['result'] > 0)
- $buffer .= chr($res['result']);
- return $res;
- }
- return array('code'=>AGIRES_OK, 'result'=>ord($buffer{strlen($buffer)-1}));
- }
- /**
- * Plays the given file and receives DTMF data.
- * Return early if $buffer is adequate for request.
- *
- * This is similar to STREAM FILE, but this command can accept and return many DTMF digits,
- * while STREAM FILE returns immediately after the first DTMF digit is detected.
- *
- * Asterisk looks for the file to play in /var/lib/asterisk/sounds by default.
- *
- * If the user doesn't press any keys when the message plays, there is $timeout milliseconds
- * of silence then the command ends.
- *
- * The user has the opportunity to press a key at any time during the message or the
- * post-message silence. If the user presses a key while the message is playing, the
- * message stops playing. When the first key is pressed a timer starts counting for
- * $timeout milliseconds. Every time the user presses another key the timer is restarted.
- * The command ends when the counter goes to zero or the maximum number of digits is entered,
- * whichever happens first.
- *
- * If you don't specify a time out then a default timeout of 2000 is used following a pressed
- * digit. If no digits are pressed then 6 seconds of silence follow the message.
- *
- * If you don't specify $max_digits then the user can enter as many digits as they want.
- *
- * Pressing the # key has the same effect as the timer running out: the command ends and
- * any previously keyed digits are returned. A side effect of this is that there is no
- * way to read a # key using this command.
- *
- * @link http://www.voip-info.org/wiki-get+data
- * @param string $buffer
- * @param string $filename file to play. Do not include file extension.
- * @param integer $timeout milliseconds
- * @param integer $max_digits
- * @return array, see evaluate for return information. ['result'] holds the digits and ['data'] holds the timeout if present.
- *
- * This differs from other commands with return DTMF as numbers representing ASCII characters.
- */
- function fastpass_get_data(&$buffer, $filename, $timeout=NULL, $max_digits=NULL)
- {
- if(is_null($max_digits) || strlen($buffer) < $max_digits)
- {
- if($buffer == '')
- {
- $res = $this->get_data($filename, $timeout, $max_digits);
- if($res['code'] == AGIRES_OK)
- $buffer .= $res['result'];
- return $res;
- }
- else
- {
- while(is_null($max_digits) || strlen($buffer) < $max_digits)
- {
- $res = $this->wait_for_digit();
- if($res['code'] != AGIRES_OK) return $res;
- if($res['result'] == ord('#')) break;
- $buffer .= chr($res['result']);
- }
- }
- }
- return array('code'=>AGIRES_OK, 'result'=>$buffer);
- }
- // *********************************************************************************************************
- // ** DERIVED **
- // *********************************************************************************************************
- /**
- * Menu.
- *
- * This function presents the user with a menu and reads the response
- *
- * @param array $choices has the following structure:
- * array('1'=>'*Press 1 for this', // festival reads if prompt starts with *
- * '2'=>'some-gsm-without-extension',
- * '*'=>'*Press star for help');
- * @return mixed key pressed on sucess, -1 on failure
- */
- function menu($choices, $timeout=2000)
- {
- $keys = join('', array_keys($choices));
- $choice = NULL;
- while(is_null($choice))
- {
- foreach($choices as $prompt)
- {
- if($prompt{0} == '*')
- $ret = $this->text2wav(substr($prompt, 1), $keys);
- else
- $ret = $this->stream_file($prompt, $keys);
- if($ret['code'] != AGIRES_OK || $ret['result'] == -1)
- {
- $choice = -1;
- break;
- }
- if($ret['result'] != 0)
- {
- $choice = chr($ret['result']);
- break;
- }
- }
- if(is_null($choice))
- {
- $ret = $this->get_data('beep', $timeout, 1);
- if($ret['code'] != AGIRES_OK || $ret['result'] == -1)
- $choice = -1;
- elseif($ret['result'] != '' && strpos(' '.$keys, $ret['result']))
- $choice = $ret['result'];
- }
- }
- return $choice;
- }
- /**
- * Goto - Set context, extension and priority.
- *
- * @param string $context
- * @param string $extension
- * @param string $priority
- */
- /* *-* function goto($context, $extension='s', $priority=1)
- {
- $this->set_context($context);
- $this->set_extension($extension);
- $this->set_priority($priority);
- }*/
- /**
- * Parse caller id.
- *
- * @example examples/dtmf.php Get DTMF tones from the user and say the digits
- * @example examples/input.php Get text input from the user and say it back
- *
- * "name" <proto:user@server:port>
- *
- * @param string $callerid
- * @return array('Name'=>$name, 'Number'=>$number)
- */
- function parse_callerid($callerid=NULL)
- {
- if(is_null($callerid))
- $callerid = $this->request['agi_callerid'];
- $ret = array('name'=>'', 'protocol'=>'', 'username'=>'', 'host'=>'', 'port'=>'');
- $callerid = trim($callerid);
- if($callerid{0} == '"' || $callerid{0} == "'")
- {
- $d = $callerid{0};
- $callerid = explode($d, substr($callerid, 1));
- $ret['name'] = array_shift($callerid);
- $callerid = join($d, $callerid);
- }
- $callerid = explode('@', trim($callerid, '<> '));
- $username = explode(':', array_shift($callerid));
- if(count($username) == 1)
- $ret['username'] = $username[0];
- else
- {
- $ret['protocol'] = ar…
Large files files are truncated, but you can click here to view the full file