Krolyxon
Commit 1f800b7

Branches

Tags

Refs →

orion-rfsrcwifiwifi_analyzer.cpp

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