?? phpagi.php
字號:
<?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; /** * 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; /** * Constructor * * @param string $config is the name of the config file to parse * @param array $optconfig is an array of configuration vars and vals, stuffed into $this->config['phpagi'] */ function AGI($config=NULL, $optconfig=array()) { // load config if(!is_null($config) && file_exists($config)) $this->config = parse_ini_file($config, true); elseif(file_exists(DEFAULT_PHPAGI_CONFIG)) //--$this->config = parse_ini_file(DEFAULT_PHPAGI_CONFIG, true); //-- DONT WANT HIM TO OPEN A FILE EACH TIME // If optconfig is specified, stuff vals and vars into 'phpagi' config array. foreach($optconfig as $var=>$val) $this->config['phpagi'][$var] = $val; // add default values to config for uninitialized values if(!isset($this->config['phpagi']['error_handler'])) $this->config['phpagi']['error_handler'] = true; if(!isset($this->config['phpagi']['debug'])) $this->config['phpagi']['debug'] = false; if(!isset($this->config['phpagi']['admin'])) $this->config['phpagi']['admin'] = NULL; if(!isset($this->config['phpagi']['tempdir'])) $this->config['phpagi']['tempdir'] = AST_TMP_DIR; // festival TTS config if(!isset($this->config['festival']['text2wave'])) $this->config['festival']['text2wave'] = $this->which('text2wave'); // swift TTS config if(!isset($this->config['cepstral']['swift'])) $this->config['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'); // initialize error handler if($this->config['phpagi']['error_handler'] == true) { set_error_handler('phpagi_error_handler'); global $phpagi_error_handler_email; $phpagi_error_handler_email = $this->config['phpagi']['admin']; error_reporting(E_ALL); } // make sure temp folder exists $this->make_folder($this->config['phpagi']['tempdir']); // read the request $str = fgets($this->in); while($str != "\n") { $this->request[substr($str, 0, strpos($str, ':'))] = trim(substr($str, strpos($str, ':') + 1)); $str = fgets($this->in); } // 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:'); $this->conlog(print_r($this->request, true)); // DONT WANT TO READ THE INTERNAL CONFIG /* $this->conlog('PHPAGI internal configuration:'); $this->conlog(print_r($this->config, true));*/ } // ********************************************************************************************************* // ** 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() { 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('|', $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 *
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -