fix TopSapp

This commit is contained in:
rodrigo committed 2025-08-10 13:54:46 -03:00
1 parent 8dc6c594c9
commit bae6adefcb
42 files changed
+43645 -105

No files matched your search

+616
View File
@@ -0,0 +1,616 @@
const { Telnet } = require('telnet-client');
const net = require('net');
class FiberhomeManager {
constructor() {
this.tl1Connection = null;
this.commandId = 1;
// Configuração apenas para UNM2000 via TL1
this.config = {
unm2000: {
host: '131.0.192.9',
port: 3337,
username: '1',
password: '1',
timeout: 15000
}
};
this.logger = require('../utils/logger');
}
/**
* Testar conectividade de rede com um host
*/
async testarConectividade(host, port, timeout = 5000) {
return new Promise((resolve) => {
const socket = new net.Socket();
socket.setTimeout(timeout);
socket.connect(port, host, () => {
this.logger.debug(`Conectividade OK: ${host}:${port}`);
socket.destroy();
resolve(true);
});
socket.on('error', (error) => {
this.logger.debug(`Erro de conectividade ${host}:${port}:`, error.message);
resolve(false);
});
socket.on('timeout', () => {
this.logger.debug(`Timeout de conectividade ${host}:${port}`);
socket.destroy();
resolve(false);
});
});
}
/**
* Conectar à OLT via Telnet
*/
async conectarOLT() {
try {
if (this.telnetConnection && this.telnetConnection.getSocket()) {
this.logger.debug('Conexão OLT já existe, reutilizando');
return true;
}
// Primeiro, testar conectividade básica
this.logger.debug('Testando conectividade com OLT...');
const conectividade = await this.testarConectividade(
this.config.olt.host,
this.config.olt.port,
5000
);
if (!conectividade) {
throw new Error(`Não foi possível conectar ao host ${this.config.olt.host}:${this.config.olt.port}`);
}
this.logger.debug('Conectando à OLT Fiberhome', this.config.olt);
this.telnetConnection = new Telnet();
const params = {
host: this.config.olt.host,
port: this.config.olt.port,
shellPrompt: this.config.olt.shellPrompt,
timeout: this.config.olt.timeout,
loginPrompt: /Username:|login:/i,
passwordPrompt: /Password:|password:/i,
username: this.config.olt.username,
password: this.config.olt.password,
echoLines: 1,
debug: true
};
this.logger.debug('Tentando conectar com parâmetros:', {
host: params.host,
port: params.port,
username: params.username,
timeout: params.timeout
});
await this.telnetConnection.connect(params);
// Aguardar o prompt aparecer
await new Promise(resolve => setTimeout(resolve, 2000));
this.logger.info('Conectado à OLT Fiberhome com sucesso');
return true;
} catch (error) {
this.logger.error('Erro ao conectar à OLT', {
error: error.message,
host: this.config.olt.host,
port: this.config.olt.port,
stack: error.stack
});
// Limpar conexão com erro
if (this.telnetConnection) {
try {
this.telnetConnection.end();
} catch (e) {
// Ignorar erros ao fechar conexão inválida
}
this.telnetConnection = null;
}
return false;
}
}
/**
* Conectar ao UNM2000 via TL1
*/
async conectarUNM2000() {
try {
if (this.tl1Connection && !this.tl1Connection.destroyed) {
this.logger.debug('Conexão TL1 já existe e está ativa');
return true;
}
this.logger.debug('Conectando ao UNM2000 via TL1', this.config.unm2000);
return new Promise((resolve, reject) => {
this.tl1Connection = new net.Socket();
let authenticated = false;
let dataBuffer = '';
this.tl1Connection.setTimeout(this.config.unm2000.timeout);
// Handler para dados recebidos
this.tl1Connection.on('data', (data) => {
dataBuffer += data.toString();
this.logger.debug('TL1 dados recebidos:', dataBuffer);
// Verificar se login foi bem-sucedido
if (!authenticated && dataBuffer.includes('COMPLD')) {
authenticated = true;
this.logger.info('Login TL1 bem-sucedido');
resolve(true);
}
});
this.tl1Connection.connect(this.config.unm2000.port, this.config.unm2000.host, () => {
this.logger.debug('Socket TL1 conectado, enviando comando de login');
// Comando de login TL1
const loginCommand = `ACT-USER::${this.config.unm2000.username}:${this.commandId++}::${this.config.unm2000.password};`;
this.tl1Connection.write(loginCommand + '\r\n');
// Timeout para autenticação
setTimeout(() => {
if (!authenticated) {
this.logger.error('Timeout na autenticação TL1');
reject(new Error('Timeout na autenticação TL1'));
}
}, 10000);
});
this.tl1Connection.on('error', (error) => {
this.logger.error('Erro na conexão TL1', error);
reject(error);
});
this.tl1Connection.on('timeout', () => {
this.logger.error('Timeout na conexão TL1');
reject(new Error('Timeout na conexão TL1'));
});
this.tl1Connection.on('close', () => {
this.logger.debug('Conexão TL1 fechada');
this.tl1Connection = null;
});
});
} catch (error) {
this.logger.error('Erro ao conectar UNM2000', error);
return false;
}
}
this.logger.error('Timeout na conexão UNM2000');
reject(new Error('Timeout na conexão'));
});
});
} catch (error) {
this.logger.error('Erro ao conectar ao UNM2000', error);
return false;
}
}
/**
* Executar comando na OLT
*/
async executarComandoOLT(comando) {
try {
if (!this.telnetConnection) {
const conectado = await this.conectarOLT();
if (!conectado) {
throw new Error('Não foi possível conectar à OLT');
}
}
this.logger.debug('Executando comando OLT', { comando });
const resultado = await this.telnetConnection.exec(comando);
this.logger.debug('Resultado do comando OLT', {
comando,
resultadoLength: resultado.length
});
return resultado;
} catch (error) {
this.logger.error('Erro ao executar comando na OLT', { comando, error: error.message });
throw error;
}
}
/**
* Executar comando TL1 no UNM2000
*/
async executarComandoTL1(comando) {
try {
if (!this.tl1Connection || this.tl1Connection.destroyed) {
const conectado = await this.conectarUNM2000();
if (!conectado) {
throw new Error('Não foi possível conectar ao UNM2000');
}
}
this.logger.debug('Executando comando TL1', { comando });
return new Promise((resolve, reject) => {
let resposta = '';
const timeout = setTimeout(() => {
reject(new Error('Timeout na execução do comando TL1'));
}, 10000);
const onData = (data) => {
resposta += data.toString();
// Verificar se a resposta está completa (termina com ;)
if (resposta.includes(';')) {
clearTimeout(timeout);
this.tl1Connection.off('data', onData);
this.logger.debug('Resposta TL1 recebida', {
comando,
respostaLength: resposta.length
});
resolve(resposta);
}
};
this.tl1Connection.on('data', onData);
this.tl1Connection.write(comando + '\r\n');
});
} catch (error) {
this.logger.error('Erro ao executar comando TL1', { comando, error: error.message });
throw error;
}
}
/**
* Obter status da ONU por serial
*/
async obterStatusONU(serial) {
try {
this.logger.debug('Obtendo status da ONU', { serial });
// Primeiro, encontrar a ONU pelo serial
const comandoBusca = `show ont info serial ${serial}`;
const resultadoBusca = await this.executarComandoOLT(comandoBusca);
if (!resultadoBusca || resultadoBusca.includes('No such ont')) {
return {
success: false,
error: 'ONU não encontrada',
serial
};
}
// Extrair informações básicas da ONU
const infoONU = this.extrairInfoONU(resultadoBusca);
if (!infoONU.slot || !infoONU.pon || !infoONU.onuId) {
return {
success: false,
error: 'Não foi possível extrair informações da ONU',
serial
};
}
// Obter status detalhado
const comandoStatus = `show ont info ${infoONU.slot} ${infoONU.pon} ${infoONU.onuId}`;
const resultadoStatus = await this.executarComandoOLT(comandoStatus);
// Obter informações de sinal
const comandoSinal = `show ont optical-info ${infoONU.slot} ${infoONU.pon} ${infoONU.onuId}`;
const resultadoSinal = await this.executarComandoOLT(comandoSinal);
// Obter status das portas Ethernet
const comandoPortas = `show ont port state ${infoONU.slot} ${infoONU.pon} ${infoONU.onuId} eth all`;
const resultadoPortas = await this.executarComandoOLT(comandoPortas);
// Obter configurações WAN
const comandoWAN = `show ont wan-info ${infoONU.slot} ${infoONU.pon} ${infoONU.onuId}`;
const resultadoWAN = await this.executarComandoOLT(comandoWAN);
const status = this.processarStatusONU({
info: resultadoStatus,
sinal: resultadoSinal,
portas: resultadoPortas,
wan: resultadoWAN,
...infoONU
});
return {
success: true,
serial,
...status
};
} catch (error) {
this.logger.error('Erro ao obter status da ONU', { serial, error: error.message });
return {
success: false,
error: error.message,
serial
};
}
}
/**
* Obter status da ONU por device name
*/
async obterStatusONUPorNome(deviceName) {
try {
this.logger.debug('Obtendo status da ONU por nome', { deviceName });
// Buscar ONU pelo device name
const comandoBusca = `show ont info summary | grep "${deviceName}"`;
const resultadoBusca = await this.executarComandoOLT(comandoBusca);
if (!resultadoBusca || resultadoBusca.trim() === '') {
return {
success: false,
error: 'ONU não encontrada pelo device name',
deviceName
};
}
// Extrair serial do resultado
const serial = this.extrairSerialDoNome(resultadoBusca);
if (!serial) {
return {
success: false,
error: 'Não foi possível extrair o serial da ONU',
deviceName
};
}
// Usar o método de busca por serial
const resultado = await this.obterStatusONU(serial);
resultado.deviceName = deviceName;
return resultado;
} catch (error) {
this.logger.error('Erro ao obter status da ONU por nome', { deviceName, error: error.message });
return {
success: false,
error: error.message,
deviceName
};
}
}
/**
* Extrair informações básicas da ONU do resultado da busca
*/
extrairInfoONU(resultado) {
const linhas = resultado.split('\n');
const info = {};
for (const linha of linhas) {
// Buscar padrão: gpon_olt-1/1/1:1
const matchSlotPon = linha.match(/gpon_olt-(\d+)\/(\d+)\/(\d+):(\d+)/);
if (matchSlotPon) {
info.slot = matchSlotPon[1];
info.board = matchSlotPon[2];
info.pon = matchSlotPon[3];
info.onuId = matchSlotPon[4];
}
// Buscar outros dados relevantes
if (linha.includes('Serial number:')) {
info.serial = linha.split(':')[1]?.trim();
}
if (linha.includes('Device name:')) {
info.deviceName = linha.split(':')[1]?.trim();
}
}
return info;
}
/**
* Extrair serial do device name
*/
extrairSerialDoNome(resultado) {
const linhas = resultado.split('\n');
for (const linha of linhas) {
// Buscar padrão com serial number
const match = linha.match(/([A-Z0-9]{12})/);
if (match) {
return match[1];
}
}
return null;
}
/**
* Processar status detalhado da ONU
*/
processarStatusONU(dados) {
const status = {
slot: dados.slot,
pon: dados.pon,
onuId: dados.onuId,
deviceName: dados.deviceName || 'N/A',
online: false,
rxPower: 'N/A',
txPower: 'N/A',
distance: 'N/A',
portasEthernet: [],
servicosWAN: []
};
// Processar status online/offline
if (dados.info) {
status.online = dados.info.includes('online') || dados.info.includes('working');
}
// Processar informações de sinal
if (dados.sinal) {
const linhas = dados.sinal.split('\n');
for (const linha of linhas) {
if (linha.includes('Rx power')) {
const match = linha.match(/([-+]?\d+\.?\d*)/);
if (match) status.rxPower = match[1] + ' dBm';
}
if (linha.includes('Tx power')) {
const match = linha.match(/([-+]?\d+\.?\d*)/);
if (match) status.txPower = match[1] + ' dBm';
}
if (linha.includes('Distance')) {
const match = linha.match(/(\d+)/);
if (match) status.distance = match[1] + ' m';
}
}
}
// Processar status das portas Ethernet
if (dados.portas) {
const linhas = dados.portas.split('\n');
for (const linha of linhas) {
const match = linha.match(/eth\s+(\d+)\s+(\w+)/);
if (match) {
status.portasEthernet.push({
porta: match[1],
status: match[2]
});
}
}
}
// Processar serviços WAN
if (dados.wan) {
const linhas = dados.wan.split('\n');
for (const linha of linhas) {
if (linha.includes('Service')) {
const servicoMatch = linha.match(/Service\s+(\d+).*?(\w+).*?(\d+\.\d+\.\d+\.\d+)?/);
if (servicoMatch) {
status.servicosWAN.push({
id: servicoMatch[1],
status: servicoMatch[2],
ip: servicoMatch[3] || 'N/A'
});
}
}
}
}
return status;
}
/**
* Desconectar todas as conexões
*/
async desconectar() {
try {
if (this.telnetConnection) {
await this.telnetConnection.end();
this.telnetConnection = null;
this.logger.debug('Conexão OLT encerrada');
}
if (this.tl1Connection && !this.tl1Connection.destroyed) {
this.tl1Connection.destroy();
this.tl1Connection = null;
this.logger.debug('Conexão UNM2000 encerrada');
}
} catch (error) {
this.logger.error('Erro ao desconectar', error);
}
}
/**
* Verificar se as conexões estão ativas
*/
verificarConexoes() {
return {
olt: this.telnetConnection && this.telnetConnection.getSocket(),
unm2000: this.tl1Connection && !this.tl1Connection.destroyed
};
}
/**
* Diagnóstico completo de conectividade
*/
async diagnosticarConectividade() {
const diagnostico = {
olt: {
host: this.config.olt.host,
port: this.config.olt.port,
conectividade: false,
telnet: false,
erro: null
},
unm2000: {
host: this.config.unm2000.host,
port: this.config.unm2000.port,
conectividade: false,
tl1: false,
erro: null
}
};
// Testar OLT
try {
this.logger.debug('Testando conectividade OLT...');
diagnostico.olt.conectividade = await this.testarConectividade(
this.config.olt.host,
this.config.olt.port
);
if (diagnostico.olt.conectividade) {
this.logger.debug('Testando login Telnet OLT...');
diagnostico.olt.telnet = await this.conectarOLT();
}
} catch (error) {
diagnostico.olt.erro = error.message;
this.logger.error('Erro no diagnóstico OLT:', error);
}
// Testar UNM2000
try {
this.logger.debug('Testando conectividade UNM2000...');
diagnostico.unm2000.conectividade = await this.testarConectividade(
this.config.unm2000.host,
this.config.unm2000.port
);
if (diagnostico.unm2000.conectividade) {
this.logger.debug('Testando login TL1 UNM2000...');
diagnostico.unm2000.tl1 = await this.conectarUNM2000();
}
} catch (error) {
diagnostico.unm2000.erro = error.message;
this.logger.error('Erro no diagnóstico UNM2000:', error);
}
return diagnostico;
}
}
module.exports = FiberhomeManager;