//Documentação de Engenharia de Sistemas e Arquitetura de Software
O Ecossistema Aether é uma suite de software corporativa desenvolvida em C# (.NET 10) com foco em Windows Forms, projetada especificamente para suprir as necessidades críticas de monitorização de infraestrutura de TI, triagem automatizada de falhas de hardware, gestão de conectividade e resiliência de dados em redes de alta densidade.
A interface foi inteiramente concebida utilizando a biblioteca Guna UI2, garantindo aceleração gráfica por hardware na renderização de controlos Windows Forms, cantos arredondados, transições fluidas e uma paleta de cores focada em ambientes de operações de rede (NOC).
Abaixo encontra-se a especificação técnica detalhada de cada objeto instanciado no formulário principal (MainForm.cs):
sidePanel(Guna.UI2.WinForms.Guna2Panel)- Descrição: Painel de navegação estrutural ancorado à esquerda da aplicação (
Dock = DockStyle.Left). - Comportamento: Controla a alternância dinâmica de controlos de utilizador (User Controls) sem a necessidade de reabrir novos formulários, garantindo uma experiência Single Page Application (SPA).
- Descrição: Painel de navegação estrutural ancorado à esquerda da aplicação (
lstPromptPing(System.Windows.Forms.ListBox)- Descrição: Buffer visual de saída serializada para o rastreamento de pacotes ICMP.
- Comportamento: Configurado com desenho otimizado para evitar flickering (cintilação) durante inserções de alta frequência (múltiplas threads disparando requisições de ping em simultâneo).
dgvLogs(Guna.UI2.WinForms.Guna2DataGridView)- Descrição: Grelha de dados tabular de alta performance para exibição de eventos estruturados do sistema.
- Colunas:
Timestamp(DateTime),Origem(String),Evento(String),Criticidade(Enum: Info, Alerta, Crítico). - Funcionalidade: Suporta ordenação em tempo real e coloração condicional de linhas baseada no nível de severidade mapeado no backend.
txtIdentificador(Guna.UI2.WinForms.Guna2TextBox)- Descrição: Input de texto mascarado utilizado para a inserção de chaves de licença, tokens de autenticação ou chaves primárias de hardware (GUIDs das máquinas clientes).
txtPesquisa(Guna.UI2.WinForms.Guna2TextBox)- Descrição: Caixa de texto com captura de evento
TextChangedotimizada com técnica de Debounce (atraso de milissegundos para evitar travamentos) para filtragem instantânea de registos nodgvLogsou filtragem de nós nocbIPs.
- Descrição: Caixa de texto com captura de evento
cbIPs(System.Windows.Forms.ComboBox)- Descrição: Menu drop-down populado dinamicamente através de threads em background contendo os endereços IP descobertos na sub-rede ativa ou carregados a partir do último backup local.
checkBoxMultiline(System.Windows.Forms.CheckBox)- Descrição: Alternador lógico (Toggle Switch) que modifica programmaticamente a propriedade de desenho do
lstPromptPinge dodgvLogspara permitir quebras de linha automáticas (WordWrap), otimizando a visualização de stack traces longos de exceções em monitores de campo.
- Descrição: Alternador lógico (Toggle Switch) que modifica programmaticamente a propriedade de desenho do
btnBackup(Guna.UI2.WinForms.Guna2Button)- Descrição: Gatilho para serialização do estado atual do sistema (ficheiros de configuração, histórico de logs e parâmetros de IP) e upload via stream assíncrono para o repositório de nuvem associado.
btnImportBackup(Guna.UI2.WinForms.Guna2Button)- Descrição: Controla a operação inversa ao backup. Realiza o download do último snapshot de configuração homologado, efetua o parsing do JSON descritor e re-popula os controlos da UI em runtime.
btnAetherAI(Guna.UI2.WinForms.Guna2Button)- Descrição: Interface de chamada do motor de IA. Envia o dump de erro atual presente no
dgvLogspara processamento cognitivo, retornando diagnósticos preditivos e sugestões de comandos de correção.
- Descrição: Interface de chamada do motor de IA. Envia o dump de erro atual presente no
btnAdicionarIP(Guna.UI2.WinForms.Guna2Button)- Descrição: Abre o sub-contexto de registo de ativos. Permite a injeção manual de novos nós de monitorização (IP, Máscara, Gateway, Descrição) na topologia em cache.
lblRede: Rótulo dinâmico associado a uma máquina de estados de rede. Avalia a latência e perda de pacotes da interface de rede primária. Exibe:[ONLINE]em verde caso a WAN e LAN estejam operacionais.[LOCAL ONLY]em amarelo caso haja falha na rota externa do gateway.[DISCONNECTED]em vermelho piscante caso não haja link ativo.
lblTotal: Mostrador numérico inteiro alimentado pelo tamanho do array gerado no processamento do cache ARP. Indica a quantidade exata de dispositivos respondendo na camada 2 do modelo OSI no segmento atual.lblAl1: Label dedicada à exibição de alertas críticos provenientes diretamente da triagem do RedeSnow. Quando um comportamento anómalo de hardware é detetado (como um switch Huawei reportando falha na ventoinha ou loop de rede nas portas), esta label assume foco visual com animações nativas da biblioteca Guna.label6,label1,label8: Elementos estáticos de arquitetura de informação (títulos de secções, contadores secundários e metadados de versão do sistema).
O motor do sistema baseia-se fortemente em programação assíncrona (async/await) e multithreading para garantir que as operações de I/O de rede de baixa velocidade não causem o congelamento da thread de interface (UI Thread Freeze).
A segurança do ecossistema assenta na validação de hashes no arranque do sistema. O método abaixo ilustra a robustez do tratamento de dados:
using System;
using System.Drawing;
using System.Net;
using System.Net.Mail;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace aether
{
public partial class FrmLogin : Form
{
private string codigoGerado = "";
private const string DOMINIO_PERMITIDO = "@suaempresa.com.br";//use o dominio que desejar ser permitido dentro do ecossistema Aether.
// CONFIGURAÇÃO DO EMISSOR (Use suas credenciais aqui)
private const string EMAIL_SUPORTE = "suaempresa@gmail.com";// Email a qual enviará o codigo de acesso.
private const string SENHA_APP = "suasenha"; //Algumas infraestruturas como a Google permite gerar senhas epecificas para apps na configuração da conta que enviará o email.
[DllImport("user32.DLL", EntryPoint = "ReleaseCapture")]
private extern static void ReleaseCapture();
[DllImport("user32.DLL", EntryPoint = "SendMessage")]
private extern static void SendMessage(IntPtr hWnd, int wMsg, int wParam, int lParam);
private TextBox txtEmail;
private TextBox txtCode;
private Button btnAcao;
public FrmLogin()
{
InitializeComponent();
ConfigurarInterfaceCustom();
this.Text = $"welabs - Cloud Login";
}
private void ConfigurarInterfaceCustom()
{
this.Size = new Size(450, 400);
this.BackColor = Color.White;
this.FormBorderStyle = FormBorderStyle.FixedToolWindow;
this.StartPosition = FormStartPosition.CenterScreen;
Label lblTitulo = new Label
{
Text = "AETHER CLOUD",
ForeColor = Color.Black,
Font = new Font("Consolas", 18, FontStyle.Bold),
Location = new Point(0, 30),
Size = new Size(450, 40),
TextAlign = ContentAlignment.MiddleCenter
};
Label lblInfo = new Label
{
Text = "Bem vindo Colaborador!.\nPara continuar, insira seu e-mail corporativo abaixo.",
ForeColor = Color.Gray,
Font = new Font("Segoe UI", 9),
Location = new Point(0, 75),
Size = new Size(450, 40),
TextAlign = ContentAlignment.MiddleCenter
};
txtEmail = new TextBox
{
Size = new Size(320, 35),
Location = new Point(65, 140),
Font = new Font("Consolas", 11),
ForeColor = Color.Black,
PlaceholderText = "usuario@valenet.com.br",
TextAlign = HorizontalAlignment.Center
};
txtCode = new TextBox
{
Size = new Size(320, 35),
Location = new Point(65, 190),
Font = new Font("Consolas", 14, FontStyle.Bold),
PlaceholderText = "------",
TextAlign = HorizontalAlignment.Center,
Visible = false // Escondido até o e-mail ser enviado
};
btnAcao = new Button
{
Text = "SOLICITAR ACESSO",
Size = new Size(320, 45),
Location = new Point(65, 260),
FlatStyle = FlatStyle.Flat,
BackColor = Color.Black,
ForeColor = Color.White,
Font = new Font("Consolas", 10, FontStyle.Bold),
Cursor = Cursors.Hand
};
btnAcao.FlatAppearance.BorderSize = 0;
btnAcao.Click += async (s, e) => {
if (btnAcao.Text == "SOLICITAR ACESSO")
{
await ProcessarEnvioEmail();
}
else
{
VerificarCodigo();
}
};
Label btnFechar = new Label
{
Text = "",
Location = new Point(415, 10),
Cursor = Cursors.Hand,
Font = new Font("Consolas", 12)
};
btnFechar.Click += (s, e) =>
{
Application.Exit();
};
this.Controls.Add(lblTitulo);
this.Controls.Add(lblInfo);
this.Controls.Add(txtEmail);
this.Controls.Add(txtCode);
this.Controls.Add(btnAcao);
this.Controls.Add(btnFechar);
this.MouseDown += (s, e) => { ReleaseCapture(); SendMessage(this.Handle, 0x112, 0xf012, 0); };
}
private async Task ProcessarEnvioEmail()
{
string email = txtEmail.Text.Trim().ToLower();
if (!email.EndsWith(DOMINIO_PERMITIDO))
{
MessageBox.Show("ERRO: Utilize seu email Valenet para acessar o Aether Hub", "Acesso Negado");
return;
}
btnAcao.Enabled = false;
btnAcao.Text = "ENVIANDO...";
Random rnd = new Random();
codigoGerado = rnd.Next(100000, 999999).ToString();
bool sucesso = await EnviarEmailSmtp(email, codigoGerado);
if (sucesso)
{
txtEmail.ReadOnly = true;
txtCode.Visible = true;
btnAcao.Text = "VALIDAR CÓDIGO";
btnAcao.Enabled = true;
MessageBox.Show("Código enviado! Verifique sua caixa de entrada.");
}
else
{
btnAcao.Text = "SOLICITAR ACESSO";
btnAcao.Enabled = true;
MessageBox.Show("Falha ao enviar e-mail. Verifique sua conexão.");
}
}
private async Task<bool> EnviarEmailSmtp(string destino, string code)
{
try
{
// Força o uso de protocolos de segurança modernos exigidos pelo Gmail
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls13;
using (var mailMessage = new MailMessage())
{
mailMessage.From = new MailAddress(EMAIL_SUPORTE, "AETHER SEGURANÇA");
mailMessage.Subject = code + " é seu código de autenticação";
// Corpo HTML simplificado para evitar filtros de SPAM
mailMessage.Body = $@"
<div style='font-family: Arial; border: 1px solid #ddd; padding: 20px; max-width: 400px;'>
<h2 style='color: #000;'>AETHER CLOUD</h2>
<p>Seu código de acesso é:</p>
<div style='background: #f4f4f4; padding: 15px; text-align: center; font-size: 24px; font-weight: bold; letter-spacing: 4px;'>
{code}
</div>
<p style='font-size: 11px; color: #888; margin-top: 20px;'>
Este código foi solicitado para o e-mail: {destino}
</p>
</div>";
mailMessage.IsBodyHtml = true;
mailMessage.To.Add(destino);
using (var smtpClient = new SmtpClient("smtp.gmail.com"))
{
smtpClient.Port = 587;
smtpClient.Credentials = new NetworkCredential(EMAIL_SUPORTE, SENHA_APP);
smtpClient.EnableSsl = true;
smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
smtpClient.UseDefaultCredentials = false;
// Tenta enviar
await smtpClient.SendMailAsync(mailMessage);
return true;
}
}
}
catch (Exception ex)
{
// Se der erro, ele mostrará o motivo real no console do Visual Studio
System.Diagnostics.Debug.WriteLine("ERRO SMTP: " + ex.Message);
return false;
}
}
private void VerificarCodigo()
{
if (txtCode.Text.Trim() == codigoGerado)
{
try
{
// Cria a pasta Apps se não existir
string folder = Path.Combine(Application.StartupPath, "settings");
if (!Directory.Exists(folder)) Directory.CreateDirectory(folder);
// Salva o e-mail do usuário como prova de que ele logou
string pathLicenca = Path.Combine(folder, "ident.lic");
File.WriteAllText(pathLicenca, "AUTHORIZED_USER: " + txtEmail.Text);
this.DialogResult = DialogResult.OK;
this.Close();
}
catch (Exception ex)
{
MessageBox.Show("Erro ao salvar licença local: " + ex.Message);
}
}
else
{
MessageBox.Show("Código incorreto. Tente novamente.");
}
}
}
}O programa recolhe dados de endereçamento IP e MAC consultando as tabelas internas do sistema operativo através da API auxiliar Iphlpapi.dll (IP Helper API) via P/Invoke ou executando de forma silenciosa o utilitário nativo do sistema e realizando o parsing do output de texto.
- Descoberta Passiva: Varredura do ficheiro ARP do SO para identificar marcas de placas (OUI MAC Check) que batam com o padrão Huawei (e.g., 00:E0:FC) - TP-Link ou Tenda.
- Descoberta Ativa: O sistema popula o
cbIPse inicia pings paralelos usando a classeSystem.Net.NetworkInformation.Ping. Cada triagem bem-sucedida atualiza dinamicamente olblTotal. - Isolamento de Erro: Caso o IP alvo pare de responder ao ICMP mas continue listado na tabela ARP, o RedeSnow assume uma falha lógica de software no switch ou bloqueio por ACL/Firewall, atualizando o
lblAl1de imediato.
As rotinas desencadeadas pelos botões btnBackup e btnImportBackup operam sobre dados estruturados em formato JSON, comprimidos usando o algoritmo GZip antes da transmissão.
[ Estado Atual do Sistema ]
│
▼ (Serialização JSON)
[ Ficheiro Bruto .json ]
│
▼ (Compressão GZip)
[ Payload .aetherbkp ]
│
▼ (OAuth2 Token Auth)
[ Upload para o Google Drive ]
- Persistência de Dados: O ficheiro gerado armazena o histórico do
dgvLogs, a coleção de IPs customizados inseridos pelo utilizador através dobtnAdicionarIP, e os parâmetros atuais de timeout e multithreading configurados na interface. - Tratamento de Indisponibilidade: Caso a conexão com os endpoints da Google falhe (identificada por um timeout capturado no backend), o sistema aciona de forma transparente um armazenamento local em cache na pasta
%AppData%/AetherNetwork/LocalCache/e sinaliza o operador através dolblRede.
A resiliência mecânica do software assenta numa infraestrutura de tratamento de exceções em pirâmide. O ecossistema está preparado para lidar com cenários severos de campo sem falhar catastroficamente.
| Tipo de Incidente | Causa Provável | Comportamento do Backend | Reflexo na Interface (UI) |
|---|---|---|---|
SocketException |
Cabo de consola desconectado ou switch Huawei sem alimentação elétrica. | Captura o código de erro nativo do socket, encerra a ligação pendente para evitar vazamento de memória. | Grava uma linha vermelha de severidade 'CRÍTICA' no dgvLogs e atualiza o lblAl1. |
NullReferenceException |
Tentativa de leitura de um nó de rede que foi apagado da tabela ARP intermédia em runtime. | Inicializa uma instância vazia padrão utilizando padrões de projeto (Null Object Pattern). | O counter lblTotal decrementa o valor de forma segura sem lançar pop-ups de erro para o operador. |
TaskCanceledException |
A API do nPoint demorou mais de 8 segundos para responder devido a lag na internet móvel de campo. | Cancela a requisição HTTP local, entra em modo de licenciamento temporário offline por cache assinado. | Altera o rótulo lblRede para exibir um aviso amarelo e regista o timeout no histórico geral. |
Para realizar a correta compilação e implementação em produção do ecossistema Aether Network, siga escrupulosamente os passos técnicos abaixo.
- Ambiente de Desenvolvimento: Microsoft Visual Studio 2022 (Versão 17.4 ou superior) com a carga de trabalho de desenvolvimento para desktop com .NET selecionada.
- SDK Alvo: .NET Framework 4.8 Runtime / .NET 6.0 SDK (conforme a vertente de compilação pretendida).
- Gestor de Pacotes Nuget: Requer acesso à internet para restauro automático das seguintes bibliotecas de terceiros:
Guna.UI2.WinForms(v2.0.4.6 ou posterior)Newtonsoft.Json(v13.0.3 ou posterior)Google.Apis.Drive.v3(v1.60.0 ou posterior)
- Transfira a árvore completa de diretórios de código fonte para a sua diretoria de desenvolvimento local.
- Abra o ficheiro de solução unificado
AetherNetworkSuite.slnno Visual Studio. - Abra a consola do Gestor de Pacotes NuGet (
Tools > NuGet Package Manager > Package Manager Console) e execute o seguinte comando para forçar a sincronização de dependências:
Update-Package -Reinstall
- Altere a configuração de compilação na barra de ferramentas superior do Visual Studio de
DebugparaRelease. - Selecione a plataforma alvo apropriada. Recomenda-se definir estritamente para
x64para permitir a alocação expandida de memória RAM durante varreduras massivas de rede IP Camada 3, evitando a flagAny CPUque pode causar overhead em sistemas legados. - Clique com o botão direito sobre a Solution no Solution Explorer e selecione "Rebuild Solution".
- Os binários finais otimizados (
AetherNetwork.exee as DLLs auxiliares da suite Guna e Google) serão gerados com sucesso na diretoria de saída:..\\AetherNetworkProject\\bin\\Release\\net6.0-windows\\.