forked from SimplesIP/pabx-app
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
400 lines
11 KiB
400 lines
11 KiB
#!/usr/bin/php -q |
|
<?php |
|
/* |
|
* Localizacao de erros em execucao. |
|
*/ |
|
error_reporting(E_ERROR); |
|
ini_set('display_errors', 1); |
|
|
|
/* |
|
* Limite de memoria para o script. |
|
*/ |
|
ini_set("memory_limit", "512M"); |
|
|
|
/* |
|
* Includes essenciais. |
|
*/ |
|
include 'util/funcoesAmi.php'; |
|
include("util/constantes.php"); |
|
include("util/util.php"); |
|
|
|
/* |
|
* Constantes de iniciais. |
|
*/ |
|
define("TIME_SQL_EXECUTE", 300); |
|
define("SERVIDOR_MONITOR_RAMAL", '192.168.115.65'); |
|
|
|
/* |
|
* Variaveis de escopo. |
|
*/ |
|
$sigame = array(); |
|
$ramais = array(); |
|
$time = TIME_SQL_EXECUTE; |
|
|
|
/* |
|
* Para rodar como um processo normal não preciso passar "N" como primeiro parametro. |
|
*/ |
|
$notDaemon = isset($argv[1]) && ( strtoupper($argv[1]) === 'N'); |
|
|
|
/* |
|
* Inicializa o daemom. |
|
*/ |
|
GetDaemon($notDaemon); |
|
|
|
|
|
try { |
|
declare(ticks = 1); |
|
$statusSignal = 0; |
|
pcntl_signal(SIGTERM, "sig_handler"); |
|
pcntl_signal(SIGHUP, "sig_handler"); |
|
pcntl_signal(SIGUSR1, "sig_handler"); |
|
pcntl_signal(SIGINT, "sig_handler"); |
|
|
|
/* |
|
* Conexoes local com Asterisk. |
|
*/ |
|
$socket = ___ConnetAmi(); |
|
|
|
/* |
|
* Inicia conexao com banco de dados. |
|
*/ |
|
$db = ___GetConnexao(); |
|
|
|
|
|
/* |
|
* Loop de monitoramento do servico. |
|
*/ |
|
while (true) { |
|
try { |
|
/* |
|
* Verifica conexao com o asterisk. |
|
*/ |
|
___RestartAmi(); |
|
|
|
/* |
|
* busca os ramais a que possuem sigame. |
|
*/ |
|
$ramais = ____GetData($db, $ramais); |
|
|
|
/* |
|
* busca os chamadas em percurso. |
|
*/ |
|
$chamadas = ___GetMonitoramentoChamadas($socket); |
|
|
|
/* |
|
* Localiza apenas as chamadas de entrada nos ramais com sigame. |
|
*/ |
|
$monitoramento = ___GetChamadasUid($chamadas, $ramais); |
|
|
|
/* |
|
* Manter os dados no banco de dados e limpa as informacoes. |
|
*/ |
|
___Query($monitoramento, $sigame); |
|
|
|
ignore_user_abort(true); |
|
} catch (Exception $ex) { |
|
echo $ex->getMessage(); |
|
} |
|
|
|
/* |
|
* Verifica se o processo deve ser encerrado |
|
*/ |
|
if (sig_status()) { |
|
break; |
|
} |
|
$time++; |
|
} |
|
} catch (Exception $ex) { |
|
exec('echo "ERRO: [ ' . $ex->getMessage() . ' ] | Data: [ ' . date('d/m/Y H:i:s') . ' ]" >> /tmp/mntRamal.log'); |
|
} |
|
|
|
// ************************************************************************* |
|
// * FUNCOES DE FUNCIONAMENTO DO SERVICO COM DAEMON * |
|
// ************************************************************************* |
|
|
|
function GetDaemon($notDaemon) { |
|
/* |
|
* Se o script não for chamado com daemon sai sem executar nada. |
|
*/ |
|
if ($notDaemon) { |
|
return 0; |
|
} |
|
|
|
$pid = pcntl_fork(); |
|
if ($pid) { |
|
exit(0); |
|
} |
|
|
|
/* PIDFile SYSTEMD |
|
* SYSTEMD irá monitorar esse pid para verificar se ainda ativo |
|
*/ |
|
$PIDFile = fopen( "/var/lock/subsys/monitor-ramal.pid", "w+" ); |
|
$pid = getmypid( ); |
|
if( $pid == false ){ |
|
exit( 1 ); |
|
} |
|
fwrite( $PIDFile, $pid); |
|
fclose( $PIDFile ); |
|
|
|
} |
|
|
|
function sig_handler($signo) { |
|
global $statusSignal; |
|
$statusSignal = 1; |
|
} |
|
|
|
function sig_status() { |
|
global $statusSignal; |
|
pcntl_signal_dispatch(); |
|
return $statusSignal; |
|
} |
|
|
|
// ************************************************************************* |
|
// * FUNCOES DE CONEXAO COM MANAGER * |
|
// ************************************************************************* |
|
|
|
function ___ConnetAmi() { |
|
/* |
|
* Parametros de leitura do manager |
|
*/ |
|
list($sckHost, $sckPort, $sckUser, $sckPass) = GetSckConnect(); |
|
$socket = ConectaAmi($sckHost, $sckPort, $sckUser, $sckPass); |
|
|
|
return $socket; |
|
} |
|
|
|
function ___RestartAmi() { |
|
global $socket; |
|
|
|
while (!$socket) { |
|
$socket = ___ConnetAmi(); |
|
sleep(5); |
|
} |
|
} |
|
|
|
function ___GetMonitoramentoChamadas($socket) { |
|
|
|
$params = array('action' => 'command', 'command' => 'core show channels concise'); |
|
$result = GetAmi($socket, $params); |
|
$res = ___GetConcise($result); |
|
|
|
$chamadas = ___GetChannels13($res); |
|
|
|
return $chamadas; |
|
} |
|
|
|
// ************************************************************************* |
|
// * ANALISE DE DADOS DO MANAGER * |
|
// ************************************************************************* |
|
|
|
function ___GetConcise($result) { |
|
|
|
/* |
|
* Limpando array do AMI. |
|
*/ |
|
$count = count($result) - 1; |
|
unset($result[$count]); |
|
|
|
for ($a = 0; $a < 3; $a++) { |
|
unset($result[$a]); |
|
} |
|
|
|
foreach ($result as $key => $chm) { |
|
$result[$key] = explode('!', $chm); |
|
} |
|
|
|
return $result; |
|
} |
|
|
|
function ___GetChannels13($chamadas) { |
|
$arChamadas = array(); |
|
|
|
/* |
|
* CLASSIFICA O TIPO DE CHAMADA |
|
*/ |
|
foreach ($chamadas as $key => $chnl) { |
|
$arChamadas[$key] = $chnl; |
|
if ($chnl[1] != "ext-transferencia") { |
|
foreach ($chamadas as $chave => $chn) { |
|
|
|
if ($chn[12] == $chnl[12] && $chn[0] != $chnl[0] && $chn[5] == "AppDial") { |
|
$arChamadas[$key][9] = $chn[7]; |
|
unset($arChamadas[$chave]); |
|
} |
|
} |
|
} else if ($chnl[1] == "ext-transferencia") { |
|
if ($chnl[2] == $chnl[7]) { |
|
unset($arChamadas[$key]); |
|
} |
|
} |
|
} |
|
|
|
/* |
|
* LIMPA OS DADOS QUE ESTÁ FORA DE CONTEXTO COM AS CHAMADAS CORRENTES |
|
*/ |
|
foreach ($arChamadas as $chv => $chamada) { |
|
if ($chamada[5] == "AppDial" && empty($chamada[9]) && $chamada[3] > 1) { |
|
unset($arChamadas[$chv]); |
|
} |
|
|
|
if ($chamada[5] == "Dial" && empty($chamada[9]) && $chamada[3] < 18) { |
|
unset($arChamadas[$chv]); |
|
} |
|
|
|
if ($chamada[1] == "ext-transferencia") { |
|
unset($arChamadas[$chv]); |
|
} |
|
} |
|
|
|
/* |
|
* LIMPA OS DADOS QUE NÃO ESTÃO SENDO UTILIZADOS |
|
*/ |
|
foreach ($arChamadas as $sc => $cham) { |
|
|
|
foreach ($arChamadas as $ky => $chm) { |
|
if ($chm[0] != $cham[0] && $cham[12] == $chm[12] && $chm[5] == "AppDial") { |
|
unset($arChamadas[$ky]); |
|
} |
|
|
|
if ($chm[0] != $cham[0] && $cham[7] == $chm[7] && $chm[5] == "AppDial") { |
|
unset($arChamadas[$ky]); |
|
} |
|
|
|
if ($chm[0] != $cham[0] && $cham[7] == $chm[7] && $chm[5] == "Dial") { |
|
unset($arChamadas[$sc]); |
|
} |
|
|
|
$chamadaChn = explode(';', $chm[0]); |
|
$chamadaChn2 = explode(';', $cham[0]); |
|
|
|
if ($chamadaChn[0] == $chamadaChn2[0] && $cham[5] == "AppQueue") { |
|
unset($arChamadas[$sc]); |
|
} |
|
} |
|
} |
|
/* |
|
* MONTA O ARRAY DE ACORDO COM A GRID NO MONITOR |
|
*/ |
|
foreach ($arChamadas as $map => $app) { |
|
if (strpos($app[9], ".") !== false) { |
|
$arChamadas[$map][8] = "Em espera"; |
|
} else if ($app[9]) { |
|
$arChamadas[$map][8] = $app[9]; |
|
} else { |
|
$arChamadas[$map][8] = "Em espera"; |
|
} |
|
$arChamadas[$map][10] = $app[11]; |
|
} |
|
|
|
return $arChamadas; |
|
} |
|
|
|
/* |
|
* PEGAS AS CHAMADAS QUE SÃO TRANSBORDADAS PELA FILA |
|
*/ |
|
|
|
function ___GetChamadasUid($arChamadas, $ramais = null) { |
|
global $sigame; |
|
|
|
if (count($ramais) <= 0) { |
|
return null; |
|
} |
|
|
|
$resp = false; |
|
foreach ($arChamadas as $fila) { |
|
|
|
foreach ($ramais as $ramal) { |
|
if ($fila[1] == 'macro-dial-saida-pstn' && $fila[8] == $ramal['sigame_interno']) { |
|
|
|
foreach ($sigame as $uid) { |
|
if ($fila[13] == $uid[13]) { |
|
$resp = true; |
|
} |
|
} |
|
|
|
if (!$resp) { |
|
$fila[12] = date('Y-m-d H:i:s'); |
|
$sigame[] = $fila; |
|
} |
|
} |
|
} |
|
} |
|
|
|
return $sigame; |
|
} |
|
|
|
// ************************************************************************* |
|
// * TROCA DE DADOS COM A BASE DE DADOS DO CLIENTE * |
|
// ************************************************************************* |
|
|
|
function ___GetConnexao() { |
|
return pg_connect(sprintf("host=%s port=5432 dbname=pbx user=contacte password=ctepgSQL", SERVIDOR_MONITOR_RAMAL)); |
|
} |
|
|
|
function ____GetData($db, $ramais) { |
|
global $time; |
|
|
|
if (TIME_SQL_EXECUTE <= $time) { |
|
$time = 0; |
|
|
|
$query = "SELECT b.sigame_interno |
|
FROM pbx_queues_grupos a, pbx_sip_ramais b |
|
WHERE b.nome = a.acao |
|
AND strtoint(a.timeout2) > 0 |
|
AND a.opcao = 'ramal'"; |
|
$result = pg_query( $db, $query ); |
|
$ramais = pg_fetch_all($result); |
|
} |
|
|
|
return $ramais; |
|
} |
|
|
|
/** |
|
* Exemplo de dados recebidos: |
|
* |
|
* [0] => IAX2/SIMPLESIP-13978 |
|
* [1] => macro-dial-saida-pstn |
|
* [2] => s |
|
* [3] => 24 |
|
* [4] => Up |
|
* [5] => Dial |
|
* [6] => SIP/CENTRAL/8293,45,TKgwWKkM(tarifa,564,500,1564165761.235,4007,8293,1,,,)L(86400000:30000:10000) |
|
* [7] => 65996392932 |
|
* [8] => 8293 |
|
* [9] => 8293 |
|
* [10] => 13 |
|
* [11] => 13 |
|
* [12] => 2019-07-26 14:29:35 |
|
* [13] => 1564165761.235 |
|
* |
|
* @param type $chamadas |
|
* @param type $sigame |
|
* @throws Exception |
|
* |
|
*/ |
|
function ___Query($chamadas, $sigame) { |
|
|
|
if ($chamadas) { |
|
|
|
$query = "INSERT INTO pbx_chamadas_sigame (chm_uniqueid,chm_dst,chm_src,chm_exten,chm_channel,chm_calldate) VALUES('%s','%s','%s','%s','%s','%s'); "; |
|
|
|
foreach ($chamadas as $uid) { |
|
$result = pg_query("SELECT chm_uniqueid FROM pbx_chamadas_sigame WHERE chm_uniqueid = '{$uid[13]}'"); |
|
if (!pg_fetch_assoc($result)) { |
|
$sql .= sprintf($query, $uid[13], $uid[8], $uid[7], $uid[1], $uid[0], $uid[12]); |
|
} |
|
} |
|
|
|
pg_query("BEGIN;"); |
|
pg_query($sql); |
|
|
|
if (pg_last_error()) { |
|
pg_query("ROLLBACK;"); |
|
throw new Exception('Não foi possível gravar as informações no banco de dados! ' . $sql . "\n"); |
|
} |
|
|
|
unset($sigame); |
|
pg_query("COMMIT;"); |
|
} |
|
} |
|
|