159 lines
5.1 KiB
PHP
159 lines
5.1 KiB
PHP
<?php
|
||
|
||
/**
|
||
* Класс для работы с Asterisk по протоколу AMI через сокет.
|
||
* Реализовано: подключение, авторизация, отправка команд, отправка СМС, отключение.
|
||
* Успешно работало на проде в связке с Yeastar TG400.
|
||
*
|
||
* Class to work with Asterisk gateway throuth AMI protocol via socket.
|
||
* Features: connection, authorization, send commands, send SMS, disconnect.
|
||
* Successfully used in production with Yeastar TG400.
|
||
*
|
||
* @see https://habr.com/post/253387/
|
||
* @see https://gist.github.com/anthonyaxenov/12cff2bea5fae1f1c5b40b886340b2ba
|
||
*/
|
||
class AMI {
|
||
|
||
/** string Параметры подключения к Asterisk. Asterisk config. */
|
||
private const AMI_HOST = '192.168.1.19';
|
||
private const AMI_PORT = 5038;
|
||
private const AMI_USER = 'user';
|
||
private const AMI_PASS = 'useruser';
|
||
|
||
/** int Код последней операции. Last action ID. */
|
||
public $lastActionID = 0;
|
||
|
||
/** array Массив строк результата последней операции. Array of strings with result of last action. */
|
||
public $lastRead = [];
|
||
|
||
/** resource Подключение к сокету. Connection socket. */
|
||
private $connection;
|
||
|
||
/** array Описывает данные о последней СМС. Describes last SMS data. */
|
||
private $sms_data = [];
|
||
|
||
/**
|
||
* AMI constructor.
|
||
*/
|
||
function __construct() {
|
||
$this->connect();
|
||
}
|
||
|
||
/**
|
||
* Соединяет со шлюзом.
|
||
* Connects with gateway.
|
||
*
|
||
* @return bool
|
||
*/
|
||
public function connect() {
|
||
$this->connection = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
|
||
if ($this->connection === FALSE) {
|
||
echo "Cannot socket_create(): ".socket_strerror(socket_last_error())."\n";
|
||
return FALSE;
|
||
}
|
||
if (socket_connect($this->connection, self::AMI_HOST, self::AMI_PORT) === FALSE) {
|
||
echo "Cannot socket_connect(): ".socket_strerror(socket_last_error())."\n";
|
||
return FALSE;
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
/**
|
||
* Авторизирует на шлюзе.
|
||
* Authorizes on gateway.
|
||
*
|
||
* @return bool
|
||
*/
|
||
public function auth(): bool {
|
||
$command = [
|
||
"Action: Login",
|
||
"Username: ".self::AMI_USER,
|
||
"Secret: ".self::AMI_PASS,
|
||
];
|
||
$this->command($command);
|
||
return $this->lastRead["Response"] === "Success";
|
||
}
|
||
|
||
/**
|
||
* Пишет данные в сокет.
|
||
* Writes data into socket.
|
||
*
|
||
* @param array $command
|
||
* @return int
|
||
*/
|
||
public function write(array $command): int {
|
||
$this->lastActionID = rand(10000000000000000, 99999999900000000);
|
||
$string = implode("\r\n", $command);
|
||
socket_write($this->connection, "ActionID: {$this->lastActionID}\r\n{$string}\r\n\r\n");
|
||
return $this->lastActionID;
|
||
}
|
||
|
||
/**
|
||
* Читает данные из сокета.
|
||
* Reads data from socket.
|
||
*
|
||
* @return array
|
||
*/
|
||
public function read(): array {
|
||
$result = [];
|
||
$data = socket_read($this->connection, 1024);
|
||
$data = str_replace("Asterisk Call Manager/1.1\r\n", '', $data);
|
||
$data = explode("\r\n", trim($data));
|
||
foreach ($data as $key => $string) {
|
||
$pos = strpos($string, ':');
|
||
$key = substr($string, 0, $pos);
|
||
$string = substr($string, $pos + 2, strlen($string));
|
||
$result[$key] = $string;
|
||
}
|
||
return $this->lastRead = $result;
|
||
}
|
||
|
||
/**
|
||
* Отправляет команду шлюзу и возвращает ответ.
|
||
* Sends command throuth socket and returns response.
|
||
*
|
||
* @param array $command
|
||
* @return array
|
||
*/
|
||
public function command(array $command): array {
|
||
$this->write($command);
|
||
return $this->read();
|
||
}
|
||
|
||
/**
|
||
* Отправляет СМС.
|
||
* Sends SMS.
|
||
*
|
||
* @param string $phone_number
|
||
* @param string $sms_text
|
||
* @param int $sim_id
|
||
* @return int SMS ID
|
||
*/
|
||
public function sendSMS(int $dispatch_id, string $phone_number, string $sms_text, int $sim_id): int {
|
||
$this->sms_data['sim_id'] = $sim_id;
|
||
$this->sms_data['phone_number'] = $phone_number;
|
||
$this->sms_data['text'] = $sms_text;
|
||
$this->sms_data['date_send'] = date('Y-m-d H:i:s');
|
||
// $this->sms_data['date_status'] = "NULL";
|
||
$this->sms_data['status'] = 0;
|
||
$smsid = $this->writeSmsReport();
|
||
$command = [
|
||
"Action: smscommand",
|
||
"command: gsm send sms ".($sim_id + 1)." {$phone_number} \"".urlencode($sms_text)."\" ID{$smsid}",
|
||
];
|
||
$this->command($command);
|
||
return $smsid;
|
||
}
|
||
|
||
/**
|
||
* Отключает от шлюза и закрывает сокет.
|
||
* Disconnects from gateway and closes socket.
|
||
*/
|
||
public function disconnect() {
|
||
if ($this->connection) {
|
||
$this->write(["Action: Logoff"]);
|
||
socket_close($this->connection);
|
||
}
|
||
}
|
||
}
|