aboutsummaryrefslogtreecommitdiff
path: root/src/wifi
diff options
context:
space:
mode:
authorkrolyxon <me@krolyxon.com>2026-05-11 14:01:44 +0530
committerkrolyxon <me@krolyxon.com>2026-05-11 14:01:44 +0530
commitf34b1e2fbd94bcc8d0ee2e2e2e43e214d0b329a1 (patch)
tree235d29da4668906d1e11d651980cea8b0c69dec7 /src/wifi
parent360d2d2ad3bd584014683f3579fc2e2348c16852 (diff)
Migrate to PlatformIO
Now since i have been able to make PSRAM working with platformio, i don't have to use this shitty Arduino-IDE anymore which does not even allow me to use subfolders like a normal programmer would do
Diffstat (limited to 'src/wifi')
-rw-r--r--src/wifi/wifi_analyzer.cpp147
-rw-r--r--src/wifi/wifi_analyzer.h4
-rw-r--r--src/wifi/wifi_scan.cpp152
-rw-r--r--src/wifi/wifi_scan.h5
4 files changed, 308 insertions, 0 deletions
diff --git a/src/wifi/wifi_analyzer.cpp b/src/wifi/wifi_analyzer.cpp
new file mode 100644
index 0000000..320e826
--- /dev/null
+++ b/src/wifi/wifi_analyzer.cpp
@@ -0,0 +1,147 @@
+#include <Arduino.h>
+#include <WiFi.h>
+#include <esp_wifi.h>
+
+#include "../ui/display.h"
+#include "../buttons.h"
+
+// ===== CONFIG =====
+#define GRAPH_WIDTH 128
+#define GRAPH_HEIGHT 44
+#define GRAPH_TOP 10
+#define MAX_POINTS 128
+#define SPIKE_THRESHOLD 30
+
+// ===== STATE =====
+struct SnifferGraph {
+ uint8_t graphData[MAX_POINTS];
+ uint8_t currentChannel = 1;
+ volatile uint16_t packetCounter = 0;
+ unsigned long lastChannelSwitch = 0;
+ unsigned long lastUpdate = 0;
+};
+
+static SnifferGraph sniffer;
+
+// ===== CALLBACK =====
+void IRAM_ATTR snifferCallback(void *buf, wifi_promiscuous_pkt_type_t type)
+{
+ if (type == WIFI_PKT_MGMT || type == WIFI_PKT_DATA || type == WIFI_PKT_CTRL)
+ {
+ sniffer.packetCounter++;
+ }
+}
+
+// ===== INIT =====
+void wifi_analyzer_start()
+{
+ // display init (safe to call again)
+ u8g2.clearBuffer();
+ u8g2.setFont(u8g2_font_5x8_tr);
+ u8g2.drawStr(0, 10, "Starting analyzer...");
+ u8g2.sendBuffer();
+
+ // reset graph
+ memset(sniffer.graphData, 0, sizeof(sniffer.graphData));
+ sniffer.packetCounter = 0;
+ sniffer.currentChannel = 1;
+
+ // reset WiFi
+ WiFi.disconnect(true, true);
+ esp_wifi_stop();
+ delay(200);
+ esp_wifi_deinit();
+
+ wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
+ esp_wifi_init(&cfg);
+ esp_wifi_set_storage(WIFI_STORAGE_RAM);
+ esp_wifi_set_mode(WIFI_MODE_NULL);
+ esp_wifi_start();
+
+ esp_wifi_set_channel(sniffer.currentChannel, WIFI_SECOND_CHAN_NONE);
+ esp_wifi_set_promiscuous_rx_cb(snifferCallback);
+ esp_wifi_set_promiscuous(true);
+}
+
+// ===== HELPERS =====
+static void switchChannel()
+{
+ sniffer.currentChannel++;
+ if (sniffer.currentChannel > 13) sniffer.currentChannel = 1;
+
+ esp_wifi_set_channel(sniffer.currentChannel, WIFI_SECOND_CHAN_NONE);
+}
+
+static void updateGraph(uint8_t value)
+{
+ for (int i = 0; i < MAX_POINTS - 1; i++)
+ {
+ sniffer.graphData[i] = sniffer.graphData[i + 1];
+ }
+
+ sniffer.graphData[MAX_POINTS - 1] = value;
+}
+
+static void drawGraph(uint16_t pktCount)
+{
+ u8g2.clearBuffer();
+ u8g2.setFont(u8g2_font_5x8_tr);
+
+ char line1[16];
+ char line2[16];
+
+ sprintf(line1, "Ch:%d", sniffer.currentChannel);
+ sprintf(line2, "Pkts:%d", pktCount * 5);
+
+ u8g2.drawStr(0, 8, line1);
+ u8g2.drawStr(60, 8, line2);
+
+ for (int x = 1; x < GRAPH_WIDTH; x++)
+ {
+ int y1 = GRAPH_TOP + GRAPH_HEIGHT - sniffer.graphData[x - 1];
+ int y2 = GRAPH_TOP + GRAPH_HEIGHT - sniffer.graphData[x];
+
+ u8g2.drawLine(x - 1, y1, x, y2);
+ }
+
+ if (pktCount >= SPIKE_THRESHOLD)
+ {
+ u8g2.drawVLine(GRAPH_WIDTH / 2, GRAPH_TOP, GRAPH_HEIGHT);
+ }
+
+ u8g2.sendBuffer();
+}
+
+// ===== LOOP =====
+void wifi_analyzer_loop()
+{
+ static uint32_t lastPress = 0;
+ unsigned long now = millis();
+
+ // channel hopping
+ if (now - sniffer.lastChannelSwitch >= 1000)
+ {
+ sniffer.lastChannelSwitch = now;
+ switchChannel();
+ }
+
+ // graph update
+ if (now - sniffer.lastUpdate >= 200)
+ {
+ sniffer.lastUpdate = now;
+
+ uint16_t pktCount = sniffer.packetCounter;
+
+ uint8_t scaled = pktCount * 2;
+ uint8_t value = min(scaled, (uint8_t)GRAPH_HEIGHT);
+
+ updateGraph(value);
+ drawGraph(pktCount);
+
+ sniffer.packetCounter = 0;
+ }
+
+ // optional: small debounce to not hammer CPU
+ if (millis() - lastPress < 10)
+ return;
+}
diff --git a/src/wifi/wifi_analyzer.h b/src/wifi/wifi_analyzer.h
new file mode 100644
index 0000000..df68284
--- /dev/null
+++ b/src/wifi/wifi_analyzer.h
@@ -0,0 +1,4 @@
+#pragma once
+
+void wifi_analyzer_start();
+void wifi_analyzer_loop();
diff --git a/src/wifi/wifi_scan.cpp b/src/wifi/wifi_scan.cpp
new file mode 100644
index 0000000..0b20d3d
--- /dev/null
+++ b/src/wifi/wifi_scan.cpp
@@ -0,0 +1,152 @@
+#include <Arduino.h>
+#include <WiFi.h>
+#include "../ui/display.h"
+#include "../buttons.h"
+
+#define MAX_NETWORKS 30
+
+struct WiFiNet {
+ String ssid;
+ int rssi;
+ int channel;
+ bool encrypted;
+};
+
+static WiFiNet networks[MAX_NETWORKS];
+static int networkCount = 0;
+static int selectedIndex = 0;
+
+// ===== SCAN =====
+void wifi_scan_start()
+{
+ u8g2.clearBuffer();
+ u8g2.drawStr(10, 30, "Scanning WiFi...");
+ u8g2.sendBuffer();
+
+ WiFi.mode(WIFI_STA);
+ WiFi.disconnect();
+
+ delay(100);
+
+ int n = WiFi.scanNetworks();
+
+ networkCount = min(n, MAX_NETWORKS);
+
+ for (int i = 0; i < networkCount; i++)
+ {
+ networks[i].ssid = WiFi.SSID(i);
+ networks[i].rssi = WiFi.RSSI(i);
+ networks[i].channel = WiFi.channel(i);
+ networks[i].encrypted = (WiFi.encryptionType(i) != WIFI_AUTH_OPEN);
+ }
+
+ selectedIndex = 0;
+}
+
+// ===== DRAW =====
+void wifi_scan_draw()
+{
+ u8g2.clearBuffer();
+
+ if (networkCount == 0)
+ {
+ u8g2.drawStr(0, 30, "No networks");
+ u8g2.drawStr(0, 45, "Press BACK");
+ }
+ else
+ {
+ char counter[20];
+ sprintf(counter, "%d/%d", selectedIndex + 1, networkCount);
+ u8g2.setFont(u8g2_font_5x8_tr);
+ u8g2.drawStr(0, 8, counter);
+
+ u8g2.setFont(u8g2_font_6x10_tr);
+
+ for (int i = 0; i < 3; i++)
+ {
+ int idx = selectedIndex + i;
+ if (idx >= networkCount) break;
+
+ int y = 22 + i * 14;
+
+ if (i == 0)
+ {
+ u8g2.drawBox(0, y - 10, 128, 12);
+ u8g2.setDrawColor(0);
+ }
+
+ String text = networks[idx].ssid;
+ if (text.length() > 10)
+ text = text.substring(0, 10) + "..";
+
+ text += " (" + String(networks[idx].rssi) + ")";
+
+ u8g2.drawStr(2, y, text.c_str());
+
+ if (i == 0)
+ u8g2.setDrawColor(1);
+ }
+ }
+
+ u8g2.sendBuffer();
+}
+
+// ===== DETAILS =====
+void wifi_drawDetails()
+{
+ if (networkCount == 0) return;
+
+ WiFiNet &net = networks[selectedIndex];
+
+ u8g2.clearBuffer();
+ u8g2.setFont(u8g2_font_5x8_tr);
+
+ u8g2.drawStr(0, 10, net.ssid.c_str());
+
+ char rssi[20];
+ sprintf(rssi, "RSSI: %d", net.rssi);
+ u8g2.drawStr(0, 20, rssi);
+
+ char ch[20];
+ sprintf(ch, "CH: %d", net.channel);
+ u8g2.drawStr(0, 30, ch);
+
+ u8g2.drawStr(0, 40, net.encrypted ? "Secured" : "Open");
+
+ u8g2.sendBuffer();
+}
+
+// ===== LOOP =====
+void wifi_scan_loop()
+{
+ static uint32_t lastPress = 0;
+
+ if (millis() - lastPress < 150)
+ return;
+
+ if (btnDown() && selectedIndex < networkCount - 1)
+ {
+ selectedIndex++;
+ wifi_scan_draw();
+ lastPress = millis();
+ }
+ else if (btnUp() && selectedIndex > 0)
+ {
+ selectedIndex--;
+ wifi_scan_draw();
+ lastPress = millis();
+ }
+ else if (btnSelect() && networkCount > 0)
+ {
+ wifi_drawDetails();
+ delay(3000);
+ wifi_scan_draw();
+ lastPress = millis();
+ }
+// else if (btnBack())
+// {
+// wifi_scan_start();
+// wifi_scan_draw();
+// lastPress = millis();
+// }
+}
diff --git a/src/wifi/wifi_scan.h b/src/wifi/wifi_scan.h
new file mode 100644
index 0000000..902054e
--- /dev/null
+++ b/src/wifi/wifi_scan.h
@@ -0,0 +1,5 @@
+#pragma once
+
+void wifi_scan_start();
+void wifi_scan_loop();
+void wifi_scan_draw();