#!/usr/bin/php -Cq get_variable('CDR(answer)', true)); $tronco = $agi->get_variable('CALLERID(name)', true); $agi = null; /* * Verifica se o tipo de execução é custom, se for desvia a execução * para um script customizado para integração, capturando antes os * parametros de entrada. O programas ou scripts ficam localizados * no diretorio /var/lib/asterisk/scripts/integracao/custom. */ if(ExecuteCustom($idMetodo, $nomeMetodo)) { __logStr("ExecuteCustom", $nomeMetodo, 'serverAgi', true); include($nomeMetodo); exit; } /* * Variável global usada em logStr. */ $nivelLog = LOG_MSG_DISPLAY; $scrpt = $argv[0]; $shmSystemKey = ShmGetId(SHM_IPC_FILE); $memoryAllocated = Malloc(); /* * Se a memoria ainda não foi criada tenta cria-la. */ $shmKey = ShmExist($shmSystemKey); if(!$shmKey) { $msg = "Não foi possível criar a memoria do servidor"; $shmKey = ShmOpen($shmSystemKey, SHM_ACESS_MODE, SHM_ACESS_PERMISSION, $memoryAllocated); if($shmKey) { /* * Formata a memoria compartilhada. */ @CreateSegment($shmKey); } } else { $msg = "Não foi possível abrir a memoria do servidor"; /* * A memoria já foi criada tenta abrir o bloco previamente alocado. */ $shmKey = ShmOpen($shmSystemKey, SHM_ACESS_MODE, SHM_ACESS_PERMISSION, $memoryAllocated); } if(!$shmKey) { $er = error_get_last(); __logStr("ShmOpen", $msg . "\nErro Geral: " . $er["message"], $scrpt, true); exit(1); } /* * Retorna o id do primeiro processo livre do segmento. */ $idProc = GetFreeProcesses($shmKey); if($idProc == -1) { $msg = sprintf( "Todos os processos estão ocupados, é necessário alocar mais memória para o servidor. Total de processos suportados: %s", MEMORY_SEGMENT_COUNT); __logStr("Inicio do Processo", $msg, $scrpt, true); } else if(ShmWrite($shmKey, PROCESSESS_START, $idProc) === false) { /* * Marca o processo com iniciado. */ $msg = sprintf("Nao foi possivel gravar o status inicial do processo. Processo: %s", $idProc); __logStr("ShmWrite", $msg, $scrpt, true); } else { $msgReg = ''; $statusReg = 0; @RegistraIntegracao($idMetodo, $uid, $uidOld, $numero); $str = sprintf("/var/lib/asterisk/scripts/integracao/agiIntegra.php %s %s %s %s %s %s %s %s > /dev/null &", $idMetodo, $numero, $uid, $uidOld, $ura, $idProc, $dataCdr, $tronco); /* * Este script é ececutado em outro processo para permitir o contro de timeout das querys, * assim o processo é encerrado caso não retorne no tempo máximo definido para timeout. */ exec($str); //__logStr("agiIntegra", $msg = $str, $scrpt, false); /* * Recupera informacoes sobre o metodo. */ $infoMetodo = GetInfoMetodo($idMetodo); if($infoMetodo === false) { $msg = "Nao foi possivel obter informacoes sobre o metodo!"; $msgReg = $msg; __logStr("GetInfoMetodo", $msg, $scrpt, true); } else { $itgc_timeout = $infoMetodo['itgc_timeout'] ? $infoMetodo['itgc_timeout'] : DB_TIMOUT_DEF; $maxTimeOut = ($itgc_timeout * 1000000); $timeout = 0; while(true) { usleep(SERVER_CYCLO); $st = @GetStatusProcesses($shmKey, $idProc); if($st == PROCESSESS_READ) { $data = trim(@ShmRead($shmKey, GetOffSet($idProc), MEMORY_SEGMENT_WITH)); $dadosConsulta = explode("|", $data); /* * a.itgm_tipo, a.itgm_comando, itgm_retorno, a.opcao as opcao_metodo, a.stored_params, c.itgp_prefix, b.itgc_host, b.itgc_port, b.itgc_database, b.itgc_user, b.itgc_password, b.itgc_timeout, b.opcao, b.acao */ if($dadosConsulta[2] == '-1') { /* * Executa ação padrao definida na configuração da integracao. */ $gotoOpcao = $infoMetodo['opcao']; $gotoAcao = $infoMetodo['acao']; $msg = "Processo executado mas não retornou dados!\nInfo: " . $data; $msgReg = $msg; $statusReg = 1; } else if(!VerificaRetorno($infoMetodo['opcao_metodo'], $dadosConsulta[2])) { /* * Executa ação padrao definida na configuração da integracao. */ $gotoOpcao = $infoMetodo['opcao']; $gotoAcao = $infoMetodo['acao']; $msg = "Processo executado mas a(o) " . $infoMetodo['opcao_metodo'] . " retornada(0) é invalida(o)!\n" . $infoMetodo['opcao_metodo'] . ": " . $dadosConsulta[2]; $msgReg = $msg; $statusReg = 2; } else { /* * Executa ação retornada da consulta do banco do cliente. */ $gotoOpcao = $infoMetodo['opcao_metodo']; $gotoAcao = $dadosConsulta[2]; $msg = "Processo: $idProc executado com sucesso!\nDados: " . $data; $msgReg = $msg; $statusReg = 0; } __logStr("ProcessRead", $msg, $scrpt, true); break; } if($timeout > $maxTimeOut) { /* * Executa ação padrao definida na configuração da integracao. */ $gotoOpcao = $infoMetodo['opcao']; $gotoAcao = $infoMetodo['acao']; $msg = "O processo nao retornou no tempo devido."; $msgReg = $msg; __logStr("Timeout", $msg, $scrpt, true); $statusReg = 3; break; } $timeout += SERVER_CYCLO; } } if(!ShmWrite($shmKey, PROCESSESS_WAIT, $idProc)) { $msg = "Nao foi possivel liberar o processo."; __logStr("ShmWrite", $msg, $scrpt, true); } @AtualizaIntegracao($uid, $gotoAcao, $msgReg, $statusReg, $data); /* * Executa redirecionamento */ $debug = true; $in = fopen("php://stdin","r"); $stdlog = fopen("/var/log/asterisk/IntegracaoRedir.log", "w"); write("SET VARIABLE ACAO $gotoAcao"); read(); write("SET VARIABLE opcao $gotoOpcao"); read(); $acao = GetAcaoOpcao($gotoOpcao, $gotoAcao); write("EXEC $acao"); read(); fclose($in); fclose($stdlog); exit(0); } if($shmKey)ShmClose($shmKey); // Do function definitions before we start the main loop function read() { global $in, $debug, $stdlog; $input = str_replace("\n", "", fgets($in, 4096)); if ($debug) { fputs($stdlog, "read: $input\n"); } return $input; } function write($line) { global $debug, $stdlog; if ($debug) { fputs($stdlog, "write: $line\n"); } echo $line."\n"; } function GetAcaoOpcao ($opcao, $acao) { if ($opcao == 'ura') { $var = explode('-', $acao); return 'Goto ura-'.$var[0].'|s|1'; } else if ($opcao == 'grupo') { return 'Goto ext-grupos|'.$acao.'|1'; } else if ($opcao == 'filas') { return 'Goto ext-fila|'.$acao.'|1'; } else if ($opcao == 'voice') { $var = explode('/',$acao); return 'Goto ext-voicemail|'.$var[0].'|'.$var[1].''; } else if ($opcao == 'ramal') { return 'Goto ext-ramais|'.$acao.'|1'; } else if ($opcao == 'horarios') { return 'Goto ext-horarios|'.$acao.'|1'; } else if ($opcao == 'disa') { return 'Goto ext-disa|'.$acao.'|1'; } else if ($opcao == 'anuncios') { return 'Goto ext-anuncios|a'.$acao.'|1'; } else if ($opcao == 'conferencia') { return 'Goto ext-conferencia|'.$acao.'|1'; } else if ($opcao == 'callback') { return 'Goto ext-callback-externo|'.$acao.'|1'; } else if ($opcao == 'rotainterna') { return 'Goto ext-rotasinternas|'.$acao.'|1'; } return false; } function VerificaRetorno($opcao, $acao) { $query = ""; if ($opcao == 'ura') { $var = explode('-', $acao); $acao = $var[0]; $query = "select count(*) FROM pbx_ura where id = '$acao'"; } else if ($opcao == 'grupo') { $query = "SELECT count(*) FROM pbx_grupos where numero = '$acao'"; } else if ($opcao == 'filas') { $query = " SELECT count(*) FROM pbx_queues_grupos where numero = '$acao' and status = 'A'"; } else if ($opcao == 'voice') { $var = explode('/',$acao); $acao = $var[0]; $query = "SELECT count(*) FROM pbx_voicemail_usuarios where caixa_postal = '$acao'"; } else if ($opcao == 'ramal') { $query = "select count(*) from pbx_ramais where nome = '$acao'"; } else if ($opcao == 'horarios') { $query = "select count(*) from pbx_horarios where id = '$acao'"; } else if ($opcao == 'disa') { $query = "SELECT count(*) FROM pbx_disa where numero = '$acao'"; } else if ($opcao == 'anuncios') { $query = "SELECT count(*) FROM pbx_anuncios where id = '$acao'"; } else if ($opcao == 'conferencia') { $query = "SELECT count(*) FROM pbx_conferencia where numero = '$acao'"; } else if ($opcao == 'callback') { $query = "select count(*) from pbx_callback where id = '$acao'"; } else if ($opcao == 'rotainterna') { $query = "select count(*) from pbx_rotas_saida_modelos b where modelo = '$acao'"; } if($query) { $connPG = $GLOBALS['connPG']; $result = pg_query($connPG, $query); if(!$result) { $msg = sprintf("Query: %s.\nErro: %s\n", $query, pg_last_error($connPG)); __logStr('VerificaRetorno', $msg); } $row = pg_fetch_row($result); return $row[0]; } return false; } function ExecuteCustom($idMetodo, &$nomeMetodo) { try { $patScript = "/var/lib/asterisk/scripts/integracao/custom/"; /* * Esta função retorna informações sobre o tipo de integração. */ $row = GetInfoMetodo($idMetodo); /* * Se o metodo informado não for custom, segue o fluxo normal. */ $tipo = strtoupper($row["itgp_prefix"]); if($tipo != 'CUSTOM') { return false; } /* * Verifica se o script informado existe, caso não exista registra no log e encerra. */ $return = explode(' ', $row["itgm_comando"]); $script = trim($return[0]); if(!file_exists($patScript . $script)) { __logStr("ExecuteCustom", "O arquivo informado não existe! Nome: $script", "serverAgi.php", true); return true; } /* * Executa o script customizado. */ $nomeMetodo = sprintf("%s%s", $patScript, $script); /* * Registra a execução do script. */ __logStr("ExecuteCustom", $nomeMetodo, "serverAgi.php", false); /* * Este script é ececutado em outro processo para permitir o contro de timeout das querys, * assim o processo é encerrado caso não retorne no tempo máximo definido para timeout. */ return true; } catch (Exception $ex) { /* * Devolve a execução para integraçao ativa. */ __logStr( "ExecuteCustom", $ex->getMessage(), "serverAgi.php", true); return false; } } ?>