Skip to content

Commit e27f677

Browse files
committed
wardrive crashing fix
1 parent 7bb8dce commit e27f677

2 files changed

Lines changed: 69 additions & 22 deletions

File tree

src/modules/gps/wardriving.cpp

Lines changed: 64 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,33 @@
1313
#include "core/wifi/wifi_common.h"
1414
#include "current_year.h"
1515
#include "modules/ble/ble_common.h"
16+
#include <cctype>
1617

1718
#define MAX_WAIT 5000
1819

1920
#if __has_include(<NimBLEExtAdvertising.h>)
2021
#define NIMBLE_V2_PLUS 1
2122
#endif
23+
24+
static bool parseMacToU64(const String &mac, uint64_t &out) {
25+
uint64_t value = 0;
26+
int nibbles = 0;
27+
for (size_t i = 0; i < mac.length(); i++) {
28+
char c = mac[i];
29+
if (c == ':' || c == '-') continue;
30+
if (!isxdigit(static_cast<unsigned char>(c))) return false;
31+
value <<= 4;
32+
if (c >= '0' && c <= '9') value |= static_cast<uint64_t>(c - '0');
33+
else if (c >= 'a' && c <= 'f') value |= static_cast<uint64_t>(c - 'a' + 10);
34+
else if (c >= 'A' && c <= 'F') value |= static_cast<uint64_t>(c - 'A' + 10);
35+
else return false;
36+
nibbles++;
37+
if (nibbles > 12) return false;
38+
}
39+
if (nibbles != 12) return false;
40+
out = value;
41+
return true;
42+
}
2243
Wardriving::Wardriving(bool scanWiFi, bool scanBLE) {
2344
this->scanWiFi = scanWiFi;
2445
this->scanBLE = scanBLE;
@@ -138,15 +159,16 @@ void Wardriving::set_position() {
138159
void Wardriving::display_banner() {
139160
drawMainBorderWithTitle("Wardriving");
140161

141-
tft.println("");
142-
if (filename != "") tft.println("File: " + filename.substring(0, filename.length() - 4));
143-
tft.print("Found");
144-
if (scanWiFi) tft.print(" WiFi: " + String(wifiNetworkCount));
145-
if (scanBLE) tft.print(" BLE: " + String(bluetoothDeviceCount));
146-
if (foundMACAddressCount) tft.print(" Alert: " + String(foundMACAddressCount));
162+
padprintln("");
163+
if (filename != "") padprintln("File: " + filename.substring(0, filename.length() - 4));
164+
String txt = "Found";
165+
if (scanWiFi) txt += " WiFi: " + String(wifiNetworkCount);
166+
if (scanBLE) txt += " BLE: " + String(bluetoothDeviceCount);
167+
padprint(txt);
168+
if (foundMACAddressCount) padprint(" Alert: " + String(foundMACAddressCount));
147169

148-
tft.println("");
149-
tft.printf("Distance: %.2fkm\n", distance / 1000);
170+
padprintln("");
171+
padprintf("Distance: %.2fkm\n", distance / 1000);
150172
}
151173

152174
void Wardriving::dump_gps_data() {
@@ -177,28 +199,36 @@ String Wardriving::auth_mode_to_string(wifi_auth_mode_t authMode) {
177199
}
178200

179201
void Wardriving::scanWiFiBLE() {
180-
padprintf(2, "Coord: %.6f, %.6f\n", gps.location.lat(), gps.location.lng());
202+
padprintf("Coord: %.6f, %.6f\n", gps.location.lat(), gps.location.lng());
181203
int networksFound = scanWiFi ? scanWiFiNetworks() : 0;
182204
int bleDevicesFound = scanBLE ? scanBLEDevices() : 0;
183205
append_to_file(networksFound, bleDevicesFound);
184206
}
185207

208+
void Wardriving::enforceRegisteredMACLimit() {
209+
if (registeredMACs.size() < MAX_REGISTERED_MACS) return;
210+
211+
registeredMACs.clear();
212+
macCacheClears++;
213+
padprintln("MAC cache cleared to prevent heap overflow");
214+
}
215+
186216
int Wardriving::scanWiFiNetworks() {
187-
tft.print("Scanning Wi-Fi...");
217+
padprint("Scanning Wi-Fi...");
188218
wifiConnected = true;
189219
int network_amount = WiFi.scanNetworks();
190220
if (network_amount == 0) {
191-
tft.print(" Found: None");
221+
padprint(" Found: None");
192222
return 0;
193223
}
194-
tft.print(" Found: " + String(network_amount));
195-
tft.println("");
224+
padprint(" Found: " + String(network_amount) + " Networks");
225+
padprintln("");
196226

197227
return network_amount;
198228
}
199229

200230
int Wardriving::scanBLEDevices() {
201-
tft.print("Scanning BLE...");
231+
padprint("Scanning BLE...");
202232
ble_scan_setup();
203233
BLEScanResults foundDevices;
204234

@@ -210,7 +240,7 @@ int Wardriving::scanBLEDevices() {
210240

211241
int count = foundDevices.getCount();
212242
if (count == 0) {
213-
tft.print(" Found None");
243+
padprint(" Found None");
214244
pBLEScan->clearResults();
215245
return 0;
216246
}
@@ -264,8 +294,8 @@ int Wardriving::scanBLEDevices() {
264294
}
265295

266296
pBLEScan->clearResults();
267-
tft.print(" Found: " + String(bleDevices.size()));
268-
tft.println("");
297+
padprint(" Found: " + String(bleDevices.size()) + " Devices ");
298+
padprintln("");
269299

270300
return bleDevices.size();
271301
}
@@ -361,11 +391,14 @@ void Wardriving::append_to_file(int network_amount, int bluetooth_amount) {
361391

362392
for (int i = 0; i < network_amount; i++) {
363393
String macAddress = WiFi.BSSIDstr(i);
394+
uint64_t macKey = 0;
395+
bool macKeyOk = parseMacToU64(macAddress, macKey);
364396

365397
// Check if MAC was already found in this session
366-
if (registeredMACs.find(macAddress) == registeredMACs.end()) {
398+
enforceRegisteredMACLimit();
399+
if (!macKeyOk || registeredMACs.find(macKey) == registeredMACs.end()) {
367400

368-
registeredMACs.insert(macAddress); // Adds MAC to file
401+
if (macKeyOk) registeredMACs.insert(macKey); // Adds MAC to cache
369402
int32_t channel = WiFi.channel(i);
370403

371404
char buffer[512];
@@ -397,14 +430,19 @@ void Wardriving::append_to_file(int network_amount, int bluetooth_amount) {
397430

398431
wifiNetworkCount++;
399432
}
433+
434+
if ((i & 0x1F) == 0) vTaskDelay(1);
400435
}
436+
// Free scan results from heap as soon as we finish consuming them
437+
WiFi.scanDelete();
401438

402439
// Bluetooth Rows
403440
// [BD_ADDR],[Device Name],[Capabilities],[First timestamp seen],[Channel],[Frequency],
404441
// [RSSI],[Latitude],[Longitude],[Altitude],[Accuracy],[RCOIs],[MfgrId],[Type]
405442
// Example: 63:56:ac:c4:d4:30,,Misc [LE],2018-08-03 18:14:12,0,,
406443
// -67,37.76090571,-122.44877987,104,49.3120002746582,,72,BLE
407444

445+
int deviceIndex = 0;
408446
for (const auto &device : bleDevices) {
409447
Serial.printf(
410448
"Processing BLE device: %s, Name: %s, RSSI: %d\n",
@@ -414,8 +452,11 @@ void Wardriving::append_to_file(int network_amount, int bluetooth_amount) {
414452
);
415453

416454
// Check if MAC was already found in this session
417-
if (registeredMACs.find(device.address) == registeredMACs.end()) {
418-
registeredMACs.insert(device.address); // Adds MAC to file
455+
enforceRegisteredMACLimit();
456+
uint64_t macKey = 0;
457+
bool macKeyOk = parseMacToU64(device.address, macKey);
458+
if (!macKeyOk || registeredMACs.find(macKey) == registeredMACs.end()) {
459+
if (macKeyOk) registeredMACs.insert(macKey); // Adds MAC to cache
419460

420461
char buffer[512];
421462
char manufacturerIdStr[8] = "";
@@ -448,6 +489,8 @@ void Wardriving::append_to_file(int network_amount, int bluetooth_amount) {
448489

449490
bluetoothDeviceCount++;
450491
}
492+
493+
if ((deviceIndex++ & 0x1F) == 0) vTaskDelay(1);
451494
}
452495
file.close();
453496
}

src/modules/gps/wardriving.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include "modules/ble/ble_common.h"
1313
#include <TinyGPS++.h>
14+
#include <cstdint>
1415
#include <esp_wifi_types.h>
1516
#include <globals.h>
1617
#include <set>
@@ -39,13 +40,15 @@ class Wardriving {
3940
String filename = "";
4041
TinyGPSPlus gps;
4142
HardwareSerial GPSserial = HardwareSerial(2); // Uses UART2 for GPS
42-
std::set<String> registeredMACs; // Store and track registered MAC
43+
std::set<uint64_t> registeredMACs; // Store and track registered MAC (packed 48-bit)
4344
std::set<String> alertMACs; // Store alert MAC addresses from file
4445
bool scanWiFi = false; // Flag to scan WiFi networks
4546
bool scanBLE = false; // Flag to scan Bluetooth devices
4647
int wifiNetworkCount = 0; // Counter fo wifi networks
4748
int bluetoothDeviceCount = 0; // Counter for bluetooth devices
4849
int foundMACAddressCount = 0; // Counter for found MAC addresses
50+
uint32_t macCacheClears = 0; // Number of times MAC cache was cleared
51+
static constexpr size_t MAX_REGISTERED_MACS = 250;
4952

5053
// Structure to safely store BLE device data
5154
struct BLEDeviceData {
@@ -79,6 +82,7 @@ class Wardriving {
7982
void scanWiFiBLE(void);
8083
int scanWiFiNetworks(void);
8184
int scanBLEDevices(void);
85+
void enforceRegisteredMACLimit(void);
8286
void loadAlertMACs(void);
8387
void checkForAlert(const String &macAddress, const String &deviceType, const String &deviceName = "");
8488
String auth_mode_to_string(wifi_auth_mode_t authMode);

0 commit comments

Comments
 (0)