Scanner de Intensidade de Sinal WiFi em C# com Estimativa de Distância

Este artigo descreve a implementação de um scanner de sinal WiFi em C# que detecta a intensidade do sinal, estima distâncias e monitora redes em tempo real.

Implementação do Componente Principal


using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Timers;
using SimpleWifi;

public class MonitorDeSinalWifi : IDisposable
{
    private Wifi _servicoWifi;
    private Timer _temporizador;
    private Dictionary<string distancia="" double="" sinal=""> _resultados = new();

    public event EventHandler<atualizacaoresultadoseventargs> ResultadosAtualizados;

    public MonitorDeSinalWifi()
    {
        _servicoWifi = new Wifi();
        ConfigurarTemporizador(5000);
    }

    private void ConfigurarTemporizador(int intervalo)
    {
        _temporizador = new Timer(intervalo);
        _temporizador.Elapsed += async (s, e) => await RealizarVarredura();
    }

    private async Task RealizarVarredura()
    {
        try
        {
            var pontosDeAcesso = await _servicoWifi.ObterPontosDeAcessoAsync();
            var listaDeResultados = new List<resultadoscan>();

            foreach (var ponto in pontosDeAcesso)
            {
                if (ponto.ForcaSinal > -100)
                {
                    double distanciaEstimada = EstimarDistancia(ponto.ForcaSinal);
                    listaDeResultados.Add(new ResultadoScan
                    {
                        Rede = ponto.Nome,
                        Sinal = ponto.ForcaSinal,
                        Distancia = distanciaEstimada,
                        Canal = ponto.Canal,
                        Seguro = ponto.EhSeguro
                    });
                }
            }

            _resultados = listaDeResultados.ToDictionary(r => r.Rede, r => (r.Sinal, r.Distancia));
            ResultadosAtualizados?.Invoke(this, new AtualizacaoResultadosEventArgs(listaDeResultados));
        }
        catch (Exception ex)
        {
            RegistrarErro(ex);
        }
    }

    private double EstimarDistancia(int sinal)
    {
        const double distanciaReferencia = 1.0;
        const int sinalReferencia = -30;

        if (sinal >= sinalReferencia) return 0.1;

        double perdaCaminho = sinalReferencia - sinal;
        return Math.Pow(10, perdaCaminho / 20) * distanciaReferencia;
    }

    public void ExibirResultados()
    {
        Console.WriteLine("Resultados da Varredura de WiFi:");
        foreach (var item in _resultados.Values)
        {
            Console.WriteLine($"Rede: {item.Rede,-15} " +
                              $"Sinal: {item.Sinal}dBm " +
                              $"Distância: {item.Distancia:F1}m " +
                              $"Canal: {item.Canal} " +
                              $"Segurança: {(item.Seguro ? "Sim" : "Não")}");
        }
    }

    public void Dispose()
    {
        _temporizador?.Dispose();
        _servicoWifi?.Dispose();
    }
}

public class ResultadoScan
{
    public string Rede { get; set; }
    public int Sinal { get; set; }
    public double Distancia { get; set; }
    public int Canal { get; set; }
    public bool Seguro { get; set; }
}

public class AtualizacaoResultadosEventArgs : EventArgs
{
    public List<resultadoscan> Resultados { get; }

    public AtualizacaoResultadosEventArgs(List<resultadoscan> resultados)
    {
        Resultados = resultados;
    }
}
</resultadoscan></resultadoscan></resultadoscan></atualizacaoresultadoseventargs></string>

Detalhes das Funcionalidades Chave

1. Detecção de Intensidade de Sinal


var pontosDeAcesso = await _servicoWifi.ObterPontosDeAcessoAsync();
foreach (var ponto in pontosDeAcesso)
{
    Console.WriteLine($"Rede: {ponto.Nome}");
    Console.WriteLine($"Intensidade: {ponto.ForcaSinal}%");
    Console.WriteLine($"Valor dBm: {ConverterParaDbm(ponto.ForcaSinal)}dBm");
}

private int ConverterParaDbm(int porcentagem)
{
    return (int)((porcentagem / 2.0) - 100);
}

2. Algoritmo de Estimativa de Distância


