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+ }
2243Wardriving::Wardriving (bool scanWiFi, bool scanBLE) {
2344 this ->scanWiFi = scanWiFi;
2445 this ->scanBLE = scanBLE;
@@ -138,15 +159,16 @@ void Wardriving::set_position() {
138159void 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
152174void Wardriving::dump_gps_data () {
@@ -177,28 +199,36 @@ String Wardriving::auth_mode_to_string(wifi_auth_mode_t authMode) {
177199}
178200
179201void 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+
186216int 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
200230int 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}
0 commit comments