PageRenderTime 56ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/A2Billing_AGI/phpagi/phpagi.php

https://github.com/xrg/a2billing
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

  1. <?php
  2. /**
  3. * phpagi.php : PHP AGI Functions for Asterisk
  4. * Website: http://phpagi.sourceforge.net/
  5. *
  6. * $Id: phpagi.php,v 2.14 2005/05/25 20:30:46 pinhole Exp $
  7. *
  8. * Copyright (c) 2003, 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. *
  18. * Written for PHP 4.3.4, should work with older PHP 4.x versions.
  19. *
  20. * Please submit bug reports, patches, etc to http://sourceforge.net/projects/phpagi/
  21. * Gracias. :)
  22. *
  23. *
  24. * @package phpAGI
  25. * @version 2.0
  26. */
  27. /**
  28. */
  29. /*if(!class_exists('AGI_AsteriskManager'))
  30. {
  31. require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'phpagi-asmanager.php');
  32. }*/
  33. define('AST_CONFIG_DIR', '/etc/asterisk/');
  34. define('AST_SPOOL_DIR', '/var/spool/asterisk/');
  35. define('AST_TMP_DIR', AST_SPOOL_DIR . '/tmp/');
  36. define('DEFAULT_PHPAGI_CONFIG', AST_CONFIG_DIR . '/phpagi.conf');
  37. define('AST_DIGIT_ANY', '0123456789#*');
  38. define('AGIRES_OK', 200);
  39. define('AST_STATE_DOWN', 0);
  40. define('AST_STATE_RESERVED', 1);
  41. define('AST_STATE_OFFHOOK', 2);
  42. define('AST_STATE_DIALING', 3);
  43. define('AST_STATE_RING', 4);
  44. define('AST_STATE_RINGING', 5);
  45. define('AST_STATE_UP', 6);
  46. define('AST_STATE_BUSY', 7);
  47. define('AST_STATE_DIALING_OFFHOOK', 8);
  48. define('AST_STATE_PRERING', 9);
  49. define('AUDIO_FILENO', 3); // STDERR_FILENO + 1
  50. /**
  51. * AGI class
  52. *
  53. * @package phpAGI
  54. * @link http://www.voip-info.org/wiki-Asterisk+agi
  55. * @example examples/dtmf.php Get DTMF tones from the user and say the digits
  56. * @example examples/input.php Get text input from the user and say it back
  57. * @example examples/ping.php Ping an IP address
  58. */
  59. class AGI
  60. {
  61. /**
  62. * Request variables read in on initialization.
  63. *
  64. * Often contains any/all of the following:
  65. * agi_request - name of agi script
  66. * agi_channel - current channel
  67. * agi_language - current language
  68. * agi_type - channel type (SIP, ZAP, IAX, ...)
  69. * agi_uniqueid - unique id based on unix time
  70. * agi_callerid - callerID string
  71. * agi_dnid - dialed number id
  72. * agi_rdnis - referring DNIS number
  73. * agi_context - current context
  74. * agi_extension - extension dialed
  75. * agi_priority - current priority
  76. * agi_enhanced - value is 1.0 if started as an EAGI script
  77. * agi_accountcode - set by SetAccount in the dialplan
  78. * agi_network - value is yes if this is a fastagi
  79. * agi_network_script - name of the script to execute
  80. *
  81. * NOTE: program arguments are still in $_SERVER['argv'].
  82. *
  83. * @var array
  84. * @access public
  85. */
  86. var $request;
  87. /**
  88. * Config variables
  89. *
  90. * @var integer
  91. * @access public
  92. */
  93. var $nlinetoread=5;
  94. /**
  95. * Config variables
  96. *
  97. * @var array
  98. * @access public
  99. */
  100. var $_config;
  101. public $config_main = 'phpagi';
  102. /**
  103. * Asterisk Manager
  104. *
  105. * @var AGI_AsteriskManager
  106. * @access public
  107. */
  108. var $asmanager;
  109. /**
  110. * Input Stream
  111. *
  112. * @access private
  113. */
  114. var $in = NULL;
  115. /**
  116. * Output Stream
  117. *
  118. * @access private
  119. */
  120. var $out = NULL;
  121. /**
  122. * Audio Stream
  123. *
  124. * @access public
  125. */
  126. var $audio = NULL;
  127. /**
  128. * Whether the channel is answered
  129. */
  130. var $is_answered = false;
  131. public $is_alive = false; ///< If input stream is still running.
  132. /** asterisk version */
  133. public $astversion = "1.4";
  134. /** asterisk major version */
  135. public $astmajor = "1.4";
  136. /** Asterisk parameter separator.
  137. In 1.6, "," should be used instead */
  138. public $ast_sep ="|";
  139. /**
  140. * Constructor
  141. *
  142. * @param $config if string, the filename of a config file (ini format), if object,
  143. * an object to dynamically fetch conf from.
  144. *
  145. */
  146. function AGI(&$config=NULL,$defconf = 'phpagi')
  147. {
  148. // load config
  149. if(is_string($config) && file_exists($config))
  150. $this->_config = new IniConfig($config);
  151. else if( is_object($config))
  152. $this->_config = &$config;
  153. else $this->_config = new IniConfig();
  154. $this->config_main = $defconf;
  155. // add default values to config for uninitialized values
  156. $this->_config->SetDefVar($this->config_main,'debug',false);
  157. $this->_config->SetDefVar($this->config_main,'admin', NULL);
  158. $this->_config->SetDefVar($this->config_main,'tempdir', AST_TMP_DIR);
  159. // festival TTS config
  160. $this->_config->SetDefVar('festival','text2wave', $this->which('text2wave'));
  161. // swift TTS config
  162. $this->_config->SetDefVar('cepstral','swift', $this->which('swift'));
  163. ob_implicit_flush(true);
  164. // open stdin & stdout
  165. $this->in = defined('STDIN') ? STDIN : fopen('php://stdin', 'r');
  166. $this->out = defined('STDOUT') ? STDOUT : fopen('php://stdout', 'w');
  167. $this->is_alive = true;
  168. // initialize error handler
  169. if($this->GetCfgVar(NULL,'error_handler', true) == true)
  170. {
  171. set_error_handler('phpagi_error_handler');
  172. global $phpagi_error_handler_email;
  173. $phpagi_error_handler_email = $this->GetCfgVar(NULL,'admin',NULL);
  174. error_reporting(E_ALL);
  175. }
  176. // make sure temp folder exists
  177. $this->make_folder($this->GetCfgVar(NULL,'tempdir',AST_TMP_DIR));
  178. try{
  179. // read the request
  180. $str = fgets($this->in);
  181. while($str && $str != "\n")
  182. {
  183. $this->request[substr($str, 0, strpos($str, ':'))] = trim(substr($str, strpos($str, ':') + 1));
  184. $str = fgets($this->in);
  185. }
  186. }catch (Exception $ex){
  187. $this->is_alive = false;
  188. $this->conlog('AGI Request read failed:');
  189. $this->conlog($ex->getMessage());
  190. }
  191. // open audio if eagi detected
  192. if($this->request['agi_enhanced'] == '1.0')
  193. {
  194. if(file_exists('/proc/' . getmypid() . '/fd/3'))
  195. $this->audio = fopen('/proc/' . getmypid() . '/fd/3', 'r');
  196. elseif(file_exists('/dev/fd/3'))
  197. {
  198. // may need to mount fdescfs
  199. $this->audio = fopen('/dev/fd/3', 'r');
  200. }
  201. else
  202. $this->conlog('Unable to open audio stream');
  203. if($this->audio) stream_set_blocking($this->audio, 0);
  204. }
  205. $this->conlog('AGI Request:',3);
  206. $this->conlog(print_r($this->request, true),3);
  207. if (!empty($this->request['agi_version']))
  208. $this->astversion = $this->request['agi_version'];
  209. $this->astversion=$this->GetCfgVar(NULL,'ast_version',$this->astversion);
  210. $this->astmajor=$this->GetCfgVar(NULL,'ast_major', $this->astversion);
  211. {
  212. $elems = explode('.', $this->astmajor, 3);
  213. $this->astmajor = $elems[0]. '.' . $elems[1];
  214. if ($elems[0] > '1' || ($elems[0] == '1' && $elems[1] >= '6'))
  215. $this->ast_sep = ',';
  216. }
  217. // DONT WANT TO READ THE INTERNAL CONFIG
  218. /* $this->conlog('PHPAGI internal configuration:');
  219. $this->conlog(print_r($this->config, true));*/
  220. }
  221. function GetCfgVar($grp, $var, $default = null){
  222. if (is_null($grp))
  223. $grp = $this->config_main;
  224. return $this->_config->GetCfgVar($grp,$var,$default);
  225. }
  226. // *********************************************************************************************************
  227. // ** COMMANDS **
  228. // *********************************************************************************************************
  229. /**
  230. * Answer channel if not already in answer state.
  231. *
  232. * @link http://www.voip-info.org/wiki-answer
  233. * @example examples/dtmf.php Get DTMF tones from the user and say the digits
  234. * @example examples/input.php Get text input from the user and say it back
  235. * @example examples/ping.php Ping an IP address
  236. *
  237. * @return array, see evaluate for return information. ['result'] is 0 on success, -1 on failure.
  238. */
  239. function answer()
  240. {
  241. $this->is_answered=true;
  242. return $this->evaluate('ANSWER');
  243. }
  244. /**
  245. * Get the status of the specified channel. If no channel name is specified, return the status of the current channel.
  246. *
  247. * @link http://www.voip-info.org/wiki-channel+status
  248. * @param string $channel
  249. * @return array, see evaluate for return information. ['data'] contains description.
  250. */
  251. function channel_status($channel='')
  252. {
  253. $ret = $this->evaluate("CHANNEL STATUS $channel");
  254. switch($ret['result'])
  255. {
  256. case -1: $ret['data'] = trim("There is no channel that matches $channel"); break;
  257. case AST_STATE_DOWN: $ret['data'] = 'Channel is down and available'; break;
  258. case AST_STATE_RESERVED: $ret['data'] = 'Channel is down, but reserved'; break;
  259. case AST_STATE_OFFHOOK: $ret['data'] = 'Channel is off hook'; break;
  260. case AST_STATE_DIALING: $ret['data'] = 'Digits (or equivalent) have been dialed'; break;
  261. case AST_STATE_RING: $ret['data'] = 'Line is ringing'; break;
  262. case AST_STATE_RINGING: $ret['data'] = 'Remote end is ringing'; break;
  263. case AST_STATE_UP: $ret['data'] = 'Line is up'; break;
  264. case AST_STATE_BUSY: $ret['data'] = 'Line is busy'; break;
  265. case AST_STATE_DIALING_OFFHOOK: $ret['data'] = 'Digits (or equivalent) have been dialed while offhook'; break;
  266. case AST_STATE_PRERING: $ret['data'] = 'Channel has detected an incoming call and is waiting for ring'; break;
  267. default: $ret['data'] = "Unknown ({$ret['result']})"; break;
  268. }
  269. return $ret;
  270. }
  271. /**
  272. * Deletes an entry in the Asterisk database for a given family and key.
  273. *
  274. * @link http://www.voip-info.org/wiki-database+del
  275. * @param string $family
  276. * @param string $key
  277. * @return array, see evaluate for return information. ['result'] is 1 on sucess, 0 otherwise.
  278. */
  279. function database_del($family, $key)
  280. {
  281. return $this->evaluate("DATABASE DEL \"$family\" \"$key\"");
  282. }
  283. /**
  284. * Deletes a family or specific keytree within a family in the Asterisk database.
  285. *
  286. * @link http://www.voip-info.org/wiki-database+deltree
  287. * @param string $family
  288. * @param string $keytree
  289. * @return array, see evaluate for return information. ['result'] is 1 on sucess, 0 otherwise.
  290. */
  291. function database_deltree($family, $keytree='')
  292. {
  293. $cmd = "DATABASE DELTREE \"$family\"";
  294. if($keytree != '') $cmd .= " \"$keytree\"";
  295. return $this->evaluate($cmd);
  296. }
  297. /**
  298. * Retrieves an entry in the Asterisk database for a given family and key.
  299. *
  300. * @link http://www.voip-info.org/wiki-database+get
  301. * @param string $family
  302. * @param string $key
  303. * @return array, see evaluate for return information. ['result'] is 1 on sucess, 0 failure. ['data'] holds the value
  304. */
  305. function database_get($family, $key)
  306. {
  307. return $this->evaluate("DATABASE GET \"$family\ \"$key\"");
  308. }
  309. /**
  310. * Adds or updates an entry in the Asterisk database for a given family, key, and value.
  311. *
  312. * @param string $family
  313. * @param string $key
  314. * @param string $value
  315. * @return array, see evaluate for return information. ['result'] is 1 on sucess, 0 otherwise
  316. */
  317. function database_put($family, $key, $value)
  318. {
  319. $value = str_replace("\n", '\n', addslashes($value));
  320. return $this->evaluate("DATABASE PUT \"$family\" \"$key\" \"$value\"");
  321. }
  322. /**
  323. * Executes the specified Asterisk application with given options.
  324. *
  325. * @link http://www.voip-info.org/wiki-exec
  326. * @link http://www.voip-info.org/wiki-Asterisk+-+documentation+of+application+commands
  327. * @param string $application
  328. * @param mixed $options
  329. * @return array, see evaluate for return information. ['result'] is whatever the application returns, or -2 on failure to find application
  330. */
  331. function exec($application, $options='')
  332. {
  333. if(is_array($options)) $options = join($this->ast_sep, $options);
  334. return $this->evaluate("EXEC $application $options");
  335. }
  336. /**
  337. * Plays the given file and receives DTMF data.
  338. *
  339. * This is similar to STREAM FILE, but this command can accept and return many DTMF digits,
  340. * while STREAM FILE returns immediately after the first DTMF digit is detected.
  341. *
  342. * Asterisk looks for the file to play in /var/lib/asterisk/sounds by default.
  343. *
  344. * If the user doesn't press any keys when the message plays, there is $timeout milliseconds
  345. * of silence then the command ends.
  346. *
  347. * The user has the opportunity to press a key at any time during the message or the
  348. * post-message silence. If the user presses a key while the message is playing, the
  349. * message stops playing. When the first key is pressed a timer starts counting for
  350. * $timeout milliseconds. Every time the user presses another key the timer is restarted.
  351. * The command ends when the counter goes to zero or the maximum number of digits is entered,
  352. * whichever happens first.
  353. *
  354. * If you don't specify a time out then a default timeout of 2000 is used following a pressed
  355. * digit. If no digits are pressed then 6 seconds of silence follow the message.
  356. *
  357. * If you don't specify $max_digits then the user can enter as many digits as they want.
  358. *
  359. * Pressing the # key has the same effect as the timer running out: the command ends and
  360. * any previously keyed digits are returned. A side effect of this is that there is no
  361. * way to read a # key using this command.
  362. *
  363. * @example examples/ping.php Ping an IP address
  364. *
  365. * @link http://www.voip-info.org/wiki-get+data
  366. * @param string $filename file to play. Do not include file extension.
  367. * @param integer $timeout milliseconds
  368. * @param integer $max_digits
  369. * @param char $escape_character
  370. * @return array, see evaluate for return information. ['result'] holds the digits and ['data'] holds the timeout if present.
  371. *
  372. * This differs from other commands with return DTMF as numbers representing ASCII characters.
  373. */
  374. function get_data($filename, $timeout=NULL, $max_digits=NULL, $escape_character=NULL)
  375. {
  376. return $this->evaluate(rtrim("GET DATA $filename $timeout $max_digits $escape_character"));
  377. }
  378. /**
  379. * Fetch the value of a variable.
  380. *
  381. * Does not work with global variables. Does not work with some variables that are generated by modules.
  382. *
  383. * @link http://www.voip-info.org/wiki-get+variable
  384. * @link http://www.voip-info.org/wiki-Asterisk+variables
  385. * @param string $variable name
  386. * @param boolean $get_value
  387. * @return array if $get_value is not set or set to false.
  388. * If $get_value is set to true, the value of the variable is returned.
  389. * See evaluate for return information. ['result'] is 0 if variable hasn't been set, 1 if it has. ['data'] holds the value.
  390. */
  391. function get_variable($variable, $get_value = false)
  392. {
  393. $var = $this->evaluate("GET VARIABLE $variable");
  394. if(isset($get_value) && $get_value){
  395. return $var['data'];
  396. } else {
  397. return $var;
  398. }
  399. }
  400. /**
  401. * Hangup the specified channel. If no channel name is given, hang up the current channel.
  402. *
  403. * With power comes responsibility. Hanging up channels other than your own isn't something
  404. * that is done routinely. If you are not sure why you are doing so, then don't.
  405. *
  406. * @link http://www.voip-info.org/wiki-hangup
  407. * @example examples/dtmf.php Get DTMF tones from the user and say the digits
  408. * @example examples/input.php Get text input from the user and say it back
  409. * @example examples/ping.php Ping an IP address
  410. *
  411. * @param string $channel
  412. * @return array, see evaluate for return information. ['result'] is 1 on success, -1 on failure.
  413. */
  414. function hangup($channel='')
  415. {
  416. return $this->evaluate("HANGUP $channel");
  417. }
  418. /**
  419. * Does nothing.
  420. *
  421. * @link http://www.voip-info.org/wiki-noop
  422. * @return array, see evaluate for return information.
  423. */
  424. function noop()
  425. {
  426. return $this->evaluate('NOOP');
  427. }
  428. /**
  429. * Receive a character of text from a connected channel. Waits up to $timeout milliseconds for
  430. * a character to arrive, or infinitely if $timeout is zero.
  431. *
  432. * @link http://www.voip-info.org/wiki-receive+char
  433. * @param integer $timeout milliseconds
  434. * @return array, see evaluate for return information. ['result'] is 0 on timeout or not supported, -1 on failure. Otherwise
  435. * it is the decimal value of the DTMF tone. Use chr() to convert to ASCII.
  436. */
  437. function receive_char($timeout=-1)
  438. {
  439. return $this->evaluate("RECEIVE CHAR $timeout");
  440. }
  441. /**
  442. * Record sound to a file until an acceptable DTMF digit is received or a specified amount of
  443. * time has passed. Optionally the file BEEP is played before recording begins.
  444. *
  445. * @link http://www.voip-info.org/wiki-record+file
  446. * @param string $file to record, without extension, often created in /var/lib/asterisk/sounds
  447. * @param string $format of the file. GSM and WAV are commonly used formats. MP3 is read-only and thus cannot be used.
  448. * @param string $escape_digits
  449. * @param integer $timeout is the maximum record time in milliseconds, or -1 for no timeout.
  450. * @param integer $offset to seek to without exceeding the end of the file.
  451. * @param boolean $beep
  452. * @param integer $silence number of seconds of silence allowed before the function returns despite the
  453. * lack of dtmf digits or reaching timeout.
  454. * @return array, see evaluate for return information. ['result'] is -1 on error, 0 on hangup, otherwise a decimal value of the
  455. * DTMF tone. Use chr() to convert to ASCII.
  456. */
  457. function record_file($file, $format, $escape_digits='', $timeout=-1, $offset=NULL, $beep=false, $silence=NULL)
  458. {
  459. $cmd = trim("RECORD FILE $file $format \"$escape_digits\" $timeout $offset");
  460. if($beep) $cmd .= ' BEEP';
  461. if(!is_null($silence)) $cmd .= " s=$silence";
  462. return $this->evaluate($cmd);
  463. }
  464. /**
  465. * Say the given digit string, returning early if any of the given DTMF escape digits are received on the channel.
  466. *
  467. * @link http://www.voip-info.org/wiki-say+digits
  468. * @param integer $digits
  469. * @param string $escape_digits
  470. * @return array, see evaluate for return information. ['result'] is -1 on hangup or error, 0 if playback completes with no
  471. * digit received, otherwise a decimal value of the DTMF tone. Use chr() to convert to ASCII.
  472. */
  473. function say_digits($digits, $escape_digits='')
  474. {
  475. if ($this->GetCfgVar(NULL,'play_audio', true)){
  476. return $this->evaluate("SAY DIGITS $digits \"$escape_digits\"");
  477. }
  478. }
  479. /**
  480. * Say the given number, returning early if any of the given DTMF escape digits are received on the channel.
  481. *
  482. * @link http://www.voip-info.org/wiki-say+number
  483. * @param integer $number
  484. * @param string $escape_digits
  485. * @return array, see evaluate for return information. ['result'] is -1 on hangup or error, 0 if playback completes with no
  486. * digit received, otherwise a decimal value of the DTMF tone. Use chr() to convert to ASCII.
  487. */
  488. function say_number($number, $escape_digits='')
  489. {
  490. if ($this->GetCfgVar(NULL,'play_audio', true)){
  491. return $this->evaluate("SAY NUMBER $number \"$escape_digits\"");
  492. }
  493. }
  494. /**
  495. * Say the given character string, returning early if any of the given DTMF escape digits are received on the channel.
  496. *
  497. * @link http://www.voip-info.org/wiki-say+phonetic
  498. * @param string $text
  499. * @param string $escape_digits
  500. * @return array, see evaluate for return information. ['result'] is -1 on hangup or error, 0 if playback completes with no
  501. * digit received, otherwise a decimal value of the DTMF tone. Use chr() to convert to ASCII.
  502. */
  503. function say_phonetic($text, $escape_digits='')
  504. {
  505. if ($this->GetCfgVar(NULL,'play_audio', true)){
  506. return $this->evaluate("SAY PHONETIC $text \"$escape_digits\"");
  507. }
  508. }
  509. /**
  510. * Say a given time, returning early if any of the given DTMF escape digits are received on the channel.
  511. *
  512. * @link http://www.voip-info.org/wiki-say+time
  513. * @param integer $time number of seconds elapsed since 00:00:00 on January 1, 1970, Coordinated Universal Time (UTC).
  514. * @param string $escape_digits
  515. * @return array, see evaluate for return information. ['result'] is -1 on hangup or error, 0 if playback completes with no
  516. * digit received, otherwise a decimal value of the DTMF tone. Use chr() to convert to ASCII.
  517. */
  518. function say_time($time=NULL, $escape_digits='')
  519. {
  520. if ($this->GetCfgVar(NULL,'play_audio', true)){
  521. if(is_null($time)) $time = time();
  522. return $this->evaluate("SAY TIME $time \"$escape_digits\"");
  523. }
  524. }
  525. /**
  526. * Send the specified image on a channel.
  527. *
  528. * Most channels do not support the transmission of images.
  529. *
  530. * @link http://www.voip-info.org/wiki-send+image
  531. * @param string $image without extension, often in /var/lib/asterisk/images
  532. * @return array, see evaluate for return information. ['result'] is -1 on hangup or error, 0 if the image is sent or
  533. * channel does not support image transmission.
  534. */
  535. function send_image($image)
  536. {
  537. return $this->evaluate("SEND IMAGE $image");
  538. }
  539. /**
  540. * Send the given text to the connected channel.
  541. *
  542. * Most channels do not support transmission of text.
  543. *
  544. * @link http://www.voip-info.org/wiki-send+text
  545. * @param $text
  546. * @return array, see evaluate for return information. ['result'] is -1 on hangup or error, 0 if the text is sent or
  547. * channel does not support text transmission.
  548. */
  549. function send_text($text)
  550. {
  551. return $this->evaluate("SEND TEXT \"$text\"");
  552. }
  553. /**
  554. * Cause the channel to automatically hangup at $time seconds in the future.
  555. * If $time is 0 then the autohangup feature is disabled on this channel.
  556. *
  557. * If the channel is hungup prior to $time seconds, this setting has no effect.
  558. *
  559. * @link http://www.voip-info.org/wiki-set+autohangup
  560. * @param integer $time until automatic hangup
  561. * @return array, see evaluate for return information.
  562. */
  563. function set_autohangup($time=0)
  564. {
  565. return $this->evaluate("SET AUTOHANGUP $time");
  566. }
  567. /**
  568. * Changes the caller ID of the current channel.
  569. *
  570. * @link http://www.voip-info.org/wiki-set+callerid
  571. * @param string $cid example: "John Smith"<1234567>
  572. * This command will let you take liberties with the <caller ID specification> but the format shown in the example above works
  573. * well: the name enclosed in double quotes followed immediately by the number inside angle brackets. If there is no name then
  574. * you can omit it. If the name contains no spaces you can omit the double quotes around it. The number must follow the name
  575. * immediately; don't put a space between them. The angle brackets around the number are necessary; if you omit them the
  576. * number will be considered to be part of the name.
  577. * @return array, see evaluate for return information.
  578. */
  579. function set_callerid($cid)
  580. {
  581. return $this->evaluate("SET CALLERID $cid");
  582. }
  583. /**
  584. * Sets the context for continuation upon exiting the application.
  585. *
  586. * Setting the context does NOT automatically reset the extension and the priority; if you want to start at the top of the new
  587. * context you should set extension and priority yourself.
  588. *
  589. * If you specify a non-existent context you receive no error indication (['result'] is still 0) but you do get a
  590. * warning message on the Asterisk console.
  591. *
  592. * @link http://www.voip-info.org/wiki-set+context
  593. * @param string $context
  594. * @return array, see evaluate for return information.
  595. */
  596. function set_context($context)
  597. {
  598. return $this->evaluate("SET CONTEXT $context");
  599. }
  600. /**
  601. * Set the extension to be used for continuation upon exiting the application.
  602. *
  603. * Setting the extension does NOT automatically reset the priority. If you want to start with the first priority of the
  604. * extension you should set the priority yourself.
  605. *
  606. * If you specify a non-existent extension you receive no error indication (['result'] is still 0) but you do
  607. * get a warning message on the Asterisk console.
  608. *
  609. * @link http://www.voip-info.org/wiki-set+extension
  610. * @param string $extension
  611. * @return array, see evaluate for return information.
  612. */
  613. function set_extension($extension)
  614. {
  615. return $this->evaluate("SET EXTENSION $extension");
  616. }
  617. /**
  618. * Enable/Disable Music on hold generator.
  619. *
  620. * @link http://www.voip-info.org/wiki-set+music
  621. * @param boolean $enabled
  622. * @param string $class
  623. * @return array, see evaluate for return information.
  624. */
  625. function set_music($enabled=true, $class='')
  626. {
  627. $enabled = ($enabled) ? 'ON' : 'OFF';
  628. return $this->evaluate("SET MUSIC $enabled $class");
  629. }
  630. /**
  631. * Set the priority to be used for continuation upon exiting the application.
  632. *
  633. * If you specify a non-existent priority you receive no error indication (['result'] is still 0)
  634. * and no warning is issued on the Asterisk console.
  635. *
  636. * @link http://www.voip-info.org/wiki-set+priority
  637. * @param integer $priority
  638. * @return array, see evaluate for return information.
  639. */
  640. function set_priority($priority)
  641. {
  642. return $this->evaluate("SET PRIORITY $priority");
  643. }
  644. /**
  645. * Sets a variable to the specified value. The variables so created can later be used by later using ${<variablename>}
  646. * in the dialplan.
  647. *
  648. * These variables live in the channel Asterisk creates when you pickup a phone and as such they are both local and temporary.
  649. * Variables created in one channel can not be accessed by another channel. When you hang up the phone, the channel is deleted
  650. * and any variables in that channel are deleted as well.
  651. *
  652. * @link http://www.voip-info.org/wiki-set+variable
  653. * @param string $variable is case sensitive
  654. * @param string $value
  655. * @return array, see evaluate for return information.
  656. */
  657. function set_variable($variable, $value)
  658. {
  659. $value = str_replace("\n", '\n', addslashes($value));
  660. return $this->evaluate("SET VARIABLE $variable \"$value\"");
  661. }
  662. /**
  663. * Play the given audio file, allowing playback to be interrupted by a DTMF digit. This command is similar to the GET DATA
  664. * command but this command returns after the first DTMF digit has been pressed while GET DATA can accumulated any number of
  665. * digits before returning.
  666. *
  667. * @note Addition: if the channel is not answered yet, respect that!
  668. * Note: If the channel is answered, it makes sense to allow skip
  669. * of the message with '#'. If not, the audio path is one-way, so
  670. * we cannot hear any sound. This fn behaves accordingly.
  671. *
  672. * @example examples/ping.php Ping an IP address
  673. *
  674. * @link http://www.voip-info.org/wiki-stream+file
  675. * @param string $filename without extension, often in /var/lib/asterisk/sounds
  676. * @param string $escape_digits
  677. * @param integer $offset
  678. * @return array, see evaluate for return information. ['result'] is -1 on hangup or error, 0 if playback completes with no
  679. * digit received, otherwise a decimal value of the DTMF tone. Use chr() to convert to ASCII.
  680. */
  681. function stream_file($filename, $escape_digits='', $offset=0)
  682. {
  683. if (!$this->GetCfgVar(NULL,'play_audio', true))
  684. return;
  685. if ($this->is_answered)
  686. return $this->evaluate("STREAM FILE $filename \"$escape_digits\" $offset");
  687. else {
  688. return $this->evaluate("EXEC Playback $filename".$this->ast_sep."noanswer");
  689. }
  690. }
  691. /**
  692. * Enable or disable TDD transmission/reception on the current channel.
  693. *
  694. * @link http://www.voip-info.org/wiki-tdd+mode
  695. * @param string $setting can be on, off or mate
  696. * @return array, see evaluate for return information. ['result'] is 1 on sucess, 0 if the channel is not TDD capable.
  697. */
  698. function tdd_mode($setting)
  699. {
  700. return $this->evaluate("TDD MODE $setting");
  701. }
  702. /**
  703. * Sends $message to the Asterisk console via the 'verbose' message system.
  704. *
  705. * If the Asterisk verbosity level is $level or greater, send $message to the console.
  706. *
  707. * The Asterisk verbosity system works as follows. The Asterisk user gets to set the desired verbosity at startup time or later
  708. * using the console 'set verbose' command. Messages are displayed on the console if their verbose level is less than or equal
  709. * to desired verbosity set by the user. More important messages should have a low verbose level; less important messages
  710. * should have a high verbose level.
  711. *
  712. * @link http://www.voip-info.org/wiki-verbose
  713. * @param string $message
  714. * @param integer $level from 1 to 4
  715. * @return array, see evaluate for return information.
  716. */
  717. function verbose($message, $level=1)
  718. {
  719. switch ($level){
  720. case 0:
  721. $syslvl = LOG_ERR;
  722. break;
  723. case 1:
  724. $syslvl = LOG_WARNING;
  725. break;
  726. case 2:
  727. $syslvl = LOG_NOTICE;
  728. break;
  729. case 3:
  730. $syslvl = LOG_INFO;
  731. break;
  732. case 4:
  733. $syslvl = LOG_DEBUG;
  734. break;
  735. default:
  736. //$msg .= "\n what is level $level?";
  737. $syslvl = LOG_NOTICE;
  738. break;
  739. }
  740. foreach(explode("\n", str_replace("\r\n", "\n", print_r($message, true))) as $msg)
  741. {
  742. @syslog($syslvl, $msg);
  743. $msg = str_replace('"',"'",$msg);
  744. $ret = $this->evaluate("VERBOSE \"$msg\" $level");
  745. }
  746. return $ret;
  747. }
  748. static function verbose_s($message, $level=1)
  749. {
  750. foreach(explode("\n", str_replace("\r\n", "\n", print_r($message, true))) as $msg)
  751. {
  752. @syslog(LOG_WARNING, $msg);
  753. echo "VERBOSE \"$msg\" $level\n";
  754. }
  755. }
  756. /**
  757. * Waits up to $timeout milliseconds for channel to receive a DTMF digit.
  758. *
  759. * @link http://www.voip-info.org/wiki-wait+for+digit
  760. * @param integer $timeout in millisecons. Use -1 for the timeout value if you want the call to wait indefinitely.
  761. * @return array, see evaluate for return information. ['result'] is 0 if wait completes with no
  762. * digit received, otherwise a decimal value of the DTMF tone. Use chr() to convert to ASCII.
  763. */
  764. function wait_for_digit($timeout=-1)
  765. {
  766. return $this->evaluate("WAIT FOR DIGIT $timeout");
  767. }
  768. // *********************************************************************************************************
  769. // ** APPLICATIONS **
  770. // *********************************************************************************************************
  771. /**
  772. * Set absolute maximum time of call.
  773. *
  774. * Note that the timeout is set from the current time forward, not counting the number of seconds the call has already been up.
  775. * Each time you call AbsoluteTimeout(), all previous absolute timeouts are cancelled.
  776. * Will return the call to the T extension so that you can playback an explanatory note to the calling party (the called party
  777. * will not hear that)
  778. *
  779. * @link http://www.voip-info.org/wiki-Asterisk+-+documentation+of+application+commands
  780. * @link http://www.dynx.net/ASTERISK/AGI/ccard/agi-ccard.agi
  781. * @param $seconds allowed, 0 disables timeout
  782. * @return array, see evaluate for return information.
  783. */
  784. function exec_absolutetimeout($seconds=0)
  785. {
  786. return $this->exec('AbsoluteTimeout', $seconds);
  787. }
  788. /**
  789. * Executes an AGI compliant application.
  790. *
  791. * @param string $command
  792. * @return array, see evaluate for return information. ['result'] is -1 on hangup or if application requested hangup, or 0 on non-hangup exit.
  793. * @param string $args
  794. */
  795. function exec_agi($command, $args)
  796. {
  797. return $this->exec("AGI $command", $args);
  798. }
  799. /**
  800. * Set Language.
  801. *
  802. * @param string $language code
  803. * @return array, see evaluate for return information.
  804. * !! Depreciate on asterisk 1.2 & 1.4
  805. */
  806. function exec_setlanguage($language='en')
  807. {
  808. return $this->exec('SetLanguage', $language);
  809. }
  810. /**
  811. * Set Account Code
  812. * Set the channel account code for billing purposes.
  813. *
  814. * @param string $accountcode
  815. * @return array, see evaluate for return information.
  816. */
  817. function exec_setaccountcode($accountcode)
  818. {
  819. return $this->exec('SetAccount', $accountcode);
  820. }
  821. /**
  822. * Do ENUM Lookup.
  823. *
  824. * Note: to retrieve the result, use
  825. * get_variable('ENUM');
  826. *
  827. * @param $exten
  828. * @return array, see evaluate for return information.
  829. */
  830. function exec_enumlookup($exten)
  831. {
  832. return $this->exec('EnumLookup', $exten);
  833. }
  834. /**
  835. * Dial.
  836. *
  837. * Dial takes input from ${VXML_URL} to send XML Url to Cisco 7960
  838. * Dial takes input from ${ALERT_INFO} to set ring cadence for Cisco phones
  839. * Dial returns ${CAUSECODE}: If the dial failed, this is the errormessage.
  840. * Dial returns ${DIALSTATUS}: Text code returning status of last dial attempt.
  841. *
  842. * @link http://www.voip-info.org/wiki-Asterisk+cmd+Dial
  843. * @param string $type
  844. * @param string $identifier
  845. * @param integer $timeout
  846. * @param string $options
  847. * @param string $url
  848. * @return array, see evaluate for return information.
  849. */
  850. function exec_dial($type, $identifier, $timeout=NULL, $options=NULL, $url=NULL)
  851. {
  852. $parms = array("$type/$identifier");
  853. if ($timeout) array_push($parms,$timeout);
  854. if ($options) array_push($parms,$options);
  855. if ($url) array_push($parms,$url);
  856. return $this->exec('Dial', $parms);
  857. }
  858. /**
  859. * Goto.
  860. *
  861. * This function takes three arguments: context,extension, and priority, but the leading arguments
  862. * are optional, not the trailing arguments. Thuse goto($z) sets the priority to $z.
  863. *
  864. * @param string $a
  865. * @param string $b;
  866. * @param string $c;
  867. * @return array, see evaluate for return information.
  868. */
  869. function exec_goto($a, $b=NULL, $c=NULL)
  870. {
  871. $parms = array("$a");
  872. if ($b) array_push($parms,$b);
  873. if ($c) array_push($parms,$c);
  874. return $this->exec('Goto', $parms);
  875. }
  876. // *********************************************************************************************************
  877. // ** FAST PASSING **
  878. // *********************************************************************************************************
  879. /**
  880. * Say the given digit string, returning early if any of the given DTMF escape digits are received on the channel.
  881. * Return early if $buffer is adequate for request.
  882. *
  883. * @link http://www.voip-info.org/wiki-say+digits
  884. * @param string $buffer
  885. * @param integer $digits
  886. * @param string $escape_digits
  887. * @return array, see evaluate for return information. ['result'] is -1 on hangup or error, 0 if playback completes with no
  888. * digit received, otherwise a decimal value of the DTMF tone. Use chr() to convert to ASCII.
  889. */
  890. function fastpass_say_digits(&$buffer, $digits, $escape_digits='')
  891. {
  892. $proceed = false;
  893. if($escape_digits != '' && $buffer != '')
  894. {
  895. if(!strpos(chr(255) . $escape_digits, $buffer{strlen($buffer)-1}))
  896. $proceed = true;
  897. }
  898. if($buffer == '' || $proceed)
  899. {
  900. $res = $this->say_digits($digits, $escape_digits);
  901. if($res['code'] == AGIRES_OK && $res['result'] > 0)
  902. $buffer .= chr($res['result']);
  903. return $res;
  904. }
  905. return array('code'=>AGIRES_OK, 'result'=>ord($buffer{strlen($buffer)-1}));
  906. }
  907. /**
  908. * Say the given number, returning early if any of the given DTMF escape digits are received on the channel.
  909. * Return early if $buffer is adequate for request.
  910. *
  911. * @link http://www.voip-info.org/wiki-say+number
  912. * @param string $buffer
  913. * @param integer $number
  914. * @param string $escape_digits
  915. * @return array, see evaluate for return information. ['result'] is -1 on hangup or error, 0 if playback completes with no
  916. * digit received, otherwise a decimal value of the DTMF tone. Use chr() to convert to ASCII.
  917. */
  918. function fastpass_say_number(&$buffer, $number, $escape_digits='')
  919. {
  920. $proceed = false;
  921. if($escape_digits != '' && $buffer != '')
  922. {
  923. if(!strpos(chr(255) . $escape_digits, $buffer{strlen($buffer)-1}))
  924. $proceed = true;
  925. }
  926. if($buffer == '' || $proceed)
  927. {
  928. $res = $this->say_number($number, $escape_digits);
  929. if($res['code'] == AGIRES_OK && $res['result'] > 0)
  930. $buffer .= chr($res['result']);
  931. return $res;
  932. }
  933. return array('code'=>AGIRES_OK, 'result'=>ord($buffer{strlen($buffer)-1}));
  934. }
  935. /**
  936. * Say the given character string, returning early if any of the given DTMF escape digits are received on the channel.
  937. * Return early if $buffer is adequate for request.
  938. *
  939. * @link http://www.voip-info.org/wiki-say+phonetic
  940. * @param string $buffer
  941. * @param string $text
  942. * @param string $escape_digits
  943. * @return array, see evaluate for return information. ['result'] is -1 on hangup or error, 0 if playback completes with no
  944. * digit received, otherwise a decimal value of the DTMF tone. Use chr() to convert to ASCII.
  945. */
  946. function fastpass_say_phonetic(&$buffer, $text, $escape_digits='')
  947. {
  948. $proceed = false;
  949. if($escape_digits != '' && $buffer != '')
  950. {
  951. if(!strpos(chr(255) . $escape_digits, $buffer{strlen($buffer)-1}))
  952. $proceed = true;
  953. }
  954. if($buffer == '' || $proceed)
  955. {
  956. $res = $this->say_phonetic($text, $escape_digits);
  957. if($res['code'] == AGIRES_OK && $res['result'] > 0)
  958. $buffer .= chr($res['result']);
  959. return $res;
  960. }
  961. return array('code'=>AGIRES_OK, 'result'=>ord($buffer{strlen($buffer)-1}));
  962. }
  963. /**
  964. * Say a given time, returning early if any of the given DTMF escape digits are received on the channel.
  965. * Return early if $buffer is adequate for request.
  966. *
  967. * @link http://www.voip-info.org/wiki-say+time
  968. * @param string $buffer
  969. * @param integer $time number of seconds elapsed since 00:00:00 on January 1, 1970, Coordinated Universal Time (UTC).
  970. * @param string $escape_digits
  971. * @return array, see evaluate for return information. ['result'] is -1 on hangup or error, 0 if playback completes with no
  972. * digit received, otherwise a decimal value of the DTMF tone. Use chr() to convert to ASCII.
  973. */
  974. function fastpass_say_time(&$buffer, $time=NULL, $escape_digits='')
  975. {
  976. $proceed = false;
  977. if($escape_digits != '' && $buffer != '')
  978. {
  979. if(!strpos(chr(255) . $escape_digits, $buffer{strlen($buffer)-1}))
  980. $proceed = true;
  981. }
  982. if($buffer == '' || $proceed)
  983. {
  984. $res = $this->say_time($time, $escape_digits);
  985. if($res['code'] == AGIRES_OK && $res['result'] > 0)
  986. $buffer .= chr($res['result']);
  987. return $res;
  988. }
  989. return array('code'=>AGIRES_OK, 'result'=>ord($buffer{strlen($buffer)-1}));
  990. }
  991. /**
  992. * Play the given audio file, allowing playback to be interrupted by a DTMF digit. This command is similar to the GET DATA
  993. * command but this command returns after the first DTMF digit has been pressed while GET DATA can accumulated any number of
  994. * digits before returning.
  995. * Return early if $buffer is adequate for request.
  996. *
  997. * @link http://www.voip-info.org/wiki-stream+file
  998. * @param string $buffer
  999. * @param string $filename without extension, often in /var/lib/asterisk/sounds
  1000. * @param string $escape_digits
  1001. * @param integer $offset
  1002. * @return array, see evaluate for return information. ['result'] is -1 on hangup or error, 0 if playback completes with no
  1003. * digit received, otherwise a decimal value of the DTMF tone. Use chr() to convert to ASCII.
  1004. */
  1005. function fastpass_stream_file(&$buffer, $filename, $escape_digits='', $offset=0)
  1006. {
  1007. $proceed = false;
  1008. if($escape_digits != '' && $buffer != '')
  1009. {
  1010. if(!strpos(chr(255) . $escape_digits, $buffer{strlen($buffer)-1}))
  1011. $proceed = true;
  1012. }
  1013. if($buffer == '' || $proceed)
  1014. {
  1015. $res = $this->stream_file($filename, $escape_digits, $offset);
  1016. if($res['code'] == AGIRES_OK && $res['result'] > 0)
  1017. $buffer .= chr($res['result']);
  1018. return $res;
  1019. }
  1020. return array('code'=>AGIRES_OK, 'result'=>ord($buffer{strlen($buffer)-1}), 'endpos'=>0);
  1021. }
  1022. /**
  1023. * Use festival to read text.
  1024. * Return early if $buffer is adequate for request.
  1025. *
  1026. * @link http://www.cstr.ed.ac.uk/projects/festival/
  1027. * @param string $buffer
  1028. * @param string $text
  1029. * @param string $escape_digits
  1030. * @param integer $frequency
  1031. * @return array, see evaluate for return information.
  1032. */
  1033. function fastpass_text2wav(&$buffer, $text, $escape_digits='', $frequency=8000)
  1034. {
  1035. $proceed = false;
  1036. if($escape_digits != '' && $buffer != '')
  1037. {
  1038. if(!strpos(chr(255) . $escape_digits, $buffer{strlen($buffer)-1}))
  1039. $proceed = true;
  1040. }
  1041. if($buffer == '' || $proceed)
  1042. {
  1043. $res = $this->text2wav($text, $escape_digits, $frequency);
  1044. if($res['code'] == AGIRES_OK && $res['result'] > 0)
  1045. $buffer .= chr($res['result']);
  1046. return $res;
  1047. }
  1048. return array('code'=>AGIRES_OK, 'result'=>ord($buffer{strlen($buffer)-1}), 'endpos'=>0);
  1049. }
  1050. /**
  1051. * Use Cepstral Swift to read text.
  1052. * Return early if $buffer is adequate for request.
  1053. *
  1054. * @link http://www.cepstral.com/
  1055. * @param string $buffer
  1056. * @param string $text
  1057. * @param string $escape_digits
  1058. * @param integer $frequency
  1059. * @return array, see evaluate for return information.
  1060. */
  1061. function fastpass_swift(&$buffer, $text, $escape_digits='', $frequency=8000, $voice=NULL)
  1062. {
  1063. $proceed = false;
  1064. if($escape_digits != '' && $buffer != '')
  1065. {
  1066. if(!strpos(chr(255) . $escape_digits, $buffer{strlen($buffer)-1}))
  1067. $proceed = true;
  1068. }
  1069. if($buffer == '' || $proceed)
  1070. {
  1071. $res = $this->swift($text, $escape_digits, $frequency, $voice);
  1072. if($res['code'] == AGIRES_OK && $res['result'] > 0)
  1073. $buffer .= chr($res['result']);
  1074. return $res;
  1075. }
  1076. return array('code'=>AGIRES_OK, 'result'=>ord($buffer{strlen($buffer)-1}), 'endpos'=>0);
  1077. }
  1078. /**
  1079. * Say Puncutation in a string.
  1080. * Return early if $buffer is adequate for request.
  1081. *
  1082. * @param string $buffer
  1083. * @param string $text
  1084. * @param string $escape_digits
  1085. * @param integer $frequency
  1086. * @return array, see evaluate for return information.
  1087. */
  1088. function fastpass_say_punctuation(&$buffer, $text, $escape_digits='', $frequency=8000)
  1089. {
  1090. $proceed = false;
  1091. if($escape_digits != '' && $buffer != '')
  1092. {
  1093. if(!strpos(chr(255) . $escape_digits, $buffer{strlen($buffer)-1}))
  1094. $proceed = true;
  1095. }
  1096. if($buffer == '' || $proceed)
  1097. {
  1098. $res = $this->say_punctuation($text, $escape_digits, $frequency);
  1099. if($res['code'] == AGIRES_OK && $res['result'] > 0)
  1100. $buffer .= chr($res['result']);
  1101. return $res;
  1102. }
  1103. return array('code'=>AGIRES_OK, 'result'=>ord($buffer{strlen($buffer)-1}));
  1104. }
  1105. /**
  1106. * Plays the given file and receives DTMF data.
  1107. * Return early if $buffer is adequate for request.
  1108. *
  1109. * This is similar to STREAM FILE, but this command can accept and return many DTMF digits,
  1110. * while STREAM FILE returns immediately after the first DTMF digit is detected.
  1111. *
  1112. * Asterisk looks for the file to play in /var/lib/asterisk/sounds by default.
  1113. *
  1114. * If the user doesn't press any keys when the message plays, there is $timeout milliseconds
  1115. * of silence then the command ends.
  1116. *
  1117. * The user has the opportunity to press a key at any time during the message or the
  1118. * post-message silence. If the user presses a key while the message is playing, the
  1119. * message stops playing. When the first key is pressed a timer starts counting for
  1120. * $timeout milliseconds. Every time the user presses another key the timer is restarted.
  1121. * The command ends when the counter goes to zero or the maximum number of digits is entered,
  1122. * whichever happens first.
  1123. *
  1124. * If you don't specify a time out then a default timeout of 2000 is used following a pressed
  1125. * digit. If no digits are pressed then 6 seconds of silence follow the message.
  1126. *
  1127. * If you don't specify $max_digits then the user can enter as many digits as they want.
  1128. *
  1129. * Pressing the # key has the same effect as the timer running out: the command ends and
  1130. * any previously keyed digits are returned. A side effect of this is that there is no
  1131. * way to read a # key using this command.
  1132. *
  1133. * @link http://www.voip-info.org/wiki-get+data
  1134. * @param string $buffer
  1135. * @param string $filename file to play. Do not include file extension.
  1136. * @param integer $timeout milliseconds
  1137. * @param integer $max_digits
  1138. * @return array, see evaluate for return information. ['result'] holds the digits and ['data'] holds the timeout if present.
  1139. *
  1140. * This differs from other commands with return DTMF as numbers representing ASCII characters.
  1141. */
  1142. function fastpass_get_data(&$buffer, $filename, $timeout=NULL, $max_digits=NULL)
  1143. {
  1144. if(is_null($max_digits) || strlen($buffer) < $max_digits)
  1145. {
  1146. if($buffer == '')
  1147. {
  1148. $res = $this->get_data($filename, $timeout, $max_digits);
  1149. if($res['code'] == AGIRES_OK)
  1150. $buffer .= $res['result'];
  1151. return $res;
  1152. }
  1153. else
  1154. {
  1155. while(is_null($max_digits) || strlen($buffer) < $max_digits)
  1156. {
  1157. $res = $this->wait_for_digit();
  1158. if($res['code'] != AGIRES_OK) return $res;
  1159. if($res['result'] == ord('#')) break;
  1160. $buffer .= chr($res['result']);
  1161. }
  1162. }
  1163. }
  1164. return array('code'=>AGIRES_OK, 'result'=>$buffer);
  1165. }
  1166. // *********************************************************************************************************
  1167. // ** DERIVED **
  1168. // *********************************************************************************************************
  1169. /**
  1170. * Menu.
  1171. *
  1172. * This function presents the user with a menu and reads the response
  1173. *
  1174. * @param array $choices has the following structure:
  1175. * array('1'=>'*Press 1 for this', // festival reads if prompt starts with *
  1176. * '2'=>'some-gsm-without-extension',
  1177. * '*'=>'*Press star for help');
  1178. * @return mixed key pressed on sucess, -1 on failure
  1179. */
  1180. function menu($choices, $timeout=2000)
  1181. {
  1182. $keys = join('', array_keys($choices));
  1183. $choice = NULL;
  1184. while(is_null($choice))
  1185. {
  1186. foreach($choices as $prompt)
  1187. {
  1188. if($prompt{0} == '*')
  1189. $ret = $this->text2wav(substr($prompt, 1), $keys);
  1190. else
  1191. $ret = $this->stream_file($prompt, $keys);
  1192. if($ret['code'] != AGIRES_OK || $ret['result'] == -1)
  1193. {
  1194. $choice = -1;
  1195. break;
  1196. }
  1197. if($ret['result'] != 0)
  1198. {
  1199. $choice = chr($ret['result']);
  1200. break;
  1201. }
  1202. }
  1203. if(is_null($choice))
  1204. {
  1205. $ret = $this->get_data('beep', $timeout, 1);
  1206. if($ret['code'] != AGIRES_OK || $ret['result'] == -1)
  1207. $choice = -1;
  1208. elseif($ret['result'] != '' && strpos(' '.$keys, $ret['result']))
  1209. $choice = $ret['result'];
  1210. }
  1211. }
  1212. return $choice;
  1213. }
  1214. /**
  1215. * Goto - Set context, extension and priority.
  1216. *
  1217. * @param string $context
  1218. * @param string $extension
  1219. * @param string $priority
  1220. */
  1221. /* *-* function goto($context, $extension='s', $priority=1)
  1222. {
  1223. $this->set_context($context);
  1224. $this->set_extension($extension);
  1225. $this->set_priority($priority);
  1226. }*/
  1227. /**
  1228. * Parse caller id.
  1229. *
  1230. * @example examples/dtmf.php Get DTMF tones from the user and say the digits
  1231. * @example examples/input.php Get text input from the user and say it back
  1232. *
  1233. * "name" <proto:user@server:port>
  1234. *
  1235. * @param string $callerid
  1236. * @return array('Name'=>$name, 'Number'=>$number)
  1237. */
  1238. function parse_callerid($callerid=NULL)
  1239. {
  1240. if(is_null($callerid))
  1241. $callerid = $this->request['agi_callerid'];
  1242. $ret = array('name'=>'', 'protocol'=>'', 'username'=>'', 'host'=>'', 'port'=>'');
  1243. $callerid = trim($callerid);
  1244. if($callerid{0} == '"' || $callerid{0} == "'")
  1245. {
  1246. $d = $callerid{0};
  1247. $callerid = explode($d, substr($callerid, 1));
  1248. $ret['name'] = array_shift($callerid);
  1249. $callerid = join($d, $callerid);
  1250. }
  1251. $callerid = explode('@', trim($callerid, '<> '));
  1252. $username = explode(':', array_shift($callerid));
  1253. if(count($username) == 1)
  1254. $ret['username'] = $username[0];
  1255. else
  1256. {
  1257. $ret['protocol'] = ar

Large files files are truncated, but you can click here to view the full file