diff --git a/src/main.cpp b/src/main.cpp index 251e02a..fb956e2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -120,6 +120,12 @@ static const char* wifi_mac_prefixes[] = { "70:ad:43" }; +// ============================================================================ +// WIFI PROMISCUOUS MODE — frame subtypes +// ============================================================================ +#define WIFI_MGMT_PROBE_REQ 0x04 +#define WIFI_MGMT_BEACON 0x08 + // ============================================================================ // RAVEN SURVEILLANCE DEVICE UUID PATTERNS // ============================================================================ @@ -178,6 +184,8 @@ static Adafruit_NeoPixel fyPixel(1, FY_NEOPIXEL_PIN, NEO_GRB + NEO_KHZ800); static bool fyPixelAlertMode = false; static unsigned long fyPixelAlertStart = 0; static unsigned long fyLastBleScan = 0; +static volatile bool fyWifiAlertPending = false; // Deferred from promiscuous CB +static int fyWifiDetCount = 0; static bool fyTriggered = false; static bool fyDeviceInRange = false; static unsigned long fyLastDetTime = 0; @@ -384,6 +392,78 @@ static bool checkWiFiMACPrefix(const uint8_t* mac) { return false; } +// ============================================================================ +// WIFI PROMISCUOUS CALLBACK +// ============================================================================ +// Called by the WiFi driver for every frame on the AP's channel. +// Probe requests from devices scanning (on ANY channel) are caught because +// WiFi devices sweep all channels when probing. Beacons only on AP channel. +// NOTE: Runs on the WiFi task — do NOT call delay()/tone() here. +// Audio/LED alerts are deferred to the main loop via fyWifiAlertPending. + +static void fyWifiPromiscuousCB(void *buf, wifi_promiscuous_pkt_type_t type) { + if (type != WIFI_PKT_MGMT) return; + + const wifi_promiscuous_pkt_t *pkt = (wifi_promiscuous_pkt_t *)buf; + const uint8_t *frame = pkt->payload; + int len = pkt->rx_ctrl.sig_len; + + // Minimum 802.11 management header: 24 bytes + // (FC:2 + Duration:2 + Addr1:6 + Addr2:6 + Addr3:6 + SeqCtrl:2) + if (len < 24) return; + + // Frame Control byte 0: bits[3:2]=type, bits[7:4]=subtype + uint8_t fc0 = frame[0]; + uint8_t frame_type = (fc0 >> 2) & 0x03; + uint8_t subtype = (fc0 >> 4) & 0x0F; + + if (frame_type != 0) return; // Not a management frame + if (subtype != WIFI_MGMT_PROBE_REQ && subtype != WIFI_MGMT_BEACON) return; + + // Address 2 (source/transmitter MAC) at offset 10 + const uint8_t *src_mac = &frame[10]; + + if (!checkWiFiMACPrefix(src_mac)) return; + + // Match! Build MAC string and register detection + char mac_str[18]; + snprintf(mac_str, sizeof(mac_str), "%02x:%02x:%02x:%02x:%02x:%02x", + src_mac[0], src_mac[1], src_mac[2], + src_mac[3], src_mac[4], src_mac[5]); + + const char *method = (subtype == WIFI_MGMT_PROBE_REQ) ? "wifi_probe" : "wifi_beacon"; + int rssi = pkt->rx_ctrl.rssi; + + int idx = fyAddDetection(mac_str, "", rssi, method); + if (idx >= 0) { + if (fyDet[idx].count == 1) { + // First sighting — new WiFi surveillance device + fyWifiDetCount++; + printf("[DANTIR] WiFi DETECTED: %s RSSI:%d [%s]\n", mac_str, rssi, method); + + // JSON serial output + char gpsBuf[80] = ""; + if (fyGPSIsFresh()) { + snprintf(gpsBuf, sizeof(gpsBuf), + ",\"gps\":{\"latitude\":%.8f,\"longitude\":%.8f,\"accuracy\":%.1f}", + fyGPSLat, fyGPSLon, fyGPSAcc); + } + printf("{\"detection_method\":\"%s\",\"protocol\":\"wifi\"," + "\"mac_address\":\"%s\",\"rssi\":%d%s}\n", + method, mac_str, rssi, gpsBuf); + } + + // Defer buzzer/LED alert to main loop (can't call delay() here) + fyDeviceInRange = true; + fyLastDetTime = millis(); + fyWifiAlertPending = true; + } +} + +// ============================================================================ +// DETECTION HELPERS — NAME & MANUFACTURER +// ============================================================================ + static bool checkDeviceName(const char* name) { if (!name || !name[0]) return false; for (size_t i = 0; i < sizeof(device_name_patterns)/sizeof(device_name_patterns[0]); i++) { @@ -845,7 +925,7 @@ h4{color:#ec4899;font-size:14px;margin-bottom:8px}