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.
440 lines
15 KiB
440 lines
15 KiB
#!/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.id_transbordo, b.nome as nome_transbordo, b.numero 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_fila"]] = $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); |
|
} |
|
?>
|
|
|