Krolyxon
Commit 206ed22

Branches

Tags

Refs →

orion-rfsrcwifiwifi_analyzer.cpp

136 lines · 3.1 KB · C++

1#include <Arduino.h>
2#include <WiFi.h>
3#include <esp_wifi.h>
4
5#include "../ui/display.h"
6#include "../utils/buttons.h"
7
8// ===== CONFIG =====
9#define GRAPH_WIDTH 128
10#define GRAPH_HEIGHT 44
11#define GRAPH_TOP 10
12#define MAX_POINTS 128
13#define SPIKE_THRESHOLD 30
14
15// ===== STATE =====
16struct SnifferGraph {
17 uint8_t graphData[MAX_POINTS];
18 uint8_t currentChannel = 1;
19 volatile uint16_t packetCounter = 0;
20 unsigned long lastChannelSwitch = 0;
21 unsigned long lastUpdate = 0;
22};
23
24static SnifferGraph sniffer;
25
26// ===== CALLBACK =====
27void IRAM_ATTR snifferCallback(void *buf, wifi_promiscuous_pkt_type_t type) {
28 if (type == WIFI_PKT_MGMT || type == WIFI_PKT_DATA || type == WIFI_PKT_CTRL) {
29 sniffer.packetCounter++;
30 }
31}
32
33// ===== INIT =====
34void wifi_analyzer_start() {
35 // display init (safe to call again)
36 u8g2.clearBuffer();
37 u8g2.setFont(u8g2_font_5x8_tr);
38 u8g2.drawStr(0, 10, "Starting analyzer...");
39 u8g2.sendBuffer();
40
41 // reset graph
42 memset(sniffer.graphData, 0, sizeof(sniffer.graphData));
43 sniffer.packetCounter = 0;
44 sniffer.currentChannel = 1;
45
46 // reset WiFi
47 WiFi.disconnect(true, true);
48 esp_wifi_stop();
49 delay(200);
50 esp_wifi_deinit();
51
52 wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
53 esp_wifi_init(&cfg);
54 esp_wifi_set_storage(WIFI_STORAGE_RAM);
55 esp_wifi_set_mode(WIFI_MODE_NULL);
56 esp_wifi_start();
57
58 esp_wifi_set_channel(sniffer.currentChannel, WIFI_SECOND_CHAN_NONE);
59 esp_wifi_set_promiscuous_rx_cb(snifferCallback);
60 esp_wifi_set_promiscuous(true);
61}
62
63// ===== HELPERS =====
64static void switchChannel() {
65 sniffer.currentChannel++;
66 if (sniffer.currentChannel > 13)
67 sniffer.currentChannel = 1;
68
69 esp_wifi_set_channel(sniffer.currentChannel, WIFI_SECOND_CHAN_NONE);
70}
71
72static void updateGraph(uint8_t value) {
73 for (int i = 0; i < MAX_POINTS - 1; i++) {
74 sniffer.graphData[i] = sniffer.graphData[i + 1];
75 }
76
77 sniffer.graphData[MAX_POINTS - 1] = value;
78}
79
80static void drawGraph(uint16_t pktCount) {
81 u8g2.clearBuffer();
82 u8g2.setFont(u8g2_font_5x8_tr);
83
84 char line1[16];
85 char line2[16];
86
87 sprintf(line1, "Ch:%d", sniffer.currentChannel);
88 sprintf(line2, "Pkts:%d", pktCount * 5);
89
90 u8g2.drawStr(0, 8, line1);
91 u8g2.drawStr(60, 8, line2);
92
93 for (int x = 1; x < GRAPH_WIDTH; x++) {
94 int y1 = GRAPH_TOP + GRAPH_HEIGHT - sniffer.graphData[x - 1];
95 int y2 = GRAPH_TOP + GRAPH_HEIGHT - sniffer.graphData[x];
96
97 u8g2.drawLine(x - 1, y1, x, y2);
98 }
99
100 if (pktCount >= SPIKE_THRESHOLD) {
101 u8g2.drawVLine(GRAPH_WIDTH / 2, GRAPH_TOP, GRAPH_HEIGHT);
102 }
103
104 u8g2.sendBuffer();
105}
106
107// ===== LOOP =====
108void wifi_analyzer_loop() {
109 static uint32_t lastPress = 0;
110 unsigned long now = millis();
111
112 // channel hopping
113 if (now - sniffer.lastChannelSwitch >= 1000) {
114 sniffer.lastChannelSwitch = now;
115 switchChannel();
116 }
117
118 // graph update
119 if (now - sniffer.lastUpdate >= 200) {
120 sniffer.lastUpdate = now;
121
122 uint16_t pktCount = sniffer.packetCounter;
123
124 uint8_t scaled = pktCount * 2;
125 uint8_t value = min(scaled, (uint8_t)GRAPH_HEIGHT);
126
127 updateGraph(value);
128 drawGraph(pktCount);
129
130 sniffer.packetCounter = 0;
131 }
132
133 // optional: small debounce to not hammer CPU
134 if (millis() - lastPress < 10)
135 return;
136}