forked from SimplesIP/pabx-app
bruno
2 months ago
1 changed files with 378 additions and 0 deletions
@ -0,0 +1,378 @@
|
||||
#!/usr/bin/php -q |
||||
<?php |
||||
/* * ************************************************************************************ |
||||
* |
||||
* TRANSBORDO AUTOMATICO |
||||
* Autores |
||||
* Amarildo Pereira/Alan Pablo |
||||
* |
||||
* ************************************************************************************* |
||||
* Definicoes do Projeto |
||||
* Nome: Transbordo Automatico |
||||
* Data Incio: 23/02/2012 |
||||
* Equipe: Amarildo Pereira, Alan Pablo |
||||
* Descrição: |
||||
* O objetivo do sistema é monitorar "Dacs" que possuam filas de atendimento |
||||
* realizando a transferencia(transbordo) dessas chamadas para outro Dac pre- |
||||
* viamente cadastrado. |
||||
* Regras: |
||||
* O transbordo sera realizado mediante a observacao das seguintes regras: |
||||
* 1 -> Dever existir chamadas em fila no Dac monitorado. Chamadas em Fila > 0. |
||||
* 2 -> Nao pode exitir agentes livres no Dac monitorado. Agentes Monitorados = 0. |
||||
* 3 -> Nao pode exitir fila no Dac de transbordo. Chamadas em Fila no Transbordo = 0. |
||||
* 4 -> Pelo menos um agente disponivel no dac de transbordo. Agentes transbordo > 0. |
||||
* ************************************************************************************* |
||||
* Copyright (c) 2012, Simples IP |
||||
* ************************************************************************************ */ |
||||
$versao = '1.0.0'; |
||||
/* |
||||
* Estabelece conexao com os servidores de socket e dados |
||||
*/ |
||||
require "util/util.php"; |
||||
$socket = ConectaManager(GetSckConnect()); |
||||
$conn = GetConnection(GetDefStrDb()); |
||||
/* |
||||
* Armazena dados das filas retornados pelo socket |
||||
*/ |
||||
$dadosFilas = array(); |
||||
/* |
||||
* Filas a monitorar originadas do banco de dados |
||||
*/ |
||||
$monitorFila = array(); |
||||
/* |
||||
* Arquivo de log |
||||
*/ |
||||
$pathLog = "/var/log/transbordo.log"; |
||||
/* |
||||
* Valor: |
||||
* 0 - grava apenas mensagens de erro |
||||
* 1 - grava todas as mensagens |
||||
* 2 - grava todas as mensagens e imprime para saida padrao |
||||
*/ |
||||
$gravaLog = 2; |
||||
define("MAX_TENTATIVA_RETORNO", 50); |
||||
if ($socket && $conn) { |
||||
logTrb('Apl', 'Teste de conexao com os servidores', "Conexao aos servidores realizada com sucesso!", 'OK'); |
||||
$monitorFila = GetFilasMonitorar($conn); |
||||
if ($monitorFila === false) { |
||||
logTrb('Apl', 'Verificacao do cadastro de fila no banco', "Nao ha filas a monitorar, ou seja nao foi configurado transbordo para nenhuma fila!", 'OK'); |
||||
} else { |
||||
$dadosFilas = DadosFila($socket); |
||||
if ($dadosFilas === false) { |
||||
logTrb('Apl', 'Verificacao do cadastro de fila no manager', "A pesquisa no manager nao encontrou chamadas em fila!", 'OK'); |
||||
} else { |
||||
foreach ($monitorFila as $key => $value) { |
||||
/* |
||||
* Fila monitorada |
||||
*/ |
||||
$filaMonitorada = $key; |
||||
/* |
||||
* Nome da fila e numero para transbordo |
||||
*/ |
||||
$filaTransbordo = $value["nome_transbordo"]; |
||||
$numeroTransbordo = $value["numero_transbordo"]; |
||||
logTrb('Apl', "Inicio da monitoracao da fila: $filaMonitorada", "Transbordo para: $filaTransbordo Numero: $numeroTransbordo", 'OK'); |
||||
/* |
||||
* Verifica chamadas em fila, no dac monitorado ou seja |
||||
* se existir ligacoes em fila sera transferido para o dac |
||||
* configurado |
||||
*/ |
||||
$chamadasFila = GetChamadasFila($dadosFilas, $filaMonitorada); |
||||
if ($chamadasFila) { |
||||
/* |
||||
* Verifica se nao ha chamadas em fila no dac que recebera o transbordo |
||||
*/ |
||||
$chamadasFilaTrans = GetChamadasFila($dadosFilas, $filaTransbordo); |
||||
if (!$chamadasFilaTrans) { |
||||
/* |
||||
* Informações dos clientes a serem transbordados, |
||||
* pesquisa no manager quantas chamadas estao em fila |
||||
* e retorna um array contendo o canal para transferencia |
||||
*/ |
||||
$arCliTransbordo = GetCliTransbordo($dadosFilas, $filaMonitorada); |
||||
/* |
||||
* Inoformacoes dos agentes livres, |
||||
* pesquisa no manager agentes disponiveis |
||||
* para receber o transbordo |
||||
*/ |
||||
$arAgenteLivre = GetAgentesLivre($dadosFilas, $filaTransbordo); |
||||
/* |
||||
* Pesquisa se existem agentes livres no dac monitorado, |
||||
* pois realizara o transbordo somente se de todas as |
||||
* posicoes de atendimento estiverem ocupadas. |
||||
*/ |
||||
//$arAgenteMonitor = GetAgentesLivre($dadosFilas, $filaMonitorada); |
||||
$arAgenteMonitor = GetMonitorLivre($socket, $dadosFilas, $filaMonitorada); |
||||
$chamadasTransbordar = count($arCliTransbordo); |
||||
$agentesLivres = count($arAgenteLivre); |
||||
$agentesMonitor = count($arAgenteMonitor); |
||||
if ((!$agentesMonitor) || ($chamadasFila > $agentesMonitor)) { |
||||
if ($agentesLivres) { |
||||
$numATransbordar = $chamadasTransbordar; |
||||
for ($i = 0; $i < $agentesLivres; $i++) { |
||||
$channelTransf = $arCliTransbordo[$i]; |
||||
if (($numATransbordar) && (Transbordo($socket, $filaMonitorada, $filaTransbordo, $channelTransf, $numeroTransbordo))) { |
||||
$numATransbordar--; |
||||
} |
||||
} |
||||
} else { |
||||
logTrb('Apl', "Final da monitoracao da fila: $filaMonitorada", "Nao ha agentes disponiveis para transbordo", 'OK'); |
||||
} |
||||
} else { |
||||
$compl = sprintf("Chamadas em Fila(%s): %s Agentes Livres: %s Agentes Livres(%s): %s", $filaMonitorada, $chamadasTransbordar, $agentesMonitor, $filaTransbordo, $agentesLivres); |
||||
logTrb('Apl', "Final da monitoracao da fila: $filaMonitorada", "Exitem agentes disponiveis no Dac Monitorado", 'ERRO', $compl); |
||||
} |
||||
} |
||||
} else { |
||||
logTrb('Apl', "Final da monitoracao da fila: $filaMonitorada", "Nao ha chamadas em fila", 'OK'); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
logTrb('FIM TRANSBORDO', "Captura ultimo erro ocorrido no sistema.", "Verifica possiveis erros nao tratados", 'ERRO'); |
||||
function DadosFila($socket) { |
||||
$actionid = rand(000000000, 9999999999); |
||||
fwrite($socket, "action: queuestatus\r\n"); |
||||
fwrite($socket, "ActionID: " . $actionid . "\r\n\r\n"); |
||||
$start = false; |
||||
$filas = array(); |
||||
$params = array(); |
||||
$dados = array(); |
||||
while (!feof($socket)) { |
||||
$buffer = fgets($socket); |
||||
/* |
||||
* Obtem os valores retornados |
||||
*/ |
||||
if ($start && (trim($buffer) != '')) { |
||||
list($param, $value) = explode(":", $buffer); |
||||
$params[trim($param)] = trim($value); |
||||
} |
||||
if ($start && (trim($buffer) == '') && count($params)) { |
||||
$dados[] = $params; |
||||
$params = array(); |
||||
} |
||||
/* |
||||
* Inicio da leitura dos dados |
||||
*/ |
||||
if (stristr($buffer, "Queue status will follow")) { |
||||
$start = true; |
||||
} |
||||
/* |
||||
* Verifica se a requisição chegou ao final |
||||
*/ |
||||
if (stristr($buffer, "QueueStatusComplete")) { |
||||
break; |
||||
} |
||||
/* |
||||
* Garante que o socket não vai procurar para sempre |
||||
*/ |
||||
if ($buffer === false) { |
||||
break; |
||||
} |
||||
} |
||||
return count($dados) ? $dados : false; |
||||
} |
||||
function GetConnection($conStr) { |
||||
$ret = pg_connect($conStr); |
||||
if (!$ret) { |
||||
logTrb('GetConnection', "Conexao com banco de dados", "Erro ao executar conexao no banco", 'ERRO', $conStr); |
||||
} |
||||
return $ret; |
||||
} |
||||
function GetFilasMonitorar($conn) { |
||||
$dadosFila = array(); |
||||
/* |
||||
* Query para recuperar as filas para transbordo, cadastradas no db |
||||
*/ |
||||
$query = "select a.id, a.nome as nome_fila, a.nome_asterisk, b.numero_asterisk, a.id_transbordo, b.nome_asterisk as nome_transbordo, b.numero_asterisk as numero_transbordo |
||||
from pbx_queues_grupos a, pbx_queues_grupos b |
||||
where b.id = a.id_transbordo |
||||
and a.id_transbordo > 0 and a.status = 'A' and b.status = 'A'"; |
||||
/* |
||||
* Recupera as filas a monitoras |
||||
*/ |
||||
$result = pg_query($conn, $query); |
||||
if (!$result) { |
||||
logTrb('GetFilasMonitorar', "Recupera as filas que tem transbordo cofigurado", "Erro ao executar consulta no banco", 'ERRO', $query); |
||||
} else { |
||||
if (!pg_num_rows($result)) |
||||
return false; |
||||
while ($row = pg_fetch_array($result)) { |
||||
$dadosFila[$row["nome_asterisk"]] = $row; |
||||
} |
||||
return $dadosFila; |
||||
} |
||||
} |
||||
function GetChamadasFila($arFilas, $fila) { |
||||
foreach ($arFilas as $infoFila) { |
||||
if (($infoFila["Queue"] == $fila) && ($infoFila["Event"] == 'QueueParams')) { |
||||
return trim($infoFila['Calls']); |
||||
} |
||||
} |
||||
} |
||||
function GetAgentesLivre($arFilas, $fila) { |
||||
$arAgt = array(); |
||||
foreach ($arFilas as $infoFila) { |
||||
if (($infoFila["Queue"] == $fila) && ($infoFila["Event"] == 'QueueMember') && ($infoFila["Status"] == '1') && ($infoFila["Paused"] == '0')) { |
||||
$arAgt[$infoFila["Name"]] = $infoFila["Location"]; |
||||
} |
||||
} |
||||
return $arAgt; |
||||
} |
||||
function GetMonitorLivre($socket, $arFilas, $fila) { |
||||
$agtOcupado = GetStatusAgente($socket); |
||||
$arAgt = array(); |
||||
foreach ($arFilas as $infoFila) { |
||||
if (($infoFila["Queue"] == $fila) && ($infoFila["Event"] == 'QueueMember') && ($infoFila["Membership"] == 'dynamic')) { |
||||
$nomeAgt = trim($infoFila["Name"]); |
||||
if ((!array_key_exists($nomeAgt, $agtOcupado)) && ($infoFila["Paused"] == '0')) { |
||||
$arAgt[$infoFila["Name"]] = $infoFila["Location"]; |
||||
} |
||||
} |
||||
} |
||||
return $arAgt; |
||||
} |
||||
function GetStatusAgente($socket) { |
||||
$actionid = rand(000000000, 9999999999); |
||||
fwrite($socket, "action: status\r\n"); |
||||
fwrite($socket, "ActionID: " . $actionid . "\r\n\r\n"); |
||||
$start = false; |
||||
$dadosAgt = array(); |
||||
while (!feof($socket)) { |
||||
$buffer = fgets($socket); |
||||
/* |
||||
* Obtem os valores retornados |
||||
*/ |
||||
if ($start && (trim($buffer) != '')) { |
||||
list($param, $value) = explode(":", $buffer); |
||||
if (strtolower(trim($param)) == 'link') { |
||||
$nomeAgente = trim($value); |
||||
$dadosAgt[$nomeAgente] = 1; |
||||
} |
||||
} |
||||
/* |
||||
* Inicio da leitura dos dados |
||||
*/ |
||||
if (stristr($buffer, "Channel status will follow")) { |
||||
$start = true; |
||||
} |
||||
/* |
||||
* Verifica se a requisição chegou ao final |
||||
*/ |
||||
if (stristr($buffer, "StatusComplete")) { |
||||
break; |
||||
} |
||||
/* |
||||
* Garante que o socket não vai procurar para sempre |
||||
*/ |
||||
if ($buffer === false) { |
||||
break; |
||||
} |
||||
} |
||||
return $dadosAgt; |
||||
} |
||||
function GetCliTransbordo($arFilas, $fila) { |
||||
$arAgt = array(); |
||||
foreach ($arFilas as $infoFila) { |
||||
if (($infoFila["Queue"] == $fila) && ($infoFila["Event"] == 'QueueEntry')) { |
||||
$arAgt[] = $infoFila["Channel"]; |
||||
} |
||||
} |
||||
return $arAgt; |
||||
} |
||||
function Transbordo($socket, $filaMonitorada, $filaTransbordo, $channelTransf, $numdisc) { |
||||
$ret = SetFila($socket, $filaMonitorada, $filaTransbordo, $channelTransf); |
||||
if (!$ret) { |
||||
logTrb('Transbordo', "Falha na chamada a funcao SetFila Fila Monitorada: $filaMonitorada FilaTransbordo: $filaTransbordo Canal: $channelTransf Dac: $numdisc", "Erro ao realizar transbordo"); |
||||
return $ret; |
||||
} |
||||
$actionid = rand(000000000, 9999999999); |
||||
fwrite($socket, "action: redirect\r\n"); |
||||
fwrite($socket, "Channel: $channelTransf\r\n"); |
||||
fwrite($socket, "Context: ext-transbordo\r\n"); |
||||
fwrite($socket, "Exten: $numdisc\r\n"); |
||||
fwrite($socket, "Priority: 1\r\n"); |
||||
fwrite($socket, "ActionID: " . $actionid . "\r\n\r\n"); |
||||
$ret = VerificaRetornoSocket($socket, "Success", "Error"); |
||||
if ($ret) { |
||||
logTrb('Transbordo', "Transbordo realizado Canal: $channelTransf Dac: $numdisc", "Transbordo realizado com sucesso", 'OK'); |
||||
} else { |
||||
logTrb('Transbordo', "Tentativa de transbordo Canal: $channelTransf Dac: $numdisc", "Erro ao realizar transbordo"); |
||||
} |
||||
return $ret; |
||||
} |
||||
function VerificaRetornoSocket($socket, $sucess, $erro) { |
||||
$i = 0; |
||||
while (!feof($socket)) { |
||||
$bufer = fgets($socket); |
||||
if (stristr($bufer, $sucess)) { |
||||
return true; |
||||
} else if (stristr($bufer, $erro)) { |
||||
return false; |
||||
} |
||||
if ($bufer === false) |
||||
break; |
||||
if ($i++ > MAX_TENTATIVA_RETORNO) |
||||
break; |
||||
} |
||||
return false; |
||||
} |
||||
function SetFila($socket, $fila, $filaTransbordo, $channelTransf) { |
||||
logTrb('SetFila', "Iniciando transbordo Canal: $channelTransf Fila Monitorada: $fila Fila Transbordo: $filaTransbordo", "Chamada a funcao SetFila", 'OK'); |
||||
$actionid = rand(000000000, 9999999999); |
||||
fwrite($socket, "action: SetVar\r\n"); |
||||
fwrite($socket, "Channel: $channelTransf\r\n"); |
||||
fwrite($socket, "variable: FILA1\r\n"); |
||||
fwrite($socket, "value: $fila\r\n"); |
||||
fwrite($socket, "ActionID: " . $actionid . "\r\n\r\n"); |
||||
$ret = VerificaRetornoSocket($socket, "Success", "Error"); |
||||
if (!$ret) |
||||
return $ret; |
||||
$actionid = rand(000000000, 9999999999); |
||||
fwrite($socket, "action: SetVar\r\n"); |
||||
fwrite($socket, "Channel: $channelTransf\r\n"); |
||||
fwrite($socket, "variable: FILA2\r\n"); |
||||
fwrite($socket, "value: $filaTransbordo\r\n"); |
||||
fwrite($socket, "ActionID: " . $actionid . "\r\n\r\n"); |
||||
$ret = VerificaRetornoSocket($socket, "Success", "Error"); |
||||
if (!$ret) |
||||
return $ret; |
||||
$actionid = rand(000000000, 9999999999); |
||||
fwrite($socket, "action: SetVar\r\n"); |
||||
fwrite($socket, "Channel: $channelTransf\r\n"); |
||||
fwrite($socket, "variable: ANUNCIO\r\n"); |
||||
fwrite($socket, "value: customizados/transbordo\r\n"); |
||||
fwrite($socket, "ActionID: " . $actionid . "\r\n\r\n"); |
||||
$ret = VerificaRetornoSocket($socket, "Success", "Error"); |
||||
return $ret; |
||||
} |
||||
function LogTrb($metodo, $descricao, $msg, $type = 'ERRO', $adc = '') { |
||||
$versao = $GLOBALS["versao"]; |
||||
$gl = $GLOBALS["gravaLog"]; |
||||
$data = date("Y-m-d H:i:s"); |
||||
; |
||||
$adc = trim($adc) == '' ? '' : sprintf("\nInformacao adicional: %s\n", $adc); |
||||
/* |
||||
* Captura informacoes sobre erros no sistema |
||||
*/ |
||||
$erro = error_get_last(); |
||||
$strErro = !$erro ? '' : sprintf("\nFile: [%s] Linha: [%s] Msg: [%s]\n", $erro["file"], $erro["line"], $erro["message"]); |
||||
$str = sprintf("Funcao: [%s] Data: [%s] Status: [%s] Versao: %s \nDescricao: %s\n%s%sMsg: %s\n\n", $metodo, $data, $type, $versao, $descricao, $adc, $strErro, $msg); |
||||
if (($gl == 0) && ($type == 'ERRO')) { |
||||
GravaLogTrans($str); |
||||
} else if ($gl == 1) { |
||||
GravaLogTrans($str); |
||||
} else if ($gl == 2) { |
||||
GravaLogTrans($str); |
||||
echo $str; |
||||
} |
||||
} |
||||
function GravaLogTrans($log) { |
||||
$path = $GLOBALS["pathLog"]; |
||||
$arq = fopen($path, 'a'); |
||||
fwrite($arq, $log); |
||||
fclose($arq); |
||||
} |
||||
?> |
||||
|
Loading…
Reference in new issue