private double EstimarDistanciaAprimorada(int sinal)
{
    const double potenciaTransmissao = -59;
    const double expoentePerda = 2.7;

    double razao = sinal * 1.0 / potenciaTransmissao;
    if (razao < 1) return Math.Pow(razao, 10);
    else return 0.89976 * Math.Pow(razao, 7.7095) + 0.111;
}

3. Interface de Monitoramento em Tempo Real (Exemplo com WinForm)


public partial class FormularioPrincipal : Form
{
    private MonitorDeSinalWifi _monitor;
    private DataGridView _gradeDeDados;

    public FormularioPrincipal()
    {
        InitializeComponent();
        InicializarComponentes();
        _monitor = new MonitorDeSinalWifi();
        _monitor.ResultadosAtualizados += AoAtualizarResultados;
    }

    private void InicializarComponentes()
    {
        _gradeDeDados = new DataGridView { Dock = DockStyle.Fill };
        _gradeDeDados.Columns.AddRange(
            new DataGridViewTextBoxColumn { Name = "Rede", HeaderText = "Nome da Rede" },
            new DataGridViewTextBoxColumn { Name = "IntensidadeSinal", HeaderText = "Sinal (dBm)" },
            new DataGridViewTextBoxColumn { Name = "Distancia", HeaderText = "Distância (m)" }
        );
        Controls.Add(_gradeDeDados);
    }

    private void AoAtualizarResultados(object sender, AtualizacaoResultadosEventArgs e)
    {
        _gradeDeDados.Invoke((MethodInvoker)delegate {
            _gradeDeDados.DataSource = e.Resultados;
        });
    }
}

Práticas de Engenharia

1. Configuração de Permissões


<!-- app.manifest -->
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />

2. Otimização de Desempenho

  • Varrredura em Lote: Combine múltiplas varreduras para reduzir chamadas ao sistema.
  • Cache de Dados: Use ConcurrentDictionary para armazenar dados históricos.
  • Processamento Assíncrono: Empregue async/await para evitar travamentos na interface.

3. Extensões de Funcionalidades Avançadas


public Dictionary<int, int> AnalisarUtilizacaoDeCanais()
{
    return _resultados.Values
        .GroupBy(r => r.Canal)
        .ToDictionary(g => g.Key, g => g.Count());
}

public Bitmap GerarMapaDeCalor()
{
    // Implementação usando GDI+ para visualizar a distribuição de sinal.
}

Implantação e Uso

1. Dependências via NuGet


Install-Package SimpleWifi.netstandard.Lsh
Install-Package LiveCharts.WinForms

2. Exemplo de Execução


var scanner = new MonitorDeSinalWifi();
scanner.ResultadosAtualizados += (s, e) =>
{
    Console.WriteLine($"Detectados {e.Resultados.Count} redes");
    e.Resultados.OrderByDescending(r => r.Sinal).Take(3).ToList().ForEach(r =>
        Console.WriteLine($"Sinal mais forte: {r.Rede} ({r.Sinal}dBm)"));
};
scanner.IniciarVarreduraContinua();

Depuração e Calibração

1. Registro de Logs


public static class Registrador
{
    public static void RegistrarDadosDeSinal(int sinal, double distancia)
    {
        File.AppendAllText("registro_wifi.txt",
            $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} | Sinal:{sinal} | Distância:{distancia}m\n");
    }
}

2. Calibração de Precisão


private static double _fatorCalibracao = 1.2;

public double DistanciaCalibrada(int sinal)
{
    double distanciaBruta = EstimarDistancia(sinal);
    return distanciaBruta * _fatorCalibracao;
}

Sugestões para Aprimoramento da Interface

1. Visualização de Intensidade de Sinal


var grafico = new CartesianChart();
grafico.Series = new SeriesCollection
{
    new LineSeries
    {
        Values = new ChartValues<double>(_resultados.Values.Select(r => (double)r.Sinal))
    }
};

2. Funcionalidade de Localização de Dispositivos


public Point CalcularPosicao()
{
    var pontosDeAcesso = _resultados.Values.ToList();
    if (pontosDeAcesso.Count < 3) return Point.Empty;

    // Implementação do algoritmo de trilateração...
}

Tags: CSharp WiFi IntensidadeDeSinal EstimativaDeDistância WinForms

Publicado em 6-16 23:40