File Source for phpagi_1.php

# Source for file phpagi_1.php

Documentation is available at phpagi_1.php

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

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