sligh changed to dashbaord

This commit is contained in:
bot
2026-04-05 11:29:59 +03:00
parent 5c0ec8cc5a
commit 2636ea1e11
10 changed files with 364 additions and 42 deletions
+8 -4
View File
@@ -15,7 +15,11 @@
#define HEARTBEAT_INTERVAL_MS 10000 // how often to send a heartbeat (ms)
// ─── Probe sniffing ──────────────────────────────────────────────────────────
#define PROBE_SNIFF 1 // 1 = enabled, 0 = disabled
#define PROBE_DEDUP_SECS 30 // suppress same MAC+SSID within this window (seconds)
#define PROBE_QUEUE_SIZE 32 // max probe events buffered between scan cycles
#define DEAUTH_QUEUE_SIZE 32 // max deauth/disassoc events buffered between scan cycles
#define PROBE_SNIFF 1 // 1 = enabled, 0 = disabled
#define PROBE_DEDUP_SECS 30 // suppress same MAC+SSID within this window (seconds)
#define DEDUP_CACHE_SIZE 64 // unique MAC+SSID pairs tracked for dedup
#define PROBE_QUEUE_SIZE 128 // max probe events buffered between flushes
#define DEAUTH_QUEUE_SIZE 128 // max deauth/disassoc events buffered between flushes
// ─── Channel hopping ─────────────────────────────────────────────────────────
#define HOP_DWELL_MS 300 // ms to dwell on each channel (13 ch × 300ms ≈ 4s/sweep)
+75 -8
View File
@@ -15,6 +15,8 @@ String nodeId;
unsigned long lastScan = 0;
unsigned long lastHeartbeat = 0;
static uint8_t homeChannel = 1; // channel of sandbox AP — updated after connect and scan
// ─── Probe sniffing globals ───────────────────────────────────────────────────
#if PROBE_SNIFF
@@ -39,12 +41,12 @@ static QueueHandle_t deauthQueue;
// Dedup cache — suppress repeated MAC+SSID pairs within PROBE_DEDUP_SECS
struct DedupEntry { uint8_t mac[6]; char ssid[33]; uint32_t last_ms; };
static DedupEntry dedupCache[32];
static DedupEntry dedupCache[DEDUP_CACHE_SIZE];
static int dedupNext = 0;
static bool isDuplicate(const uint8_t* mac, const char* ssid) {
uint32_t now = millis();
for (int i = 0; i < 32; i++) {
for (int i = 0; i < DEDUP_CACHE_SIZE; i++) {
if (dedupCache[i].last_ms == 0) continue;
if (memcmp(dedupCache[i].mac, mac, 6) == 0 &&
strcmp(dedupCache[i].ssid, ssid) == 0) {
@@ -59,10 +61,17 @@ static bool isDuplicate(const uint8_t* mac, const char* ssid) {
strncpy(dedupCache[dedupNext].ssid, ssid, 32);
dedupCache[dedupNext].ssid[32] = '\0';
dedupCache[dedupNext].last_ms = now;
dedupNext = (dedupNext + 1) % 32;
dedupNext = (dedupNext + 1) % DEDUP_CACHE_SIZE;
return false;
}
// ─── Channel hop state ───────────────────────────────────────────────────────
static const uint8_t HOP_LIST[] = {1,2,3,4,5,6,7,8,9,10,11,12,13};
static const int HOP_COUNT = sizeof(HOP_LIST) / sizeof(HOP_LIST[0]);
static int hopIdx = 0;
static unsigned long lastHop = 0;
// Promiscuous callback — runs in WiFi task context, not safe to call UDP here.
// Parse probe request, deauth, and disassoc frames and push to queues.
static void promiscuous_rx_cb(void* buf, wifi_promiscuous_pkt_type_t type) {
@@ -153,7 +162,16 @@ void setup() {
void loop() {
if (WiFi.status() != WL_CONNECTED) {
Serial.println("[WIFI] Lost connection, reconnecting...");
#if PROBE_SNIFF
esp_wifi_set_promiscuous(false);
#endif
connectWiFi();
#if PROBE_SNIFF
esp_wifi_set_channel(homeChannel, WIFI_SECOND_CHAN_NONE);
esp_wifi_set_promiscuous(true);
hopIdx = 0;
lastHop = millis();
#endif
return;
}
@@ -167,9 +185,14 @@ void loop() {
if (now - lastScan >= SCAN_INTERVAL_MS) {
lastScan = now;
scanAndSend();
return;
}
delay(100);
#if PROBE_SNIFF
advanceHop();
#endif
delay(10);
}
// ─── WiFi ────────────────────────────────────────────────────────────────────
@@ -188,6 +211,12 @@ void connectWiFi() {
if (WiFi.status() == WL_CONNECTED) {
Serial.printf("\n[WIFI] Connected — IP: %s\n", WiFi.localIP().toString().c_str());
#if PROBE_SNIFF
uint8_t primary; wifi_second_chan_t second;
esp_wifi_get_channel(&primary, &second);
if (primary > 0) homeChannel = primary;
Serial.printf("[HOP] Home channel: %d\n", homeChannel);
#endif
} else {
Serial.println("\n[WIFI] Failed to connect, will retry in loop");
}
@@ -196,11 +225,21 @@ void connectWiFi() {
// ─── Scan ────────────────────────────────────────────────────────────────────
void scanAndSend() {
#if PROBE_SNIFF
// Stop hopping and return to home channel — scan requires a stable channel to start.
esp_wifi_set_promiscuous(false);
esp_wifi_set_channel(homeChannel, WIFI_SECOND_CHAN_NONE);
delay(50);
#endif
Serial.println("[SCAN] Starting...");
int n = WiFi.scanNetworks(false, true); // async=false, show_hidden=true
if (n == WIFI_SCAN_FAILED) {
Serial.println("[SCAN] Failed");
#if PROBE_SNIFF
esp_wifi_set_promiscuous(true);
#endif
return;
}
@@ -213,10 +252,19 @@ void scanAndSend() {
WiFi.scanDelete();
#if PROBE_SNIFF
// Scan may have disabled promiscuous mode internally — re-enable it.
// Re-read home channel — scan resets the radio, AP channel may have shifted.
uint8_t primary; wifi_second_chan_t second;
esp_wifi_get_channel(&primary, &second);
if (primary > 0) homeChannel = primary;
// Re-enable promiscuous and flush anything queued before the scan.
esp_wifi_set_promiscuous(true);
flushProbeQueue();
flushDeauthQueue();
// Reset hop state so next cycle starts cleanly from channel 1.
hopIdx = 0;
lastHop = millis();
#endif
}
@@ -276,12 +324,13 @@ void sendBeaconEvent(int idx) {
// ─── Heartbeat ───────────────────────────────────────────────────────────────
void sendHeartbeat() {
unsigned long now = millis();
char buf[256];
snprintf(buf, sizeof(buf),
"{\"node_id\":\"%s\",\"ts\":%lu,\"type\":\"heartbeat\","
"\"uptime_ms\":%lu,\"free_heap\":%lu,\"wifi_rssi\":%d}",
nodeId.c_str(), millis(),
millis(),
nodeId.c_str(), now,
now,
(unsigned long)ESP.getFreeHeap(),
WiFi.RSSI()
);
@@ -289,7 +338,7 @@ void sendHeartbeat() {
udp.print(buf);
udp.endPacket();
Serial.printf("[HB] uptime=%lus heap=%luK ap=%ddBm\n",
millis() / 1000,
now / 1000,
(unsigned long)ESP.getFreeHeap() / 1024,
WiFi.RSSI()
);
@@ -377,4 +426,22 @@ void flushDeauthQueue() {
}
}
// Advance to the next channel in the hop list.
// Non-blocking — returns immediately if the dwell time hasn't elapsed.
// Flushes queues each time we land back on homeChannel (WiFi is usable there).
void advanceHop() {
unsigned long now = millis();
if (now - lastHop < HOP_DWELL_MS) return;
lastHop = now;
hopIdx = (hopIdx + 1) % HOP_COUNT;
uint8_t ch = HOP_LIST[hopIdx];
esp_wifi_set_channel(ch, WIFI_SECOND_CHAN_NONE);
if (ch == homeChannel && WiFi.status() == WL_CONNECTED) {
flushProbeQueue();
flushDeauthQueue();
}
}
#endif // PROBE_SNIFF