master
Anthony Axenov 2022-01-11 08:13:24 +08:00
parent ed3a5e044f
commit f4d8a27b5b
Signed by: anthony
GPG Key ID: EA9EC32FF7CCD4EC
4 changed files with 163 additions and 1 deletions

View File

@ -12,3 +12,5 @@ cmake ..
make
make install
```
https://gist.github.com/anthonyaxenov/0ca957e4aab7bae3636746dc696346ec

158
php/AMI.php 100644
View File

@ -0,0 +1,158 @@
<?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);
}
}
}

View File

@ -3,7 +3,8 @@
* Простой класс для получения данных о пространстве на диске, разделе, в директории
* Может работать некорректно на shared-хостингах и при попытке получить данные
* о корневом разделе.
* https://gist.github.com/anthonyaxenov/5db7be8b514f30ab2658150f2c018740
*
* @see https://gist.github.com/anthonyaxenov/5db7be8b514f30ab2658150f2c018740
*/
class DiskSpace
{

View File

@ -4,6 +4,7 @@
* Checks if script running under php-cli
*
* @return bool
* @see https://gist.github.com/anthonyaxenov/c1b237af14ec91aead19be66cdfc29e3
*/
function is_cli(): bool
{