-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathAMI.php
106 lines (99 loc) · 2.91 KB
/
AMI.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
<?php
define('AMI_DEBUG_LOG', 'log.txt');
class AMI {
public $aslver = '2.0/unknown';
function connect($host) {
// Set default port if not provided
$arr = explode(':', $host);
$ip = $arr[0];
$port = isset($arr[1]) ? $arr[1] : 5038;
return fsockopen($ip, $port, $errno, $errstr, 5);
}
function login($fp, $user, $password) {
$actionID = $user . $password;
fwrite($fp,"ACTION: LOGIN\r\nUSERNAME: $user\r\nSECRET: $password\r\nEVENTS: 0\r\nActionID: $actionID\r\n\r\n");
$res = $this->getResponse($fp, $actionID);
// logToFile('RES: ' . varDumpClean($res, true), AMI_DEBUG_LOG);
$ok = (strpos($res[2], "Authentication accepted") !== false);
// Determine App-rpt version. ASL3 and Asterisk 20 have some differences in AMI commands
// eg. in ASL2 restart command is "restart now" but in ASL3 it's "core restart now".
$s = $this->command($fp, 'rpt show version');
if(preg_match('/app_rpt version: ([0-9\.]{1,9})/', $s, $m) == 1)
$this->aslver = $m[1];
}
function command($fp, $cmdString, $debug=false) {
// Generate ActionID to associate with response
$actionID = 'cpAction_' . mt_rand();
$ok = true;
$msg = [];
if((fwrite($fp, "ACTION: COMMAND\r\nCOMMAND: $cmdString\r\nActionID: $actionID\r\n\r\n")) > 0) {
if($debug)
logToFile('CMD: ' . $cmdString . ' - ' . $actionID, AMI_DEBUG_LOG);
$res = $this->getResponse($fp, $actionID, $debug);
if(!is_array($res))
return $res;
// Check for Asterisk AMI Success/Error response
foreach($res as $r) {
if($r === 'Response: Error')
$ok = false;
elseif(preg_match('/Output: (.*)/', $r, $m) == 1)
$msg[] = $m[1];
}
if(_count($msg))
return implode(NL, $msg);
if($ok)
return 'OK';
return 'ERROR';
}
return "Get node $cmdString failed";
}
/* Example ASL2 AMI response:
Response: Follows
Privilege: Command
ActionID: cpAction_...
--END COMMAND--
Example ASL3 AMI response:
Response: Success
Command output follows
Output:
ActionID: cpAction_...
=> "Response:" line indicates success of associated ActionID.
*/
function getResponse($fp, $actionID, $debug=false) {
$ignore = ['Privilege: Command', 'Command output follows'];
$t0 = time();
$response = [];
if($debug)
$sn = getScriptName();
while(time() - $t0 < 20) {
$str = fgets($fp);
if($str === false)
return $response;
$str = trim($str);
if($str === '')
continue;
if($debug)
logToFile("$sn 1: $str", AMI_DEBUG_LOG);
if(strpos($str, 'Response: ') === 0) {
$response[] = $str;
} elseif($str === "ActionID: $actionID") {
$response[] = $str;
while(time() - $t0 < 20) {
$str = fgets($fp);
if($str === "\r\n" || $str[0] === "\n" || $str === false)
return $response;
$str = trim($str);
if($str === '' || in_array($str, $ignore))
continue;
$response[] = $str;
if($debug)
logToFile("$sn 2: $str", AMI_DEBUG_LOG);
}
}
}
if(count($response))
return $response;
logToFile("$sn: Timeout", AMI_DEBUG_LOG);
return 'Timeout';
}
}